/* 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);