[RFC][PATCH 1/7] efivars: Keep a private global pointer to efivars

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux