diff options
author | Seiji Aguchi <seiji.aguchi@hds.com> | 2013-02-12 15:59:07 -0500 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2013-02-12 15:59:07 -0500 |
commit | 81fa4e581d9283f7992a0d8c534bb141eb840a14 (patch) | |
tree | 2bc7677534c1cef8dfb5388059777bfb1164e66c /drivers/firmware | |
parent | e59310adf5eebce108f78b6c47bb330aae2e1666 (diff) |
efivars: Disable external interrupt while holding efivars->lock
[Problem]
There is a scenario which efi_pstore fails to log messages in a panic case.
- CPUA holds an efi_var->lock in either efivarfs parts
or efi_pstore with interrupt enabled.
- CPUB panics and sends IPI to CPUA in smp_send_stop().
- CPUA stops with holding the lock.
- CPUB kicks efi_pstore_write() via kmsg_dump(KSMG_DUMP_PANIC)
but it returns without logging messages.
[Patch Description]
This patch disables an external interruption while holding efivars->lock
as follows.
In efi_pstore_write() and get_var_data(), spin_lock/spin_unlock is
replaced by spin_lock_irqsave/spin_unlock_irqrestore because they may
be called in an interrupt context.
In other functions, they are replaced by spin_lock_irq/spin_unlock_irq.
because they are all called from a process context.
By applying this patch, we can avoid the problem above with
a following senario.
- CPUA holds an efi_var->lock with interrupt disabled.
- CPUB panics and sends IPI to CPUA in smp_send_stop().
- CPUA receives the IPI after releasing the lock because it is
disabling interrupt while holding the lock.
- CPUB waits for one sec until CPUA releases the lock.
- CPUB kicks efi_pstore_write() via kmsg_dump(KSMG_DUMP_PANIC)
And it can hold the lock successfully.
Signed-off-by: Seiji Aguchi <seiji.aguchi@hds.com>
Acked-by: Mike Waychison <mikew@google.com>
Acked-by: Matt Fleming <matt.fleming@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'drivers/firmware')
-rw-r--r-- | drivers/firmware/efivars.c | 86 |
1 files changed, 44 insertions, 42 deletions
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index ef5070d86f88..a64fb7bda365 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c | |||
@@ -405,10 +405,11 @@ static efi_status_t | |||
405 | get_var_data(struct efivars *efivars, struct efi_variable *var) | 405 | get_var_data(struct efivars *efivars, struct efi_variable *var) |
406 | { | 406 | { |
407 | efi_status_t status; | 407 | efi_status_t status; |
408 | unsigned long flags; | ||
408 | 409 | ||
409 | spin_lock(&efivars->lock); | 410 | spin_lock_irqsave(&efivars->lock, flags); |
410 | status = get_var_data_locked(efivars, var); | 411 | status = get_var_data_locked(efivars, var); |
411 | spin_unlock(&efivars->lock); | 412 | spin_unlock_irqrestore(&efivars->lock, flags); |
412 | 413 | ||
413 | if (status != EFI_SUCCESS) { | 414 | if (status != EFI_SUCCESS) { |
414 | printk(KERN_WARNING "efivars: get_variable() failed 0x%lx!\n", | 415 | printk(KERN_WARNING "efivars: get_variable() failed 0x%lx!\n", |
@@ -537,14 +538,14 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count) | |||
537 | return -EINVAL; | 538 | return -EINVAL; |
538 | } | 539 | } |
539 | 540 | ||
540 | spin_lock(&efivars->lock); | 541 | spin_lock_irq(&efivars->lock); |
541 | status = efivars->ops->set_variable(new_var->VariableName, | 542 | status = efivars->ops->set_variable(new_var->VariableName, |
542 | &new_var->VendorGuid, | 543 | &new_var->VendorGuid, |
543 | new_var->Attributes, | 544 | new_var->Attributes, |
544 | new_var->DataSize, | 545 | new_var->DataSize, |
545 | new_var->Data); | 546 | new_var->Data); |
546 | 547 | ||
547 | spin_unlock(&efivars->lock); | 548 | spin_unlock_irq(&efivars->lock); |
548 | 549 | ||
549 | if (status != EFI_SUCCESS) { | 550 | if (status != EFI_SUCCESS) { |
550 | printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n", | 551 | printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n", |
@@ -713,7 +714,7 @@ static ssize_t efivarfs_file_write(struct file *file, | |||
713 | * amounts of memory. Pick a default size of 64K if | 714 | * amounts of memory. Pick a default size of 64K if |
714 | * QueryVariableInfo() isn't supported by the firmware. | 715 | * QueryVariableInfo() isn't supported by the firmware. |
715 | */ | 716 | */ |
716 | spin_lock(&efivars->lock); | 717 | spin_lock_irq(&efivars->lock); |
717 | 718 | ||
718 | if (!efivars->ops->query_variable_info) | 719 | if (!efivars->ops->query_variable_info) |
719 | status = EFI_UNSUPPORTED; | 720 | status = EFI_UNSUPPORTED; |
@@ -723,7 +724,7 @@ static ssize_t efivarfs_file_write(struct file *file, | |||
723 | &remaining_size, &max_size); | 724 | &remaining_size, &max_size); |
724 | } | 725 | } |
725 | 726 | ||
726 | spin_unlock(&efivars->lock); | 727 | spin_unlock_irq(&efivars->lock); |
727 | 728 | ||
728 | if (status != EFI_SUCCESS) { | 729 | if (status != EFI_SUCCESS) { |
729 | if (status != EFI_UNSUPPORTED) | 730 | if (status != EFI_UNSUPPORTED) |
@@ -754,7 +755,7 @@ static ssize_t efivarfs_file_write(struct file *file, | |||
754 | * set_variable call, and removal of the variable from the efivars | 755 | * set_variable call, and removal of the variable from the efivars |
755 | * list (in the case of an authenticated delete). | 756 | * list (in the case of an authenticated delete). |
756 | */ | 757 | */ |
757 | spin_lock(&efivars->lock); | 758 | spin_lock_irq(&efivars->lock); |
758 | 759 | ||
759 | status = efivars->ops->set_variable(var->var.VariableName, | 760 | status = efivars->ops->set_variable(var->var.VariableName, |
760 | &var->var.VendorGuid, | 761 | &var->var.VendorGuid, |
@@ -762,7 +763,7 @@ static ssize_t efivarfs_file_write(struct file *file, | |||
762 | data); | 763 | data); |
763 | 764 | ||
764 | if (status != EFI_SUCCESS) { | 765 | if (status != EFI_SUCCESS) { |
765 | spin_unlock(&efivars->lock); | 766 | spin_unlock_irq(&efivars->lock); |
766 | kfree(data); | 767 | kfree(data); |
767 | 768 | ||
768 | return efi_status_to_err(status); | 769 | return efi_status_to_err(status); |
@@ -783,20 +784,20 @@ static ssize_t efivarfs_file_write(struct file *file, | |||
783 | NULL); | 784 | NULL); |
784 | 785 | ||
785 | if (status == EFI_BUFFER_TOO_SMALL) { | 786 | if (status == EFI_BUFFER_TOO_SMALL) { |
786 | spin_unlock(&efivars->lock); | 787 | spin_unlock_irq(&efivars->lock); |
787 | mutex_lock(&inode->i_mutex); | 788 | mutex_lock(&inode->i_mutex); |
788 | i_size_write(inode, newdatasize + sizeof(attributes)); | 789 | i_size_write(inode, newdatasize + sizeof(attributes)); |
789 | mutex_unlock(&inode->i_mutex); | 790 | mutex_unlock(&inode->i_mutex); |
790 | 791 | ||
791 | } else if (status == EFI_NOT_FOUND) { | 792 | } else if (status == EFI_NOT_FOUND) { |
792 | list_del(&var->list); | 793 | list_del(&var->list); |
793 | spin_unlock(&efivars->lock); | 794 | spin_unlock_irq(&efivars->lock); |
794 | efivar_unregister(var); | 795 | efivar_unregister(var); |
795 | drop_nlink(inode); | 796 | drop_nlink(inode); |
796 | dput(file->f_dentry); | 797 | dput(file->f_dentry); |
797 | 798 | ||
798 | } else { | 799 | } else { |
799 | spin_unlock(&efivars->lock); | 800 | spin_unlock_irq(&efivars->lock); |
800 | pr_warn("efivarfs: inconsistent EFI variable implementation? " | 801 | pr_warn("efivarfs: inconsistent EFI variable implementation? " |
801 | "status = %lx\n", status); | 802 | "status = %lx\n", status); |
802 | } | 803 | } |
@@ -818,11 +819,11 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf, | |||
818 | void *data; | 819 | void *data; |
819 | ssize_t size = 0; | 820 | ssize_t size = 0; |
820 | 821 | ||
821 | spin_lock(&efivars->lock); | 822 | spin_lock_irq(&efivars->lock); |
822 | status = efivars->ops->get_variable(var->var.VariableName, | 823 | status = efivars->ops->get_variable(var->var.VariableName, |
823 | &var->var.VendorGuid, | 824 | &var->var.VendorGuid, |
824 | &attributes, &datasize, NULL); | 825 | &attributes, &datasize, NULL); |
825 | spin_unlock(&efivars->lock); | 826 | spin_unlock_irq(&efivars->lock); |
826 | 827 | ||
827 | if (status != EFI_BUFFER_TOO_SMALL) | 828 | if (status != EFI_BUFFER_TOO_SMALL) |
828 | return efi_status_to_err(status); | 829 | return efi_status_to_err(status); |
@@ -832,12 +833,12 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf, | |||
832 | if (!data) | 833 | if (!data) |
833 | return -ENOMEM; | 834 | return -ENOMEM; |
834 | 835 | ||
835 | spin_lock(&efivars->lock); | 836 | spin_lock_irq(&efivars->lock); |
836 | status = efivars->ops->get_variable(var->var.VariableName, | 837 | status = efivars->ops->get_variable(var->var.VariableName, |
837 | &var->var.VendorGuid, | 838 | &var->var.VendorGuid, |
838 | &attributes, &datasize, | 839 | &attributes, &datasize, |
839 | (data + sizeof(attributes))); | 840 | (data + sizeof(attributes))); |
840 | spin_unlock(&efivars->lock); | 841 | spin_unlock_irq(&efivars->lock); |
841 | 842 | ||
842 | if (status != EFI_SUCCESS) { | 843 | if (status != EFI_SUCCESS) { |
843 | size = efi_status_to_err(status); | 844 | size = efi_status_to_err(status); |
@@ -965,9 +966,9 @@ static int efivarfs_create(struct inode *dir, struct dentry *dentry, | |||
965 | goto out; | 966 | goto out; |
966 | 967 | ||
967 | kobject_uevent(&var->kobj, KOBJ_ADD); | 968 | kobject_uevent(&var->kobj, KOBJ_ADD); |
968 | spin_lock(&efivars->lock); | 969 | spin_lock_irq(&efivars->lock); |
969 | list_add(&var->list, &efivars->list); | 970 | list_add(&var->list, &efivars->list); |
970 | spin_unlock(&efivars->lock); | 971 | spin_unlock_irq(&efivars->lock); |
971 | d_instantiate(dentry, inode); | 972 | d_instantiate(dentry, inode); |
972 | dget(dentry); | 973 | dget(dentry); |
973 | out: | 974 | out: |
@@ -984,7 +985,7 @@ static int efivarfs_unlink(struct inode *dir, struct dentry *dentry) | |||
984 | struct efivars *efivars = var->efivars; | 985 | struct efivars *efivars = var->efivars; |
985 | efi_status_t status; | 986 | efi_status_t status; |
986 | 987 | ||
987 | spin_lock(&efivars->lock); | 988 | spin_lock_irq(&efivars->lock); |
988 | 989 | ||
989 | status = efivars->ops->set_variable(var->var.VariableName, | 990 | status = efivars->ops->set_variable(var->var.VariableName, |
990 | &var->var.VendorGuid, | 991 | &var->var.VendorGuid, |
@@ -992,14 +993,14 @@ static int efivarfs_unlink(struct inode *dir, struct dentry *dentry) | |||
992 | 993 | ||
993 | if (status == EFI_SUCCESS || status == EFI_NOT_FOUND) { | 994 | if (status == EFI_SUCCESS || status == EFI_NOT_FOUND) { |
994 | list_del(&var->list); | 995 | list_del(&var->list); |
995 | spin_unlock(&efivars->lock); | 996 | spin_unlock_irq(&efivars->lock); |
996 | efivar_unregister(var); | 997 | efivar_unregister(var); |
997 | drop_nlink(dir); | 998 | drop_nlink(dir); |
998 | dput(dentry); | 999 | dput(dentry); |
999 | return 0; | 1000 | return 0; |
1000 | } | 1001 | } |
1001 | 1002 | ||
1002 | spin_unlock(&efivars->lock); | 1003 | spin_unlock_irq(&efivars->lock); |
1003 | return -EINVAL; | 1004 | return -EINVAL; |
1004 | }; | 1005 | }; |
1005 | 1006 | ||
@@ -1065,13 +1066,13 @@ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent) | |||
1065 | /* copied by the above to local storage in the dentry. */ | 1066 | /* copied by the above to local storage in the dentry. */ |
1066 | kfree(name); | 1067 | kfree(name); |
1067 | 1068 | ||
1068 | spin_lock(&efivars->lock); | 1069 | spin_lock_irq(&efivars->lock); |
1069 | efivars->ops->get_variable(entry->var.VariableName, | 1070 | efivars->ops->get_variable(entry->var.VariableName, |
1070 | &entry->var.VendorGuid, | 1071 | &entry->var.VendorGuid, |
1071 | &entry->var.Attributes, | 1072 | &entry->var.Attributes, |
1072 | &size, | 1073 | &size, |
1073 | NULL); | 1074 | NULL); |
1074 | spin_unlock(&efivars->lock); | 1075 | spin_unlock_irq(&efivars->lock); |
1075 | 1076 | ||
1076 | mutex_lock(&inode->i_mutex); | 1077 | mutex_lock(&inode->i_mutex); |
1077 | inode->i_private = entry; | 1078 | inode->i_private = entry; |
@@ -1122,7 +1123,7 @@ static int efi_pstore_open(struct pstore_info *psi) | |||
1122 | { | 1123 | { |
1123 | struct efivars *efivars = psi->data; | 1124 | struct efivars *efivars = psi->data; |
1124 | 1125 | ||
1125 | spin_lock(&efivars->lock); | 1126 | spin_lock_irq(&efivars->lock); |
1126 | efivars->walk_entry = list_first_entry(&efivars->list, | 1127 | efivars->walk_entry = list_first_entry(&efivars->list, |
1127 | struct efivar_entry, list); | 1128 | struct efivar_entry, list); |
1128 | return 0; | 1129 | return 0; |
@@ -1132,7 +1133,7 @@ static int efi_pstore_close(struct pstore_info *psi) | |||
1132 | { | 1133 | { |
1133 | struct efivars *efivars = psi->data; | 1134 | struct efivars *efivars = psi->data; |
1134 | 1135 | ||
1135 | spin_unlock(&efivars->lock); | 1136 | spin_unlock_irq(&efivars->lock); |
1136 | return 0; | 1137 | return 0; |
1137 | } | 1138 | } |
1138 | 1139 | ||
@@ -1208,6 +1209,7 @@ static int efi_pstore_write(enum pstore_type_id type, | |||
1208 | int i, ret = 0; | 1209 | int i, ret = 0; |
1209 | u64 storage_space, remaining_space, max_variable_size; | 1210 | u64 storage_space, remaining_space, max_variable_size; |
1210 | efi_status_t status = EFI_NOT_FOUND; | 1211 | efi_status_t status = EFI_NOT_FOUND; |
1212 | unsigned long flags; | ||
1211 | 1213 | ||
1212 | if (pstore_cannot_block_path(reason)) { | 1214 | if (pstore_cannot_block_path(reason)) { |
1213 | /* | 1215 | /* |
@@ -1215,10 +1217,10 @@ static int efi_pstore_write(enum pstore_type_id type, | |||
1215 | * this driver returns without entering firmware to avoid | 1217 | * this driver returns without entering firmware to avoid |
1216 | * hanging up. | 1218 | * hanging up. |
1217 | */ | 1219 | */ |
1218 | if (!spin_trylock(&efivars->lock)) | 1220 | if (!spin_trylock_irqsave(&efivars->lock, flags)) |
1219 | return -EBUSY; | 1221 | return -EBUSY; |
1220 | } else | 1222 | } else |
1221 | spin_lock(&efivars->lock); | 1223 | spin_lock_irqsave(&efivars->lock, flags); |
1222 | 1224 | ||
1223 | /* | 1225 | /* |
1224 | * Check if there is a space enough to log. | 1226 | * Check if there is a space enough to log. |
@@ -1230,7 +1232,7 @@ static int efi_pstore_write(enum pstore_type_id type, | |||
1230 | &remaining_space, | 1232 | &remaining_space, |
1231 | &max_variable_size); | 1233 | &max_variable_size); |
1232 | if (status || remaining_space < size + DUMP_NAME_LEN * 2) { | 1234 | if (status || remaining_space < size + DUMP_NAME_LEN * 2) { |
1233 | spin_unlock(&efivars->lock); | 1235 | spin_unlock_irqrestore(&efivars->lock, flags); |
1234 | *id = part; | 1236 | *id = part; |
1235 | return -ENOSPC; | 1237 | return -ENOSPC; |
1236 | } | 1238 | } |
@@ -1244,7 +1246,7 @@ static int efi_pstore_write(enum pstore_type_id type, | |||
1244 | efivars->ops->set_variable(efi_name, &vendor, PSTORE_EFI_ATTRIBUTES, | 1246 | efivars->ops->set_variable(efi_name, &vendor, PSTORE_EFI_ATTRIBUTES, |
1245 | size, psi->buf); | 1247 | size, psi->buf); |
1246 | 1248 | ||
1247 | spin_unlock(&efivars->lock); | 1249 | spin_unlock_irqrestore(&efivars->lock, flags); |
1248 | 1250 | ||
1249 | if (size) | 1251 | if (size) |
1250 | ret = efivar_create_sysfs_entry(efivars, | 1252 | ret = efivar_create_sysfs_entry(efivars, |
@@ -1271,7 +1273,7 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count, | |||
1271 | sprintf(name, "dump-type%u-%u-%d-%lu", type, (unsigned int)id, count, | 1273 | sprintf(name, "dump-type%u-%u-%d-%lu", type, (unsigned int)id, count, |
1272 | time.tv_sec); | 1274 | time.tv_sec); |
1273 | 1275 | ||
1274 | spin_lock(&efivars->lock); | 1276 | spin_lock_irq(&efivars->lock); |
1275 | 1277 | ||
1276 | for (i = 0; i < DUMP_NAME_LEN; i++) | 1278 | for (i = 0; i < DUMP_NAME_LEN; i++) |
1277 | efi_name[i] = name[i]; | 1279 | efi_name[i] = name[i]; |
@@ -1315,7 +1317,7 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count, | |||
1315 | if (found) | 1317 | if (found) |
1316 | list_del(&found->list); | 1318 | list_del(&found->list); |
1317 | 1319 | ||
1318 | spin_unlock(&efivars->lock); | 1320 | spin_unlock_irq(&efivars->lock); |
1319 | 1321 | ||
1320 | if (found) | 1322 | if (found) |
1321 | efivar_unregister(found); | 1323 | efivar_unregister(found); |
@@ -1385,7 +1387,7 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj, | |||
1385 | return -EINVAL; | 1387 | return -EINVAL; |
1386 | } | 1388 | } |
1387 | 1389 | ||
1388 | spin_lock(&efivars->lock); | 1390 | spin_lock_irq(&efivars->lock); |
1389 | 1391 | ||
1390 | /* | 1392 | /* |
1391 | * Does this variable already exist? | 1393 | * Does this variable already exist? |
@@ -1403,7 +1405,7 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj, | |||
1403 | } | 1405 | } |
1404 | } | 1406 | } |
1405 | if (found) { | 1407 | if (found) { |
1406 | spin_unlock(&efivars->lock); | 1408 | spin_unlock_irq(&efivars->lock); |
1407 | return -EINVAL; | 1409 | return -EINVAL; |
1408 | } | 1410 | } |
1409 | 1411 | ||
@@ -1417,10 +1419,10 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj, | |||
1417 | if (status != EFI_SUCCESS) { | 1419 | if (status != EFI_SUCCESS) { |
1418 | printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n", | 1420 | printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n", |
1419 | status); | 1421 | status); |
1420 | spin_unlock(&efivars->lock); | 1422 | spin_unlock_irq(&efivars->lock); |
1421 | return -EIO; | 1423 | return -EIO; |
1422 | } | 1424 | } |
1423 | spin_unlock(&efivars->lock); | 1425 | spin_unlock_irq(&efivars->lock); |
1424 | 1426 | ||
1425 | /* Create the entry in sysfs. Locking is not required here */ | 1427 | /* Create the entry in sysfs. Locking is not required here */ |
1426 | status = efivar_create_sysfs_entry(efivars, | 1428 | status = efivar_create_sysfs_entry(efivars, |
@@ -1448,7 +1450,7 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj, | |||
1448 | if (!capable(CAP_SYS_ADMIN)) | 1450 | if (!capable(CAP_SYS_ADMIN)) |
1449 | return -EACCES; | 1451 | return -EACCES; |
1450 | 1452 | ||
1451 | spin_lock(&efivars->lock); | 1453 | spin_lock_irq(&efivars->lock); |
1452 | 1454 | ||
1453 | /* | 1455 | /* |
1454 | * Does this variable already exist? | 1456 | * Does this variable already exist? |
@@ -1466,7 +1468,7 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj, | |||
1466 | } | 1468 | } |
1467 | } | 1469 | } |
1468 | if (!found) { | 1470 | if (!found) { |
1469 | spin_unlock(&efivars->lock); | 1471 | spin_unlock_irq(&efivars->lock); |
1470 | return -EINVAL; | 1472 | return -EINVAL; |
1471 | } | 1473 | } |
1472 | /* force the Attributes/DataSize to 0 to ensure deletion */ | 1474 | /* force the Attributes/DataSize to 0 to ensure deletion */ |
@@ -1482,12 +1484,12 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj, | |||
1482 | if (status != EFI_SUCCESS) { | 1484 | if (status != EFI_SUCCESS) { |
1483 | printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n", | 1485 | printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n", |
1484 | status); | 1486 | status); |
1485 | spin_unlock(&efivars->lock); | 1487 | spin_unlock_irq(&efivars->lock); |
1486 | return -EIO; | 1488 | return -EIO; |
1487 | } | 1489 | } |
1488 | list_del(&search_efivar->list); | 1490 | list_del(&search_efivar->list); |
1489 | /* We need to release this lock before unregistering. */ | 1491 | /* We need to release this lock before unregistering. */ |
1490 | spin_unlock(&efivars->lock); | 1492 | spin_unlock_irq(&efivars->lock); |
1491 | efivar_unregister(search_efivar); | 1493 | efivar_unregister(search_efivar); |
1492 | 1494 | ||
1493 | /* It's dead Jim.... */ | 1495 | /* It's dead Jim.... */ |
@@ -1602,9 +1604,9 @@ efivar_create_sysfs_entry(struct efivars *efivars, | |||
1602 | kfree(short_name); | 1604 | kfree(short_name); |
1603 | short_name = NULL; | 1605 | short_name = NULL; |
1604 | 1606 | ||
1605 | spin_lock(&efivars->lock); | 1607 | spin_lock_irq(&efivars->lock); |
1606 | list_add(&new_efivar->list, &efivars->list); | 1608 | list_add(&new_efivar->list, &efivars->list); |
1607 | spin_unlock(&efivars->lock); | 1609 | spin_unlock_irq(&efivars->lock); |
1608 | 1610 | ||
1609 | return 0; | 1611 | return 0; |
1610 | } | 1612 | } |
@@ -1673,9 +1675,9 @@ void unregister_efivars(struct efivars *efivars) | |||
1673 | struct efivar_entry *entry, *n; | 1675 | struct efivar_entry *entry, *n; |
1674 | 1676 | ||
1675 | list_for_each_entry_safe(entry, n, &efivars->list, list) { | 1677 | list_for_each_entry_safe(entry, n, &efivars->list, list) { |
1676 | spin_lock(&efivars->lock); | 1678 | spin_lock_irq(&efivars->lock); |
1677 | list_del(&entry->list); | 1679 | list_del(&entry->list); |
1678 | spin_unlock(&efivars->lock); | 1680 | spin_unlock_irq(&efivars->lock); |
1679 | efivar_unregister(entry); | 1681 | efivar_unregister(entry); |
1680 | } | 1682 | } |
1681 | if (efivars->new_var) | 1683 | if (efivars->new_var) |