Skip to content

Commit 232f4eb

Browse files
committed
efi: pstore: disentangle from deprecated efivars module
The EFI pstore implementation relies on the 'efivars' abstraction, which encapsulates the EFI variable store in a way that can be overridden by other backing stores, like the Google SMI one. On top of that, the EFI pstore implementation also relies on the efivars.ko module, which is a separate layer built on top of the 'efivars' abstraction that exposes the [deprecated] sysfs entries for each variable that exists in the backing store. Since the efivars.ko module is deprecated, and all users appear to have moved to the efivarfs file system instead, let's prepare for its removal, by removing EFI pstore's dependency on it. Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
1 parent b89114c commit 232f4eb

4 files changed

Lines changed: 74 additions & 49 deletions

File tree

drivers/firmware/efi/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ config EFI_ESRT
2626

2727
config EFI_VARS_PSTORE
2828
tristate "Register efivars backend for pstore"
29-
depends on EFI_VARS && PSTORE
29+
depends on PSTORE
3030
default y
3131
help
3232
Say Y here to enable use efivars as a backend to pstore. This

drivers/firmware/efi/efi-pstore.c

Lines changed: 72 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
#define DUMP_NAME_LEN 66
1010

11+
#define EFIVARS_DATA_SIZE_MAX 1024
12+
1113
static bool efivars_pstore_disable =
1214
IS_ENABLED(CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE);
1315

@@ -18,6 +20,8 @@ module_param_named(pstore_disable, efivars_pstore_disable, bool, 0644);
1820
EFI_VARIABLE_BOOTSERVICE_ACCESS | \
1921
EFI_VARIABLE_RUNTIME_ACCESS)
2022

23+
static LIST_HEAD(efi_pstore_list);
24+
2125
static int efi_pstore_open(struct pstore_info *psi)
2226
{
2327
psi->data = NULL;
@@ -126,7 +130,7 @@ static inline int __efi_pstore_scan_sysfs_exit(struct efivar_entry *entry,
126130
if (entry->deleting) {
127131
list_del(&entry->list);
128132
efivar_entry_iter_end();
129-
efivar_unregister(entry);
133+
kfree(entry);
130134
if (efivar_entry_iter_begin())
131135
return -EINTR;
132136
} else if (turn_off_scanning)
@@ -169,7 +173,7 @@ static int efi_pstore_sysfs_entry_iter(struct pstore_record *record)
169173
{
170174
struct efivar_entry **pos = (struct efivar_entry **)&record->psi->data;
171175
struct efivar_entry *entry, *n;
172-
struct list_head *head = &efivar_sysfs_list;
176+
struct list_head *head = &efi_pstore_list;
173177
int size = 0;
174178
int ret;
175179

@@ -314,12 +318,12 @@ static int efi_pstore_erase_name(const char *name)
314318
if (efivar_entry_iter_begin())
315319
return -EINTR;
316320

317-
found = __efivar_entry_iter(efi_pstore_erase_func, &efivar_sysfs_list,
321+
found = __efivar_entry_iter(efi_pstore_erase_func, &efi_pstore_list,
318322
efi_name, &entry);
319323
efivar_entry_iter_end();
320324

321325
if (found && !entry->scanning)
322-
efivar_unregister(entry);
326+
kfree(entry);
323327

324328
return found ? 0 : -ENOENT;
325329
}
@@ -354,14 +358,76 @@ static struct pstore_info efi_pstore_info = {
354358
.erase = efi_pstore_erase,
355359
};
356360

361+
static int efi_pstore_callback(efi_char16_t *name, efi_guid_t vendor,
362+
unsigned long name_size, void *data)
363+
{
364+
struct efivar_entry *entry;
365+
int ret;
366+
367+
entry = kzalloc(sizeof(*entry), GFP_KERNEL);
368+
if (!entry)
369+
return -ENOMEM;
370+
371+
memcpy(entry->var.VariableName, name, name_size);
372+
entry->var.VendorGuid = vendor;
373+
374+
ret = efivar_entry_add(entry, &efi_pstore_list);
375+
if (ret)
376+
kfree(entry);
377+
378+
return ret;
379+
}
380+
381+
static int efi_pstore_update_entry(efi_char16_t *name, efi_guid_t vendor,
382+
unsigned long name_size, void *data)
383+
{
384+
struct efivar_entry *entry = data;
385+
386+
if (efivar_entry_find(name, vendor, &efi_pstore_list, false))
387+
return 0;
388+
389+
memcpy(entry->var.VariableName, name, name_size);
390+
memcpy(&(entry->var.VendorGuid), &vendor, sizeof(efi_guid_t));
391+
392+
return 1;
393+
}
394+
395+
static void efi_pstore_update_entries(struct work_struct *work)
396+
{
397+
struct efivar_entry *entry;
398+
int err;
399+
400+
/* Add new sysfs entries */
401+
while (1) {
402+
entry = kzalloc(sizeof(*entry), GFP_KERNEL);
403+
if (!entry)
404+
return;
405+
406+
err = efivar_init(efi_pstore_update_entry, entry,
407+
false, &efi_pstore_list);
408+
if (!err)
409+
break;
410+
411+
efivar_entry_add(entry, &efi_pstore_list);
412+
}
413+
414+
kfree(entry);
415+
}
416+
357417
static __init int efivars_pstore_init(void)
358418
{
419+
int ret;
420+
359421
if (!efivars_kobject() || !efivar_supports_writes())
360422
return 0;
361423

362424
if (efivars_pstore_disable)
363425
return 0;
364426

427+
ret = efivar_init(efi_pstore_callback, NULL, true, &efi_pstore_list);
428+
if (ret)
429+
return ret;
430+
365431
efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL);
366432
if (!efi_pstore_info.buf)
367433
return -ENOMEM;
@@ -374,6 +440,8 @@ static __init int efivars_pstore_init(void)
374440
efi_pstore_info.bufsize = 0;
375441
}
376442

443+
INIT_WORK(&efivar_work, efi_pstore_update_entries);
444+
377445
return 0;
378446
}
379447

drivers/firmware/efi/efivars.c

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ MODULE_LICENSE("GPL");
2424
MODULE_VERSION(EFIVARS_VERSION);
2525
MODULE_ALIAS("platform:efivars");
2626

27-
LIST_HEAD(efivar_sysfs_list);
28-
EXPORT_SYMBOL_GPL(efivar_sysfs_list);
27+
static LIST_HEAD(efivar_sysfs_list);
2928

3029
static struct kset *efivars_kset;
3130

@@ -591,42 +590,6 @@ create_efivars_bin_attributes(void)
591590
return error;
592591
}
593592

