From: Matt Fleming <matt.fleming@xxxxxxxxx> This may seem like a step backwards in terms of modularity, but we don't need to track more than one 'struct efivars' at one time. There is no synchronisation done between multiple EFI variable operations, and according to Mike no one is using both the generic EFI var ops and CONFIG_GOOGLE_SMI. Make this explicit by returning -EBUSY if someone has already called register_efivars(). Cc: Mike Waychison <mikew@xxxxxxxxxx> Signed-off-by: Matt Fleming <matt.fleming@xxxxxxxxx> --- drivers/firmware/efivars.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index 5eafa22..24585c3 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -132,8 +132,11 @@ struct efivar_attribute { ssize_t (*store)(struct efivar_entry *entry, const char *buf, size_t count); }; -static struct efivars __efivars; -static struct efivar_operations ops; +static struct efivars generic_efivars; +static struct efivar_operations generic_ops; + +/* Private pointer to registered efivars */ +static struct efivars *__efivars; #define PSTORE_EFI_ATTRIBUTES \ (EFI_VARIABLE_NON_VOLATILE | \ @@ -974,7 +977,7 @@ static int efivarfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool excl) { struct inode *inode; - struct efivars *efivars = &__efivars; + struct efivars *efivars = __efivars; struct efivar_entry *var; int namelen, i = 0, err = 0; @@ -1140,7 +1143,7 @@ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent) struct inode *inode = NULL; struct dentry *root; struct efivar_entry *entry, *n; - struct efivars *efivars = &__efivars; + struct efivars *efivars = __efivars; char *name; efivarfs_sb = sb; @@ -1835,6 +1838,12 @@ int register_efivars(struct efivars *efivars, unsigned long variable_name_size = 1024; int error = 0; + if (__efivars) { + return -EBUSY; + } + + __efivars = efivars; + variable_name = kzalloc(variable_name_size, GFP_KERNEL); if (!variable_name) { printk(KERN_ERR "efivars: Memory allocation failed.\n"); @@ -1937,12 +1946,12 @@ efivars_init(void) return -ENOMEM; } - ops.get_variable = efi.get_variable; - ops.set_variable = efi.set_variable; - ops.get_next_variable = efi.get_next_variable; - ops.query_variable_info = efi.query_variable_info; + generic_ops.get_variable = efi.get_variable; + generic_ops.set_variable = efi.set_variable; + generic_ops.get_next_variable = efi.get_next_variable; + generic_ops.query_variable_info = efi.query_variable_info; - error = register_efivars(&__efivars, &ops, efi_kobj); + error = register_efivars(&generic_efivars, &generic_ops, efi_kobj); if (error) goto err_put; @@ -1958,7 +1967,7 @@ efivars_init(void) return 0; err_unregister: - unregister_efivars(&__efivars); + unregister_efivars(&generic_efivars); err_put: kobject_put(efi_kobj); return error; @@ -1968,7 +1977,7 @@ static void __exit efivars_exit(void) { if (efi_enabled(EFI_RUNTIME_SERVICES)) { - unregister_efivars(&__efivars); + unregister_efivars(&generic_efivars); kobject_put(efi_kobj); } } -- 1.7.11.7 -- To unsubscribe from this list: send the line "unsubscribe linux-efi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html