aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2013-02-02 10:22:24 -0500
committerMatt Fleming <matt.fleming@intel.com>2013-04-17 03:30:06 -0400
commit4423d779af2a8f1fbd01aeca5c56522efce7262f (patch)
tree7a3b39ccdd4022075324545b49237c86d36bfe1a /drivers/firmware
parentd5abc7c1050ab2b9556a4bf21626cd74e83cd086 (diff)
efivars: Keep a private global pointer to efivars
Some machines have an EFI variable interface that does not conform to the UEFI specification, e.g. CONFIG_GOOGLE_SMI. Add the necessary code so that it's only possible to use one implementation of EFI variable operations at runtime. This allows us to keep a single (file-scope) global pointer 'struct efivars', which simplifies access. This will hopefully dissuade developers from accessing the generic operations struct directly in the future, as was done in the efivarfs and pstore code, thereby allowing future code to work with both the generic efivar ops and the google SMI ops. 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 simultaneously, though a single kernel build _does_ need to able to support both. It also helps to clearly highlight which functions form the core of the efivars interface - those that require access to __efivars. Reviewed-by: Tom Gundersen <teg@jklm.no> Tested-by: Tom Gundersen <teg@jklm.no> Acked-by: Mike Waychison <mikew@google.com> Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/efivars.c80
1 files changed, 46 insertions, 34 deletions
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index 34c8783a2aa8..eab4ec41c523 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -125,7 +125,6 @@ struct efi_variable {
125} __attribute__((packed)); 125} __attribute__((packed));
126 126
127struct efivar_entry { 127struct efivar_entry {
128 struct efivars *efivars;
129 struct efi_variable var; 128 struct efi_variable var;
130 struct list_head list; 129 struct list_head list;
131 struct kobject kobj; 130 struct kobject kobj;
@@ -137,8 +136,8 @@ struct efivar_attribute {
137 ssize_t (*store)(struct efivar_entry *entry, const char *buf, size_t count); 136 ssize_t (*store)(struct efivar_entry *entry, const char *buf, size_t count);
138}; 137};
139 138
140static struct efivars __efivars; 139/* Private pointer to registered efivars */
141static struct efivar_operations ops; 140static struct efivars *__efivars;
142 141
143#define PSTORE_EFI_ATTRIBUTES \ 142#define PSTORE_EFI_ATTRIBUTES \
144 (EFI_VARIABLE_NON_VOLATILE | \ 143 (EFI_VARIABLE_NON_VOLATILE | \
@@ -479,7 +478,7 @@ efivar_attr_read(struct efivar_entry *entry, char *buf)
479 if (!entry || !buf) 478 if (!entry || !buf)
480 return -EINVAL; 479 return -EINVAL;
481 480
482 status = get_var_data(entry->efivars, var); 481 status = get_var_data(__efivars, var);
483 if (status != EFI_SUCCESS) 482 if (status != EFI_SUCCESS)
484 return -EIO; 483 return -EIO;
485 484
@@ -513,7 +512,7 @@ efivar_size_read(struct efivar_entry *entry, char *buf)
513 if (!entry || !buf) 512 if (!entry || !buf)
514 return -EINVAL; 513 return -EINVAL;
515 514
516 status = get_var_data(entry->efivars, var); 515 status = get_var_data(__efivars, var);
517 if (status != EFI_SUCCESS) 516 if (status != EFI_SUCCESS)
518 return -EIO; 517 return -EIO;
519 518
@@ -530,7 +529,7 @@ efivar_data_read(struct efivar_entry *entry, char *buf)
530 if (!entry || !buf) 529 if (!entry || !buf)
531 return -EINVAL; 530 return -EINVAL;
532 531
533 status = get_var_data(entry->efivars, var); 532 status = get_var_data(__efivars, var);
534 if (status != EFI_SUCCESS) 533 if (status != EFI_SUCCESS)
535 return -EIO; 534 return -EIO;
536 535
@@ -545,7 +544,7 @@ static ssize_t
545efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count) 544efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
546{ 545{
547 struct efi_variable *new_var, *var = &entry->var; 546 struct efi_variable *new_var, *var = &entry->var;
548 struct efivars *efivars = entry->efivars; 547 struct efivars *efivars = __efivars;
549 efi_status_t status = EFI_NOT_FOUND; 548 efi_status_t status = EFI_NOT_FOUND;
550 549
551 if (count != sizeof(struct efi_variable)) 550 if (count != sizeof(struct efi_variable))
@@ -606,7 +605,7 @@ efivar_show_raw(struct efivar_entry *entry, char *buf)
606 if (!entry || !buf) 605 if (!entry || !buf)
607 return 0; 606 return 0;
608 607
609 status = get_var_data(entry->efivars, var); 608 status = get_var_data(__efivars, var);
610 if (status != EFI_SUCCESS) 609 if (status != EFI_SUCCESS)
611 return -EIO; 610 return -EIO;
612 611
@@ -728,7 +727,7 @@ static ssize_t efivarfs_file_write(struct file *file,
728 const char __user *userbuf, size_t count, loff_t *ppos) 727 const char __user *userbuf, size_t count, loff_t *ppos)
729{ 728{
730 struct efivar_entry *var = file->private_data; 729 struct efivar_entry *var = file->private_data;
731 struct efivars *efivars; 730 struct efivars *efivars = __efivars;
732 efi_status_t status; 731 efi_status_t status;
733 void *data; 732 void *data;
734 u32 attributes; 733 u32 attributes;
@@ -746,8 +745,6 @@ static ssize_t efivarfs_file_write(struct file *file,
746 if (attributes & ~(EFI_VARIABLE_MASK)) 745 if (attributes & ~(EFI_VARIABLE_MASK))
747 return -EINVAL; 746 return -EINVAL;
748 747
749 efivars = var->efivars;
750
751 /* 748 /*
752 * Ensure that the user can't allocate arbitrarily large 749 * Ensure that the user can't allocate arbitrarily large
753 * amounts of memory. Pick a default size of 64K if 750 * amounts of memory. Pick a default size of 64K if
@@ -855,7 +852,7 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
855 size_t count, loff_t *ppos) 852 size_t count, loff_t *ppos)
856{ 853{
857 struct efivar_entry *var = file->private_data; 854 struct efivar_entry *var = file->private_data;
858 struct efivars *efivars = var->efivars; 855 struct efivars *efivars = __efivars;
859 efi_status_t status; 856 efi_status_t status;
860 unsigned long datasize = 0; 857 unsigned long datasize = 0;
861 u32 attributes; 858 u32 attributes;
@@ -1009,7 +1006,7 @@ static int efivarfs_create(struct inode *dir, struct dentry *dentry,
1009 umode_t mode, bool excl) 1006 umode_t mode, bool excl)
1010{ 1007{
1011 struct inode *inode; 1008 struct inode *inode;
1012 struct efivars *efivars = &__efivars; 1009 struct efivars *efivars = __efivars;
1013 struct efivar_entry *var; 1010 struct efivar_entry *var;
1014 int namelen, i = 0, err = 0; 1011 int namelen, i = 0, err = 0;
1015 1012
@@ -1038,7 +1035,6 @@ static int efivarfs_create(struct inode *dir, struct dentry *dentry,
1038 var->var.VariableName[i] = '\0'; 1035 var->var.VariableName[i] = '\0';
1039 1036
1040 inode->i_private = var; 1037 inode->i_private = var;
1041 var->efivars = efivars;
1042 var->kobj.kset = efivars->kset; 1038 var->kobj.kset = efivars->kset;
1043 1039
1044 err = kobject_init_and_add(&var->kobj, &efivar_ktype, NULL, "%s", 1040 err = kobject_init_and_add(&var->kobj, &efivar_ktype, NULL, "%s",
@@ -1063,7 +1059,7 @@ out:
1063static int efivarfs_unlink(struct inode *dir, struct dentry *dentry) 1059static int efivarfs_unlink(struct inode *dir, struct dentry *dentry)
1064{ 1060{
1065 struct efivar_entry *var = dentry->d_inode->i_private; 1061 struct efivar_entry *var = dentry->d_inode->i_private;
1066 struct efivars *efivars = var->efivars; 1062 struct efivars *efivars = __efivars;
1067 efi_status_t status; 1063 efi_status_t status;
1068 1064
1069 spin_lock_irq(&efivars->lock); 1065 spin_lock_irq(&efivars->lock);
@@ -1175,7 +1171,7 @@ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
1175 struct inode *inode = NULL; 1171 struct inode *inode = NULL;
1176 struct dentry *root; 1172 struct dentry *root;
1177 struct efivar_entry *entry, *n; 1173 struct efivar_entry *entry, *n;
1178 struct efivars *efivars = &__efivars; 1174 struct efivars *efivars = __efivars;
1179 char *name; 1175 char *name;
1180 int err = -ENOMEM; 1176 int err = -ENOMEM;
1181 1177
@@ -1302,7 +1298,7 @@ static const struct inode_operations efivarfs_dir_inode_operations = {
1302 1298
1303static int efi_pstore_open(struct pstore_info *psi) 1299static int efi_pstore_open(struct pstore_info *psi)
1304{ 1300{
1305 struct efivars *efivars = psi->data; 1301 struct efivars *efivars = __efivars;
1306 1302
1307 spin_lock_irq(&efivars->lock); 1303 spin_lock_irq(&efivars->lock);
1308 efivars->walk_entry = list_first_entry(&efivars->list, 1304 efivars->walk_entry = list_first_entry(&efivars->list,
@@ -1312,7 +1308,7 @@ static int efi_pstore_open(struct pstore_info *psi)
1312 1308
1313static int efi_pstore_close(struct pstore_info *psi) 1309static int efi_pstore_close(struct pstore_info *psi)
1314{ 1310{
1315 struct efivars *efivars = psi->data; 1311 struct efivars *efivars = __efivars;
1316 1312
1317 spin_unlock_irq(&efivars->lock); 1313 spin_unlock_irq(&efivars->lock);
1318 return 0; 1314 return 0;
@@ -1323,7 +1319,7 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
1323 char **buf, struct pstore_info *psi) 1319 char **buf, struct pstore_info *psi)
1324{ 1320{
1325 efi_guid_t vendor = LINUX_EFI_CRASH_GUID; 1321 efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
1326 struct efivars *efivars = psi->data; 1322 struct efivars *efivars = __efivars;
1327 char name[DUMP_NAME_LEN]; 1323 char name[DUMP_NAME_LEN];
1328 int i; 1324 int i;
1329 int cnt; 1325 int cnt;
@@ -1386,7 +1382,7 @@ static int efi_pstore_write(enum pstore_type_id type,
1386 char name[DUMP_NAME_LEN]; 1382 char name[DUMP_NAME_LEN];
1387 efi_char16_t efi_name[DUMP_NAME_LEN]; 1383 efi_char16_t efi_name[DUMP_NAME_LEN];
1388 efi_guid_t vendor = LINUX_EFI_CRASH_GUID; 1384 efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
1389 struct efivars *efivars = psi->data; 1385 struct efivars *efivars = __efivars;
1390 int i, ret = 0; 1386 int i, ret = 0;
1391 efi_status_t status = EFI_NOT_FOUND; 1387 efi_status_t status = EFI_NOT_FOUND;
1392 unsigned long flags; 1388 unsigned long flags;
@@ -1443,7 +1439,7 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
1443 char name_old[DUMP_NAME_LEN]; 1439 char name_old[DUMP_NAME_LEN];
1444 efi_char16_t efi_name_old[DUMP_NAME_LEN]; 1440 efi_char16_t efi_name_old[DUMP_NAME_LEN];
1445 efi_guid_t vendor = LINUX_EFI_CRASH_GUID; 1441 efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
1446 struct efivars *efivars = psi->data; 1442 struct efivars *efivars = __efivars;
1447 struct efivar_entry *entry, *found = NULL; 1443 struct efivar_entry *entry, *found = NULL;
1448 int i; 1444 int i;
1449 1445
@@ -1535,7 +1531,7 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
1535 char *buf, loff_t pos, size_t count) 1531 char *buf, loff_t pos, size_t count)
1536{ 1532{
1537 struct efi_variable *new_var = (struct efi_variable *)buf; 1533 struct efi_variable *new_var = (struct efi_variable *)buf;
1538 struct efivars *efivars = bin_attr->private; 1534 struct efivars *efivars = __efivars;
1539 struct efivar_entry *search_efivar, *n; 1535 struct efivar_entry *search_efivar, *n;
1540 unsigned long strsize1, strsize2; 1536 unsigned long strsize1, strsize2;
1541 efi_status_t status = EFI_NOT_FOUND; 1537 efi_status_t status = EFI_NOT_FOUND;
@@ -1612,7 +1608,7 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
1612 char *buf, loff_t pos, size_t count) 1608 char *buf, loff_t pos, size_t count)
1613{ 1609{
1614 struct efi_variable *del_var = (struct efi_variable *)buf; 1610 struct efi_variable *del_var = (struct efi_variable *)buf;
1615 struct efivars *efivars = bin_attr->private; 1611 struct efivars *efivars = __efivars;
1616 struct efivar_entry *search_efivar, *n; 1612 struct efivar_entry *search_efivar, *n;
1617 unsigned long strsize1, strsize2; 1613 unsigned long strsize1, strsize2;
1618 efi_status_t status = EFI_NOT_FOUND; 1614 efi_status_t status = EFI_NOT_FOUND;
@@ -1670,7 +1666,7 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
1670static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor) 1666static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor)
1671{ 1667{
1672 struct efivar_entry *entry, *n; 1668 struct efivar_entry *entry, *n;
1673 struct efivars *efivars = &__efivars; 1669 struct efivars *efivars = __efivars;
1674 unsigned long strsize1, strsize2; 1670 unsigned long strsize1, strsize2;
1675 bool found = false; 1671 bool found = false;
1676 1672
@@ -1716,7 +1712,7 @@ static unsigned long var_name_strnsize(efi_char16_t *variable_name,
1716 1712
1717static void efivar_update_sysfs_entries(struct work_struct *work) 1713static void efivar_update_sysfs_entries(struct work_struct *work)
1718{ 1714{
1719 struct efivars *efivars = &__efivars; 1715 struct efivars *efivars = __efivars;
1720 efi_guid_t vendor; 1716 efi_guid_t vendor;
1721 efi_char16_t *variable_name; 1717 efi_char16_t *variable_name;
1722 unsigned long variable_name_size = 1024; 1718 unsigned long variable_name_size = 1024;
@@ -1843,7 +1839,6 @@ efivar_create_sysfs_entry(struct efivars *efivars,
1843 return 1; 1839 return 1;
1844 } 1840 }
1845 1841
1846 new_efivar->efivars = efivars;
1847 memcpy(new_efivar->var.VariableName, variable_name, 1842 memcpy(new_efivar->var.VariableName, variable_name,
1848 variable_name_size); 1843 variable_name_size);
1849 memcpy(&(new_efivar->var.VendorGuid), vendor_guid, sizeof(efi_guid_t)); 1844 memcpy(&(new_efivar->var.VendorGuid), vendor_guid, sizeof(efi_guid_t));
@@ -1942,6 +1937,8 @@ void unregister_efivars(struct efivars *efivars)
1942{ 1937{
1943 struct efivar_entry *entry, *n; 1938 struct efivar_entry *entry, *n;
1944 1939
1940 __efivars = NULL;
1941
1945 list_for_each_entry_safe(entry, n, &efivars->list, list) { 1942 list_for_each_entry_safe(entry, n, &efivars->list, list) {
1946 spin_lock_irq(&efivars->lock); 1943 spin_lock_irq(&efivars->lock);
1947 list_del(&entry->list); 1944 list_del(&entry->list);
@@ -1998,6 +1995,8 @@ int register_efivars(struct efivars *efivars,
1998 unsigned long variable_name_size = 1024; 1995 unsigned long variable_name_size = 1024;
1999 int error = 0; 1996 int error = 0;
2000 1997
1998 __efivars = efivars;
1999
2001 variable_name = kzalloc(variable_name_size, GFP_KERNEL); 2000 variable_name = kzalloc(variable_name_size, GFP_KERNEL);
2002 if (!variable_name) { 2001 if (!variable_name) {
2003 printk(KERN_ERR "efivars: Memory allocation failed.\n"); 2002 printk(KERN_ERR "efivars: Memory allocation failed.\n");
@@ -2085,6 +2084,24 @@ out:
2085} 2084}
2086EXPORT_SYMBOL_GPL(register_efivars); 2085EXPORT_SYMBOL_GPL(register_efivars);
2087 2086
2087static struct efivars generic_efivars;
2088static struct efivar_operations generic_ops;
2089
2090static int generic_ops_register(void)
2091{
2092 generic_ops.get_variable = efi.get_variable;
2093 generic_ops.set_variable = efi.set_variable;
2094 generic_ops.get_next_variable = efi.get_next_variable;
2095 generic_ops.query_variable_info = efi.query_variable_info;
2096
2097 return register_efivars(&generic_efivars, &generic_ops, efi_kobj);
2098}
2099
2100static void generic_ops_unregister(void)
2101{
2102 unregister_efivars(&generic_efivars);
2103}
2104
2088/* 2105/*
2089 * For now we register the efi subsystem with the firmware subsystem 2106 * For now we register the efi subsystem with the firmware subsystem
2090 * and the vars subsystem with the efi subsystem. In the future, it 2107 * and the vars subsystem with the efi subsystem. In the future, it
@@ -2111,12 +2128,7 @@ efivars_init(void)
2111 return -ENOMEM; 2128 return -ENOMEM;
2112 } 2129 }
2113 2130
2114 ops.get_variable = efi.get_variable; 2131 error = generic_ops_register();
2115 ops.set_variable = efi.set_variable;
2116 ops.get_next_variable = efi.get_next_variable;
2117 ops.query_variable_info = efi.query_variable_info;
2118
2119 error = register_efivars(&__efivars, &ops, efi_kobj);
2120 if (error) 2132 if (error)
2121 goto err_put; 2133 goto err_put;
2122 2134
@@ -2132,7 +2144,7 @@ efivars_init(void)
2132 return 0; 2144 return 0;
2133 2145
2134err_unregister: 2146err_unregister:
2135 unregister_efivars(&__efivars); 2147 generic_ops_unregister();
2136err_put: 2148err_put:
2137 kobject_put(efi_kobj); 2149 kobject_put(efi_kobj);
2138 return error; 2150 return error;
@@ -2144,7 +2156,7 @@ efivars_exit(void)
2144 cancel_work_sync(&efivar_work); 2156 cancel_work_sync(&efivar_work);
2145 2157
2146 if (efi_enabled(EFI_RUNTIME_SERVICES)) { 2158 if (efi_enabled(EFI_RUNTIME_SERVICES)) {
2147 unregister_efivars(&__efivars); 2159 generic_ops_unregister();
2148 kobject_put(efi_kobj); 2160 kobject_put(efi_kobj);
2149 } 2161 }
2150} 2162}