aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/firmware/efivars.c29
1 files changed, 12 insertions, 17 deletions
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index 5ab5e393b882..c6281ccd4fe7 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -122,8 +122,6 @@ struct efivar_entry {
122 struct kobject kobj; 122 struct kobject kobj;
123}; 123};
124 124
125#define get_efivar_entry(n) list_entry(n, struct efivar_entry, list)
126
127struct efivar_attribute { 125struct efivar_attribute {
128 struct attribute attr; 126 struct attribute attr;
129 ssize_t (*show) (struct efivar_entry *entry, char *buf); 127 ssize_t (*show) (struct efivar_entry *entry, char *buf);
@@ -386,9 +384,6 @@ static struct sysfs_ops efivar_attr_ops = {
386static void efivar_release(struct kobject *kobj) 384static void efivar_release(struct kobject *kobj)
387{ 385{
388 struct efivar_entry *var = container_of(kobj, struct efivar_entry, kobj); 386 struct efivar_entry *var = container_of(kobj, struct efivar_entry, kobj);
389 spin_lock(&efivars_lock);
390 list_del(&var->list);
391 spin_unlock(&efivars_lock);
392 kfree(var); 387 kfree(var);
393} 388}
394 389
@@ -430,9 +425,8 @@ static ssize_t
430efivar_create(struct subsystem *sub, const char *buf, size_t count) 425efivar_create(struct subsystem *sub, const char *buf, size_t count)
431{ 426{
432 struct efi_variable *new_var = (struct efi_variable *)buf; 427 struct efi_variable *new_var = (struct efi_variable *)buf;
433 struct efivar_entry *search_efivar = NULL; 428 struct efivar_entry *search_efivar, *n;
434 unsigned long strsize1, strsize2; 429 unsigned long strsize1, strsize2;
435 struct list_head *pos, *n;
436 efi_status_t status = EFI_NOT_FOUND; 430 efi_status_t status = EFI_NOT_FOUND;
437 int found = 0; 431 int found = 0;
438 432
@@ -444,8 +438,7 @@ efivar_create(struct subsystem *sub, const char *buf, size_t count)
444 /* 438 /*
445 * Does this variable already exist? 439 * Does this variable already exist?
446 */ 440 */
447 list_for_each_safe(pos, n, &efivar_list) { 441 list_for_each_entry_safe(search_efivar, n, &efivar_list, list) {
448 search_efivar = get_efivar_entry(pos);
449 strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024); 442 strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024);
450 strsize2 = utf8_strsize(new_var->VariableName, 1024); 443 strsize2 = utf8_strsize(new_var->VariableName, 1024);
451 if (strsize1 == strsize2 && 444 if (strsize1 == strsize2 &&
@@ -490,9 +483,8 @@ static ssize_t
490efivar_delete(struct subsystem *sub, const char *buf, size_t count) 483efivar_delete(struct subsystem *sub, const char *buf, size_t count)
491{ 484{
492 struct efi_variable *del_var = (struct efi_variable *)buf; 485 struct efi_variable *del_var = (struct efi_variable *)buf;
493 struct efivar_entry *search_efivar = NULL; 486 struct efivar_entry *search_efivar, *n;
494 unsigned long strsize1, strsize2; 487 unsigned long strsize1, strsize2;
495 struct list_head *pos, *n;
496 efi_status_t status = EFI_NOT_FOUND; 488 efi_status_t status = EFI_NOT_FOUND;
497 int found = 0; 489 int found = 0;
498 490
@@ -504,8 +496,7 @@ efivar_delete(struct subsystem *sub, const char *buf, size_t count)
504 /* 496 /*
505 * Does this variable already exist? 497 * Does this variable already exist?
506 */ 498 */
507 list_for_each_safe(pos, n, &efivar_list) { 499 list_for_each_entry_safe(search_efivar, n, &efivar_list, list) {
508 search_efivar = get_efivar_entry(pos);
509 strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024); 500 strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024);
510 strsize2 = utf8_strsize(del_var->VariableName, 1024); 501 strsize2 = utf8_strsize(del_var->VariableName, 1024);
511 if (strsize1 == strsize2 && 502 if (strsize1 == strsize2 &&
@@ -537,9 +528,9 @@ efivar_delete(struct subsystem *sub, const char *buf, size_t count)
537 spin_unlock(&efivars_lock); 528 spin_unlock(&efivars_lock);
538 return -EIO; 529 return -EIO;
539 } 530 }
531 list_del(&search_efivar->list);
540 /* We need to release this lock before unregistering. */ 532 /* We need to release this lock before unregistering. */
541 spin_unlock(&efivars_lock); 533 spin_unlock(&efivars_lock);
542
543 efivar_unregister(search_efivar); 534 efivar_unregister(search_efivar);
544 535
545 /* It's dead Jim.... */ 536 /* It's dead Jim.... */
@@ -768,10 +759,14 @@ out_free:
768static void __exit 759static void __exit
769efivars_exit(void) 760efivars_exit(void)
770{ 761{
771 struct list_head *pos, *n; 762 struct efivar_entry *entry, *n;
772 763
773 list_for_each_safe(pos, n, &efivar_list) 764 list_for_each_entry_safe(entry, n, &efivar_list, list) {
774 efivar_unregister(get_efivar_entry(pos)); 765 spin_lock(&efivars_lock);
766 list_del(&entry->list);
767 spin_unlock(&efivars_lock);
768 efivar_unregister(entry);
769 }
775 770
776 subsystem_unregister(&vars_subsys); 771 subsystem_unregister(&vars_subsys);
777 firmware_unregister(&efi_subsys); 772 firmware_unregister(&efi_subsys);