forked from mirrors/linux
		
	efi: Don't use spinlocks for efi vars
All efivars operations are protected by a spinlock which prevents interruptions and preemption. This is too restricted, we just need a lock preventing concurrency. The idea is to use a semaphore of count 1 and to have two ways of locking, depending on the context: - In interrupt context, we call down_trylock(), if it fails we return an error - In normal context, we call down_interruptible() We don't use a mutex here because the mutex_trylock() function must not be called from interrupt context, whereas the down_trylock() can. Signed-off-by: Sylvain Chouleur <sylvain.chouleur@intel.com> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Leif Lindholm <leif.lindholm@linaro.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Sylvain Chouleur <sylvain.chouleur@gmail.com> Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk>
This commit is contained in:
		
							parent
							
								
									217b27d467
								
							
						
					
					
						commit
						21b3ddd39f
					
				
					 6 changed files with 139 additions and 76 deletions
				
			
		| 
						 | 
					@ -125,16 +125,19 @@ static void efi_pstore_scan_sysfs_enter(struct efivar_entry *pos,
 | 
				
			||||||
 * @entry: deleting entry
 | 
					 * @entry: deleting entry
 | 
				
			||||||
 * @turn_off_scanning: Check if a scanning flag should be turned off
 | 
					 * @turn_off_scanning: Check if a scanning flag should be turned off
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static inline void __efi_pstore_scan_sysfs_exit(struct efivar_entry *entry,
 | 
					static inline int __efi_pstore_scan_sysfs_exit(struct efivar_entry *entry,
 | 
				
			||||||
						bool turn_off_scanning)
 | 
											bool turn_off_scanning)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (entry->deleting) {
 | 
						if (entry->deleting) {
 | 
				
			||||||
		list_del(&entry->list);
 | 
							list_del(&entry->list);
 | 
				
			||||||
		efivar_entry_iter_end();
 | 
							efivar_entry_iter_end();
 | 
				
			||||||
		efivar_unregister(entry);
 | 
							efivar_unregister(entry);
 | 
				
			||||||
		efivar_entry_iter_begin();
 | 
							if (efivar_entry_iter_begin())
 | 
				
			||||||
 | 
								return -EINTR;
 | 
				
			||||||
	} else if (turn_off_scanning)
 | 
						} else if (turn_off_scanning)
 | 
				
			||||||
		entry->scanning = false;
 | 
							entry->scanning = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -144,13 +147,18 @@ static inline void __efi_pstore_scan_sysfs_exit(struct efivar_entry *entry,
 | 
				
			||||||
 * @head: list head
 | 
					 * @head: list head
 | 
				
			||||||
 * @stop: a flag checking if scanning will stop
 | 
					 * @stop: a flag checking if scanning will stop
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void efi_pstore_scan_sysfs_exit(struct efivar_entry *pos,
 | 
					static int efi_pstore_scan_sysfs_exit(struct efivar_entry *pos,
 | 
				
			||||||
				       struct efivar_entry *next,
 | 
									       struct efivar_entry *next,
 | 
				
			||||||
				       struct list_head *head, bool stop)
 | 
									       struct list_head *head, bool stop)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	__efi_pstore_scan_sysfs_exit(pos, true);
 | 
						int ret = __efi_pstore_scan_sysfs_exit(pos, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (stop)
 | 
						if (stop)
 | 
				
			||||||
		__efi_pstore_scan_sysfs_exit(next, &next->list != head);
 | 
							ret = __efi_pstore_scan_sysfs_exit(next, &next->list != head);
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -172,13 +180,17 @@ static int efi_pstore_sysfs_entry_iter(void *data, struct efivar_entry **pos)
 | 
				
			||||||
	struct efivar_entry *entry, *n;
 | 
						struct efivar_entry *entry, *n;
 | 
				
			||||||
	struct list_head *head = &efivar_sysfs_list;
 | 
						struct list_head *head = &efivar_sysfs_list;
 | 
				
			||||||
	int size = 0;
 | 
						int size = 0;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!*pos) {
 | 
						if (!*pos) {
 | 
				
			||||||
		list_for_each_entry_safe(entry, n, head, list) {
 | 
							list_for_each_entry_safe(entry, n, head, list) {
 | 
				
			||||||
			efi_pstore_scan_sysfs_enter(entry, n, head);
 | 
								efi_pstore_scan_sysfs_enter(entry, n, head);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			size = efi_pstore_read_func(entry, data);
 | 
								size = efi_pstore_read_func(entry, data);
 | 
				
			||||||
			efi_pstore_scan_sysfs_exit(entry, n, head, size < 0);
 | 
								ret = efi_pstore_scan_sysfs_exit(entry, n, head,
 | 
				
			||||||
 | 
												 size < 0);
 | 
				
			||||||
 | 
								if (ret)
 | 
				
			||||||
 | 
									return ret;
 | 
				
			||||||
			if (size)
 | 
								if (size)
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -190,7 +202,9 @@ static int efi_pstore_sysfs_entry_iter(void *data, struct efivar_entry **pos)
 | 
				
			||||||
		efi_pstore_scan_sysfs_enter((*pos), n, head);
 | 
							efi_pstore_scan_sysfs_enter((*pos), n, head);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		size = efi_pstore_read_func((*pos), data);
 | 
							size = efi_pstore_read_func((*pos), data);
 | 
				
			||||||
		efi_pstore_scan_sysfs_exit((*pos), n, head, size < 0);
 | 
							ret = efi_pstore_scan_sysfs_exit((*pos), n, head, size < 0);
 | 
				
			||||||
 | 
							if (ret)
 | 
				
			||||||
 | 
								return ret;
 | 
				
			||||||
		if (size)
 | 
							if (size)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -232,7 +246,10 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
 | 
				
			||||||
	if (!*data.buf)
 | 
						if (!*data.buf)
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	efivar_entry_iter_begin();
 | 
						if (efivar_entry_iter_begin()) {
 | 
				
			||||||
 | 
							kfree(*data.buf);
 | 
				
			||||||
 | 
							return -EINTR;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	size = efi_pstore_sysfs_entry_iter(&data,
 | 
						size = efi_pstore_sysfs_entry_iter(&data,
 | 
				
			||||||
					   (struct efivar_entry **)&psi->data);
 | 
										   (struct efivar_entry **)&psi->data);
 | 
				
			||||||
	efivar_entry_iter_end();
 | 
						efivar_entry_iter_end();
 | 
				
			||||||
| 
						 | 
					@ -347,7 +364,8 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
 | 
				
			||||||
	edata.time = time;
 | 
						edata.time = time;
 | 
				
			||||||
	edata.name = efi_name;
 | 
						edata.name = efi_name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	efivar_entry_iter_begin();
 | 
						if (efivar_entry_iter_begin())
 | 
				
			||||||
 | 
							return -EINTR;
 | 
				
			||||||
	found = __efivar_entry_iter(efi_pstore_erase_func, &efivar_sysfs_list, &edata, &entry);
 | 
						found = __efivar_entry_iter(efi_pstore_erase_func, &efivar_sysfs_list, &edata, &entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (found && !entry->scanning) {
 | 
						if (found && !entry->scanning) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -510,7 +510,8 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
 | 
				
			||||||
		vendor = del_var->VendorGuid;
 | 
							vendor = del_var->VendorGuid;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	efivar_entry_iter_begin();
 | 
						if (efivar_entry_iter_begin())
 | 
				
			||||||
 | 
							return -EINTR;
 | 
				
			||||||
	entry = efivar_entry_find(name, vendor, &efivar_sysfs_list, true);
 | 
						entry = efivar_entry_find(name, vendor, &efivar_sysfs_list, true);
 | 
				
			||||||
	if (!entry)
 | 
						if (!entry)
 | 
				
			||||||
		err = -EINVAL;
 | 
							err = -EINVAL;
 | 
				
			||||||
| 
						 | 
					@ -575,7 +576,10 @@ efivar_create_sysfs_entry(struct efivar_entry *new_var)
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	kobject_uevent(&new_var->kobj, KOBJ_ADD);
 | 
						kobject_uevent(&new_var->kobj, KOBJ_ADD);
 | 
				
			||||||
	efivar_entry_add(new_var, &efivar_sysfs_list);
 | 
						if (efivar_entry_add(new_var, &efivar_sysfs_list)) {
 | 
				
			||||||
 | 
							efivar_unregister(new_var);
 | 
				
			||||||
 | 
							return -EINTR;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -690,7 +694,10 @@ static int efivars_sysfs_callback(efi_char16_t *name, efi_guid_t vendor,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int efivar_sysfs_destroy(struct efivar_entry *entry, void *data)
 | 
					static int efivar_sysfs_destroy(struct efivar_entry *entry, void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	efivar_entry_remove(entry);
 | 
						int err = efivar_entry_remove(entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (err)
 | 
				
			||||||
 | 
							return err;
 | 
				
			||||||
	efivar_unregister(entry);
 | 
						efivar_unregister(entry);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -698,7 +705,14 @@ static int efivar_sysfs_destroy(struct efivar_entry *entry, void *data)
 | 
				
			||||||
static void efivars_sysfs_exit(void)
 | 
					static void efivars_sysfs_exit(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/* Remove all entries and destroy */
 | 
						/* Remove all entries and destroy */
 | 
				
			||||||
	__efivar_entry_iter(efivar_sysfs_destroy, &efivar_sysfs_list, NULL, NULL);
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = __efivar_entry_iter(efivar_sysfs_destroy, &efivar_sysfs_list,
 | 
				
			||||||
 | 
									  NULL, NULL);
 | 
				
			||||||
 | 
						if (err) {
 | 
				
			||||||
 | 
							pr_err("efivars: Failed to destroy sysfs entries\n");
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (efivars_new_var)
 | 
						if (efivars_new_var)
 | 
				
			||||||
		sysfs_remove_bin_file(&efivars_kset->kobj, efivars_new_var);
 | 
							sysfs_remove_bin_file(&efivars_kset->kobj, efivars_new_var);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,7 +43,7 @@ static struct efivars *__efivars;
 | 
				
			||||||
 * 2) ->ops calls
 | 
					 * 2) ->ops calls
 | 
				
			||||||
 * 3) (un)registration of __efivars
 | 
					 * 3) (un)registration of __efivars
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static DEFINE_SPINLOCK(efivars_lock);
 | 
					static DEFINE_SEMAPHORE(efivars_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool efivar_wq_enabled = true;
 | 
					static bool efivar_wq_enabled = true;
 | 
				
			||||||
DECLARE_WORK(efivar_work, NULL);
 | 
					DECLARE_WORK(efivar_work, NULL);
 | 
				
			||||||
| 
						 | 
					@ -442,7 +442,10 @@ int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *),
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock_irq(&efivars_lock);
 | 
						if (down_interruptible(&efivars_lock)) {
 | 
				
			||||||
 | 
							err = -EINTR;
 | 
				
			||||||
 | 
							goto free;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Per EFI spec, the maximum storage allocated for both
 | 
						 * Per EFI spec, the maximum storage allocated for both
 | 
				
			||||||
| 
						 | 
					@ -458,7 +461,7 @@ int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *),
 | 
				
			||||||
		switch (status) {
 | 
							switch (status) {
 | 
				
			||||||
		case EFI_SUCCESS:
 | 
							case EFI_SUCCESS:
 | 
				
			||||||
			if (duplicates)
 | 
								if (duplicates)
 | 
				
			||||||
				spin_unlock_irq(&efivars_lock);
 | 
									up(&efivars_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			variable_name_size = var_name_strnsize(variable_name,
 | 
								variable_name_size = var_name_strnsize(variable_name,
 | 
				
			||||||
							       variable_name_size);
 | 
												       variable_name_size);
 | 
				
			||||||
| 
						 | 
					@ -484,8 +487,12 @@ int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *),
 | 
				
			||||||
					status = EFI_NOT_FOUND;
 | 
										status = EFI_NOT_FOUND;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (duplicates)
 | 
								if (duplicates) {
 | 
				
			||||||
				spin_lock_irq(&efivars_lock);
 | 
									if (down_interruptible(&efivars_lock)) {
 | 
				
			||||||
 | 
										err = -EINTR;
 | 
				
			||||||
 | 
										goto free;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case EFI_NOT_FOUND:
 | 
							case EFI_NOT_FOUND:
 | 
				
			||||||
| 
						 | 
					@ -499,8 +506,8 @@ int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	} while (status != EFI_NOT_FOUND);
 | 
						} while (status != EFI_NOT_FOUND);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_unlock_irq(&efivars_lock);
 | 
						up(&efivars_lock);
 | 
				
			||||||
 | 
					free:
 | 
				
			||||||
	kfree(variable_name);
 | 
						kfree(variable_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
| 
						 | 
					@ -511,24 +518,34 @@ EXPORT_SYMBOL_GPL(efivar_init);
 | 
				
			||||||
 * efivar_entry_add - add entry to variable list
 | 
					 * efivar_entry_add - add entry to variable list
 | 
				
			||||||
 * @entry: entry to add to list
 | 
					 * @entry: entry to add to list
 | 
				
			||||||
 * @head: list head
 | 
					 * @head: list head
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Returns 0 on success, or a kernel error code on failure.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void efivar_entry_add(struct efivar_entry *entry, struct list_head *head)
 | 
					int efivar_entry_add(struct efivar_entry *entry, struct list_head *head)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	spin_lock_irq(&efivars_lock);
 | 
						if (down_interruptible(&efivars_lock))
 | 
				
			||||||
 | 
							return -EINTR;
 | 
				
			||||||
	list_add(&entry->list, head);
 | 
						list_add(&entry->list, head);
 | 
				
			||||||
	spin_unlock_irq(&efivars_lock);
 | 
						up(&efivars_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(efivar_entry_add);
 | 
					EXPORT_SYMBOL_GPL(efivar_entry_add);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * efivar_entry_remove - remove entry from variable list
 | 
					 * efivar_entry_remove - remove entry from variable list
 | 
				
			||||||
 * @entry: entry to remove from list
 | 
					 * @entry: entry to remove from list
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Returns 0 on success, or a kernel error code on failure.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void efivar_entry_remove(struct efivar_entry *entry)
 | 
					int efivar_entry_remove(struct efivar_entry *entry)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	spin_lock_irq(&efivars_lock);
 | 
						if (down_interruptible(&efivars_lock))
 | 
				
			||||||
 | 
							return -EINTR;
 | 
				
			||||||
	list_del(&entry->list);
 | 
						list_del(&entry->list);
 | 
				
			||||||
	spin_unlock_irq(&efivars_lock);
 | 
						up(&efivars_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(efivar_entry_remove);
 | 
					EXPORT_SYMBOL_GPL(efivar_entry_remove);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -545,10 +562,8 @@ EXPORT_SYMBOL_GPL(efivar_entry_remove);
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void efivar_entry_list_del_unlock(struct efivar_entry *entry)
 | 
					static void efivar_entry_list_del_unlock(struct efivar_entry *entry)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	lockdep_assert_held(&efivars_lock);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	list_del(&entry->list);
 | 
						list_del(&entry->list);
 | 
				
			||||||
	spin_unlock_irq(&efivars_lock);
 | 
						up(&efivars_lock);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -571,8 +586,6 @@ int __efivar_entry_delete(struct efivar_entry *entry)
 | 
				
			||||||
	const struct efivar_operations *ops = __efivars->ops;
 | 
						const struct efivar_operations *ops = __efivars->ops;
 | 
				
			||||||
	efi_status_t status;
 | 
						efi_status_t status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lockdep_assert_held(&efivars_lock);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	status = ops->set_variable(entry->var.VariableName,
 | 
						status = ops->set_variable(entry->var.VariableName,
 | 
				
			||||||
				   &entry->var.VendorGuid,
 | 
									   &entry->var.VendorGuid,
 | 
				
			||||||
				   0, 0, NULL);
 | 
									   0, 0, NULL);
 | 
				
			||||||
| 
						 | 
					@ -589,20 +602,22 @@ EXPORT_SYMBOL_GPL(__efivar_entry_delete);
 | 
				
			||||||
 * variable list. It is the caller's responsibility to free @entry
 | 
					 * variable list. It is the caller's responsibility to free @entry
 | 
				
			||||||
 * once we return.
 | 
					 * once we return.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Returns 0 on success, or a converted EFI status code if
 | 
					 * Returns 0 on success, -EINTR if we can't grab the semaphore,
 | 
				
			||||||
 * set_variable() fails.
 | 
					 * converted EFI status code if set_variable() fails.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int efivar_entry_delete(struct efivar_entry *entry)
 | 
					int efivar_entry_delete(struct efivar_entry *entry)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const struct efivar_operations *ops = __efivars->ops;
 | 
						const struct efivar_operations *ops = __efivars->ops;
 | 
				
			||||||
	efi_status_t status;
 | 
						efi_status_t status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock_irq(&efivars_lock);
 | 
						if (down_interruptible(&efivars_lock))
 | 
				
			||||||
 | 
							return -EINTR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	status = ops->set_variable(entry->var.VariableName,
 | 
						status = ops->set_variable(entry->var.VariableName,
 | 
				
			||||||
				   &entry->var.VendorGuid,
 | 
									   &entry->var.VendorGuid,
 | 
				
			||||||
				   0, 0, NULL);
 | 
									   0, 0, NULL);
 | 
				
			||||||
	if (!(status == EFI_SUCCESS || status == EFI_NOT_FOUND)) {
 | 
						if (!(status == EFI_SUCCESS || status == EFI_NOT_FOUND)) {
 | 
				
			||||||
		spin_unlock_irq(&efivars_lock);
 | 
							up(&efivars_lock);
 | 
				
			||||||
		return efi_status_to_err(status);
 | 
							return efi_status_to_err(status);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -628,9 +643,9 @@ EXPORT_SYMBOL_GPL(efivar_entry_delete);
 | 
				
			||||||
 * If @head is not NULL a lookup is performed to determine whether
 | 
					 * If @head is not NULL a lookup is performed to determine whether
 | 
				
			||||||
 * the entry is already on the list.
 | 
					 * the entry is already on the list.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Returns 0 on success, -EEXIST if a lookup is performed and the entry
 | 
					 * Returns 0 on success, -EINTR if we can't grab the semaphore,
 | 
				
			||||||
 * already exists on the list, or a converted EFI status code if
 | 
					 * -EEXIST if a lookup is performed and the entry already exists on
 | 
				
			||||||
 * set_variable() fails.
 | 
					 * the list, or a converted EFI status code if set_variable() fails.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int efivar_entry_set(struct efivar_entry *entry, u32 attributes,
 | 
					int efivar_entry_set(struct efivar_entry *entry, u32 attributes,
 | 
				
			||||||
		     unsigned long size, void *data, struct list_head *head)
 | 
							     unsigned long size, void *data, struct list_head *head)
 | 
				
			||||||
| 
						 | 
					@ -640,10 +655,10 @@ int efivar_entry_set(struct efivar_entry *entry, u32 attributes,
 | 
				
			||||||
	efi_char16_t *name = entry->var.VariableName;
 | 
						efi_char16_t *name = entry->var.VariableName;
 | 
				
			||||||
	efi_guid_t vendor = entry->var.VendorGuid;
 | 
						efi_guid_t vendor = entry->var.VendorGuid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock_irq(&efivars_lock);
 | 
						if (down_interruptible(&efivars_lock))
 | 
				
			||||||
 | 
							return -EINTR;
 | 
				
			||||||
	if (head && efivar_entry_find(name, vendor, head, false)) {
 | 
						if (head && efivar_entry_find(name, vendor, head, false)) {
 | 
				
			||||||
		spin_unlock_irq(&efivars_lock);
 | 
							up(&efivars_lock);
 | 
				
			||||||
		return -EEXIST;
 | 
							return -EEXIST;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -652,7 +667,7 @@ int efivar_entry_set(struct efivar_entry *entry, u32 attributes,
 | 
				
			||||||
		status = ops->set_variable(name, &vendor,
 | 
							status = ops->set_variable(name, &vendor,
 | 
				
			||||||
					   attributes, size, data);
 | 
										   attributes, size, data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_unlock_irq(&efivars_lock);
 | 
						up(&efivars_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return efi_status_to_err(status);
 | 
						return efi_status_to_err(status);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -673,23 +688,22 @@ efivar_entry_set_nonblocking(efi_char16_t *name, efi_guid_t vendor,
 | 
				
			||||||
			     u32 attributes, unsigned long size, void *data)
 | 
								     u32 attributes, unsigned long size, void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const struct efivar_operations *ops = __efivars->ops;
 | 
						const struct efivar_operations *ops = __efivars->ops;
 | 
				
			||||||
	unsigned long flags;
 | 
					 | 
				
			||||||
	efi_status_t status;
 | 
						efi_status_t status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!spin_trylock_irqsave(&efivars_lock, flags))
 | 
						if (down_trylock(&efivars_lock))
 | 
				
			||||||
		return -EBUSY;
 | 
							return -EBUSY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	status = check_var_size_nonblocking(attributes,
 | 
						status = check_var_size_nonblocking(attributes,
 | 
				
			||||||
					    size + ucs2_strsize(name, 1024));
 | 
										    size + ucs2_strsize(name, 1024));
 | 
				
			||||||
	if (status != EFI_SUCCESS) {
 | 
						if (status != EFI_SUCCESS) {
 | 
				
			||||||
		spin_unlock_irqrestore(&efivars_lock, flags);
 | 
							up(&efivars_lock);
 | 
				
			||||||
		return -ENOSPC;
 | 
							return -ENOSPC;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	status = ops->set_variable_nonblocking(name, &vendor, attributes,
 | 
						status = ops->set_variable_nonblocking(name, &vendor, attributes,
 | 
				
			||||||
					       size, data);
 | 
										       size, data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_unlock_irqrestore(&efivars_lock, flags);
 | 
						up(&efivars_lock);
 | 
				
			||||||
	return efi_status_to_err(status);
 | 
						return efi_status_to_err(status);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -714,7 +728,6 @@ int efivar_entry_set_safe(efi_char16_t *name, efi_guid_t vendor, u32 attributes,
 | 
				
			||||||
			  bool block, unsigned long size, void *data)
 | 
								  bool block, unsigned long size, void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const struct efivar_operations *ops = __efivars->ops;
 | 
						const struct efivar_operations *ops = __efivars->ops;
 | 
				
			||||||
	unsigned long flags;
 | 
					 | 
				
			||||||
	efi_status_t status;
 | 
						efi_status_t status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!ops->query_variable_store)
 | 
						if (!ops->query_variable_store)
 | 
				
			||||||
| 
						 | 
					@ -735,21 +748,22 @@ int efivar_entry_set_safe(efi_char16_t *name, efi_guid_t vendor, u32 attributes,
 | 
				
			||||||
						    size, data);
 | 
											    size, data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!block) {
 | 
						if (!block) {
 | 
				
			||||||
		if (!spin_trylock_irqsave(&efivars_lock, flags))
 | 
							if (down_trylock(&efivars_lock))
 | 
				
			||||||
			return -EBUSY;
 | 
								return -EBUSY;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		spin_lock_irqsave(&efivars_lock, flags);
 | 
							if (down_interruptible(&efivars_lock))
 | 
				
			||||||
 | 
								return -EINTR;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	status = check_var_size(attributes, size + ucs2_strsize(name, 1024));
 | 
						status = check_var_size(attributes, size + ucs2_strsize(name, 1024));
 | 
				
			||||||
	if (status != EFI_SUCCESS) {
 | 
						if (status != EFI_SUCCESS) {
 | 
				
			||||||
		spin_unlock_irqrestore(&efivars_lock, flags);
 | 
							up(&efivars_lock);
 | 
				
			||||||
		return -ENOSPC;
 | 
							return -ENOSPC;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	status = ops->set_variable(name, &vendor, attributes, size, data);
 | 
						status = ops->set_variable(name, &vendor, attributes, size, data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_unlock_irqrestore(&efivars_lock, flags);
 | 
						up(&efivars_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return efi_status_to_err(status);
 | 
						return efi_status_to_err(status);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -779,8 +793,6 @@ struct efivar_entry *efivar_entry_find(efi_char16_t *name, efi_guid_t guid,
 | 
				
			||||||
	int strsize1, strsize2;
 | 
						int strsize1, strsize2;
 | 
				
			||||||
	bool found = false;
 | 
						bool found = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lockdep_assert_held(&efivars_lock);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	list_for_each_entry_safe(entry, n, head, list) {
 | 
						list_for_each_entry_safe(entry, n, head, list) {
 | 
				
			||||||
		strsize1 = ucs2_strsize(name, 1024);
 | 
							strsize1 = ucs2_strsize(name, 1024);
 | 
				
			||||||
		strsize2 = ucs2_strsize(entry->var.VariableName, 1024);
 | 
							strsize2 = ucs2_strsize(entry->var.VariableName, 1024);
 | 
				
			||||||
| 
						 | 
					@ -822,10 +834,11 @@ int efivar_entry_size(struct efivar_entry *entry, unsigned long *size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	*size = 0;
 | 
						*size = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock_irq(&efivars_lock);
 | 
						if (down_interruptible(&efivars_lock))
 | 
				
			||||||
 | 
							return -EINTR;
 | 
				
			||||||
	status = ops->get_variable(entry->var.VariableName,
 | 
						status = ops->get_variable(entry->var.VariableName,
 | 
				
			||||||
				   &entry->var.VendorGuid, NULL, size, NULL);
 | 
									   &entry->var.VendorGuid, NULL, size, NULL);
 | 
				
			||||||
	spin_unlock_irq(&efivars_lock);
 | 
						up(&efivars_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (status != EFI_BUFFER_TOO_SMALL)
 | 
						if (status != EFI_BUFFER_TOO_SMALL)
 | 
				
			||||||
		return efi_status_to_err(status);
 | 
							return efi_status_to_err(status);
 | 
				
			||||||
| 
						 | 
					@ -851,8 +864,6 @@ int __efivar_entry_get(struct efivar_entry *entry, u32 *attributes,
 | 
				
			||||||
	const struct efivar_operations *ops = __efivars->ops;
 | 
						const struct efivar_operations *ops = __efivars->ops;
 | 
				
			||||||
	efi_status_t status;
 | 
						efi_status_t status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lockdep_assert_held(&efivars_lock);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	status = ops->get_variable(entry->var.VariableName,
 | 
						status = ops->get_variable(entry->var.VariableName,
 | 
				
			||||||
				   &entry->var.VendorGuid,
 | 
									   &entry->var.VendorGuid,
 | 
				
			||||||
				   attributes, size, data);
 | 
									   attributes, size, data);
 | 
				
			||||||
| 
						 | 
					@ -874,11 +885,12 @@ int efivar_entry_get(struct efivar_entry *entry, u32 *attributes,
 | 
				
			||||||
	const struct efivar_operations *ops = __efivars->ops;
 | 
						const struct efivar_operations *ops = __efivars->ops;
 | 
				
			||||||
	efi_status_t status;
 | 
						efi_status_t status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock_irq(&efivars_lock);
 | 
						if (down_interruptible(&efivars_lock))
 | 
				
			||||||
 | 
							return -EINTR;
 | 
				
			||||||
	status = ops->get_variable(entry->var.VariableName,
 | 
						status = ops->get_variable(entry->var.VariableName,
 | 
				
			||||||
				   &entry->var.VendorGuid,
 | 
									   &entry->var.VendorGuid,
 | 
				
			||||||
				   attributes, size, data);
 | 
									   attributes, size, data);
 | 
				
			||||||
	spin_unlock_irq(&efivars_lock);
 | 
						up(&efivars_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return efi_status_to_err(status);
 | 
						return efi_status_to_err(status);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -925,7 +937,8 @@ int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes,
 | 
				
			||||||
	 * set_variable call, and removal of the variable from the efivars
 | 
						 * set_variable call, and removal of the variable from the efivars
 | 
				
			||||||
	 * list (in the case of an authenticated delete).
 | 
						 * list (in the case of an authenticated delete).
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	spin_lock_irq(&efivars_lock);
 | 
						if (down_interruptible(&efivars_lock))
 | 
				
			||||||
 | 
							return -EINTR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Ensure that the available space hasn't shrunk below the safe level
 | 
						 * Ensure that the available space hasn't shrunk below the safe level
 | 
				
			||||||
| 
						 | 
					@ -965,7 +978,7 @@ int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes,
 | 
				
			||||||
	if (status == EFI_NOT_FOUND)
 | 
						if (status == EFI_NOT_FOUND)
 | 
				
			||||||
		efivar_entry_list_del_unlock(entry);
 | 
							efivar_entry_list_del_unlock(entry);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		spin_unlock_irq(&efivars_lock);
 | 
							up(&efivars_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (status && status != EFI_BUFFER_TOO_SMALL)
 | 
						if (status && status != EFI_BUFFER_TOO_SMALL)
 | 
				
			||||||
		return efi_status_to_err(status);
 | 
							return efi_status_to_err(status);
 | 
				
			||||||
| 
						 | 
					@ -973,7 +986,7 @@ int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes,
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
	spin_unlock_irq(&efivars_lock);
 | 
						up(&efivars_lock);
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -986,9 +999,9 @@ EXPORT_SYMBOL_GPL(efivar_entry_set_get_size);
 | 
				
			||||||
 * efivar_entry_iter_end() is called. This function is usually used in
 | 
					 * efivar_entry_iter_end() is called. This function is usually used in
 | 
				
			||||||
 * conjunction with __efivar_entry_iter() or efivar_entry_iter().
 | 
					 * conjunction with __efivar_entry_iter() or efivar_entry_iter().
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void efivar_entry_iter_begin(void)
 | 
					int efivar_entry_iter_begin(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	spin_lock_irq(&efivars_lock);
 | 
						return down_interruptible(&efivars_lock);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(efivar_entry_iter_begin);
 | 
					EXPORT_SYMBOL_GPL(efivar_entry_iter_begin);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -999,7 +1012,7 @@ EXPORT_SYMBOL_GPL(efivar_entry_iter_begin);
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void efivar_entry_iter_end(void)
 | 
					void efivar_entry_iter_end(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	spin_unlock_irq(&efivars_lock);
 | 
						up(&efivars_lock);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(efivar_entry_iter_end);
 | 
					EXPORT_SYMBOL_GPL(efivar_entry_iter_end);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1075,7 +1088,9 @@ int efivar_entry_iter(int (*func)(struct efivar_entry *, void *),
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int err = 0;
 | 
						int err = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	efivar_entry_iter_begin();
 | 
						err = efivar_entry_iter_begin();
 | 
				
			||||||
 | 
						if (err)
 | 
				
			||||||
 | 
							return err;
 | 
				
			||||||
	err = __efivar_entry_iter(func, head, data, NULL);
 | 
						err = __efivar_entry_iter(func, head, data, NULL);
 | 
				
			||||||
	efivar_entry_iter_end();
 | 
						efivar_entry_iter_end();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1120,12 +1135,17 @@ int efivars_register(struct efivars *efivars,
 | 
				
			||||||
		     const struct efivar_operations *ops,
 | 
							     const struct efivar_operations *ops,
 | 
				
			||||||
		     struct kobject *kobject)
 | 
							     struct kobject *kobject)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	spin_lock_irq(&efivars_lock);
 | 
						if (down_interruptible(&efivars_lock))
 | 
				
			||||||
 | 
							return -EINTR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	efivars->ops = ops;
 | 
						efivars->ops = ops;
 | 
				
			||||||
	efivars->kobject = kobject;
 | 
						efivars->kobject = kobject;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	__efivars = efivars;
 | 
						__efivars = efivars;
 | 
				
			||||||
	spin_unlock_irq(&efivars_lock);
 | 
					
 | 
				
			||||||
 | 
						pr_info("Registered efivars operations\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						up(&efivars_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1142,7 +1162,9 @@ int efivars_unregister(struct efivars *efivars)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int rv;
 | 
						int rv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock_irq(&efivars_lock);
 | 
						if (down_interruptible(&efivars_lock))
 | 
				
			||||||
 | 
							return -EINTR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!__efivars) {
 | 
						if (!__efivars) {
 | 
				
			||||||
		printk(KERN_ERR "efivars not registered\n");
 | 
							printk(KERN_ERR "efivars not registered\n");
 | 
				
			||||||
		rv = -EINVAL;
 | 
							rv = -EINVAL;
 | 
				
			||||||
| 
						 | 
					@ -1154,11 +1176,12 @@ int efivars_unregister(struct efivars *efivars)
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pr_info("Unregistered efivars operations\n");
 | 
				
			||||||
	__efivars = NULL;
 | 
						__efivars = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rv = 0;
 | 
						rv = 0;
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
	spin_unlock_irq(&efivars_lock);
 | 
						up(&efivars_lock);
 | 
				
			||||||
	return rv;
 | 
						return rv;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(efivars_unregister);
 | 
					EXPORT_SYMBOL_GPL(efivars_unregister);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -105,7 +105,10 @@ static int efivarfs_create(struct inode *dir, struct dentry *dentry,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inode->i_private = var;
 | 
						inode->i_private = var;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	efivar_entry_add(var, &efivarfs_list);
 | 
						err = efivar_entry_add(var, &efivarfs_list);
 | 
				
			||||||
 | 
						if (err)
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	d_instantiate(dentry, inode);
 | 
						d_instantiate(dentry, inode);
 | 
				
			||||||
	dget(dentry);
 | 
						dget(dentry);
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -161,7 +161,9 @@ static int efivarfs_callback(efi_char16_t *name16, efi_guid_t vendor,
 | 
				
			||||||
	kfree(name);
 | 
						kfree(name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	efivar_entry_size(entry, &size);
 | 
						efivar_entry_size(entry, &size);
 | 
				
			||||||
	efivar_entry_add(entry, &efivarfs_list);
 | 
						err = efivar_entry_add(entry, &efivarfs_list);
 | 
				
			||||||
 | 
						if (err)
 | 
				
			||||||
 | 
							goto fail_inode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inode_lock(inode);
 | 
						inode_lock(inode);
 | 
				
			||||||
	inode->i_private = entry;
 | 
						inode->i_private = entry;
 | 
				
			||||||
| 
						 | 
					@ -182,7 +184,10 @@ static int efivarfs_callback(efi_char16_t *name16, efi_guid_t vendor,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int efivarfs_destroy(struct efivar_entry *entry, void *data)
 | 
					static int efivarfs_destroy(struct efivar_entry *entry, void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	efivar_entry_remove(entry);
 | 
						int err = efivar_entry_remove(entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (err)
 | 
				
			||||||
 | 
							return err;
 | 
				
			||||||
	kfree(entry);
 | 
						kfree(entry);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1297,8 +1297,8 @@ struct kobject *efivars_kobject(void);
 | 
				
			||||||
int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *),
 | 
					int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *),
 | 
				
			||||||
		void *data, bool duplicates, struct list_head *head);
 | 
							void *data, bool duplicates, struct list_head *head);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void efivar_entry_add(struct efivar_entry *entry, struct list_head *head);
 | 
					int efivar_entry_add(struct efivar_entry *entry, struct list_head *head);
 | 
				
			||||||
void efivar_entry_remove(struct efivar_entry *entry);
 | 
					int 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_delete(struct efivar_entry *entry);
 | 
					int efivar_entry_delete(struct efivar_entry *entry);
 | 
				
			||||||
| 
						 | 
					@ -1315,7 +1315,7 @@ int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes,
 | 
				
			||||||
int efivar_entry_set_safe(efi_char16_t *name, efi_guid_t vendor, u32 attributes,
 | 
					int efivar_entry_set_safe(efi_char16_t *name, efi_guid_t vendor, u32 attributes,
 | 
				
			||||||
			  bool block, unsigned long size, void *data);
 | 
								  bool block, unsigned long size, void *data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void efivar_entry_iter_begin(void);
 | 
					int efivar_entry_iter_begin(void);
 | 
				
			||||||
void efivar_entry_iter_end(void);
 | 
					void efivar_entry_iter_end(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int __efivar_entry_iter(int (*func)(struct efivar_entry *, void *),
 | 
					int __efivar_entry_iter(int (*func)(struct efivar_entry *, void *),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue