mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>
To: Muralidhara M K <muralidhara.mk@amd.com>
Cc: platform-driver-x86@vger.kernel.org,
	LKML <linux-kernel@vger.kernel.org>,
	 Muthusamy Ramalingam <muthusamy.ramalingam@amd.com>
Subject: Re: [PATCH v5 8/8] platform/x86/amd/hsmp: Make metric table read locking use guard(mutex)
Date: Thu, 11 Jun 2026 16:18:01 +0300 (EEST)	[thread overview]
Message-ID: <f4086725-9d83-31f0-77be-34b8ebceb2eb@linux.intel.com> (raw)
In-Reply-To: <20260611052919.1095549-9-muralidhara.mk@amd.com>

On Thu, 11 Jun 2026, Muralidhara M K wrote:

> hsmp_metric_tbl_read() refreshes the SMU-side metric table and then
> memcpy_fromio()'s the result. Without serialization, two parallel
> readers can interleave the refresh and the copy and the caller
> observes a torn (mixed old/new) snapshot. Add a per-socket
> metric_tbl_lock so the refresh-and-copy sequence is atomic from
> userspace's point of view.
> 
> Use scoped guard(mutex) so the lock is released on every return
> path without hand-written goto chains, and initialize the mutex
> with devm_mutex_init() so no explicit mutex_destroy() cleanup is
> required.
> 
> Initialize the mutex before devm_ioremap() so the invariant
> "sock->metric_tbl_addr != NULL implies metric_tbl_lock is usable"
> holds on every error exit. Both callers of hsmp_get_tbl_dram_base()
> (init_acpi() and init_platform_device()) intentionally only log a
> failure and continue probing, so initializing the mutex after a
> successful ioremap would leave sock->metric_tbl_addr populated with
> an uninitialized lock, and the next hsmp_metric_tbl_read() would
> take guard(mutex)() on garbage memory. With the order swapped, a
> devm_mutex_init() failure returns early before metric_tbl_addr is
> ever set, and the existing NULL check in hsmp_metric_tbl_read()
> keeps rejecting the read with -ENOMEM as before.
> 
> Reviewed-by: Muthusamy Ramalingam <muthusamy.ramalingam@amd.com>
> Signed-off-by: Muralidhara M K <muralidhara.mk@amd.com>
> ---
>  drivers/platform/x86/amd/hsmp/hsmp.c | 19 +++++++++++++++++++
>  drivers/platform/x86/amd/hsmp/hsmp.h |  3 +++
>  2 files changed, 22 insertions(+)
> 
> diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c
> index a9dca97568b8..46e8dc7cfb60 100644
> --- a/drivers/platform/x86/amd/hsmp/hsmp.c
> +++ b/drivers/platform/x86/amd/hsmp/hsmp.c
> @@ -479,6 +479,7 @@ ssize_t hsmp_metric_tbl_read(struct hsmp_socket *sock, char *buf, size_t size)
>  	msg.msg_id	= HSMP_GET_METRIC_TABLE;
>  	msg.sock_ind	= sock->sock_ind;
>  
> +	guard(mutex)(&sock->metric_tbl_lock);
>  	ret = hsmp_send_message(&msg);
>  	if (ret)
>  		return ret;
> @@ -495,6 +496,24 @@ int hsmp_get_tbl_dram_base(u16 sock_ind)
>  	phys_addr_t dram_addr;
>  	int ret;
>  
> +	/*
> +	 * Initialize the per-socket lock before anything that can set
> +	 * sock->metric_tbl_addr to a non-NULL value.  hsmp_metric_tbl_read()
> +	 * gates on sock->metric_tbl_addr being non-NULL and then takes
> +	 * metric_tbl_lock unconditionally; both callers of this function
> +	 * (init_acpi() and init_platform_device()) intentionally only log
> +	 * a failure here and continue probing, so an init order that left
> +	 * metric_tbl_addr populated while devm_mutex_init() failed would
> +	 * leave the read path locking an uninitialized mutex.  Doing the
> +	 * mutex init first preserves the invariant "metric_tbl_addr !=
> +	 * NULL implies the lock is usable" on every error exit.
> +	 */
> +	ret = devm_mutex_init(sock->dev, &sock->metric_tbl_lock);
> +	if (ret) {
> +		dev_err(sock->dev, "Failed to initialize metric table lock\n");
> +		return ret;
> +	}

Sashiko flags a concurrency problem here.

This fundamentally stems from earlier design decisions:

1) hsmp_acpi_probe() is not really doing any concurrency control for 
.is_probed access. I somehow seem to recall I did brought this up earlier 
with somebody else working with this driver earlier but apparently there 
still are not locks or other concurrency control in the probe. 
I don't remember anymore what happened with it back then.

