1 #include <linux/efi.h> 2 #include <linux/module.h> 3 #include <linux/pstore.h> 4 #include <linux/slab.h> 5 #include <linux/ucs2_string.h> 6 7 #define DUMP_NAME_LEN 52 8 9 static bool efivars_pstore_disable = 10 IS_ENABLED(CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE); 11 12 module_param_named(pstore_disable, efivars_pstore_disable, bool, 0644); 13 14 #define PSTORE_EFI_ATTRIBUTES \ 15 (EFI_VARIABLE_NON_VOLATILE | \ 16 EFI_VARIABLE_BOOTSERVICE_ACCESS | \ 17 EFI_VARIABLE_RUNTIME_ACCESS) 18 19 static int efi_pstore_open(struct pstore_info *psi) 20 { 21 psi->data = NULL; 22 return 0; 23 } 24 25 static int efi_pstore_close(struct pstore_info *psi) 26 { 27 psi->data = NULL; 28 return 0; 29 } 30 31 struct pstore_read_data { 32 u64 *id; 33 enum pstore_type_id *type; 34 int *count; 35 struct timespec *timespec; 36 bool *compressed; 37 char **buf; 38 }; 39 40 static inline u64 generic_id(unsigned long timestamp, 41 unsigned int part, int count) 42 { 43 return (timestamp * 100 + part) * 1000 + count; 44 } 45 46 static int efi_pstore_read_func(struct efivar_entry *entry, void *data) 47 { 48 efi_guid_t vendor = LINUX_EFI_CRASH_GUID; 49 struct pstore_read_data *cb_data = data; 50 char name[DUMP_NAME_LEN], data_type; 51 int i; 52 int cnt; 53 unsigned int part; 54 unsigned long time, size; 55 56 if (efi_guidcmp(entry->var.VendorGuid, vendor)) 57 return 0; 58 59 for (i = 0; i < DUMP_NAME_LEN; i++) 60 name[i] = entry->var.VariableName[i]; 61 62 if (sscanf(name, "dump-type%u-%u-%d-%lu-%c", 63 cb_data->type, &part, &cnt, &time, &data_type) == 5) { 64 *cb_data->id = generic_id(time, part, cnt); 65 *cb_data->count = cnt; 66 cb_data->timespec->tv_sec = time; 67 cb_data->timespec->tv_nsec = 0; 68 if (data_type == 'C') 69 *cb_data->compressed = true; 70 else 71 *cb_data->compressed = false; 72 } else if (sscanf(name, "dump-type%u-%u-%d-%lu", 73 cb_data->type, &part, &cnt, &time) == 4) { 74 *cb_data->id = generic_id(time, part, cnt); 75 *cb_data->count = cnt; 76 cb_data->timespec->tv_sec = time; 77 cb_data->timespec->tv_nsec = 0; 78 *cb_data->compressed = false; 79 } else if (sscanf(name, "dump-type%u-%u-%lu", 80 cb_data->type, &part, &time) == 3) { 81 /* 82 * Check if an old format, 83 * which doesn't support holding 84 * multiple logs, remains. 85 */ 86 *cb_data->id = generic_id(time, part, 0); 87 *cb_data->count = 0; 88 cb_data->timespec->tv_sec = time; 89 cb_data->timespec->tv_nsec = 0; 90 *cb_data->compressed = false; 91 } else 92 return 0; 93 94 entry->var.DataSize = 1024; 95 __efivar_entry_get(entry, &entry->var.Attributes, 96 &entry->var.DataSize, entry->var.Data); 97 size = entry->var.DataSize; 98 memcpy(*cb_data->buf, entry->var.Data, 99 (size_t)min_t(unsigned long, EFIVARS_DATA_SIZE_MAX, size)); 100 101 return size; 102 } 103 104 /** 105 * efi_pstore_scan_sysfs_enter 106 * @entry: scanning entry 107 * @next: next entry 108 * @head: list head 109 */ 110 static void efi_pstore_scan_sysfs_enter(struct efivar_entry *pos, 111 struct efivar_entry *next, 112 struct list_head *head) 113 { 114 pos->scanning = true; 115 if (&next->list != head) 116 next->scanning = true; 117 } 118 119 /** 120 * __efi_pstore_scan_sysfs_exit 121 * @entry: deleting entry 122 * @turn_off_scanning: Check if a scanning flag should be turned off 123 */ 124 static inline void __efi_pstore_scan_sysfs_exit(struct efivar_entry *entry, 125 bool turn_off_scanning) 126 { 127 if (entry->deleting) { 128 list_del(&entry->list); 129 efivar_entry_iter_end(); 130 efivar_unregister(entry); 131 efivar_entry_iter_begin(); 132 } else if (turn_off_scanning) 133 entry->scanning = false; 134 } 135 136 /** 137 * efi_pstore_scan_sysfs_exit 138 * @pos: scanning entry 139 * @next: next entry 140 * @head: list head 141 * @stop: a flag checking if scanning will stop 142 */ 143 static void efi_pstore_scan_sysfs_exit(struct efivar_entry *pos, 144 struct efivar_entry *next, 145 struct list_head *head, bool stop) 146 { 147 __efi_pstore_scan_sysfs_exit(pos, true); 148 if (stop) 149 __efi_pstore_scan_sysfs_exit(next, &next->list != head); 150 } 151 152 /** 153 * efi_pstore_sysfs_entry_iter 154 * 155 * @data: function-specific data to pass to callback 156 * @pos: entry to begin iterating from 157 * 158 * You MUST call efivar_enter_iter_begin() before this function, and 159 * efivar_entry_iter_end() afterwards. 160 * 161 * It is possible to begin iteration from an arbitrary entry within 162 * the list by passing @pos. @pos is updated on return to point to 163 * the next entry of the last one passed to efi_pstore_read_func(). 164 * To begin iterating from the beginning of the list @pos must be %NULL. 165 */ 166 static int efi_pstore_sysfs_entry_iter(void *data, struct efivar_entry **pos) 167 { 168 struct efivar_entry *entry, *n; 169 struct list_head *head = &efivar_sysfs_list; 170 int size = 0; 171 172 if (!*pos) { 173 list_for_each_entry_safe(entry, n, head, list) { 174 efi_pstore_scan_sysfs_enter(entry, n, head); 175 176 size = efi_pstore_read_func(entry, data); 177 efi_pstore_scan_sysfs_exit(entry, n, head, size < 0); 178 if (size) 179 break; 180 } 181 *pos = n; 182 return size; 183 } 184 185 list_for_each_entry_safe_from((*pos), n, head, list) { 186 efi_pstore_scan_sysfs_enter((*pos), n, head); 187 188 size = efi_pstore_read_func((*pos), data); 189 efi_pstore_scan_sysfs_exit((*pos), n, head, size < 0); 190 if (size) 191 break; 192 } 193 *pos = n; 194 return size; 195 } 196 197 /** 198 * efi_pstore_read 199 * 200 * This function returns a size of NVRAM entry logged via efi_pstore_write(). 201 * The meaning and behavior of efi_pstore/pstore are as below. 202 * 203 * size > 0: Got data of an entry logged via efi_pstore_write() successfully, 204 * and pstore filesystem will continue reading subsequent entries. 205 * size == 0: Entry was not logged via efi_pstore_write(), 206 * and efi_pstore driver will continue reading subsequent entries. 207 * size < 0: Failed to get data of entry logging via efi_pstore_write(), 208 * and pstore will stop reading entry. 209 */ 210 static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, 211 int *count, struct timespec *timespec, 212 char **buf, bool *compressed, 213 struct pstore_info *psi) 214 { 215 struct pstore_read_data data; 216 ssize_t size; 217 218 data.id = id; 219 data.type = type; 220 data.count = count; 221 data.timespec = timespec; 222 data.compressed = compressed; 223 data.buf = buf; 224 225 *data.buf = kzalloc(EFIVARS_DATA_SIZE_MAX, GFP_KERNEL); 226 if (!*data.buf) 227 return -ENOMEM; 228 229 efivar_entry_iter_begin(); 230 size = efi_pstore_sysfs_entry_iter(&data, 231 (struct efivar_entry **)&psi->data); 232 efivar_entry_iter_end(); 233 if (size <= 0) 234 kfree(*data.buf); 235 return size; 236 } 237 238 static int efi_pstore_write(enum pstore_type_id type, 239 enum kmsg_dump_reason reason, u64 *id, 240 unsigned int part, int count, bool compressed, size_t size, 241 struct pstore_info *psi) 242 { 243 char name[DUMP_NAME_LEN]; 244 efi_char16_t efi_name[DUMP_NAME_LEN]; 245 efi_guid_t vendor = LINUX_EFI_CRASH_GUID; 246 int i, ret = 0; 247 248 sprintf(name, "dump-type%u-%u-%d-%lu-%c", type, part, count, 249 get_seconds(), compressed ? 'C' : 'D'); 250 251 for (i = 0; i < DUMP_NAME_LEN; i++) 252 efi_name[i] = name[i]; 253 254 efivar_entry_set_safe(efi_name, vendor, PSTORE_EFI_ATTRIBUTES, 255 !pstore_cannot_block_path(reason), 256 size, psi->buf); 257 258 if (reason == KMSG_DUMP_OOPS) 259 efivar_run_worker(); 260 261 *id = part; 262 return ret; 263 }; 264 265 struct pstore_erase_data { 266 u64 id; 267 enum pstore_type_id type; 268 int count; 269 struct timespec time; 270 efi_char16_t *name; 271 }; 272 273 /* 274 * Clean up an entry with the same name 275 */ 276 static int efi_pstore_erase_func(struct efivar_entry *entry, void *data) 277 { 278 struct pstore_erase_data *ed = data; 279 efi_guid_t vendor = LINUX_EFI_CRASH_GUID; 280 efi_char16_t efi_name_old[DUMP_NAME_LEN]; 281 efi_char16_t *efi_name = ed->name; 282 unsigned long ucs2_len = ucs2_strlen(ed->name); 283 char name_old[DUMP_NAME_LEN]; 284 int i; 285 286 if (efi_guidcmp(entry->var.VendorGuid, vendor)) 287 return 0; 288 289 if (ucs2_strncmp(entry->var.VariableName, 290 efi_name, (size_t)ucs2_len)) { 291 /* 292 * Check if an old format, which doesn't support 293 * holding multiple logs, remains. 294 */ 295 sprintf(name_old, "dump-type%u-%u-%lu", ed->type, 296 (unsigned int)ed->id, ed->time.tv_sec); 297 298 for (i = 0; i < DUMP_NAME_LEN; i++) 299 efi_name_old[i] = name_old[i]; 300 301 if (ucs2_strncmp(entry->var.VariableName, efi_name_old, 302 ucs2_strlen(efi_name_old))) 303 return 0; 304 } 305 306 if (entry->scanning) { 307 /* 308 * Skip deletion because this entry will be deleted 309 * after scanning is completed. 310 */ 311 entry->deleting = true; 312 } else 313 list_del(&entry->list); 314 315 /* found */ 316 __efivar_entry_delete(entry); 317 318 return 1; 319 } 320 321 static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count, 322 struct timespec time, struct pstore_info *psi) 323 { 324 struct pstore_erase_data edata; 325 struct efivar_entry *entry = NULL; 326 char name[DUMP_NAME_LEN]; 327 efi_char16_t efi_name[DUMP_NAME_LEN]; 328 int found, i; 329 unsigned int part; 330 331 do_div(id, 1000); 332 part = do_div(id, 100); 333 sprintf(name, "dump-type%u-%u-%d-%lu", type, part, count, time.tv_sec); 334 335 for (i = 0; i < DUMP_NAME_LEN; i++) 336 efi_name[i] = name[i]; 337 338 edata.id = part; 339 edata.type = type; 340 edata.count = count; 341 edata.time = time; 342 edata.name = efi_name; 343 344 efivar_entry_iter_begin(); 345 found = __efivar_entry_iter(efi_pstore_erase_func, &efivar_sysfs_list, &edata, &entry); 346 347 if (found && !entry->scanning) { 348 efivar_entry_iter_end(); 349 efivar_unregister(entry); 350 } else 351 efivar_entry_iter_end(); 352 353 return 0; 354 } 355 356 static struct pstore_info efi_pstore_info = { 357 .owner = THIS_MODULE, 358 .name = "efi", 359 .flags = PSTORE_FLAGS_FRAGILE, 360 .open = efi_pstore_open, 361 .close = efi_pstore_close, 362 .read = efi_pstore_read, 363 .write = efi_pstore_write, 364 .erase = efi_pstore_erase, 365 }; 366 367 static __init int efivars_pstore_init(void) 368 { 369 if (!efi_enabled(EFI_RUNTIME_SERVICES)) 370 return 0; 371 372 if (!efivars_kobject()) 373 return 0; 374 375 if (efivars_pstore_disable) 376 return 0; 377 378 efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL); 379 if (!efi_pstore_info.buf) 380 return -ENOMEM; 381 382 efi_pstore_info.bufsize = 1024; 383 spin_lock_init(&efi_pstore_info.buf_lock); 384 385 if (pstore_register(&efi_pstore_info)) { 386 kfree(efi_pstore_info.buf); 387 efi_pstore_info.buf = NULL; 388 efi_pstore_info.bufsize = 0; 389 } 390 391 return 0; 392 } 393 394 static __exit void efivars_pstore_exit(void) 395 { 396 } 397 398 module_init(efivars_pstore_init); 399 module_exit(efivars_pstore_exit); 400 401 MODULE_DESCRIPTION("EFI variable backend for pstore"); 402 MODULE_LICENSE("GPL"); 403