diff options
| -rw-r--r-- | drivers/firmware/efivars.c | 29 |
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 | |||
| 127 | struct efivar_attribute { | 125 | struct 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 = { | |||
| 386 | static void efivar_release(struct kobject *kobj) | 384 | static 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 | |||
| 430 | efivar_create(struct subsystem *sub, const char *buf, size_t count) | 425 | efivar_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 | |||
| 490 | efivar_delete(struct subsystem *sub, const char *buf, size_t count) | 483 | efivar_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: | |||
| 768 | static void __exit | 759 | static void __exit |
| 769 | efivars_exit(void) | 760 | efivars_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); |
