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>
This commit is contained in:
parent
12abcfde1a
commit
8a415b8c05
|
@ -73,7 +73,11 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
|
|||
} else
|
||||
return 0;
|
||||
|
||||
__efivar_entry_size(entry, &size);
|
||||
entry->var.DataSize = 1024;
|
||||
__efivar_entry_get(entry, &entry->var.Attributes,
|
||||
&entry->var.DataSize, entry->var.Data);
|
||||
size = entry->var.DataSize;
|
||||
|
||||
*cb_data->buf = kmalloc(size, GFP_KERNEL);
|
||||
if (*cb_data->buf == NULL)
|
||||
return -ENOMEM;
|
||||
|
|
|
@ -688,32 +688,6 @@ struct efivar_entry *efivar_entry_find(efi_char16_t *name, efi_guid_t guid,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(efivar_entry_find);
|
||||
|
||||
/**
|
||||
* __efivar_entry_size - obtain the size of a variable
|
||||
* @entry: entry for this variable
|
||||
* @size: location to store the variable's size
|
||||
*
|
||||
* The caller MUST call efivar_entry_iter_begin() and
|
||||
* efivar_entry_iter_end() before and after the invocation of this
|
||||
* function, respectively.
|
||||
*/
|
||||
int __efivar_entry_size(struct efivar_entry *entry, unsigned long *size)
|
||||
{
|
||||
const struct efivar_operations *ops = __efivars->ops;
|
||||
efi_status_t status;
|
||||
|
||||
WARN_ON(!spin_is_locked(&__efivars->lock));
|
||||
|
||||
*size = 0;
|
||||
status = ops->get_variable(entry->var.VariableName,
|
||||
&entry->var.VendorGuid, NULL, size, NULL);
|
||||
if (status != EFI_BUFFER_TOO_SMALL)
|
||||
return efi_status_to_err(status);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__efivar_entry_size);
|
||||
|
||||
/**
|
||||
* efivar_entry_size - obtain the size of a variable
|
||||
* @entry: entry for this variable
|
||||
|
@ -738,6 +712,33 @@ int efivar_entry_size(struct efivar_entry *entry, unsigned long *size)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(efivar_entry_size);
|
||||
|
||||
/**
|
||||
* __efivar_entry_get - call get_variable()
|
||||
* @entry: read data for this variable
|
||||
* @attributes: variable attributes
|
||||
* @size: size of @data buffer
|
||||
* @data: buffer to store variable data
|
||||
*
|
||||
* The caller MUST call efivar_entry_iter_begin() and
|
||||
* efivar_entry_iter_end() before and after the invocation of this
|
||||
* function, respectively.
|
||||
*/
|
||||
int __efivar_entry_get(struct efivar_entry *entry, u32 *attributes,
|
||||
unsigned long *size, void *data)
|
||||
{
|
||||
const struct efivar_operations *ops = __efivars->ops;
|
||||
efi_status_t status;
|
||||
|
||||
WARN_ON(!spin_is_locked(&__efivars->lock));
|
||||
|
||||
status = ops->get_variable(entry->var.VariableName,
|
||||
&entry->var.VendorGuid,
|
||||
attributes, size, data);
|
||||
|
||||
return efi_status_to_err(status);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__efivar_entry_get);
|
||||
|
||||
/**
|
||||
* efivar_entry_get - call get_variable()
|
||||
* @entry: read data for this variable
|
||||
|
|
|
@ -808,8 +808,9 @@ void efivar_entry_remove(struct efivar_entry *entry);
|
|||
int __efivar_entry_delete(struct efivar_entry *entry);
|
||||
int efivar_entry_delete(struct efivar_entry *entry);
|
||||
|
||||
int __efivar_entry_size(struct efivar_entry *entry, unsigned long *size);
|
||||
int efivar_entry_size(struct efivar_entry *entry, unsigned long *size);
|
||||
int __efivar_entry_get(struct efivar_entry *entry, u32 *attributes,
|
||||
unsigned long *size, void *data);
|
||||
int efivar_entry_get(struct efivar_entry *entry, u32 *attributes,
|
||||
unsigned long *size, void *data);
|
||||
int efivar_entry_set(struct efivar_entry *entry, u32 attributes,
|
||||
|
|
Loading…
Reference in New Issue