594-
static int efivar_update_sysfs_entry(efi_char16_t *name, efi_guid_t vendor,
595-
unsigned long name_size, void *data)
596-
{
597-
struct efivar_entry *entry = data;
598-
599-
if (efivar_entry_find(name, vendor, &efivar_sysfs_list, false))
600-
return 0;
601-
602-
memcpy(entry->var.VariableName, name, name_size);
603-
memcpy(&(entry->var.VendorGuid), &vendor, sizeof(efi_guid_t));
604-
605-
return 1;
606-
}
607-
608-
static void efivar_update_sysfs_entries(struct work_struct *work)
609-
{
610-
struct efivar_entry *entry;
611-
int err;
612-
613-
/* Add new sysfs entries */
614-
while (1) {
615-
entry = kzalloc(sizeof(*entry), GFP_KERNEL);
616-
if (!entry)
617-
return;
618-
619-
err = efivar_init(efivar_update_sysfs_entry, entry,
620-
false, &efivar_sysfs_list);
621-
if (!err)
622-
break;
623-
624-
efivar_create_sysfs_entry(entry);
625-
}
626-
627-
kfree(entry);
628-
}
629-
630593
static int efivars_sysfs_callback(efi_char16_t *name, efi_guid_t vendor,
631594
unsigned long name_size, void *data)
632595
{
@@ -701,8 +664,6 @@ int efivars_sysfs_init(void)
701664
return error;
702665
}
703666

704-
INIT_WORK(&efivar_work, efivar_update_sysfs_entries);
705-
706667
return 0;
707668
}
708669
EXPORT_SYMBOL_GPL(efivars_sysfs_init);

include/linux/efi.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -986,8 +986,6 @@ struct efivar_entry {
986986
bool deleting;
987987
};
988988

989-
extern struct list_head efivar_sysfs_list;
990-
991989
static inline void
992990
efivar_unregister(struct efivar_entry *var)
993991
{
@@ -1045,8 +1043,6 @@ void efivar_run_worker(void);
10451043
#if defined(CONFIG_EFI_VARS) || defined(CONFIG_EFI_VARS_MODULE)
10461044
int efivars_sysfs_init(void);
10471045

1048-
#define EFIVARS_DATA_SIZE_MAX 1024
1049-
10501046
#endif /* CONFIG_EFI_VARS */
10511047
extern bool efi_capsule_pending(int *reset_type);
10521048

0 commit comments

Comments
 (0)