diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-23 14:45:09 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-23 14:45:09 -0700 | 
| commit | 8c81f48e16fbe103e682d7ee7b2f16d065c42954 (patch) | |
| tree | 1eac3abf36ed9330b3d5f9e550d1ccbc0c174f9b /drivers/firmware | |
| parent | 5de551e0eeddf470928e9fee59825a3645641bc7 (diff) | |
| parent | 75b128573b275d5a5a7210b98c4b8cb3b39c12e7 (diff) | |
Merge branch 'x86-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 EFI updates from Peter Anvin:
 "This patchset falls under the "maintainers that grovel" clause in the
  v3.18-rc1 announcement.  We had intended to push it late in the merge
  window since we got it into the -tip tree relatively late.
  Many of these are relatively simple things, but there are a couple of
  key bits, especially Ard's and Matt's patches"
* 'x86-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (24 commits)
  rtc: Disable EFI rtc for x86
  efi: rtc-efi: Export platform:rtc-efi as module alias
  efi: Delete the in_nmi() conditional runtime locking
  efi: Provide a non-blocking SetVariable() operation
  x86/efi: Adding efi_printks on memory allocationa and pci.reads
  x86/efi: Mark initialization code as such
  x86/efi: Update comment regarding required phys mapped EFI services
  x86/efi: Unexport add_efi_memmap variable
  x86/efi: Remove unused efi_call* macros
  efi: Resolve some shadow warnings
  arm64: efi: Format EFI memory type & attrs with efi_md_typeattr_format()
  ia64: efi: Format EFI memory type & attrs with efi_md_typeattr_format()
  x86: efi: Format EFI memory type & attrs with efi_md_typeattr_format()
  efi: Introduce efi_md_typeattr_format()
  efi: Add macro for EFI_MEMORY_UCE memory attribute
  x86/efi: Clear EFI_RUNTIME_SERVICES if failing to enter virtual mode
  arm64/efi: Do not enter virtual mode if booting with efi=noruntime or noefi
  arm64/efi: uefi_init error handling fix
  efi: Add kernel param efi=noruntime
  lib: Add a generic cmdline parse function parse_option_str
  ...
