[PATCH v6 1/6] platform/x86/amd/hsmp: Serialize ACPI HSMP probe and remove with an rwsem

From: Muralidhara M K

Date: Mon Jul 13 2026 - 00:43:02 EST


Add hsmp_sock_rwsem and export it, then hold it for write across ACPI
probe, remove and init_acpi() so concurrent per-socket platform probes
cannot race the is_probed handshake or the one-time socket-array
allocation. Use lockdep_assert_held_write() in init_acpi() to catch
incorrect locking under lockdep.

An rw_semaphore is used rather than a plain mutex because an upcoming
change adds a read side so the lock-free data plane runs concurrently with
itself while probe/remove hold it for write to drain in-flight messages.
Introducing it as an rwsem now keeps the lock type stable across that
change.

Signed-off-by: Muralidhara M K <muralidhara.mk@xxxxxxx>
---
drivers/platform/x86/amd/hsmp/acpi.c | 22 ++++++++++++++++++++++
drivers/platform/x86/amd/hsmp/hsmp.c | 9 +++++++++
drivers/platform/x86/amd/hsmp/hsmp.h | 7 +++++++
3 files changed, 38 insertions(+)

diff --git a/drivers/platform/x86/amd/hsmp/acpi.c b/drivers/platform/x86/amd/hsmp/acpi.c
index 72f68cef1297..a23797bd1dd5 100644
--- a/drivers/platform/x86/amd/hsmp/acpi.c
+++ b/drivers/platform/x86/amd/hsmp/acpi.c
@@ -15,12 +15,15 @@
#include <linux/array_size.h>
#include <linux/bits.h>
#include <linux/bitfield.h>
+#include <linux/cleanup.h>
#include <linux/device.h>
#include <linux/dev_printk.h>
#include <linux/ioport.h>
#include <linux/kstrtox.h>
+#include <linux/lockdep.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/rwsem.h>
#include <linux/string.h>
#include <linux/sysfs.h>
#include <linux/topology.h>
@@ -482,11 +485,20 @@ static ssize_t hsmp_freq_limit_source_show(struct device *dev, struct device_att
return len;
}

+/*
+ * Bring up one ACPI HSMP socket: parse its ACPI table, run the mailbox
+ * handshake and register its sysfs/hwmon interfaces.
+ *
+ * Called with hsmp_sock_rwsem held for write by hsmp_acpi_probe(), so the
+ * per-socket bring-up cannot race a concurrent probe or remove.
+ */
static int init_acpi(struct device *dev)
{
u16 sock_ind;
int ret;

+ lockdep_assert_held_write(&hsmp_sock_rwsem);
+
ret = hsmp_get_uid(dev, &sock_ind);
if (ret)
return ret;
@@ -607,6 +619,14 @@ static int hsmp_acpi_probe(struct platform_device *pdev)
if (!hsmp_pdev)
return -ENOMEM;

+ /*
+ * Multiple ACPI socket devices probe in parallel, but the is_probed
+ * handshake and the one-time socket-array allocation below must run
+ * exactly once. Serialize the whole bring-up against concurrent
+ * probe/remove by holding the socket rwsem for write.
+ */
+ guard(rwsem_write)(&hsmp_sock_rwsem);
+
if (!hsmp_pdev->is_probed) {
hsmp_pdev->num_sockets = topology_max_packages();
if (!hsmp_pdev->num_sockets) {
@@ -642,6 +662,8 @@ static int hsmp_acpi_probe(struct platform_device *pdev)

static void hsmp_acpi_remove(struct platform_device *pdev)
{
+ guard(rwsem_write)(&hsmp_sock_rwsem);
+
/*
* We register only one misc_device even on multi-socket system.
* So, deregister should happen only once.
diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c
index 1a87931136fd..e9c17698983c 100644
--- a/drivers/platform/x86/amd/hsmp/hsmp.c
+++ b/drivers/platform/x86/amd/hsmp/hsmp.c
@@ -12,6 +12,7 @@
#include <linux/acpi.h>
#include <linux/delay.h>
#include <linux/device.h>
+#include <linux/rwsem.h>
#include <linux/semaphore.h>
#include <linux/sysfs.h>

@@ -40,6 +41,14 @@

static struct hsmp_plat_device hsmp_pdev;

+/*
+ * Serializes AMD HSMP socket bring-up and teardown: ACPI probe and remove take
+ * it for write so concurrent per-socket probes cannot race the is_probed
+ * handshake or the one-time socket-array allocation.
+ */
+DECLARE_RWSEM(hsmp_sock_rwsem);
+EXPORT_SYMBOL_NS_GPL(hsmp_sock_rwsem, "AMD_HSMP");
+
/*
* Send a message to the HSMP port via PCI-e config space registers
* or by writing to MMIO space.
diff --git a/drivers/platform/x86/amd/hsmp/hsmp.h b/drivers/platform/x86/amd/hsmp/hsmp.h
index 0509a442eaae..129200d0cf81 100644
--- a/drivers/platform/x86/amd/hsmp/hsmp.h
+++ b/drivers/platform/x86/amd/hsmp/hsmp.h
@@ -16,6 +16,7 @@
#include <linux/kconfig.h>
#include <linux/miscdevice.h>
#include <linux/pci.h>
+#include <linux/rwsem.h>
#include <linux/semaphore.h>
#include <linux/sysfs.h>

@@ -71,4 +72,10 @@ int hsmp_create_sensor(struct device *dev, u16 sock_ind);
static inline int hsmp_create_sensor(struct device *dev, u16 sock_ind) { return 0; }
#endif
int hsmp_msg_get_nargs(u16 sock_ind, u32 msg_id, u32 *data, u8 num_args);
+
+/*
+ * Serializes HSMP socket bring-up and teardown. ACPI probe and remove take it
+ * for write.
+ */
+extern struct rw_semaphore hsmp_sock_rwsem;
#endif /* HSMP_H */
--
2.34.1