/* Private pointer to registered efivars */
static struct efivars *__efivars;
+/*
+ * efivars_lock protects three things:
+ * 1) efivarfs_list and efivars_sysfs_list
+ * 2) ->ops calls
+ * 3) (un)registration of __efivars
+ */
+static DEFINE_SPINLOCK(efivars_lock);
+
static bool efivar_wq_enabled = true;
DECLARE_WORK(efivar_work, NULL);
EXPORT_SYMBOL_GPL(efivar_work);
return -ENOMEM;
}
- spin_lock_irq(&__efivars->lock);
+ spin_lock_irq(&efivars_lock);
/*
* Per EFI spec, the maximum storage allocated for both
switch (status) {
case EFI_SUCCESS:
if (duplicates)
- spin_unlock_irq(&__efivars->lock);
+ spin_unlock_irq(&efivars_lock);
variable_name_size = var_name_strnsize(variable_name,
variable_name_size);
}
if (duplicates)
- spin_lock_irq(&__efivars->lock);
+ spin_lock_irq(&efivars_lock);
break;
case EFI_NOT_FOUND:
} while (status != EFI_NOT_FOUND);
- spin_unlock_irq(&__efivars->lock);
+ spin_unlock_irq(&efivars_lock);
kfree(variable_name);
*/
void efivar_entry_add(struct efivar_entry *entry, struct list_head *head)
{
- spin_lock_irq(&__efivars->lock);
+ spin_lock_irq(&efivars_lock);
list_add(&entry->list, head);
- spin_unlock_irq(&__efivars->lock);
+ spin_unlock_irq(&efivars_lock);
}
EXPORT_SYMBOL_GPL(efivar_entry_add);
*/
void efivar_entry_remove(struct efivar_entry *entry)
{
- spin_lock_irq(&__efivars->lock);
+ spin_lock_irq(&efivars_lock);
list_del(&entry->list);
- spin_unlock_irq(&__efivars->lock);
+ spin_unlock_irq(&efivars_lock);
}
EXPORT_SYMBOL_GPL(efivar_entry_remove);
*/
static void efivar_entry_list_del_unlock(struct efivar_entry *entry)
{
- lockdep_assert_held(&__efivars->lock);
+ lockdep_assert_held(&efivars_lock);
list_del(&entry->list);
- spin_unlock_irq(&__efivars->lock);
+ spin_unlock_irq(&efivars_lock);
}
/**
const struct efivar_operations *ops = __efivars->ops;
efi_status_t status;
- lockdep_assert_held(&__efivars->lock);
+ lockdep_assert_held(&efivars_lock);
status = ops->set_variable(entry->var.VariableName,
&entry->var.VendorGuid,
const struct efivar_operations *ops = __efivars->ops;
efi_status_t status;
- spin_lock_irq(&__efivars->lock);
+ spin_lock_irq(&efivars_lock);
status = ops->set_variable(entry->var.VariableName,
&entry->var.VendorGuid,
0, 0, NULL);
if (!(status == EFI_SUCCESS || status == EFI_NOT_FOUND)) {
- spin_unlock_irq(&__efivars->lock);
+ spin_unlock_irq(&efivars_lock);
return efi_status_to_err(status);
}
efi_char16_t *name = entry->var.VariableName;
efi_guid_t vendor = entry->var.VendorGuid;
- spin_lock_irq(&__efivars->lock);
+ spin_lock_irq(&efivars_lock);
if (head && efivar_entry_find(name, vendor, head, false)) {
- spin_unlock_irq(&__efivars->lock);
+ spin_unlock_irq(&efivars_lock);
return -EEXIST;
}
status = ops->set_variable(name, &vendor,
attributes, size, data);
- spin_unlock_irq(&__efivars->lock);
+ spin_unlock_irq(&efivars_lock);
return efi_status_to_err(status);
* from crash/panic handlers.
*
* Crucially, this function will not block if it cannot acquire
- * __efivars->lock. Instead, it returns -EBUSY.
+ * efivars_lock. Instead, it returns -EBUSY.
*/
static int
efivar_entry_set_nonblocking(efi_char16_t *name, efi_guid_t vendor,
unsigned long flags;
efi_status_t status;
- if (!spin_trylock_irqsave(&__efivars->lock, flags))
+ if (!spin_trylock_irqsave(&efivars_lock, flags))
return -EBUSY;
status = check_var_size_nonblocking(attributes,
size + ucs2_strsize(name, 1024));
if (status != EFI_SUCCESS) {
- spin_unlock_irqrestore(&__efivars->lock, flags);
+ spin_unlock_irqrestore(&efivars_lock, flags);
return -ENOSPC;
}
status = ops->set_variable_nonblocking(name, &vendor, attributes,
size, data);
- spin_unlock_irqrestore(&__efivars->lock, flags);
+ spin_unlock_irqrestore(&efivars_lock, flags);
return efi_status_to_err(status);
}
size, data);
if (!block) {
- if (!spin_trylock_irqsave(&__efivars->lock, flags))
+ if (!spin_trylock_irqsave(&efivars_lock, flags))
return -EBUSY;
} else {
- spin_lock_irqsave(&__efivars->lock, flags);
+ spin_lock_irqsave(&efivars_lock, flags);
}
status = check_var_size(attributes, size + ucs2_strsize(name, 1024));
if (status != EFI_SUCCESS) {
- spin_unlock_irqrestore(&__efivars->lock, flags);
+ spin_unlock_irqrestore(&efivars_lock, flags);
return -ENOSPC;
}
status = ops->set_variable(name, &vendor, attributes, size, data);
- spin_unlock_irqrestore(&__efivars->lock, flags);
+ spin_unlock_irqrestore(&efivars_lock, flags);
return efi_status_to_err(status);
}
int strsize1, strsize2;
bool found = false;
- lockdep_assert_held(&__efivars->lock);
+ lockdep_assert_held(&efivars_lock);
list_for_each_entry_safe(entry, n, head, list) {
strsize1 = ucs2_strsize(name, 1024);
*size = 0;
- spin_lock_irq(&__efivars->lock);
+ spin_lock_irq(&efivars_lock);
status = ops->get_variable(entry->var.VariableName,
&entry->var.VendorGuid, NULL, size, NULL);
- spin_unlock_irq(&__efivars->lock);
+ spin_unlock_irq(&efivars_lock);
if (status != EFI_BUFFER_TOO_SMALL)
return efi_status_to_err(status);
const struct efivar_operations *ops = __efivars->ops;
efi_status_t status;
- lockdep_assert_held(&__efivars->lock);
+ lockdep_assert_held(&efivars_lock);
status = ops->get_variable(entry->var.VariableName,
&entry->var.VendorGuid,
const struct efivar_operations *ops = __efivars->ops;
efi_status_t status;
- spin_lock_irq(&__efivars->lock);
+ spin_lock_irq(&efivars_lock);
status = ops->get_variable(entry->var.VariableName,
&entry->var.VendorGuid,
attributes, size, data);
- spin_unlock_irq(&__efivars->lock);
+ spin_unlock_irq(&efivars_lock);
return efi_status_to_err(status);
}
* set_variable call, and removal of the variable from the efivars
* list (in the case of an authenticated delete).
*/
- spin_lock_irq(&__efivars->lock);
+ spin_lock_irq(&efivars_lock);
/*
* Ensure that the available space hasn't shrunk below the safe level
if (status == EFI_NOT_FOUND)
efivar_entry_list_del_unlock(entry);
else
- spin_unlock_irq(&__efivars->lock);
+ spin_unlock_irq(&efivars_lock);
if (status && status != EFI_BUFFER_TOO_SMALL)
return efi_status_to_err(status);
return 0;
out:
- spin_unlock_irq(&__efivars->lock);
+ spin_unlock_irq(&efivars_lock);
return err;
}
*/
void efivar_entry_iter_begin(void)
{
- spin_lock_irq(&__efivars->lock);
+ spin_lock_irq(&efivars_lock);
}
EXPORT_SYMBOL_GPL(efivar_entry_iter_begin);
*/
void efivar_entry_iter_end(void)
{
- spin_unlock_irq(&__efivars->lock);
+ spin_unlock_irq(&efivars_lock);
}
EXPORT_SYMBOL_GPL(efivar_entry_iter_end);
const struct efivar_operations *ops,
struct kobject *kobject)
{
- spin_lock_init(&efivars->lock);
+ spin_lock_irq(&efivars_lock);
efivars->ops = ops;
efivars->kobject = kobject;
__efivars = efivars;
+ spin_unlock_irq(&efivars_lock);
return 0;
}
{
int rv;
+ spin_lock_irq(&efivars_lock);
if (!__efivars) {
printk(KERN_ERR "efivars not registered\n");
rv = -EINVAL;
rv = 0;
out:
+ spin_unlock_irq(&efivars_lock);
return rv;
}
EXPORT_SYMBOL_GPL(efivars_unregister);