From: Matt Fleming <[email protected]>

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 <[email protected]>
Signed-off-by: Matt Fleming <[email protected]>
---
 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 [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to