aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware
diff options
context:
space:
mode:
authorSeiji Aguchi <seiji.aguchi@hds.com>2012-11-14 15:26:46 -0500
committerTony Luck <tony.luck@intel.com>2012-11-26 19:02:04 -0500
commit96480d9c8fcfd7e325e9be6a6c6846689707f8e0 (patch)
tree5bd027ca5ee3f71a0945add556601dbdf05a20c1 /drivers/firmware
parentdd230fecab5e5833b11941f7f4a5732be78b1975 (diff)
efi_pstore: Remove a logic erasing entries from a write callback to hold multiple logs
[Issue] Currently, efi_pstore driver simply overwrites existing panic messages in NVRAM. So, in the following scenario, we will lose 1st panic messages. 1. kernel panics. 2. efi_pstore is kicked and writes panic messages to NVRAM. 3. system reboots. 4. kernel panics again before a user checks the 1st panic messages in NVRAM. [Solution] A reasonable solution to fix the issue is just holding multiple logs without erasing existing entries. This patch removes a logic erasing existing entries in a write callback because the logic is not needed in the write callback to support holding multiple logs. Signed-off-by: Seiji Aguchi <seiji.aguchi@hds.com> Acked-by: Mike Waychison <mikew@google.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/efivars.c39
1 files changed, 2 insertions, 37 deletions
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index bee14cc47c03..fbe9202c2678 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -701,18 +701,13 @@ static int efi_pstore_write(enum pstore_type_id type,
701 unsigned int part, size_t size, struct pstore_info *psi) 701 unsigned int part, size_t size, struct pstore_info *psi)
702{ 702{
703 char name[DUMP_NAME_LEN]; 703 char name[DUMP_NAME_LEN];
704 char stub_name[DUMP_NAME_LEN];
705 efi_char16_t efi_name[DUMP_NAME_LEN]; 704 efi_char16_t efi_name[DUMP_NAME_LEN];
706 efi_guid_t vendor = LINUX_EFI_CRASH_GUID; 705 efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
707 struct efivars *efivars = psi->data; 706 struct efivars *efivars = psi->data;
708 struct efivar_entry *entry, *found = NULL;
709 int i, ret = 0; 707 int i, ret = 0;
710 u64 storage_space, remaining_space, max_variable_size; 708 u64 storage_space, remaining_space, max_variable_size;
711 efi_status_t status = EFI_NOT_FOUND; 709 efi_status_t status = EFI_NOT_FOUND;
712 710
713 sprintf(stub_name, "dump-type%u-%u-", type, part);
714 sprintf(name, "%s%lu", stub_name, get_seconds());
715
716 spin_lock(&efivars->lock); 711 spin_lock(&efivars->lock);
717 712
718 /* 713 /*
@@ -730,35 +725,8 @@ static int efi_pstore_write(enum pstore_type_id type,
730 return -ENOSPC; 725 return -ENOSPC;
731 } 726 }
732 727
733 for (i = 0; i < DUMP_NAME_LEN; i++) 728 sprintf(name, "dump-type%u-%u-%lu", type, part,
734 efi_name[i] = stub_name[i]; 729 get_seconds());
735
736 /*
737 * Clean up any entries with the same name
738 */
739
740 list_for_each_entry(entry, &efivars->list, list) {
741 get_var_data_locked(efivars, &entry->var);
742
743 if (efi_guidcmp(entry->var.VendorGuid, vendor))
744 continue;
745 if (utf16_strncmp(entry->var.VariableName, efi_name,
746 utf16_strlen(efi_name)))
747 continue;
748 /* Needs to be a prefix */
749 if (entry->var.VariableName[utf16_strlen(efi_name)] == 0)
750 continue;
751
752 /* found */
753 found = entry;
754 efivars->ops->set_variable(entry->var.VariableName,
755 &entry->var.VendorGuid,
756 PSTORE_EFI_ATTRIBUTES,
757 0, NULL);
758 }
759
760 if (found)
761 list_del(&found->list);
762 730
763 for (i = 0; i < DUMP_NAME_LEN; i++) 731 for (i = 0; i < DUMP_NAME_LEN; i++)
764 efi_name[i] = name[i]; 732 efi_name[i] = name[i];
@@ -768,9 +736,6 @@ static int efi_pstore_write(enum pstore_type_id type,
768 736
769 spin_unlock(&efivars->lock); 737 spin_unlock(&efivars->lock);
770 738
771 if (found)
772 efivar_unregister(found);
773
774 if (size) 739 if (size)
775 ret = efivar_create_sysfs_entry(efivars, 740 ret = efivar_create_sysfs_entry(efivars,
776 utf16_strsize(efi_name, 741 utf16_strsize(efi_name,