Diffstat (limited to 'drivers/firmware')
| -rw-r--r-- | drivers/firmware/efi/efi.c | 79 | ||||
| -rw-r--r-- | drivers/firmware/efi/libstub/arm-stub.c | 4 | ||||
| -rw-r--r-- | drivers/firmware/efi/libstub/efi-stub-helper.c | 62 | ||||
| -rw-r--r-- | drivers/firmware/efi/runtime-wrappers.c | 164 | ||||
| -rw-r--r-- | drivers/firmware/efi/vars.c | 61 | 
5 files changed, 351 insertions, 19 deletions
| diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 64ecbb501c50..8590099ac148 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -41,6 +41,28 @@ struct efi __read_mostly efi = {  };  EXPORT_SYMBOL(efi); +static bool disable_runtime; +static int __init setup_noefi(char *arg) +{ +	disable_runtime = true; +	return 0; +} +early_param("noefi", setup_noefi); + +bool efi_runtime_disabled(void) +{ +	return disable_runtime; +} + +static int __init parse_efi_cmdline(char *str) +{ +	if (parse_option_str(str, "noruntime")) +		disable_runtime = true; + +	return 0; +} +early_param("efi", parse_efi_cmdline); +  static struct kobject *efi_kobj;  static struct kobject *efivars_kobj; @@ -423,3 +445,60 @@ int __init efi_get_fdt_params(struct efi_fdt_params *params, int verbose)  	return ret;  }  #endif /* CONFIG_EFI_PARAMS_FROM_FDT */ + +static __initdata char memory_type_name[][20] = { +	"Reserved", +	"Loader Code", +	"Loader Data", +	"Boot Code", +	"Boot Data", +	"Runtime Code", +	"Runtime Data", +	"Conventional Memory", +	"Unusable Memory", +	"ACPI Reclaim Memory", +	"ACPI Memory NVS", +	"Memory Mapped I/O", +	"MMIO Port Space", +	"PAL Code" +}; + +char * __init efi_md_typeattr_format(char *buf, size_t size, +				     const efi_memory_desc_t *md) +{ +	char *pos; +	int type_len; +	u64 attr; + +	pos = buf; +	if (md->type >= ARRAY_SIZE(memory_type_name)) +		type_len = snprintf(pos, size, "[type=%u", md->type); +	else +		type_len = snprintf(pos, size, "[%-*s", +				    (int)(sizeof(memory_type_name[0]) - 1), +				    memory_type_name[md->type]); +	if (type_len >= size) +		return buf; + +	pos += type_len; +	size -= type_len; + +	attr = md->attribute; +	if (attr & ~(EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT | +		     EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_WP | +		     EFI_MEMORY_RP | EFI_MEMORY_XP | EFI_MEMORY_RUNTIME)) +		snprintf(pos, size, "|attr=0x%016llx]", +			 (unsigned long long)attr); +	else +		snprintf(pos, size, "|%3s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]", +			 attr & EFI_MEMORY_RUNTIME ? "RUN" : "", +			 attr & EFI_MEMORY_XP      ? "XP"  : "", +			 attr & EFI_MEMORY_RP      ? "RP"  : "", +			 attr & EFI_MEMORY_WP      ? "WP"  : "", +			 attr & EFI_MEMORY_UCE     ? "UCE" : "", +			 attr & EFI_MEMORY_WB      ? "WB"  : "", +			 attr & EFI_MEMORY_WT      ? "WT"  : "", +			 attr & EFI_MEMORY_WC      ? "WC"  : "", +			 attr & EFI_MEMORY_UC      ? "UC"  : ""); +	return buf; +} diff --git a/drivers/firmware/efi/libstub/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c index 480339b6b110..75ee05964cbc 100644 --- a/drivers/firmware/efi/libstub/arm-stub.c +++ b/drivers/firmware/efi/libstub/arm-stub.c @@ -226,6 +226,10 @@ unsigned long __init efi_entry(void *handle, efi_system_table_t *sys_table,  		goto fail_free_image;  	} +	status = efi_parse_options(cmdline_ptr); +	if (status != EFI_SUCCESS) +		pr_efi_err(sys_table, "Failed to parse EFI cmdline options\n"); +  	/*  	 * Unauthenticated device tree data is a security hazard, so  	 * ignore 'dtb=' unless UEFI Secure Boot is disabled. diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c index 32d5cca30f49..a920fec8fe88 100644 --- a/drivers/firmware/efi/libstub/efi-stub-helper.c +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c @@ -15,8 +15,23 @@  #include "efistub.h" +/* + * Some firmware implementations have problems reading files in one go. + * A read chunk size of 1MB seems to work for most platforms. + * + * Unfortunately, reading files in chunks triggers *other* bugs on some + * platforms, so we provide a way to disable this workaround, which can + * be done by passing "efi=nochunk" on the EFI boot stub command line. + * + * If you experience issues with initrd images being corrupt it's worth + * trying efi=nochunk, but chunking is enabled by default because there + * are far more machines that require the workaround than those that + * break with it enabled. + */  #define EFI_READ_CHUNK_SIZE	(1024 * 1024) +static unsigned long __chunk_size = EFI_READ_CHUNK_SIZE; +  struct file_info {  	efi_file_handle_t *handle;  	u64 size; @@ -281,6 +296,49 @@ void efi_free(efi_system_table_t *sys_table_arg, unsigned long size,  	efi_call_early(free_pages, addr, nr_pages);  } +/* + * Parse the ASCII string 'cmdline' for EFI options, denoted by the efi= + * option, e.g. efi=nochunk. + * + * It should be noted that efi= is parsed in two very different + * environments, first in the early boot environment of the EFI boot + * stub, and subsequently during the kernel boot. + */ +efi_status_t efi_parse_options(char *cmdline) +{ +	char *str; + +	/* +	 * If no EFI parameters were specified on the cmdline we've got +	 * nothing to do. +	 */ +	str = strstr(cmdline, "efi="); +	if (!str) +		return EFI_SUCCESS; + +	/* Skip ahead to first argument */ +	str += strlen("efi="); + +	/* +	 * Remember, because efi= is also used by the kernel we need to +	 * skip over arguments we don't understand. +	 */ +	while (*str) { +		if (!strncmp(str, "nochunk", 7)) { +			str += strlen("nochunk"); +			__chunk_size = -1UL; +		} + +		/* Group words together, delimited by "," */ +		while (*str && *str != ',') +			str++; + +		if (*str == ',') +			str++; +	} + +	return EFI_SUCCESS; +}  /*   * Check the cmdline for a LILO-style file= arguments. @@ -423,8 +481,8 @@ efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,  			size = files[j].size;  			while (size) {  				unsigned long chunksize; -				if (size > EFI_READ_CHUNK_SIZE) -					chunksize = EFI_READ_CHUNK_SIZE; +				if (size > __chunk_size) +					chunksize = __chunk_size;  				else  					chunksize = size; diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c index 10daa4bbb258..228bbf910461 100644 --- a/drivers/firmware/efi/runtime-wrappers.c +++ b/drivers/firmware/efi/runtime-wrappers.c @@ -14,11 +14,80 @@   * This file is released under the GPLv2.   */ +#include <linux/bug.h>  #include <linux/efi.h> -#include <linux/spinlock.h>             /* spinlock_t */ +#include <linux/mutex.h> +#include <linux/spinlock.h>  #include <asm/efi.h>  /* + * According to section 7.1 of the UEFI spec, Runtime Services are not fully + * reentrant, and there are particular combinations of calls that need to be + * serialized. (source: UEFI Specification v2.4A) + * + * Table 31. Rules for Reentry Into Runtime Services + * +------------------------------------+-------------------------------+ + * | If previous call is busy in	| Forbidden to call		| + * +------------------------------------+-------------------------------+ + * | Any				| SetVirtualAddressMap()	| + * +------------------------------------+-------------------------------+ + * | ConvertPointer()			| ConvertPointer()		| + * +------------------------------------+-------------------------------+ + * | SetVariable()			| ResetSystem()			| + * | UpdateCapsule()			|				| + * | SetTime()				|				| + * | SetWakeupTime()			|				| + * | GetNextHighMonotonicCount()	|				| + * +------------------------------------+-------------------------------+ + * | GetVariable()			| GetVariable()			| + * | GetNextVariableName()		| GetNextVariableName()		| + * | SetVariable()			| SetVariable()			| + * | QueryVariableInfo()		| QueryVariableInfo()		| + * | UpdateCapsule()			| UpdateCapsule()		| + * | QueryCapsuleCapabilities()		| QueryCapsuleCapabilities()	| + * | GetNextHighMonotonicCount()	| GetNextHighMonotonicCount()	| + * +------------------------------------+-------------------------------+ + * | GetTime()				| GetTime()			| + * | SetTime()				| SetTime()			| + * | GetWakeupTime()			| GetWakeupTime()		| + * | SetWakeupTime()			| SetWakeupTime()		| + * +------------------------------------+-------------------------------+ + * + * Due to the fact that the EFI pstore may write to the variable store in + * interrupt context, we need to use a spinlock for at least the groups that + * contain SetVariable() and QueryVariableInfo(). That leaves little else, as + * none of the remaining functions are actually ever called at runtime. + * So let's just use a single spinlock to serialize all Runtime Services calls. + */ +static DEFINE_SPINLOCK(efi_runtime_lock); + +/* + * Some runtime services calls can be reentrant under NMI, even if the table + * above says they are not. (source: UEFI Specification v2.4A) + * + * Table 32. Functions that may be called after Machine Check, INIT and NMI + * +----------------------------+------------------------------------------+ + * | Function			| Called after Machine Check, INIT and NMI | + * +----------------------------+------------------------------------------+ + * | GetTime()			| Yes, even if previously busy.		   | + * | GetVariable()		| Yes, even if previously busy		   | + * | GetNextVariableName()	| Yes, even if previously busy		   | + * | QueryVariableInfo()	| Yes, even if previously busy		   | + * | SetVariable()		| Yes, even if previously busy		   | + * | UpdateCapsule()		| Yes, even if previously busy		   | + * | QueryCapsuleCapabilities()	| Yes, even if previously busy		   | + * | ResetSystem()		| Yes, even if previously busy		   | + * +----------------------------+------------------------------------------+ + * + * In order to prevent deadlocks under NMI, the wrappers for these functions + * may only grab the efi_runtime_lock or rtc_lock spinlocks if !efi_in_nmi(). + * However, not all of the services listed are reachable through NMI code paths, + * so the the special handling as suggested by the UEFI spec is only implemented + * for QueryVariableInfo() and SetVariable(), as these can be reached in NMI + * context through efi_pstore_write(). + */ + +/*   * As per commit ef68c8f87ed1 ("x86: Serialize EFI time accesses on rtc_lock"),   * the EFI specification requires that callers of the time related runtime   * functions serialize with other CMOS accesses in the kernel, as the EFI time @@ -32,7 +101,9 @@ static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)  	efi_status_t status;  	spin_lock_irqsave(&rtc_lock, flags); +	spin_lock(&efi_runtime_lock);  	status = efi_call_virt(get_time, tm, tc); +	spin_unlock(&efi_runtime_lock);  	spin_unlock_irqrestore(&rtc_lock, flags);  	return status;  } @@ -43,7 +114,9 @@ static efi_status_t virt_efi_set_time(efi_time_t *tm)  	efi_status_t status;  	spin_lock_irqsave(&rtc_lock, flags); +	spin_lock(&efi_runtime_lock);  	status = efi_call_virt(set_time, tm); +	spin_unlock(&efi_runtime_lock);  	spin_unlock_irqrestore(&rtc_lock, flags);  	return status;  } @@ -56,7 +129,9 @@ static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled,  	efi_status_t status;  	spin_lock_irqsave(&rtc_lock, flags); +	spin_lock(&efi_runtime_lock);  	status = efi_call_virt(get_wakeup_time, enabled, pending, tm); +	spin_unlock(&efi_runtime_lock);  	spin_unlock_irqrestore(&rtc_lock, flags);  	return status;  } @@ -67,7 +142,9 @@ static efi_status_t virt_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)  	efi_status_t status;  	spin_lock_irqsave(&rtc_lock, flags); +	spin_lock(&efi_runtime_lock);  	status = efi_call_virt(set_wakeup_time, enabled, tm); +	spin_unlock(&efi_runtime_lock);  	spin_unlock_irqrestore(&rtc_lock, flags);  	return status;  } @@ -78,14 +155,27 @@ static efi_status_t virt_efi_get_variable(efi_char16_t *name,  					  unsigned long *data_size,  					  void *data)  { -	return efi_call_virt(get_variable, name, vendor, attr, data_size, data); +	unsigned long flags; +	efi_status_t status; + +	spin_lock_irqsave(&efi_runtime_lock, flags); +	status = efi_call_virt(get_variable, name, vendor, attr, data_size, +			       data); +	spin_unlock_irqrestore(&efi_runtime_lock, flags); +	return status;  }  static efi_status_t virt_efi_get_next_variable(unsigned long *name_size,  					       efi_char16_t *name,  					       efi_guid_t *vendor)  { -	return efi_call_virt(get_next_variable, name_size, name, vendor); +	unsigned long flags; +	efi_status_t status; + +	spin_lock_irqsave(&efi_runtime_lock, flags); +	status = efi_call_virt(get_next_variable, name_size, name, vendor); +	spin_unlock_irqrestore(&efi_runtime_lock, flags); +	return status;  }  static efi_status_t virt_efi_set_variable(efi_char16_t *name, @@ -94,24 +184,61 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name,  					  unsigned long data_size,  					  void *data)  { -	return efi_call_virt(set_variable, name, vendor, attr, data_size, data); +	unsigned long flags; +	efi_status_t status; + +	spin_lock_irqsave(&efi_runtime_lock, flags); +	status = efi_call_virt(set_variable, name, vendor, attr, data_size, +			       data); +	spin_unlock_irqrestore(&efi_runtime_lock, flags); +	return status;  } +static efi_status_t +virt_efi_set_variable_nonblocking(efi_char16_t *name, efi_guid_t *vendor, +				  u32 attr, unsigned long data_size, +				  void *data) +{ +	unsigned long flags; +	efi_status_t status; + +	if (!spin_trylock_irqsave(&efi_runtime_lock, flags)) +		return EFI_NOT_READY; + +	status = efi_call_virt(set_variable, name, vendor, attr, data_size, +			       data); +	spin_unlock_irqrestore(&efi_runtime_lock, flags); +	return status; +} + +  static efi_status_t virt_efi_query_variable_info(u32 attr,  						 u64 *storage_space,  						 u64 *remaining_space,  						 u64 *max_variable_size)  { +	unsigned long flags; +	efi_status_t status; +  	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)  		return EFI_UNSUPPORTED; -	return efi_call_virt(query_variable_info, attr, storage_space, -			     remaining_space, max_variable_size); +	spin_lock_irqsave(&efi_runtime_lock, flags); +	status = efi_call_virt(query_variable_info, attr, storage_space, +			       remaining_space, max_variable_size); +	spin_unlock_irqrestore(&efi_runtime_lock, flags); +	return status;  }  static efi_status_t virt_efi_get_next_high_mono_count(u32 *count)  { -	return efi_call_virt(get_next_high_mono_count, count); +	unsigned long flags; +	efi_status_t status; + +	spin_lock_irqsave(&efi_runtime_lock, flags); +	status = efi_call_virt(get_next_high_mono_count, count); +	spin_unlock_irqrestore(&efi_runtime_lock, flags); +	return status;  }  static void virt_efi_reset_system(int reset_type, @@ -119,17 +246,27 @@ static void virt_efi_reset_system(int reset_type,  				  unsigned long data_size,  				  efi_char16_t *data)  { +	unsigned long flags; + +	spin_lock_irqsave(&efi_runtime_lock, flags);  	__efi_call_virt(reset_system, reset_type, status, data_size, data); +	spin_unlock_irqrestore(&efi_runtime_lock, flags);  }  static efi_status_t virt_efi_update_capsule(efi_capsule_header_t **capsules,  					    unsigned long count,  					    unsigned long sg_list)  { +	unsigned long flags; +	efi_status_t status; +  	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)  		return EFI_UNSUPPORTED; -	return efi_call_virt(update_capsule, capsules, count, sg_list); +	spin_lock_irqsave(&efi_runtime_lock, flags); +	status = efi_call_virt(update_capsule, capsules, count, sg_list); +	spin_unlock_irqrestore(&efi_runtime_lock, flags); +	return status;  }  static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules, @@ -137,11 +274,17 @@ static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules,  						u64 *max_size,  						int *reset_type)  { +	unsigned long flags; +	efi_status_t status; +  	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)  		return EFI_UNSUPPORTED; -	return efi_call_virt(query_capsule_caps, capsules, count, max_size, -			     reset_type); +	spin_lock_irqsave(&efi_runtime_lock, flags); +	status = efi_call_virt(query_capsule_caps, capsules, count, max_size, +			       reset_type); +	spin_unlock_irqrestore(&efi_runtime_lock, flags); +	return status;  }  void efi_native_runtime_setup(void) @@ -153,6 +296,7 @@ void efi_native_runtime_setup(void)  	efi.get_variable = virt_efi_get_variable;  	efi.get_next_variable = virt_efi_get_next_variable;  	efi.set_variable = virt_efi_set_variable; +	efi.set_variable_nonblocking = virt_efi_set_variable_nonblocking;  	efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count;  	efi.reset_system = virt_efi_reset_system;  	efi.query_variable_info = virt_efi_query_variable_info; diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c index 5abe943e3404..70a0fb10517f 100644 --- a/drivers/firmware/efi/vars.c +++ b/drivers/firmware/efi/vars.c @@ -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; | 
