Hi Mark, On 5/25/23 21:31, Mark Pearson wrote: > Add mutex protection around cases where an operation needs multiple > WMI calls - e.g. setting password. > > Signed-off-by: Mark Pearson <mpearson-lenovo@xxxxxxxxx> > --- > Changes in V2: New commit added after review of other patches in series. > > drivers/platform/x86/think-lmi.c | 46 ++++++++++++++++++++++++-------- > 1 file changed, 35 insertions(+), 11 deletions(-) > > diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c > index 64cd453d6e7d..f3e1e4dacba2 100644 > --- a/drivers/platform/x86/think-lmi.c > +++ b/drivers/platform/x86/think-lmi.c > @@ -14,6 +14,7 @@ > #include <linux/acpi.h> > #include <linux/errno.h> > #include <linux/fs.h> > +#include <linux/mutex.h> > #include <linux/string.h> > #include <linux/types.h> > #include <linux/dmi.h> > @@ -195,6 +196,7 @@ static const char * const level_options[] = { > }; > static struct think_lmi tlmi_priv; > static struct class *fw_attr_class; > +static DEFINE_MUTEX(tlmi_mutex); > > /* ------ Utility functions ------------*/ > /* Strip out CR if one is present */ > @@ -463,23 +465,32 @@ static ssize_t new_password_store(struct kobject *kobj, > sprintf(pwd_type, "%s", setting->pwd_type); > } > > + mutex_lock(&tlmi_mutex); > ret = tlmi_opcode_setting("WmiOpcodePasswordType", pwd_type); > - if (ret) > + if (ret) { > + mutex_unlock(&tlmi_mutex); > goto out; > - > + } > if (tlmi_priv.pwd_admin->valid) { > ret = tlmi_opcode_setting("WmiOpcodePasswordAdmin", > tlmi_priv.pwd_admin->password); > - if (ret) > + if (ret) { > + mutex_unlock(&tlmi_mutex); > goto out; > + } > } > ret = tlmi_opcode_setting("WmiOpcodePasswordCurrent01", setting->password); > - if (ret) > + if (ret) { > + mutex_unlock(&tlmi_mutex); > goto out; > + } > ret = tlmi_opcode_setting("WmiOpcodePasswordNew01", new_pwd); > - if (ret) > + if (ret) { > + mutex_unlock(&tlmi_mutex); > goto out; > + } > ret = tlmi_simple_call(LENOVO_OPCODE_IF_GUID, "WmiOpcodePasswordSetUpdate;"); > + mutex_unlock(&tlmi_mutex); > } else { > /* Format: 'PasswordType,CurrentPw,NewPw,Encoding,KbdLang;' */ > auth_str = kasprintf(GFP_KERNEL, "%s,%s,%s,%s,%s;", I haven't take a really close / good look yet. But at a first glance I think it would be cleaner to just take the mutex at the top and unlock it after the out label to which all the existing goto-s already go ? > @@ -1000,11 +1011,16 @@ static ssize_t current_value_store(struct kobject *kobj, > goto out; > } > > + mutex_lock(&tlmi_mutex); > ret = tlmi_simple_call(LENOVO_SET_BIOS_SETTING_CERT_GUID, set_str); > - if (ret) > + if (ret) { > + mutex_unlock(&tlmi_mutex); > goto out; > + } > ret = tlmi_simple_call(LENOVO_SAVE_BIOS_SETTING_CERT_GUID, > tlmi_priv.pwd_admin->save_signature); > + > + mutex_unlock(&tlmi_mutex); > if (ret) > goto out; > } else if (tlmi_priv.opcode_support) { > @@ -1021,18 +1037,23 @@ static ssize_t current_value_store(struct kobject *kobj, > goto out; > } > > + mutex_lock(&tlmi_mutex); > ret = tlmi_simple_call(LENOVO_SET_BIOS_SETTINGS_GUID, set_str); > - if (ret) > + if (ret) { > + mutex_unlock(&tlmi_mutex); > goto out; > + } > > if (tlmi_priv.pwd_admin->valid && tlmi_priv.pwd_admin->password[0]) { > ret = tlmi_opcode_setting("WmiOpcodePasswordAdmin", > tlmi_priv.pwd_admin->password); > - if (ret) > + if (ret) { > + mutex_unlock(&tlmi_mutex); > goto out; > + } > } > - > ret = tlmi_save_bios_settings(""); > + mutex_unlock(&tlmi_mutex); > } else { /* old non opcode based authentication method (deprecated)*/ > if (tlmi_priv.pwd_admin->valid && tlmi_priv.pwd_admin->password[0]) { > auth_str = kasprintf(GFP_KERNEL, "%s,%s,%s;", > @@ -1056,14 +1077,17 @@ static ssize_t current_value_store(struct kobject *kobj, > goto out; > } > > + mutex_lock(&tlmi_mutex); > ret = tlmi_simple_call(LENOVO_SET_BIOS_SETTINGS_GUID, set_str); > - if (ret) > + if (ret) { > + mutex_unlock(&tlmi_mutex); > goto out; > - > + } > if (auth_str) > ret = tlmi_save_bios_settings(auth_str); > else > ret = tlmi_save_bios_settings(""); > + mutex_unlock(&tlmi_mutex); > } > if (!ret && !tlmi_priv.pending_changes) { > tlmi_priv.pending_changes = true; And the same here. Regards, Hans