From: "Mark Pearson" <mpearson-lenovo@squebb.ca>
To: "Hans de Goede" <hdegoede@redhat.com>
Cc: "markgross@kernel.org" <markgross@kernel.org>,
"platform-driver-x86@vger.kernel.org"
<platform-driver-x86@vger.kernel.org>,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH 5/5] platform/x86: think-lmi: mutex protection around multiple WMI calls
Date: Fri, 26 May 2023 10:00:18 -0400 [thread overview]
Message-ID: <33ca3ba1-e770-4c75-81fc-60dc2561c68d@app.fastmail.com> (raw)
In-Reply-To: <4b49873e-48ae-1164-739f-78d96ca3a7bb@redhat.com>
On Fri, May 26, 2023, at 4:12 AM, Hans de Goede wrote:
> Hi,
>
> On 5/25/23 21:50, Mark Pearson wrote:
>>
>>
>> On Thu, May 25, 2023, at 3:41 PM, Hans de Goede wrote:
>>> 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@squebb.ca>
>>>> ---
>>>> 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 ?
>>>
>> I did consider that - and it was in my first implementation; but then I got concerned
>> about if the mutex_unlock could potentially get called without mutex_lock having been
>> called beforehand. I couldn't find any good reference as to whether that was safe or not.
>>
>> I ended up deciding that a few extra brackets and unlock calls wasn't that ugly and was 'safer'...and
>> so went that route.
>>
>> Happy to change it - but do you happen to know if it's safe to call unlock without a lock? If it is then
>> that implementation is cleaner.
>
> It is not allowed to unlock without a lock. But if you put the lock
> directly after the malloc for which the out: does the free then there
> should be no goto out paths which don't have the lock.
>
> E.g. for new_password_store() put it here:
>
> new_pwd = kstrdup(buf, GFP_KERNEL);
> if (!new_pwd)
> return -ENOMEM;
>
> mutex_lock(&tlmi_mutex);
>
> /* Strip out CR if one is present, setting password won't work if it
> is present */
> ...
>
> This does mean also taking the lock in the case where the new password
> store is done with a single WMI call, but that is not an issue. It
> makes things a tiny bit slower but WMI calls already are not fast and
> it is not like we are going to change the password / settings 100-times
> per second.
>
> And the same thing can be done in current_value_store():
>
> new_setting = kstrdup(buf, GFP_KERNEL);
> if (!new_setting)
> return -ENOMEM;
>
> mutex_lock(&tlmi_mutex);
>
> /* Strip out CR if one is present */
> ...
>
Yeah - you're right.
For some reason I was trying to do the lock only in the block of code that needed locking...but it makes more sense to do it earlier. I'll update.
Thanks!
Mark
prev parent reply other threads:[~2023-05-26 14:00 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-05-25 19:31 [PATCH 1/5] platform/x86: think-lmi: Enable opcode support on BIOS settings Mark Pearson
2023-05-25 19:31 ` [PATCH 2/5] platform/x86: think-lmi: Correct System password interface Mark Pearson
2023-05-25 19:31 ` [PATCH 3/5] platform/x86: think-lmi: Correct NVME password handling Mark Pearson
2023-05-25 19:39 ` Mark Pearson
2023-05-25 19:43 ` Hans de Goede
2023-05-25 19:45 ` Mark Pearson
2023-05-25 19:31 ` [PATCH 4/5] platform/x86: think-lmi: Don't display unnecessary authentication settings Mark Pearson
2023-05-25 19:31 ` [PATCH 5/5] platform/x86: think-lmi: mutex protection around multiple WMI calls Mark Pearson
2023-05-25 19:41 ` Hans de Goede
2023-05-25 19:50 ` Mark Pearson
2023-05-26 8:12 ` Hans de Goede
2023-05-26 14:00 ` Mark Pearson [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=33ca3ba1-e770-4c75-81fc-60dc2561c68d@app.fastmail.com \
--to=mpearson-lenovo@squebb.ca \
--cc=hdegoede@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=markgross@kernel.org \
--cc=platform-driver-x86@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®