(The problem #1 is not exactly mentioned by sashiko but it's there, 
AFAICT, nothing guarantees only one probe sees !hsmp_pdev->is_probed and 
assigns to ->sock.)

2) ->sock teardown being bound to which ever socket allocated ->sock. 
Leading to use-after-free in devm_ teardown for any remove that runs after 
it.

I think the early teardown of the misc device was the only thing that 
initially prevented use-after-frees. As it kind of worked, I never voiced 
my concerns about how fragile the teardown was. Looking through the 
history now, it seems things got broken after adding hwmon code which does 
use devm and calls hsmp_send_message(). As a result, removing this driver 
is currently broken. This patch adds to the problem.


I don't think is_probed is good solution here but the release of ->sock
should be properly reference counted and that might be reusable for the 
alloc side.

>  	msg.sock_ind	= sock_ind;
>  	msg.response_sz	= hsmp_msg_desc_table[HSMP_GET_METRIC_TABLE_DRAM_ADDR].response_sz;
>  	msg.msg_id	= HSMP_GET_METRIC_TABLE_DRAM_ADDR;
> diff --git a/drivers/platform/x86/amd/hsmp/hsmp.h b/drivers/platform/x86/amd/hsmp/hsmp.h
> index e7f051475728..f7b1cbf19932 100644
> --- a/drivers/platform/x86/amd/hsmp/hsmp.h
> +++ b/drivers/platform/x86/amd/hsmp/hsmp.h
> @@ -15,6 +15,7 @@
>  #include <linux/hwmon.h>
>  #include <linux/kconfig.h>
>  #include <linux/miscdevice.h>
> +#include <linux/mutex.h>
>  #include <linux/pci.h>
>  #include <linux/semaphore.h>
>  #include <linux/sysfs.h>
> @@ -41,6 +42,8 @@ struct hsmp_socket {
>  	struct bin_attribute hsmp_attr;
>  	struct hsmp_mbaddr_info mbinfo;
>  	void __iomem *metric_tbl_addr;
> +	/* Serializes concurrent metric table refreshes from the sysfs path */
> +	struct mutex metric_tbl_lock;
>  	void __iomem *virt_base_addr;
>  	struct semaphore hsmp_sem;
>  	char name[HSMP_ATTR_GRP_NAME_SIZE];
> 

-- 
 i.


  reply	other threads:[~2026-06-11 13:18 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-11  5:29 [PATCH v5 0/8] platform/x86/amd/hsmp: Family 1Ah Model 50h-5Fh HSMP and metrics Muralidhara M K
2026-06-11  5:29 ` [PATCH v5 1/8] platform/x86/amd/hsmp: Add HSMP messages for Family 1Ah, Model 50h-5Fh Muralidhara M K
2026-06-11  5:29 ` [PATCH v5 2/8] platform/x86/amd/hsmp: Add UAPI structures for Family 1Ah Model 50h-5Fh metrics table Muralidhara M K
2026-06-11  5:29 ` [PATCH v5 3/8] platform/x86/amd/hsmp: Unify response_sz validation to an upper-bound check Muralidhara M K
2026-06-11  5:29 ` [PATCH v5 4/8] platform/x86/amd/hsmp: Source metric-table size from firmware Muralidhara M K
2026-06-11  5:29 ` [PATCH v5 5/8] platform/x86/amd/hsmp: Add IOCTL_GET_TELEMETRY_DATA for metric table reads Muralidhara M K
2026-06-11  5:29 ` [PATCH v5 6/8] platform/x86/amd/hsmp: Sanitize hsmp_ioctl_msg() msg_id for Spectre v1 Muralidhara M K
2026-06-11 12:09   ` Ilpo Järvinen
2026-06-11 16:46     ` M K, Muralidhara
2026-06-11  5:29 ` [PATCH v5 7/8] platform/x86/amd/hsmp: Enable HSMP_PROTO_VER7 metric tables on the ACPI driver via the IOCTL Muralidhara M K
2026-06-11  5:29 ` [PATCH v5 8/8] platform/x86/amd/hsmp: Make metric table read locking use guard(mutex) Muralidhara M K
2026-06-11 13:18   ` Ilpo Järvinen [this message]
2026-06-11 16:51     ` M K, Muralidhara

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=f4086725-9d83-31f0-77be-34b8ebceb2eb@linux.intel.com \
    --to=ilpo.jarvinen@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=muralidhara.mk@amd.com \
    --cc=muthusamy.ramalingam@amd.com \
    --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®