aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2013-04-29 15:08:02 -0400
committerMatt Fleming <matt.fleming@intel.com>2013-04-30 11:03:10 -0400
commit8a415b8c05f261a52f45f2271b6c4731376fd5b5 (patch)
treede233c9382c3f4a08fcdd1b26be38810fdf2ce25 /drivers/firmware
parent12abcfde1ad3ee9bed726d25fdd4eeb31026b187 (diff)
efi, pstore: Read data from variable store before memcpy()
Seiji reported getting empty dmesg-* files, because the data was never actually read in efi_pstore_read_func(), and so the memcpy() was copying garbage data. This patch necessitated adding __efivar_entry_get() which is callable between efivar_entry_iter_{begin,end}(). We can also delete __efivar_entry_size() because efi_pstore_read_func() was the only caller. Reported-by: Seiji Aguchi <seiji.aguchi@hds.com> Tested-by: Seiji Aguchi <seiji.aguchi@hds.com> Cc: Tony Luck <tony.luck@intel.com> Cc: Matthew Garrett <matthew.garrett@nebula.com> Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/efi/efi-pstore.c6
-rw-r--r--drivers/firmware/efi/vars.c45
2 files changed, 28 insertions, 23 deletions
diff --git a/drivers/firmware/efi/efi-pstore.c b/drivers/firmware/efi/efi-pstore.c
index af45c42086e1..67615d6d038d 100644
--- a/drivers/firmware/efi/efi-pstore.c
+++ b/drivers/firmware/efi/efi-pstore.c
@@ -73,7 +73,11 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
73 } else 73 } else
74 return 0; 74 return 0;
75 75
76 __efivar_entry_size(entry, &size); 76 entry->var.DataSize = 1024;
77 __efivar_entry_get(entry, &entry->var.Attributes,
78 &entry->var.DataSize, entry->var.Data);
79 size = entry->var.DataSize;
80
77 *cb_data->buf = kmalloc(size, GFP_KERNEL); 81 *cb_data->buf = kmalloc(size, GFP_KERNEL);
78 if (*cb_data->buf == NULL) 82 if (*cb_data->buf == NULL)
79 return -ENOMEM; 83 return -ENOMEM;
diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c
index 1d80c1ca39c5..96d328b21c3e 100644
--- a/drivers/firmware/efi/vars.c
+++ b/drivers/firmware/efi/vars.c
@@ -689,54 +689,55 @@ struct efivar_entry *efivar_entry_find(efi_char16_t *name, efi_guid_t guid,
689EXPORT_SYMBOL_GPL(efivar_entry_find); 689EXPORT_SYMBOL_GPL(efivar_entry_find);
690 690
691/** 691/**
692 * __efivar_entry_size - obtain the size of a variable 692 * efivar_entry_size - obtain the size of a variable
693 * @entry: entry for this variable 693 * @entry: entry for this variable
694 * @size: location to store the variable's size 694 * @size: location to store the variable's size
695 *
696 * The caller MUST call efivar_entry_iter_begin() and
697 * efivar_entry_iter_end() before and after the invocation of this
698 * function, respectively.
699 */ 695 */
700int __efivar_entry_size(struct efivar_entry *entry, unsigned long *size) 696int efivar_entry_size(struct efivar_entry *entry, unsigned long *size)
701{ 697{
702 const struct efivar_operations *ops = __efivars->ops; 698 const struct efivar_operations *ops = __efivars->ops;
703 efi_status_t status; 699 efi_status_t status;
704 700
705 WARN_ON(!spin_is_locked(&__efivars->lock));
706
707 *size = 0; 701 *size = 0;
702
703 spin_lock_irq(&__efivars->lock);
708 status = ops->get_variable(entry->var.VariableName, 704 status = ops->get_variable(entry->var.VariableName,
709 &entry->var.VendorGuid, NULL, size, NULL); 705 &entry->var.VendorGuid, NULL, size, NULL);
706 spin_unlock_irq(&__efivars->lock);
707
710 if (status != EFI_BUFFER_TOO_SMALL) 708 if (status != EFI_BUFFER_TOO_SMALL)
711 return efi_status_to_err(status); 709 return efi_status_to_err(status);
712 710
713 return 0; 711 return 0;
714} 712}
715EXPORT_SYMBOL_GPL(__efivar_entry_size); 713EXPORT_SYMBOL_GPL(efivar_entry_size);
716 714
717/** 715/**
718 * efivar_entry_size - obtain the size of a variable 716 * __efivar_entry_get - call get_variable()
719 * @entry: entry for this variable 717 * @entry: read data for this variable
720 * @size: location to store the variable's size 718 * @attributes: variable attributes
719 * @size: size of @data buffer
720 * @data: buffer to store variable data
721 *
722 * The caller MUST call efivar_entry_iter_begin() and
723 * efivar_entry_iter_end() before and after the invocation of this
724 * function, respectively.
721 */ 725 */
722int efivar_entry_size(struct efivar_entry *entry, unsigned long *size) 726int __efivar_entry_get(struct efivar_entry *entry, u32 *attributes,
727 unsigned long *size, void *data)
723{ 728{
724 const struct efivar_operations *ops = __efivars->ops; 729 const struct efivar_operations *ops = __efivars->ops;
725 efi_status_t status; 730 efi_status_t status;
726 731
727 *size = 0; 732 WARN_ON(!spin_is_locked(&__efivars->lock));
728 733
729 spin_lock_irq(&__efivars->lock);
730 status = ops->get_variable(entry->var.VariableName, 734 status = ops->get_variable(entry->var.VariableName,
731 &entry->var.VendorGuid, NULL, size, NULL); 735 &entry->var.VendorGuid,
732 spin_unlock_irq(&__efivars->lock); 736 attributes, size, data);
733
734 if (status != EFI_BUFFER_TOO_SMALL)
735 return efi_status_to_err(status);
736 737
737 return 0; 738 return efi_status_to_err(status);
738} 739}
739EXPORT_SYMBOL_GPL(efivar_entry_size); 740EXPORT_SYMBOL_GPL(__efivar_entry_get);
740 741
741/** 742/**
742 * efivar_entry_get - call get_variable() 743 * efivar_entry_get - call get_variable()