Merge branch 'next' into efi-next-merge

Conflicts:
	arch/x86/boot/compressed/eboot.c
This commit is contained in:
Matt Fleming
2014-10-03 22:15:56 +01:00
20 changed files with 528 additions and 123 deletions

View File

@@ -321,11 +321,11 @@ static unsigned long var_name_strnsize(efi_char16_t *variable_name,
* Print a warning when duplicate EFI variables are encountered and
* disable the sysfs workqueue since the firmware is buggy.
*/
static void dup_variable_bug(efi_char16_t *s16, efi_guid_t *vendor_guid,
static void dup_variable_bug(efi_char16_t *str16, efi_guid_t *vendor_guid,
unsigned long len16)
{
size_t i, len8 = len16 / sizeof(efi_char16_t);
char *s8;
char *str8;
/*
* Disable the workqueue since the algorithm it uses for
@@ -334,16 +334,16 @@ static void dup_variable_bug(efi_char16_t *s16, efi_guid_t *vendor_guid,
*/
efivar_wq_enabled = false;
s8 = kzalloc(len8, GFP_KERNEL);
if (!s8)
str8 = kzalloc(len8, GFP_KERNEL);
if (!str8)
return;
for (i = 0; i < len8; i++)
s8[i] = s16[i];
str8[i] = str16[i];
printk(KERN_WARNING "efivars: duplicate variable: %s-%pUl\n",
s8, vendor_guid);
kfree(s8);
str8, vendor_guid);
kfree(str8);
}
/**
@@ -595,6 +595,39 @@ int efivar_entry_set(struct efivar_entry *entry, u32 attributes,
}
EXPORT_SYMBOL_GPL(efivar_entry_set);
/*
* efivar_entry_set_nonblocking - call set_variable_nonblocking()
*
* This function is guaranteed to not block and is suitable for calling
* from crash/panic handlers.
*
* Crucially, this function will not block if it cannot acquire
* __efivars->lock. Instead, it returns -EBUSY.
*/
static int
efivar_entry_set_nonblocking(efi_char16_t *name, efi_guid_t vendor,
u32 attributes, unsigned long size, void *data)
{
const struct efivar_operations *ops = __efivars->ops;
unsigned long flags;
efi_status_t status;
if (!spin_trylock_irqsave(&__efivars->lock, flags))
return -EBUSY;
status = check_var_size(attributes, size + ucs2_strsize(name, 1024));
if (status != EFI_SUCCESS) {
spin_unlock_irqrestore(&__efivars->lock, flags);
return -ENOSPC;
}
status = ops->set_variable_nonblocking(name, &vendor, attributes,
size, data);
spin_unlock_irqrestore(&__efivars->lock, flags);
return efi_status_to_err(status);
}
/**
* efivar_entry_set_safe - call set_variable() if enough space in firmware
* @name: buffer containing the variable name
@@ -622,6 +655,20 @@ int efivar_entry_set_safe(efi_char16_t *name, efi_guid_t vendor, u32 attributes,
if (!ops->query_variable_store)
return -ENOSYS;
/*
* If the EFI variable backend provides a non-blocking
* ->set_variable() operation and we're in a context where we
* cannot block, then we need to use it to avoid live-locks,
* since the implication is that the regular ->set_variable()
* will block.
*
* If no ->set_variable_nonblocking() is provided then
* ->set_variable() is assumed to be non-blocking.
*/
if (!block && ops->set_variable_nonblocking)
return efivar_entry_set_nonblocking(name, vendor, attributes,
size, data);
if (!block) {
if (!spin_trylock_irqsave(&__efivars->lock, flags))
return -EBUSY;