aboutsummaryrefslogtreecommitdiffstats
path: root/fs/efivarfs
diff options
context:
space:
mode:
authorSylvain Chouleur <sylvain.chouleur@intel.com>2016-07-15 15:36:30 -0400
committerMatt Fleming <matt@codeblueprint.co.uk>2016-09-09 11:08:42 -0400
commit21b3ddd39feecd2f4d6c52bcd30f0a4fa14f125a (patch)
tree40773635e6415ce23293c67eda0327dddec90ae7 /fs/efivarfs
parent217b27d4671a0a3f34147f1b341683d36b7457db (diff)
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>
Diffstat (limited to 'fs/efivarfs')
-rw-r--r--fs/efivarfs/inode.c5
-rw-r--r--fs/efivarfs/super.c9
2 files changed, 11 insertions, 3 deletions
diff --git a/fs/efivarfs/inode.c b/fs/efivarfs/inode.c
index 1d73fc6dba13..cbb50cadcffc 100644
--- a/fs/efivarfs/inode.c
+++ b/fs/efivarfs/inode.c
@@ -105,7 +105,10 @@ static int efivarfs_create(struct inode *dir, struct dentry *dentry,
105 105
106 inode->i_private = var; 106 inode->i_private = var;
107 107
108 efivar_entry_add(var, &efivarfs_list); 108 err = efivar_entry_add(var, &efivarfs_list);
109 if (err)
110 goto out;
111
109 d_instantiate(dentry, inode); 112 d_instantiate(dentry, inode);
110 dget(dentry); 113 dget(dentry);
111out: 114out:
diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
index 688ccc16b702..01e3d6e53944 100644
--- a/fs/efivarfs/super.c
+++ b/fs/efivarfs/super.c
@@ -161,7 +161,9 @@ static int efivarfs_callback(efi_char16_t *name16, efi_guid_t vendor,
161 kfree(name); 161 kfree(name);
162 162
163 efivar_entry_size(entry, &size); 163 efivar_entry_size(entry, &size);
164 efivar_entry_add(entry, &efivarfs_list); 164 err = efivar_entry_add(entry, &efivarfs_list);
165 if (err)
166 goto fail_inode;
165 167
166 inode_lock(inode); 168 inode_lock(inode);
167 inode->i_private = entry; 169 inode->i_private = entry;
@@ -182,7 +184,10 @@ fail:
182 184
183static int efivarfs_destroy(struct efivar_entry *entry, void *data) 185static int efivarfs_destroy(struct efivar_entry *entry, void *data)
184{ 186{
185 efivar_entry_remove(entry); 187 int err = efivar_entry_remove(entry);
188
189 if (err)
190 return err;
186 kfree(entry); 191 kfree(entry);
187 return 0; 192 return 0;
188} 193}