forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-02-20 ea08eeccae9297f7aabd2ef7f0c2517ac4549acc
kernel/drivers/firmware/efi/efi-pstore.c
....@@ -1,3 +1,5 @@
1
+// SPDX-License-Identifier: GPL-2.0+
2
+
13 #include <linux/efi.h>
24 #include <linux/module.h>
35 #include <linux/pstore.h>
....@@ -5,6 +7,8 @@
57 #include <linux/ucs2_string.h>
68
79 #define DUMP_NAME_LEN 66
10
+
11
+#define EFIVARS_DATA_SIZE_MAX 1024
812
913 static bool efivars_pstore_disable =
1014 IS_ENABLED(CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE);
....@@ -15,6 +19,9 @@
1519 (EFI_VARIABLE_NON_VOLATILE | \
1620 EFI_VARIABLE_BOOTSERVICE_ACCESS | \
1721 EFI_VARIABLE_RUNTIME_ACCESS)
22
+
23
+static LIST_HEAD(efi_pstore_list);
24
+static DECLARE_WORK(efivar_work, NULL);
1825
1926 static int efi_pstore_open(struct pstore_info *psi)
2027 {
....@@ -124,7 +131,7 @@
124131 if (entry->deleting) {
125132 list_del(&entry->list);
126133 efivar_entry_iter_end();
127
- efivar_unregister(entry);
134
+ kfree(entry);
128135 if (efivar_entry_iter_begin())
129136 return -EINTR;
130137 } else if (turn_off_scanning)
....@@ -159,7 +166,7 @@
159166 *
160167 * @record: pstore record to pass to callback
161168 *
162
- * You MUST call efivar_enter_iter_begin() before this function, and
169
+ * You MUST call efivar_entry_iter_begin() before this function, and
163170 * efivar_entry_iter_end() afterwards.
164171 *
165172 */
....@@ -167,7 +174,7 @@
167174 {
168175 struct efivar_entry **pos = (struct efivar_entry **)&record->psi->data;
169176 struct efivar_entry *entry, *n;
170
- struct list_head *head = &efivar_sysfs_list;
177
+ struct list_head *head = &efi_pstore_list;
171178 int size = 0;
172179 int ret;
173180
....@@ -261,8 +268,9 @@
261268 ret = efivar_entry_set_safe(efi_name, vendor, PSTORE_EFI_ATTRIBUTES,
262269 preemptible(), record->size, record->psi->buf);
263270
264
- if (record->reason == KMSG_DUMP_OOPS)
265
- efivar_run_worker();
271
+ if (record->reason == KMSG_DUMP_OOPS && try_module_get(THIS_MODULE))
272
+ if (!schedule_work(&efivar_work))
273
+ module_put(THIS_MODULE);
266274
267275 return ret;
268276 };
....@@ -312,12 +320,12 @@
312320 if (efivar_entry_iter_begin())
313321 return -EINTR;
314322
315
- found = __efivar_entry_iter(efi_pstore_erase_func, &efivar_sysfs_list,
323
+ found = __efivar_entry_iter(efi_pstore_erase_func, &efi_pstore_list,
316324 efi_name, &entry);
317325 efivar_entry_iter_end();
318326
319327 if (found && !entry->scanning)
320
- efivar_unregister(entry);
328
+ kfree(entry);
321329
322330 return found ? 0 : -ENOENT;
323331 }
....@@ -352,16 +360,76 @@
352360 .erase = efi_pstore_erase,
353361 };
354362
355
-static __init int efivars_pstore_init(void)
363
+static int efi_pstore_callback(efi_char16_t *name, efi_guid_t vendor,
364
+ unsigned long name_size, void *data)
356365 {
357
- if (!efi_enabled(EFI_RUNTIME_SERVICES))
366
+ struct efivar_entry *entry;
367
+ int ret;
368
+
369
+ entry = kzalloc(sizeof(*entry), GFP_KERNEL);
370
+ if (!entry)
371
+ return -ENOMEM;
372
+
373
+ memcpy(entry->var.VariableName, name, name_size);
374
+ entry->var.VendorGuid = vendor;
375
+
376
+ ret = efivar_entry_add(entry, &efi_pstore_list);
377
+ if (ret)
378
+ kfree(entry);
379
+
380
+ return ret;
381
+}
382
+
383
+static int efi_pstore_update_entry(efi_char16_t *name, efi_guid_t vendor,
384
+ unsigned long name_size, void *data)
385
+{
386
+ struct efivar_entry *entry = data;
387
+
388
+ if (efivar_entry_find(name, vendor, &efi_pstore_list, false))
358389 return 0;
359390
360
- if (!efivars_kobject())
391
+ memcpy(entry->var.VariableName, name, name_size);
392
+ memcpy(&(entry->var.VendorGuid), &vendor, sizeof(efi_guid_t));
393
+
394
+ return 1;
395
+}
396
+
397
+static void efi_pstore_update_entries(struct work_struct *work)
398
+{
399
+ struct efivar_entry *entry;
400
+ int err;
401
+
402
+ /* Add new sysfs entries */
403
+ while (1) {
404
+ entry = kzalloc(sizeof(*entry), GFP_KERNEL);
405
+ if (!entry)
406
+ return;
407
+
408
+ err = efivar_init(efi_pstore_update_entry, entry,
409
+ false, &efi_pstore_list);
410
+ if (!err)
411
+ break;
412
+
413
+ efivar_entry_add(entry, &efi_pstore_list);
414
+ }
415
+
416
+ kfree(entry);
417
+ module_put(THIS_MODULE);
418
+}
419
+
420
+static __init int efivars_pstore_init(void)
421
+{
422
+ int ret;
423
+
424
+ if (!efivars_kobject() || !efivar_supports_writes())
361425 return 0;
362426
363427 if (efivars_pstore_disable)
364428 return 0;
429
+
430
+ ret = efivar_init(efi_pstore_callback, NULL, true, &efi_pstore_list);
431
+ if (ret)
432
+ return ret;
365433
366434 efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL);
367435 if (!efi_pstore_info.buf)
....@@ -375,6 +443,8 @@
375443 efi_pstore_info.bufsize = 0;
376444 }
377445
446
+ INIT_WORK(&efivar_work, efi_pstore_update_entries);
447
+
378448 return 0;
379449 }
380450