* [PATCH 0/4] platform/x86/amd/hsmp: ACPI input hardening and data-plane readiness gating
@ 2026-06-29 7:39 Muralidhara M K
2026-06-29 7:39 ` [PATCH 1/4] platform/x86/amd/hsmp: Validate ACPI UID before parsing socket index Muralidhara M K
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Muralidhara M K @ 2026-06-29 7:39 UTC (permalink / raw)
To: ilpo.jarvinen; +Cc: platform-driver-x86, linux-kernel, Muralidhara M K
This series hardens the AMD HSMP ACPI driver against malformed firmware
and fixes a data-plane readiness race on multi-socket systems. It is
split out and reworked from the larger HSMP concurrency series.
Patches 1-2 validate ACPI input before it is used:
- hsmp_get_uid() passed the device UID straight to kstrtou16(uid + 2)
without checking it; a NULL or too-short UID could dereference NULL
or read past the end of the string.
- hsmp_read_acpi_dsd() dereferenced elements[0] and elements[1] of each
mailbox sub-package before confirming the package held two elements,
allowing an out-of-bounds read on a malformed _DSD.
These two are based on the review discussion at [1].
Patches 3-4 close a startup race on the lock-free data plane. On a
multi-socket system socket 0 exposes /dev/hsmp before later sockets
finish probing, so a message aimed at a socket still in bring-up could
pass the sock->dev readiness gate and dereference a NULL virt_base_addr:
- Patch 3 is a pure refactor that threads struct device explicitly
through the ACPI mailbox parsers so they no longer depend on sock->dev
being set early.
- Patch 4 publishes sock->dev last with smp_store_release() once the
mailbox and semaphore are initialized, and consumes it with
smp_load_acquire() in hsmp_send_message().
These two are based on the earlier submission at [2].
Each patch was built individually with W=1 (no new warnings) and passes
checkpatch.pl --strict and codespell.
[1] https://lore.kernel.org/platform-driver-x86/b723da76-6309-0cd4-59e0-5931231f585d@linux.intel.com/T/#u
[2] https://lore.kernel.org/platform-driver-x86/20260625123337.886435-5-muralidhara.mk@amd.com/T/#u
Muralidhara M K (4):
platform/x86/amd/hsmp: Validate ACPI UID before parsing socket index
platform/x86/amd/hsmp: Validate _DSD mailbox sub-package element count
platform/x86/amd/hsmp: Pass struct device explicitly to ACPI mailbox
parsers
platform/x86/amd/hsmp: Gate the data plane on a fully initialized
socket
drivers/platform/x86/amd/hsmp/acpi.c | 53 ++++++++++++++++++++--------
drivers/platform/x86/amd/hsmp/hsmp.c | 12 +++++++
2 files changed, 50 insertions(+), 15 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 1/4] platform/x86/amd/hsmp: Validate ACPI UID before parsing socket index 2026-06-29 7:39 [PATCH 0/4] platform/x86/amd/hsmp: ACPI input hardening and data-plane readiness gating Muralidhara M K @ 2026-06-29 7:39 ` Muralidhara M K 2026-06-29 7:39 ` [PATCH 2/4] platform/x86/amd/hsmp: Validate _DSD mailbox sub-package element count Muralidhara M K ` (2 subsequent siblings) 3 siblings, 0 replies; 9+ messages in thread From: Muralidhara M K @ 2026-06-29 7:39 UTC (permalink / raw) To: ilpo.jarvinen; +Cc: platform-driver-x86, linux-kernel, Muralidhara M K hsmp_get_uid() passed the device UID directly to kstrtou16(uid + 2) without checking it. A NULL UID or one shorter than three characters would dereference a NULL pointer or read past the end of the string. Reject such UIDs with -EINVAL before stripping the "ID" prefix. Signed-off-by: Muralidhara M K <muralidhara.mk@amd.com> Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Link: https://lore.kernel.org/platform-driver-x86/b723da76-6309-0cd4-59e0-5931231f585d@linux.intel.com/T/#u [1] --- drivers/platform/x86/amd/hsmp/acpi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/platform/x86/amd/hsmp/acpi.c b/drivers/platform/x86/amd/hsmp/acpi.c index 97ed71593bdf..4a1ce4cb25e7 100644 --- a/drivers/platform/x86/amd/hsmp/acpi.c +++ b/drivers/platform/x86/amd/hsmp/acpi.c @@ -21,6 +21,7 @@ #include <linux/kstrtox.h> #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/string.h> #include <linux/sysfs.h> #include <linux/topology.h> #include <linux/uuid.h> @@ -77,6 +78,8 @@ static inline int hsmp_get_uid(struct device *dev, u16 *sock_ind) * bytes to integer. */ uid = acpi_device_uid(ACPI_COMPANION(dev)); + if (!uid || strlen(uid) < 3) + return -EINVAL; return kstrtou16(uid + 2, 10, sock_ind); } -- 2.43.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/4] platform/x86/amd/hsmp: Validate _DSD mailbox sub-package element count 2026-06-29 7:39 [PATCH 0/4] platform/x86/amd/hsmp: ACPI input hardening and data-plane readiness gating Muralidhara M K 2026-06-29 7:39 ` [PATCH 1/4] platform/x86/amd/hsmp: Validate ACPI UID before parsing socket index Muralidhara M K @ 2026-06-29 7:39 ` Muralidhara M K 2026-06-29 7:39 ` [PATCH 3/4] platform/x86/amd/hsmp: Pass struct device explicitly to ACPI mailbox parsers Muralidhara M K 2026-06-29 7:39 ` [PATCH 4/4] platform/x86/amd/hsmp: Gate the data plane on a fully initialized socket Muralidhara M K 3 siblings, 0 replies; 9+ messages in thread From: Muralidhara M K @ 2026-06-29 7:39 UTC (permalink / raw) To: ilpo.jarvinen; +Cc: platform-driver-x86, linux-kernel, Muralidhara M K hsmp_read_acpi_dsd() dereferenced elements[0] and elements[1] of each mailbox sub-package before confirming the package actually held two elements, allowing an out-of-bounds read on a malformed _DSD. Verify package.count >= 2 first, then fetch the string and integer objects. Signed-off-by: Muralidhara M K <muralidhara.mk@amd.com> Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Link: https://lore.kernel.org/platform-driver-x86/b723da76-6309-0cd4-59e0-5931231f585d@linux.intel.com/T/#u [1] --- drivers/platform/x86/amd/hsmp/acpi.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/amd/hsmp/acpi.c b/drivers/platform/x86/amd/hsmp/acpi.c index 4a1ce4cb25e7..8c3185ae6395 100644 --- a/drivers/platform/x86/amd/hsmp/acpi.c +++ b/drivers/platform/x86/amd/hsmp/acpi.c @@ -151,12 +151,18 @@ static int hsmp_read_acpi_dsd(struct hsmp_socket *sock) union acpi_object *msgobj, *msgstr, *msgint; msgobj = &mailbox_package->package.elements[j]; - msgstr = &msgobj->package.elements[0]; - msgint = &msgobj->package.elements[1]; /* package should have 1 string and 1 integer object */ if (msgobj->type != ACPI_TYPE_PACKAGE || - msgstr->type != ACPI_TYPE_STRING || + msgobj->package.count < 2) { + ret = -EINVAL; + goto free_buf; + } + + msgstr = &msgobj->package.elements[0]; + msgint = &msgobj->package.elements[1]; + + if (msgstr->type != ACPI_TYPE_STRING || msgint->type != ACPI_TYPE_INTEGER) { ret = -EINVAL; goto free_buf; -- 2.43.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/4] platform/x86/amd/hsmp: Pass struct device explicitly to ACPI mailbox parsers 2026-06-29 7:39 [PATCH 0/4] platform/x86/amd/hsmp: ACPI input hardening and data-plane readiness gating Muralidhara M K 2026-06-29 7:39 ` [PATCH 1/4] platform/x86/amd/hsmp: Validate ACPI UID before parsing socket index Muralidhara M K 2026-06-29 7:39 ` [PATCH 2/4] platform/x86/amd/hsmp: Validate _DSD mailbox sub-package element count Muralidhara M K @ 2026-06-29 7:39 ` Muralidhara M K 2026-06-29 12:46 ` Ilpo Järvinen 2026-06-29 7:39 ` [PATCH 4/4] platform/x86/amd/hsmp: Gate the data plane on a fully initialized socket Muralidhara M K 3 siblings, 1 reply; 9+ messages in thread From: Muralidhara M K @ 2026-06-29 7:39 UTC (permalink / raw) To: ilpo.jarvinen; +Cc: platform-driver-x86, linux-kernel, Muralidhara M K hsmp_read_acpi_crs() and hsmp_read_acpi_dsd() read the ACPI handle and emit error messages via sock->dev. Pass the struct device explicitly to both helpers instead of reading it back from sock->dev. This is a pure refactor with no functional change; it prepares for publishing sock->dev as the data-plane readiness gate only after the socket has been fully initialized, so the parsers must not depend on sock->dev already being set. Signed-off-by: Muralidhara M K <muralidhara.mk@amd.com> Link: https://lore.kernel.org/platform-driver-x86/20260625123337.886435-5-muralidhara.mk@amd.com/T/#u [1] --- drivers/platform/x86/amd/hsmp/acpi.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/platform/x86/amd/hsmp/acpi.c b/drivers/platform/x86/amd/hsmp/acpi.c index 8c3185ae6395..f7fbba4c6b66 100644 --- a/drivers/platform/x86/amd/hsmp/acpi.c +++ b/drivers/platform/x86/amd/hsmp/acpi.c @@ -107,7 +107,7 @@ static acpi_status hsmp_resource(struct acpi_resource *res, void *data) return AE_OK; } -static int hsmp_read_acpi_dsd(struct hsmp_socket *sock) +static int hsmp_read_acpi_dsd(struct hsmp_socket *sock, struct device *dev) { struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *guid, *mailbox_package; @@ -116,10 +116,10 @@ static int hsmp_read_acpi_dsd(struct hsmp_socket *sock) int ret = 0; int j; - status = acpi_evaluate_object_typed(ACPI_HANDLE(sock->dev), "_DSD", NULL, + status = acpi_evaluate_object_typed(ACPI_HANDLE(dev), "_DSD", NULL, &buf, ACPI_TYPE_PACKAGE); if (ACPI_FAILURE(status)) { - dev_err(sock->dev, "Failed to read mailbox reg offsets from DSD table, err: %s\n", + dev_err(dev, "Failed to read mailbox reg offsets from DSD table, err: %s\n", acpi_format_exception(status)); return -ENODEV; } @@ -142,7 +142,7 @@ static int hsmp_read_acpi_dsd(struct hsmp_socket *sock) guid = &dsd->package.elements[0]; mailbox_package = &dsd->package.elements[1]; if (!is_acpi_hsmp_uuid(guid) || mailbox_package->type != ACPI_TYPE_PACKAGE) { - dev_err(sock->dev, "Invalid hsmp _DSD table data\n"); + dev_err(dev, "Invalid hsmp _DSD table data\n"); ret = -EINVAL; goto free_buf; } @@ -192,14 +192,14 @@ static int hsmp_read_acpi_dsd(struct hsmp_socket *sock) return ret; } -static int hsmp_read_acpi_crs(struct hsmp_socket *sock) +static int hsmp_read_acpi_crs(struct hsmp_socket *sock, struct device *dev) { acpi_status status; - status = acpi_walk_resources(ACPI_HANDLE(sock->dev), METHOD_NAME__CRS, + status = acpi_walk_resources(ACPI_HANDLE(dev), METHOD_NAME__CRS, hsmp_resource, sock); if (ACPI_FAILURE(status)) { - dev_err(sock->dev, "Failed to look up MP1 base address from CRS method, err: %s\n", + dev_err(dev, "Failed to look up MP1 base address from CRS method, err: %s\n", acpi_format_exception(status)); return -EINVAL; } @@ -207,10 +207,10 @@ static int hsmp_read_acpi_crs(struct hsmp_socket *sock) return -EINVAL; /* The mapped region should be un-cached */ - sock->virt_base_addr = devm_ioremap_uc(sock->dev, sock->mbinfo.base_addr, + sock->virt_base_addr = devm_ioremap_uc(dev, sock->mbinfo.base_addr, sock->mbinfo.size); if (!sock->virt_base_addr) { - dev_err(sock->dev, "Failed to ioremap MP1 base address\n"); + dev_err(dev, "Failed to ioremap MP1 base address\n"); return -ENOMEM; } @@ -232,12 +232,12 @@ static int hsmp_parse_acpi_table(struct device *dev, u16 sock_ind) dev_set_drvdata(dev, sock); /* Read MP1 base address from CRS method */ - ret = hsmp_read_acpi_crs(sock); + ret = hsmp_read_acpi_crs(sock, dev); if (ret) return ret; /* Read mailbox offsets from DSD table */ - return hsmp_read_acpi_dsd(sock); + return hsmp_read_acpi_dsd(sock, dev); } static ssize_t hsmp_metric_tbl_acpi_read(struct file *filp, struct kobject *kobj, -- 2.43.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 3/4] platform/x86/amd/hsmp: Pass struct device explicitly to ACPI mailbox parsers 2026-06-29 7:39 ` [PATCH 3/4] platform/x86/amd/hsmp: Pass struct device explicitly to ACPI mailbox parsers Muralidhara M K @ 2026-06-29 12:46 ` Ilpo Järvinen 2026-06-29 14:07 ` M K, Muralidhara 0 siblings, 1 reply; 9+ messages in thread From: Ilpo Järvinen @ 2026-06-29 12:46 UTC (permalink / raw) To: Muralidhara M K; +Cc: platform-driver-x86, LKML On Mon, 29 Jun 2026, Muralidhara M K wrote: > hsmp_read_acpi_crs() and hsmp_read_acpi_dsd() read the ACPI handle and > emit error messages via sock->dev. Pass the struct device explicitly to > both helpers instead of reading it back from sock->dev. > > This is a pure refactor with no functional change; it prepares for > publishing sock->dev as the data-plane readiness gate only after the > socket has been fully initialized, so the parsers must not depend on > sock->dev already being set. > > Signed-off-by: Muralidhara M K <muralidhara.mk@amd.com> > Link: https://lore.kernel.org/platform-driver-x86/20260625123337.886435-5-muralidhara.mk@amd.com/T/#u [1] > --- > drivers/platform/x86/amd/hsmp/acpi.c | 22 +++++++++++----------- > 1 file changed, 11 insertions(+), 11 deletions(-) > > diff --git a/drivers/platform/x86/amd/hsmp/acpi.c b/drivers/platform/x86/amd/hsmp/acpi.c > index 8c3185ae6395..f7fbba4c6b66 100644 > --- a/drivers/platform/x86/amd/hsmp/acpi.c > +++ b/drivers/platform/x86/amd/hsmp/acpi.c > @@ -107,7 +107,7 @@ static acpi_status hsmp_resource(struct acpi_resource *res, void *data) > return AE_OK; > } > > -static int hsmp_read_acpi_dsd(struct hsmp_socket *sock) > +static int hsmp_read_acpi_dsd(struct hsmp_socket *sock, struct device *dev) > { > struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL }; > union acpi_object *guid, *mailbox_package; > @@ -116,10 +116,10 @@ static int hsmp_read_acpi_dsd(struct hsmp_socket *sock) > int ret = 0; > int j; > > - status = acpi_evaluate_object_typed(ACPI_HANDLE(sock->dev), "_DSD", NULL, > + status = acpi_evaluate_object_typed(ACPI_HANDLE(dev), "_DSD", NULL, > &buf, ACPI_TYPE_PACKAGE); > if (ACPI_FAILURE(status)) { > - dev_err(sock->dev, "Failed to read mailbox reg offsets from DSD table, err: %s\n", > + dev_err(dev, "Failed to read mailbox reg offsets from DSD table, err: %s\n", > acpi_format_exception(status)); > return -ENODEV; > } > @@ -142,7 +142,7 @@ static int hsmp_read_acpi_dsd(struct hsmp_socket *sock) > guid = &dsd->package.elements[0]; > mailbox_package = &dsd->package.elements[1]; > if (!is_acpi_hsmp_uuid(guid) || mailbox_package->type != ACPI_TYPE_PACKAGE) { > - dev_err(sock->dev, "Invalid hsmp _DSD table data\n"); > + dev_err(dev, "Invalid hsmp _DSD table data\n"); > ret = -EINVAL; > goto free_buf; > } > @@ -192,14 +192,14 @@ static int hsmp_read_acpi_dsd(struct hsmp_socket *sock) > return ret; > } > > -static int hsmp_read_acpi_crs(struct hsmp_socket *sock) > +static int hsmp_read_acpi_crs(struct hsmp_socket *sock, struct device *dev) > { > acpi_status status; > > - status = acpi_walk_resources(ACPI_HANDLE(sock->dev), METHOD_NAME__CRS, > + status = acpi_walk_resources(ACPI_HANDLE(dev), METHOD_NAME__CRS, > hsmp_resource, sock); > if (ACPI_FAILURE(status)) { > - dev_err(sock->dev, "Failed to look up MP1 base address from CRS method, err: %s\n", > + dev_err(dev, "Failed to look up MP1 base address from CRS method, err: %s\n", > acpi_format_exception(status)); > return -EINVAL; > } > @@ -207,10 +207,10 @@ static int hsmp_read_acpi_crs(struct hsmp_socket *sock) > return -EINVAL; > > /* The mapped region should be un-cached */ > - sock->virt_base_addr = devm_ioremap_uc(sock->dev, sock->mbinfo.base_addr, > + sock->virt_base_addr = devm_ioremap_uc(dev, sock->mbinfo.base_addr, > sock->mbinfo.size); > if (!sock->virt_base_addr) { > - dev_err(sock->dev, "Failed to ioremap MP1 base address\n"); > + dev_err(dev, "Failed to ioremap MP1 base address\n"); > return -ENOMEM; > } > > @@ -232,12 +232,12 @@ static int hsmp_parse_acpi_table(struct device *dev, u16 sock_ind) > dev_set_drvdata(dev, sock); > > /* Read MP1 base address from CRS method */ > - ret = hsmp_read_acpi_crs(sock); > + ret = hsmp_read_acpi_crs(sock, dev); > if (ret) > return ret; > > /* Read mailbox offsets from DSD table */ > - return hsmp_read_acpi_dsd(sock); > + return hsmp_read_acpi_dsd(sock, dev); It would probably make more sense to have the arguments other way around (dev, sock) in both of these calls as dev is "complete" and we're still filling sock at this point. -- i. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 3/4] platform/x86/amd/hsmp: Pass struct device explicitly to ACPI mailbox parsers 2026-06-29 12:46 ` Ilpo Järvinen @ 2026-06-29 14:07 ` M K, Muralidhara 2026-06-29 14:52 ` Ilpo Järvinen 0 siblings, 1 reply; 9+ messages in thread From: M K, Muralidhara @ 2026-06-29 14:07 UTC (permalink / raw) To: Ilpo Järvinen, Muralidhara M K; +Cc: platform-driver-x86, LKML On 6/29/2026 6:16 PM, Ilpo Järvinen wrote: > Caution: This message originated from an External Source. Use proper caution when opening attachments, clicking links, or responding. > > > On Mon, 29 Jun 2026, Muralidhara M K wrote: > >> hsmp_read_acpi_crs() and hsmp_read_acpi_dsd() read the ACPI handle and >> emit error messages via sock->dev. Pass the struct device explicitly to >> both helpers instead of reading it back from sock->dev. >> >> This is a pure refactor with no functional change; it prepares for >> publishing sock->dev as the data-plane readiness gate only after the >> socket has been fully initialized, so the parsers must not depend on >> sock->dev already being set. >> >> Signed-off-by: Muralidhara M K <muralidhara.mk@amd.com> >> Link: https://lore.kernel.org/platform-driver-x86/20260625123337.886435-5-muralidhara.mk@amd.com/T/#u [1] >> --- >> drivers/platform/x86/amd/hsmp/acpi.c | 22 +++++++++++----------- >> 1 file changed, 11 insertions(+), 11 deletions(-) >> >> diff --git a/drivers/platform/x86/amd/hsmp/acpi.c b/drivers/platform/x86/amd/hsmp/acpi.c >> index 8c3185ae6395..f7fbba4c6b66 100644 >> --- a/drivers/platform/x86/amd/hsmp/acpi.c >> +++ b/drivers/platform/x86/amd/hsmp/acpi.c >> @@ -107,7 +107,7 @@ static acpi_status hsmp_resource(struct acpi_resource *res, void *data) >> return AE_OK; >> } >> >> -static int hsmp_read_acpi_dsd(struct hsmp_socket *sock) >> +static int hsmp_read_acpi_dsd(struct hsmp_socket *sock, struct device *dev) >> { >> struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL }; >> union acpi_object *guid, *mailbox_package; >> @@ -116,10 +116,10 @@ static int hsmp_read_acpi_dsd(struct hsmp_socket *sock) >> int ret = 0; >> int j; >> >> - status = acpi_evaluate_object_typed(ACPI_HANDLE(sock->dev), "_DSD", NULL, >> + status = acpi_evaluate_object_typed(ACPI_HANDLE(dev), "_DSD", NULL, >> &buf, ACPI_TYPE_PACKAGE); >> if (ACPI_FAILURE(status)) { >> - dev_err(sock->dev, "Failed to read mailbox reg offsets from DSD table, err: %s\n", >> + dev_err(dev, "Failed to read mailbox reg offsets from DSD table, err: %s\n", >> acpi_format_exception(status)); >> return -ENODEV; >> } >> @@ -142,7 +142,7 @@ static int hsmp_read_acpi_dsd(struct hsmp_socket *sock) >> guid = &dsd->package.elements[0]; >> mailbox_package = &dsd->package.elements[1]; >> if (!is_acpi_hsmp_uuid(guid) || mailbox_package->type != ACPI_TYPE_PACKAGE) { >> - dev_err(sock->dev, "Invalid hsmp _DSD table data\n"); >> + dev_err(dev, "Invalid hsmp _DSD table data\n"); >> ret = -EINVAL; >> goto free_buf; >> } >> @@ -192,14 +192,14 @@ static int hsmp_read_acpi_dsd(struct hsmp_socket *sock) >> return ret; >> } >> >> -static int hsmp_read_acpi_crs(struct hsmp_socket *sock) >> +static int hsmp_read_acpi_crs(struct hsmp_socket *sock, struct device *dev) >> { >> acpi_status status; >> >> - status = acpi_walk_resources(ACPI_HANDLE(sock->dev), METHOD_NAME__CRS, >> + status = acpi_walk_resources(ACPI_HANDLE(dev), METHOD_NAME__CRS, >> hsmp_resource, sock); >> if (ACPI_FAILURE(status)) { >> - dev_err(sock->dev, "Failed to look up MP1 base address from CRS method, err: %s\n", >> + dev_err(dev, "Failed to look up MP1 base address from CRS method, err: %s\n", >> acpi_format_exception(status)); >> return -EINVAL; >> } >> @@ -207,10 +207,10 @@ static int hsmp_read_acpi_crs(struct hsmp_socket *sock) >> return -EINVAL; >> >> /* The mapped region should be un-cached */ >> - sock->virt_base_addr = devm_ioremap_uc(sock->dev, sock->mbinfo.base_addr, >> + sock->virt_base_addr = devm_ioremap_uc(dev, sock->mbinfo.base_addr, >> sock->mbinfo.size); >> if (!sock->virt_base_addr) { >> - dev_err(sock->dev, "Failed to ioremap MP1 base address\n"); >> + dev_err(dev, "Failed to ioremap MP1 base address\n"); >> return -ENOMEM; >> } >> >> @@ -232,12 +232,12 @@ static int hsmp_parse_acpi_table(struct device *dev, u16 sock_ind) >> dev_set_drvdata(dev, sock); >> >> /* Read MP1 base address from CRS method */ >> - ret = hsmp_read_acpi_crs(sock); >> + ret = hsmp_read_acpi_crs(sock, dev); >> if (ret) >> return ret; >> >> /* Read mailbox offsets from DSD table */ >> - return hsmp_read_acpi_dsd(sock); >> + return hsmp_read_acpi_dsd(sock, dev); > > It would probably make more sense to have the arguments other way around > (dev, sock) in both of these calls as dev is "complete" and we're still > filling sock at this point. > Thanks I will fix this. Ilpo, could you please confirm whether patches 0001 and 0002 have already been accepted in the maintainer branch, or if I should resubmit them as v2 along with patches 0003 and 0004 ? > -- > i. > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 3/4] platform/x86/amd/hsmp: Pass struct device explicitly to ACPI mailbox parsers 2026-06-29 14:07 ` M K, Muralidhara @ 2026-06-29 14:52 ` Ilpo Järvinen 0 siblings, 0 replies; 9+ messages in thread From: Ilpo Järvinen @ 2026-06-29 14:52 UTC (permalink / raw) To: M K, Muralidhara; +Cc: Muralidhara M K, platform-driver-x86, LKML [-- Attachment #1: Type: text/plain, Size: 5854 bytes --] On Mon, 29 Jun 2026, M K, Muralidhara wrote: > On 6/29/2026 6:16 PM, Ilpo Järvinen wrote: > > Caution: This message originated from an External Source. Use proper caution > > when opening attachments, clicking links, or responding. > > > > > > On Mon, 29 Jun 2026, Muralidhara M K wrote: > > > > > hsmp_read_acpi_crs() and hsmp_read_acpi_dsd() read the ACPI handle and > > > emit error messages via sock->dev. Pass the struct device explicitly to > > > both helpers instead of reading it back from sock->dev. > > > > > > This is a pure refactor with no functional change; it prepares for > > > publishing sock->dev as the data-plane readiness gate only after the > > > socket has been fully initialized, so the parsers must not depend on > > > sock->dev already being set. > > > > > > Signed-off-by: Muralidhara M K <muralidhara.mk@amd.com> > > > Link: > > > https://lore.kernel.org/platform-driver-x86/20260625123337.886435-5-muralidhara.mk@amd.com/T/#u > > > [1] > > > --- > > > drivers/platform/x86/amd/hsmp/acpi.c | 22 +++++++++++----------- > > > 1 file changed, 11 insertions(+), 11 deletions(-) > > > > > > diff --git a/drivers/platform/x86/amd/hsmp/acpi.c > > > b/drivers/platform/x86/amd/hsmp/acpi.c > > > index 8c3185ae6395..f7fbba4c6b66 100644 > > > --- a/drivers/platform/x86/amd/hsmp/acpi.c > > > +++ b/drivers/platform/x86/amd/hsmp/acpi.c > > > @@ -107,7 +107,7 @@ static acpi_status hsmp_resource(struct acpi_resource > > > *res, void *data) > > > return AE_OK; > > > } > > > > > > -static int hsmp_read_acpi_dsd(struct hsmp_socket *sock) > > > +static int hsmp_read_acpi_dsd(struct hsmp_socket *sock, struct device > > > *dev) > > > { > > > struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL }; > > > union acpi_object *guid, *mailbox_package; > > > @@ -116,10 +116,10 @@ static int hsmp_read_acpi_dsd(struct hsmp_socket > > > *sock) > > > int ret = 0; > > > int j; > > > > > > - status = acpi_evaluate_object_typed(ACPI_HANDLE(sock->dev), "_DSD", > > > NULL, > > > + status = acpi_evaluate_object_typed(ACPI_HANDLE(dev), "_DSD", NULL, > > > &buf, ACPI_TYPE_PACKAGE); > > > if (ACPI_FAILURE(status)) { > > > - dev_err(sock->dev, "Failed to read mailbox reg offsets from > > > DSD table, err: %s\n", > > > + dev_err(dev, "Failed to read mailbox reg offsets from DSD > > > table, err: %s\n", > > > acpi_format_exception(status)); > > > return -ENODEV; > > > } > > > @@ -142,7 +142,7 @@ static int hsmp_read_acpi_dsd(struct hsmp_socket > > > *sock) > > > guid = &dsd->package.elements[0]; > > > mailbox_package = &dsd->package.elements[1]; > > > if (!is_acpi_hsmp_uuid(guid) || mailbox_package->type != > > > ACPI_TYPE_PACKAGE) { > > > - dev_err(sock->dev, "Invalid hsmp _DSD table data\n"); > > > + dev_err(dev, "Invalid hsmp _DSD table data\n"); > > > ret = -EINVAL; > > > goto free_buf; > > > } > > > @@ -192,14 +192,14 @@ static int hsmp_read_acpi_dsd(struct hsmp_socket > > > *sock) > > > return ret; > > > } > > > > > > -static int hsmp_read_acpi_crs(struct hsmp_socket *sock) > > > +static int hsmp_read_acpi_crs(struct hsmp_socket *sock, struct device > > > *dev) > > > { > > > acpi_status status; > > > > > > - status = acpi_walk_resources(ACPI_HANDLE(sock->dev), > > > METHOD_NAME__CRS, > > > + status = acpi_walk_resources(ACPI_HANDLE(dev), METHOD_NAME__CRS, > > > hsmp_resource, sock); > > > if (ACPI_FAILURE(status)) { > > > - dev_err(sock->dev, "Failed to look up MP1 base address from > > > CRS method, err: %s\n", > > > + dev_err(dev, "Failed to look up MP1 base address from CRS > > > method, err: %s\n", > > > acpi_format_exception(status)); > > > return -EINVAL; > > > } > > > @@ -207,10 +207,10 @@ static int hsmp_read_acpi_crs(struct hsmp_socket > > > *sock) > > > return -EINVAL; > > > > > > /* The mapped region should be un-cached */ > > > - sock->virt_base_addr = devm_ioremap_uc(sock->dev, > > > sock->mbinfo.base_addr, > > > + sock->virt_base_addr = devm_ioremap_uc(dev, sock->mbinfo.base_addr, > > > sock->mbinfo.size); > > > if (!sock->virt_base_addr) { > > > - dev_err(sock->dev, "Failed to ioremap MP1 base address\n"); > > > + dev_err(dev, "Failed to ioremap MP1 base address\n"); > > > return -ENOMEM; > > > } > > > > > > @@ -232,12 +232,12 @@ static int hsmp_parse_acpi_table(struct device *dev, > > > u16 sock_ind) > > > dev_set_drvdata(dev, sock); > > > > > > /* Read MP1 base address from CRS method */ > > > - ret = hsmp_read_acpi_crs(sock); > > > + ret = hsmp_read_acpi_crs(sock, dev); > > > if (ret) > > > return ret; > > > > > > /* Read mailbox offsets from DSD table */ > > > - return hsmp_read_acpi_dsd(sock); > > > + return hsmp_read_acpi_dsd(sock, dev); > > > > It would probably make more sense to have the arguments other way around > > (dev, sock) in both of these calls as dev is "complete" and we're still > > filling sock at this point. > > > Thanks I will fix this. > > Ilpo, could you please confirm whether patches 0001 and 0002 have already been > accepted in the maintainer branch, or if I should resubmit them as v2 along > with patches 0003 and 0004 ? I've not applied any patches yet in this cycle so please resubmit the whole series. -- i. ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 4/4] platform/x86/amd/hsmp: Gate the data plane on a fully initialized socket 2026-06-29 7:39 [PATCH 0/4] platform/x86/amd/hsmp: ACPI input hardening and data-plane readiness gating Muralidhara M K ` (2 preceding siblings ...) 2026-06-29 7:39 ` [PATCH 3/4] platform/x86/amd/hsmp: Pass struct device explicitly to ACPI mailbox parsers Muralidhara M K @ 2026-06-29 7:39 ` Muralidhara M K 2026-06-29 12:50 ` Ilpo Järvinen 3 siblings, 1 reply; 9+ messages in thread From: Muralidhara M K @ 2026-06-29 7:39 UTC (permalink / raw) To: ilpo.jarvinen; +Cc: platform-driver-x86, linux-kernel, Muralidhara M K hsmp_parse_acpi_table() published sock->dev before hsmp_read_acpi_crs() had mapped virt_base_addr. sock->dev is the readiness gate for the lock-free data plane, so on a multi-socket system - where socket 0 exposes /dev/hsmp before later sockets finish probing - an ioctl aimed at a socket still in bring-up could pass the gate and dereference a NULL virt_base_addr. Publish sock->dev last with smp_store_release() once virt_base_addr, the mailbox offsets and the semaphore are initialized, and read it with smp_load_acquire() in hsmp_send_message() so a non-NULL dev guarantees the rest of the socket state is visible. Signed-off-by: Muralidhara M K <muralidhara.mk@amd.com> Link: https://lore.kernel.org/platform-driver-x86/20260625123337.886435-5-muralidhara.mk@amd.com/T/#u [1] --- drivers/platform/x86/amd/hsmp/acpi.c | 18 ++++++++++++++++-- drivers/platform/x86/amd/hsmp/hsmp.c | 12 ++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/amd/hsmp/acpi.c b/drivers/platform/x86/amd/hsmp/acpi.c index f7fbba4c6b66..5aec3bded712 100644 --- a/drivers/platform/x86/amd/hsmp/acpi.c +++ b/drivers/platform/x86/amd/hsmp/acpi.c @@ -224,7 +224,6 @@ static int hsmp_parse_acpi_table(struct device *dev, u16 sock_ind) int ret; sock->sock_ind = sock_ind; - sock->dev = dev; sock->amd_hsmp_rdwr = amd_hsmp_acpi_rdwr; sema_init(&sock->hsmp_sem, 1); @@ -237,7 +236,22 @@ static int hsmp_parse_acpi_table(struct device *dev, u16 sock_ind) return ret; /* Read mailbox offsets from DSD table */ - return hsmp_read_acpi_dsd(sock, dev); + ret = hsmp_read_acpi_dsd(sock, dev); + if (ret) + return ret; + + /* + * Publish sock->dev last. hsmp_send_message() uses it (via + * smp_load_acquire()) as the readiness gate for the lock-free data + * plane, so it must become visible only after virt_base_addr, the + * mailbox offsets and the semaphore are fully initialized. On a + * multi-socket system socket 0 exposes /dev/hsmp before later sockets + * finish probing, so without this an ioctl aimed at a socket still in + * bring-up could pass the gate and dereference a NULL virt_base_addr. + */ + smp_store_release(&sock->dev, dev); + + return 0; } static ssize_t hsmp_metric_tbl_acpi_read(struct file *filp, struct kobject *kobj, diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c index 6a26937fc2b5..0cd4f691db49 100644 --- a/drivers/platform/x86/amd/hsmp/hsmp.c +++ b/drivers/platform/x86/amd/hsmp/hsmp.c @@ -223,6 +223,18 @@ int hsmp_send_message(struct hsmp_message *msg) sock_ind = array_index_nospec(msg->sock_ind, hsmp_pdev.num_sockets); sock = &hsmp_pdev.sock[sock_ind]; + /* + * A slot exists for every possible socket, but it is only usable once + * that socket has actually been probed. Reject messages aimed at a + * socket that was never brought up or is still in bring-up, so we never + * operate on a zero-initialized semaphore or an unmapped mailbox. A + * non-NULL dev also guarantees virt_base_addr, the mailbox offsets and + * the semaphore are visible. + */ + /* Pairs with smp_store_release(&sock->dev) in hsmp_parse_acpi_table(). */ + if (!smp_load_acquire(&sock->dev)) + return -ENODEV; + ret = down_interruptible(&sock->hsmp_sem); if (ret < 0) return ret; -- 2.43.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 4/4] platform/x86/amd/hsmp: Gate the data plane on a fully initialized socket 2026-06-29 7:39 ` [PATCH 4/4] platform/x86/amd/hsmp: Gate the data plane on a fully initialized socket Muralidhara M K @ 2026-06-29 12:50 ` Ilpo Järvinen 0 siblings, 0 replies; 9+ messages in thread From: Ilpo Järvinen @ 2026-06-29 12:50 UTC (permalink / raw) To: Muralidhara M K; +Cc: platform-driver-x86, LKML On Mon, 29 Jun 2026, Muralidhara M K wrote: > hsmp_parse_acpi_table() published sock->dev before hsmp_read_acpi_crs() > had mapped virt_base_addr. sock->dev is the readiness gate for the > lock-free data plane, so on a multi-socket system - where socket 0 > exposes /dev/hsmp before later sockets finish probing - an ioctl aimed > at a socket still in bring-up could pass the gate and dereference a NULL > virt_base_addr. > > Publish sock->dev last with smp_store_release() once virt_base_addr, the > mailbox offsets and the semaphore are initialized, and read it with > smp_load_acquire() in hsmp_send_message() so a non-NULL dev guarantees > the rest of the socket state is visible. > > Signed-off-by: Muralidhara M K <muralidhara.mk@amd.com> > Link: https://lore.kernel.org/platform-driver-x86/20260625123337.886435-5-muralidhara.mk@amd.com/T/#u [1] What is the purpose of these links? We don't generally link to older version of the change unless there's clearly some useful discussion there. > --- > drivers/platform/x86/amd/hsmp/acpi.c | 18 ++++++++++++++++-- > drivers/platform/x86/amd/hsmp/hsmp.c | 12 ++++++++++++ > 2 files changed, 28 insertions(+), 2 deletions(-) > > diff --git a/drivers/platform/x86/amd/hsmp/acpi.c b/drivers/platform/x86/amd/hsmp/acpi.c > index f7fbba4c6b66..5aec3bded712 100644 > --- a/drivers/platform/x86/amd/hsmp/acpi.c > +++ b/drivers/platform/x86/amd/hsmp/acpi.c > @@ -224,7 +224,6 @@ static int hsmp_parse_acpi_table(struct device *dev, u16 sock_ind) > int ret; > > sock->sock_ind = sock_ind; > - sock->dev = dev; > sock->amd_hsmp_rdwr = amd_hsmp_acpi_rdwr; > > sema_init(&sock->hsmp_sem, 1); > @@ -237,7 +236,22 @@ static int hsmp_parse_acpi_table(struct device *dev, u16 sock_ind) > return ret; > > /* Read mailbox offsets from DSD table */ > - return hsmp_read_acpi_dsd(sock, dev); > + ret = hsmp_read_acpi_dsd(sock, dev); > + if (ret) > + return ret; > + > + /* > + * Publish sock->dev last. hsmp_send_message() uses it (via > + * smp_load_acquire()) as the readiness gate for the lock-free data > + * plane, so it must become visible only after virt_base_addr, the > + * mailbox offsets and the semaphore are fully initialized. On a > + * multi-socket system socket 0 exposes /dev/hsmp before later sockets > + * finish probing, so without this an ioctl aimed at a socket still in > + * bring-up could pass the gate and dereference a NULL virt_base_addr. > + */ > + smp_store_release(&sock->dev, dev); > + > + return 0; > } > > static ssize_t hsmp_metric_tbl_acpi_read(struct file *filp, struct kobject *kobj, > diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c > index 6a26937fc2b5..0cd4f691db49 100644 > --- a/drivers/platform/x86/amd/hsmp/hsmp.c > +++ b/drivers/platform/x86/amd/hsmp/hsmp.c > @@ -223,6 +223,18 @@ int hsmp_send_message(struct hsmp_message *msg) > sock_ind = array_index_nospec(msg->sock_ind, hsmp_pdev.num_sockets); > sock = &hsmp_pdev.sock[sock_ind]; > > + /* > + * A slot exists for every possible socket, but it is only usable once > + * that socket has actually been probed. Reject messages aimed at a > + * socket that was never brought up or is still in bring-up, so we never > + * operate on a zero-initialized semaphore or an unmapped mailbox. A > + * non-NULL dev also guarantees virt_base_addr, the mailbox offsets and > + * the semaphore are visible. > + */ > + /* Pairs with smp_store_release(&sock->dev) in hsmp_parse_acpi_table(). */ Change to: /* ... * the semaphore are visible. * * Pairs with smp_store_release(&sock->dev) in hsmp_parse_acpi_table(). */ > + if (!smp_load_acquire(&sock->dev)) > + return -ENODEV; > + > ret = down_interruptible(&sock->hsmp_sem); > if (ret < 0) > return ret; > -- i. ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-06-29 14:52 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-06-29 7:39 [PATCH 0/4] platform/x86/amd/hsmp: ACPI input hardening and data-plane readiness gating Muralidhara M K 2026-06-29 7:39 ` [PATCH 1/4] platform/x86/amd/hsmp: Validate ACPI UID before parsing socket index Muralidhara M K 2026-06-29 7:39 ` [PATCH 2/4] platform/x86/amd/hsmp: Validate _DSD mailbox sub-package element count Muralidhara M K 2026-06-29 7:39 ` [PATCH 3/4] platform/x86/amd/hsmp: Pass struct device explicitly to ACPI mailbox parsers Muralidhara M K 2026-06-29 12:46 ` Ilpo Järvinen 2026-06-29 14:07 ` M K, Muralidhara 2026-06-29 14:52 ` Ilpo Järvinen 2026-06-29 7:39 ` [PATCH 4/4] platform/x86/amd/hsmp: Gate the data plane on a fully initialized socket Muralidhara M K 2026-06-29 12:50 ` Ilpo Järvinen
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox