From: "M K, Muralidhara" <muralimk@amd.com>
To: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>,
"Muralidhara M K" <muralidhara.mk@amd.com>
Cc: Mario.Limonciello@amd.com, platform-driver-x86@vger.kernel.org,
LKML <linux-kernel@vger.kernel.org>,
Mario Limonciello <superm1@kernel.org>
Subject: Re: [PATCH v5 1/4] platform/x86/amd/hsmp: Add HSMP client support for Family 1Ah
Date: Sat, 19 Sep 2026 11:02:41 +0530 [thread overview]
Message-ID: <d3e9e152-07b0-4672-aa97-018c7da236f3@amd.com> (raw)
In-Reply-To: <f700dbe0-707b-c43d-b7c2-2962662340f2@linux.intel.com>
On 9/18/2026 5:04 PM, Ilpo Järvinen wrote:
> Caution: This message originated from an External Source. Use proper caution when opening attachments, clicking links, or responding.
>
>
> On Tue, 1 Sep 2026, Muralidhara M K wrote:
>
>> Enable the HSMP driver on the Family 1Ah client platforms, Models
>> 80h-8Fh and E0h-E3h. These parts speak the Ryzen Master SMC (RMSMC)
>> message set instead of the server HSMP messages, but describe their
>> mailbox via ACPI _CRS/_DSD the same way a server socket does, so only
>> the ACPI driver needs to probe them.
>>
>> Add the client message set to the UAPI header and its descriptor
>> table to the driver. struct hsmp_plat_desc picks the right table and
>> driver-issued message IDs once per boot based on the ACPI-reported PM
>> profile, which tells client and server apart without pinning the
>> driver to a fixed set of family/model ranges. Document the client
>> models in amd_hsmp.rst.
>>
>> Signed-off-by: Muralidhara M K <muralidhara.mk@amd.com>
>> Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
>> ---
>> Documentation/arch/x86/amd_hsmp.rst | 10 +-
>> arch/x86/include/uapi/asm/amd_hsmp.h | 135 ++++++++++++++
>> drivers/platform/x86/amd/hsmp/hsmp.c | 255 ++++++++++++++++++++++++---
>> drivers/platform/x86/amd/hsmp/hsmp.h | 27 +++
>> 4 files changed, 398 insertions(+), 29 deletions(-)
>>
>> diff --git a/Documentation/arch/x86/amd_hsmp.rst b/Documentation/arch/x86/amd_hsmp.rst
>> index fa1fc240e212..b95f09945193 100644
>> --- a/Documentation/arch/x86/amd_hsmp.rst
>> +++ b/Documentation/arch/x86/amd_hsmp.rst
>> @@ -8,6 +8,13 @@ Newer Fam19h(model 0x00-0x1f, 0x30-0x3f, 0x90-0x9f, 0xa0-0xaf),
>> Fam1Ah(model 0x00-0x1f) EPYC server line of processors from AMD support
>> system management functionality via HSMP (Host System Management Port).
>>
>> +The Fam1Ah(model 0x80-0x8f, 0xe0-0xe3) client line of processors is
>> +supported as well. Those models share one mailbox and speak the Ryzen
>> +Master SMC message set instead of the server HSMP message set, so the
>> +message IDs accepted on them are the HSMP_CLIENT_* ones listed in
>> +arch/x86/include/uapi/asm/amd_hsmp.h. The character device and ioctl
>> +interface described below are the same.
>> +
>> The Host System Management Port (HSMP) is an interface to provide
>> OS-level software with access to system management functions via a
>> set of mailbox registers.
>> @@ -17,7 +24,8 @@ More details on the interface can be found in chapter
>> Eg: https://docs.amd.com/v/u/en-US/55898_B1_pub_0_50
>>
>>
>> -HSMP interface is supported on EPYC line of server CPUs and MI300A (APU).
>> +HSMP interface is supported on EPYC line of server CPUs, MI300A (APU) and
>> +the Fam1Ah client models listed above.
>>
>>
>> HSMP device
>> diff --git a/arch/x86/include/uapi/asm/amd_hsmp.h b/arch/x86/include/uapi/asm/amd_hsmp.h
>> index eda336bfd3e9..00ca7855ca00 100644
>> --- a/arch/x86/include/uapi/asm/amd_hsmp.h
>> +++ b/arch/x86/include/uapi/asm/amd_hsmp.h
>> @@ -664,4 +664,139 @@ struct hsmp_telemetry_data {
>> #define HSMP_IOCTL_GET_TELEMETRY_DATA \
>> _IOW(HSMP_BASE_IOCTL_NR, 1, struct hsmp_telemetry_data)
>>
>> +/**
>> + * enum hsmp_client_message_ids - Ryzen Master SMC (RMSMC) message IDs
>> + * @HSMP_CLIENT_TEST: 01h. Test message. input: args[0] = xx. output:
>> + * args[0] = xx + 1.
>> + * @HSMP_CLIENT_GET_SMU_VER: 02h. Get MP1 firmware version. output:
>> + * args[0] = MP1 firmware version.
>> + * @HSMP_CLIENT_GET_INTERFACE_VER: 03h. Get interface version. output:
>> + * args[0] = interface version.
>> + * @HSMP_CLIENT_GET_METRICS_TABLE_VER: 04h. Get metrics table version.
>> + * output: args[0] = metrics table version.
>> + * @HSMP_CLIENT_GET_METRICS_TABLE: 05h. Get metrics table. No arguments.
>> + * Success means firmware has written the metrics table to the DRAM
>> + * address reported by @HSMP_CLIENT_GET_METRICS_TABLE_DRAM_ADDR.
>> + * @HSMP_CLIENT_GET_METRICS_TABLE_DRAM_ADDR: 06h. Get metrics table DRAM
>> + * address. output: args[0] = address[31:0], args[1] = address[63:32],
>> + * args[2] = table size in bytes.
>> + * @HSMP_CLIENT_SET_CORE_PSM_MARGIN: 07h. Set core voltage margin. input:
>> + * args[0] = ApicId[31:16] + margin in mV[15:0].
>> + * @HSMP_CLIENT_SET_ALL_CORE_PSM_MARGIN: 08h. Set voltage margin for all
>> + * cores. input: args[0] = margin in mV[15:0].
>> + * @HSMP_CLIENT_SET_FAST_PPT_LIMIT: 09h. Set APU fast PPT limit. input:
>> + * args[0] = limit in mW.
>> + * @HSMP_CLIENT_SET_VRM_VDD_CURRENT_LIMIT: 0Ah. Set VDDCR_VDD TDC. input:
>> + * args[0] = limit in mA.
>> + * @HSMP_CLIENT_SET_VRM_VDD_MAX_CURRENT_LIMIT: 0Bh. Set VDDCR_VDD EDC.
>> + * input: args[0] = limit in mA.
>> + * @HSMP_CLIENT_SET_TJ_MAX: 0Ch. Set maximum junction temperature. input:
>> + * args[0] = temperature in degrees C.
>> + * @HSMP_CLIENT_SET_FIT_LIMIT_SCALAR: 0Dh. Set failures-in-time limit
>> + * scalar. input: args[0] = scalar (0 to 100).
>> + * @HSMP_CLIENT_ENABLE_OVERCLOCKING: 0Eh. Enable overclocking. No
>> + * arguments.
>> + * @HSMP_CLIENT_DISABLE_OVERCLOCKING: 0Fh. Disable overclocking. No
>> + * arguments.
>> + * @HSMP_CLIENT_SET_OVERCLOCK_FREQ_ALL_CORES: 10h. Set all-core overclock
>> + * frequency. input: args[0] = frequency in MHz[15:0].
>> + * @HSMP_CLIENT_SET_OVERCLOCK_FREQ_PER_CORE: 11h. Set per-core overclock
>> + * frequency. input: args[0] = ApicId[31:16] + frequency in MHz[15:0].
>> + * @HSMP_CLIENT_SET_OVERCLOCK_VID: 12h. Set overclock VID. input:
>> + * args[0] = voltage in mV[15:0].
>> + * @HSMP_CLIENT_SET_FCLK_OVERCLOCK_ON_THE_FLY: 13h. Set FCLK overclock on
>> + * the fly. input: args[0] = FCLK in MHz[15:0].
>> + * @HSMP_CLIENT_GET_CORE_PERF_ORDER: 14h. Get core performance order.
>> + * input: args[0] = ApicId[15:0]. output: args[0] = frequency in
>> + * MHz[15:0].
>> + * @HSMP_CLIENT_SET_SUSTAINED_POWER_LIMIT: 15h. Set SOC sustained power
>> + * limit. input: args[0] = limit in mW.
>> + * @HSMP_CLIENT_SET_SLOW_PPT_LIMIT: 16h. Set APU slow PPT limit. input:
>> + * args[0] = limit in mW.
>> + * @HSMP_CLIENT_SET_VRM_GFX_MAX_CURRENT_LIMIT: 17h. Set VDDCR_GFX EDC.
>> + * input: args[0] = limit in mA.
>> + * @HSMP_CLIENT_SET_VRM_SOC_CURRENT_LIMIT: 18h. Set VDDCR_SOC TDC. input:
>> + * args[0] = limit in mA.
>> + * @HSMP_CLIENT_SET_FAST_SPM_LIMIT: 19h. Set fast SPM limit. input:
>> + * args[0] = limit in mW.
>> + * @HSMP_CLIENT_SET_SLOW_SPM_LIMIT: 1Ah. Set slow SPM limit. input:
>> + * args[0] = limit in mW.
>> + * @HSMP_CLIENT_GET_CORE_PSM_MARGIN: 1Bh. Get core voltage margin. input:
>> + * args[0] = ApicId[15:0]. output: args[0] = margin in mV[15:0].
>> + * @HSMP_CLIENT_GET_GFX_PSM_MARGIN: 1Ch. Get graphics voltage margin.
>> + * output: args[0] = margin in mV[15:0].
>> + * @HSMP_CLIENT_SPARE_0X1D: 1Dh. Reserved.
>> + * @HSMP_CLIENT_SPARE_0X1E: 1Eh. Reserved.
>> + * @HSMP_CLIENT_SPARE_0X1F: 1Fh. Reserved.
>> + * @HSMP_CLIENT_SPARE_0X20: 20h. Reserved.
>> + * @HSMP_CLIENT_SET_GFXCLK_OVERDRIVE_BY_FREQ_VID: 21h. Set GfxClk
>> + * overdrive by frequency/VID. input: args[0] = frequency in
>> + * MHz[31:16] + voltage in mV[15:0].
>> + * @HSMP_CLIENT_DISABLE_GFXCLK_OVERDRIVE: 22h. Disable GfxClk overdrive.
>> + * No arguments.
>> + * @HSMP_CLIENT_SET_GFX_PSM_MARGIN: 23h. Set graphics voltage margin.
>> + * input: args[0] = margin in mV[15:0].
>> + * @HSMP_CLIENT_SET_CCLK_FMAX_OFFSET: 24h. Set CCLK Fmax offset. input:
>> + * args[0] = maximum frequency in MHz[15:0].
>> + * @HSMP_CLIENT_SET_CORE_POWER_LIMIT_OFFSET: 25h. Set core power limit
>> + * offset. input: args[0] = limit in mW.
>> + * @HSMP_CLIENT_ADD_EXTRA_PSM_GUARDBAND: 26h. Add extra core PSM
>> + * guardband. input: args[0] = voltage in mV[15:0].
>> + * @HSMP_CLIENT_ADD_EXTRA_PSM_GUARDBAND_GFX: 27h. Add extra graphics PSM
>> + * guardband. input: args[0] = voltage in mV[15:0].
>> + * @HSMP_CLIENT_SET_GFXCLK_FMAX: 28h. Set GfxClk Fmax. input: args[0] =
>> + * maximum frequency in MHz[15:0].
>> + * @HSMP_CLIENT_MSG_ID_MAX: Number of message IDs, not a valid ID itself.
>> + *
>> + * Message IDs accepted on the Family 1Ah client platforms, Models 80h-8Fh
>> + * and E0h-E3h. These parts drive one mailbox and speak the Ryzen Master
>> + * SMC message set instead of the server HSMP message set enumerated in
>> + * &enum hsmp_message_ids. Not all platforms support all messages; consult
>> + * the supported list of messages in the HSMP chapter of the respective
>> + * family/model PPR. Unsupported messages return -ENOMSG.
>> + */
>> +enum hsmp_client_message_ids {
>> + HSMP_CLIENT_TEST = 1,
>> + HSMP_CLIENT_GET_SMU_VER,
>> + HSMP_CLIENT_GET_INTERFACE_VER,
>> + HSMP_CLIENT_GET_METRICS_TABLE_VER,
>> + HSMP_CLIENT_GET_METRICS_TABLE,
>> + HSMP_CLIENT_GET_METRICS_TABLE_DRAM_ADDR,
>> + HSMP_CLIENT_SET_CORE_PSM_MARGIN,
>> + HSMP_CLIENT_SET_ALL_CORE_PSM_MARGIN,
>> + HSMP_CLIENT_SET_FAST_PPT_LIMIT,
>> + HSMP_CLIENT_SET_VRM_VDD_CURRENT_LIMIT,
>> + HSMP_CLIENT_SET_VRM_VDD_MAX_CURRENT_LIMIT,
>> + HSMP_CLIENT_SET_TJ_MAX,
>> + HSMP_CLIENT_SET_FIT_LIMIT_SCALAR,
>> + HSMP_CLIENT_ENABLE_OVERCLOCKING,
>> + HSMP_CLIENT_DISABLE_OVERCLOCKING,
>> + HSMP_CLIENT_SET_OVERCLOCK_FREQ_ALL_CORES,
>> + HSMP_CLIENT_SET_OVERCLOCK_FREQ_PER_CORE,
>> + HSMP_CLIENT_SET_OVERCLOCK_VID,
>> + HSMP_CLIENT_SET_FCLK_OVERCLOCK_ON_THE_FLY,
>> + HSMP_CLIENT_GET_CORE_PERF_ORDER,
>> + HSMP_CLIENT_SET_SUSTAINED_POWER_LIMIT,
>> + HSMP_CLIENT_SET_SLOW_PPT_LIMIT,
>> + HSMP_CLIENT_SET_VRM_GFX_MAX_CURRENT_LIMIT,
>> + HSMP_CLIENT_SET_VRM_SOC_CURRENT_LIMIT,
>> + HSMP_CLIENT_SET_FAST_SPM_LIMIT,
>> + HSMP_CLIENT_SET_SLOW_SPM_LIMIT,
>> + HSMP_CLIENT_GET_CORE_PSM_MARGIN,
>> + HSMP_CLIENT_GET_GFX_PSM_MARGIN,
>> + HSMP_CLIENT_SPARE_0X1D,
>> + HSMP_CLIENT_SPARE_0X1E,
>> + HSMP_CLIENT_SPARE_0X1F,
>> + HSMP_CLIENT_SPARE_0X20,
>> + HSMP_CLIENT_SET_GFXCLK_OVERDRIVE_BY_FREQ_VID,
>> + HSMP_CLIENT_DISABLE_GFXCLK_OVERDRIVE,
>> + HSMP_CLIENT_SET_GFX_PSM_MARGIN,
>> + HSMP_CLIENT_SET_CCLK_FMAX_OFFSET,
>> + HSMP_CLIENT_SET_CORE_POWER_LIMIT_OFFSET,
>> + HSMP_CLIENT_ADD_EXTRA_PSM_GUARDBAND,
>> + HSMP_CLIENT_ADD_EXTRA_PSM_GUARDBAND_GFX,
>> + HSMP_CLIENT_SET_GFXCLK_FMAX,
>> + HSMP_CLIENT_MSG_ID_MAX,
>> +};
>> +
>> #endif /*_ASM_X86_AMD_HSMP_H_*/
>> diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c
>> index 5e123a4ecea9..e8fac2d299f3 100644
>> --- a/drivers/platform/x86/amd/hsmp/hsmp.c
>> +++ b/drivers/platform/x86/amd/hsmp/hsmp.c
>> @@ -10,6 +10,8 @@
>> #include <asm/amd/hsmp.h>
>>
>> #include <linux/acpi.h>
>> +#include <linux/array_size.h>
>> +#include <linux/build_bug.h>
>> #include <linux/cleanup.h>
>> #include <linux/delay.h>
>> #include <linux/device.h>
>> @@ -45,8 +47,197 @@
>> */
>> #define CHECK_GET_BIT BIT(31)
>>
>> +/* Indexed by enum hsmp_client_message_ids; see there for per-message details */
>> +static const struct hsmp_msg_desc hsmp_client_msg_desc_table[] = {
>> + /* RESERVED */
>> + {0, 0, HSMP_RSVD},
>> +
>> + /* HSMP_CLIENT_TEST */
>> + {1, 1, HSMP_GET},
>> +
>> + /* HSMP_CLIENT_GET_SMU_VER */
>> + {0, 1, HSMP_GET},
>> +
>> + /* HSMP_CLIENT_GET_INTERFACE_VER */
>> + {0, 1, HSMP_GET},
>> +
>> + /* HSMP_CLIENT_GET_METRICS_TABLE_VER */
>> + {0, 1, HSMP_GET},
>> +
>> + /* HSMP_CLIENT_GET_METRICS_TABLE */
>> + {0, 0, HSMP_GET},
>> +
>> + /* HSMP_CLIENT_GET_METRICS_TABLE_DRAM_ADDR */
>> + {0, 3, HSMP_GET},
>> +
>> + /* HSMP_CLIENT_SET_CORE_PSM_MARGIN */
>> + {1, 0, HSMP_SET},
>> +
>> + /* HSMP_CLIENT_SET_ALL_CORE_PSM_MARGIN */
>> + {1, 0, HSMP_SET},
>> +
>> + /* HSMP_CLIENT_SET_FAST_PPT_LIMIT */
>> + {1, 0, HSMP_SET},
>> +
>> + /* HSMP_CLIENT_SET_VRM_VDD_CURRENT_LIMIT */
>> + {1, 0, HSMP_SET},
>> +
>> + /* HSMP_CLIENT_SET_VRM_VDD_MAX_CURRENT_LIMIT */
>> + {1, 0, HSMP_SET},
>> +
>> + /* HSMP_CLIENT_SET_TJ_MAX */
>> + {1, 0, HSMP_SET},
>> +
>> + /* HSMP_CLIENT_SET_FIT_LIMIT_SCALAR */
>> + {1, 0, HSMP_SET},
>> +
>> + /* HSMP_CLIENT_ENABLE_OVERCLOCKING */
>> + {0, 0, HSMP_SET},
>> +
>> + /* HSMP_CLIENT_DISABLE_OVERCLOCKING */
>> + {0, 0, HSMP_SET},
>> +
>> + /* HSMP_CLIENT_SET_OVERCLOCK_FREQ_ALL_CORES */
>> + {1, 0, HSMP_SET},
>> +
>> + /* HSMP_CLIENT_SET_OVERCLOCK_FREQ_PER_CORE */
>> + {1, 0, HSMP_SET},
>> +
>> + /* HSMP_CLIENT_SET_OVERCLOCK_VID */
>> + {1, 0, HSMP_SET},
>> +
>> + /* HSMP_CLIENT_SET_FCLK_OVERCLOCK_ON_THE_FLY */
>> + {1, 0, HSMP_SET},
>> +
>> + /* HSMP_CLIENT_GET_CORE_PERF_ORDER */
>> + {1, 1, HSMP_GET},
>> +
>> + /* HSMP_CLIENT_SET_SUSTAINED_POWER_LIMIT */
>> + {1, 0, HSMP_SET},
>> +
>> + /* HSMP_CLIENT_SET_SLOW_PPT_LIMIT */
>> + {1, 0, HSMP_SET},
>> +
>> + /* HSMP_CLIENT_SET_VRM_GFX_MAX_CURRENT_LIMIT */
>> + {1, 0, HSMP_SET},
>> +
>> + /* HSMP_CLIENT_SET_VRM_SOC_CURRENT_LIMIT */
>> + {1, 0, HSMP_SET},
>> +
>> + /* HSMP_CLIENT_SET_FAST_SPM_LIMIT */
>> + {1, 0, HSMP_SET},
>> +
>> + /* HSMP_CLIENT_SET_SLOW_SPM_LIMIT */
>> + {1, 0, HSMP_SET},
>> +
>> + /* HSMP_CLIENT_GET_CORE_PSM_MARGIN */
>> + {1, 1, HSMP_GET},
>> +
>> + /* HSMP_CLIENT_GET_GFX_PSM_MARGIN */
>> + {0, 1, HSMP_GET},
>> +
>> + /* HSMP_CLIENT_SPARE_0X1D */
>> + {0, 0, HSMP_RSVD},
>> +
>> + /* HSMP_CLIENT_SPARE_0X1E */
>> + {0, 0, HSMP_RSVD},
>> +
>> + /* HSMP_CLIENT_SPARE_0X1F */
>> + {0, 0, HSMP_RSVD},
>> +
>> + /* HSMP_CLIENT_SPARE_0X20 */
>> + {0, 0, HSMP_RSVD},
>> +
>> + /* HSMP_CLIENT_SET_GFXCLK_OVERDRIVE_BY_FREQ_VID */
>> + {1, 0, HSMP_SET},
>> +
>> + /* HSMP_CLIENT_DISABLE_GFXCLK_OVERDRIVE */
>> + {0, 0, HSMP_SET},
>> +
>> + /* HSMP_CLIENT_SET_GFX_PSM_MARGIN */
>> + {1, 0, HSMP_SET},
>> +
>> + /* HSMP_CLIENT_SET_CCLK_FMAX_OFFSET */
>> + {1, 0, HSMP_SET},
>> +
>> + /* HSMP_CLIENT_SET_CORE_POWER_LIMIT_OFFSET */
>> + {1, 0, HSMP_SET},
>> +
>> + /* HSMP_CLIENT_ADD_EXTRA_PSM_GUARDBAND */
>> + {1, 0, HSMP_SET},
>> +
>> + /* HSMP_CLIENT_ADD_EXTRA_PSM_GUARDBAND_GFX */
>> + {1, 0, HSMP_SET},
>> +
>> + /* HSMP_CLIENT_SET_GFXCLK_FMAX */
>> + {1, 0, HSMP_SET},
>> +};
>> +
>> +/* Catch a table left out of sync with its enum at build time */
>> +static_assert(ARRAY_SIZE(hsmp_msg_desc_table) == HSMP_MSG_ID_MAX);
>> +static_assert(ARRAY_SIZE(hsmp_client_msg_desc_table) == HSMP_CLIENT_MSG_ID_MAX);
>> +
>> +/* Per-platform message set: which table to use, and driver-issued msg IDs */
>> +struct hsmp_plat_desc {
>> + const struct hsmp_msg_desc *msg_desc;
>> + u32 num_msgs;
>> + u32 test_msg;
>> + u32 proto_ver_msg;
>> +};
>> +
>> +static const struct hsmp_plat_desc hsmp_desc_server = {
>> + .msg_desc = hsmp_msg_desc_table,
>> + .num_msgs = HSMP_MSG_ID_MAX,
>> + .test_msg = HSMP_TEST,
>> + .proto_ver_msg = HSMP_GET_PROTO_VER,
>> +};
>> +
>> +/* The client drives a different mailbox with the Ryzen Master SMC message set */
>> +static const struct hsmp_plat_desc hsmp_desc_client = {
>> + .msg_desc = hsmp_client_msg_desc_table,
>> + .num_msgs = HSMP_CLIENT_MSG_ID_MAX,
>> + .test_msg = HSMP_CLIENT_TEST,
>> + .proto_ver_msg = HSMP_CLIENT_GET_INTERFACE_VER,
>> +};
>> +
>> static struct hsmp_plat_device hsmp_pdev;
>>
>> +/*
>> + * Resolved on first use and cached, since is_client_platform() always
>> + * settles on the same descriptor once booted. Concurrent first callers are
>> + * benign: every one of them computes and stores that same pointer, so
>> + * READ_ONCE()/WRITE_ONCE() only need to keep the access from being torn or
>> + * reordered by the compiler, not order it against anything else.
>> + */
>> +static const struct hsmp_plat_desc *hsmp_desc_cache;
>> +
>> +static inline const struct hsmp_plat_desc *hsmp_desc(void)
>
> In C files, please drop inline from anything non-trivial and let the
> compiler decide if it inlines or not.
>
Thanks. Will drop this.
>> +{
>> + const struct hsmp_plat_desc *desc = READ_ONCE(hsmp_desc_cache);
>> +
>> + if (likely(desc))
>
> Add include.
>
>> + return desc;
>> +
>> + desc = is_client_platform() ? &hsmp_desc_client : &hsmp_desc_server;
>> + WRITE_ONCE(hsmp_desc_cache, desc);
>
> Add include.
>
Sure will add #include <linux/compiler.h> which is needed explicitly for
likely()/READ_ONCE()/WRITE_ONCE()
>> +
>> + return desc;
>> +}
>> +
>> +/* Returns NULL if msg_id is out of range or reserved for this platform */
>> +static inline const struct hsmp_msg_desc *get_msg_desc(u32 msg_id)
>> +{
>> + const struct hsmp_plat_desc *desc = hsmp_desc();
>> +
>> + if (msg_id >= desc->num_msgs)
>> + return NULL;
>> +
>> + if (desc->msg_desc[msg_id].type == HSMP_RSVD)
>> + return NULL;
>> +
>> + return &desc->msg_desc[msg_id];
>> +}
>> +
>> /*
>> * Gates the AMD HSMP data plane against socket bring-up and teardown.
>> *
>> @@ -184,30 +375,29 @@ static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *ms
>>
>> static int validate_message(struct hsmp_message *msg)
>> {
>> - /* msg_id against valid range of message IDs */
>> - if (msg->msg_id < HSMP_TEST || msg->msg_id >= HSMP_MSG_ID_MAX)
>> - return -ENOMSG;
>> + const struct hsmp_msg_desc *desc;
>>
>> - /* msg_id is a reserved message ID */
>> - if (hsmp_msg_desc_table[msg->msg_id].type == HSMP_RSVD)
>> + /* Unknown or reserved message ID for this platform */
>> + desc = get_msg_desc(msg->msg_id);
>> + if (!desc)
>> return -ENOMSG;
>>
>> /*
>> * num_args passed by user should match the num_args specified in
>> * message description table.
>> */
>> - if (msg->num_args != hsmp_msg_desc_table[msg->msg_id].num_args)
>> + if (msg->num_args != desc->num_args)
>> return -EINVAL;
>>
>> /*
>> * As the HSMP protocol evolves, newer platforms may define more
>> * response arguments for existing messages. Use an upper-bound
>> * check so that older userspace callers requesting fewer response
>> - * words than what the current hsmp_msg_desc_table[] defines are
>> - * still accepted, while rejecting requests that exceed the
>> - * hardware capability.
>> + * words than what the current descriptor table defines are still
>> + * accepted, while rejecting requests that exceed the hardware
>> + * capability.
>> */
>> - if (msg->response_sz > hsmp_msg_desc_table[msg->msg_id].response_sz)
>> + if (msg->response_sz > desc->response_sz)
>> return -EINVAL;
>>
>> return 0;
>> @@ -316,7 +506,7 @@ int hsmp_test(u16 sock_ind, u32 value)
>> * Test the hsmp port by performing TEST command. The test message
>> * takes one argument and returns the value of that argument + 1.
>> */
>> - msg.msg_id = HSMP_TEST;
>> + msg.msg_id = hsmp_desc()->test_msg;
>> msg.num_args = 1;
>> msg.response_sz = 1;
>> msg.args[0] = value;
>> @@ -338,12 +528,12 @@ int hsmp_test(u16 sock_ind, u32 value)
>> }
>> EXPORT_SYMBOL_NS_GPL(hsmp_test, "AMD_HSMP");
>>
>> -static bool is_get_msg(struct hsmp_message *msg)
>> +static bool is_get_msg(const struct hsmp_msg_desc *desc, struct hsmp_message *msg)
>> {
>> - if (hsmp_msg_desc_table[msg->msg_id].type == HSMP_GET)
>> + if (desc->type == HSMP_GET)
>> return true;
>>
>> - if (hsmp_msg_desc_table[msg->msg_id].type == HSMP_SET_GET &&
>> + if (desc->type == HSMP_SET_GET &&
>> (msg->args[0] & CHECK_GET_BIT))
>
> Should fit to one line now?
>
> (Heh, I was going to say this is open-coding coding is_get_msg() before
> realizing it's the very thing :-)).
>
>> return true;
>>
>> @@ -354,6 +544,8 @@ static long hsmp_ioctl_msg(struct file *fp, unsigned long arg)
>> {
>> int __user *arguser = (int __user *)arg;
>> struct hsmp_message msg = { 0 };
>> + const struct hsmp_plat_desc *plat_desc = hsmp_desc();
>> + const struct hsmp_msg_desc *desc;
>> int ret;
>>
>> if (copy_struct_from_user(&msg, sizeof(msg), arguser, sizeof(struct hsmp_message)))
>> @@ -361,23 +553,25 @@ static long hsmp_ioctl_msg(struct file *fp, unsigned long arg)
>>
>> /*
>> * Check msg_id is within the range of supported msg ids
>> - * i.e within the array bounds of hsmp_msg_desc_table
>> + * i.e within the array bounds of the platform's descriptor table
>> */
>> - if (msg.msg_id < HSMP_TEST || msg.msg_id >= HSMP_MSG_ID_MAX)
>> + if (msg.msg_id < plat_desc->test_msg || msg.msg_id >= plat_desc->num_msgs)
>> return -ENOMSG;
>>
>> /*
>> * Sanitize the user-controlled msg_id against speculative
>> * execution. The bounds check above retires the out-of-range
>> * case with -ENOMSG, but a mispredicted branch can still let the
>> - * CPU speculatively use msg_id as an index into
>> - * hsmp_msg_desc_table[] (here and in validate_message() /
>> - * is_get_msg() called downstream via hsmp_send_message()), and
>> - * pull arbitrary kernel memory into the cache (Spectre v1,
>> - * CVE-2017-5753). Clamp once into msg.msg_id so every downstream
>> - * dereference sees the sanitized value.
>> + * CPU speculatively use msg_id as an index into the message
>> + * descriptor table, here and again in validate_message() called
>> + * downstream via hsmp_send_message().
>> */
>> - msg.msg_id = array_index_nospec(msg.msg_id, HSMP_MSG_ID_MAX);
>> + msg.msg_id = array_index_nospec(msg.msg_id, plat_desc->num_msgs);
>> +
>> + /* Rejects the reserved IDs the table describes as such */
>> + desc = get_msg_desc(msg.msg_id);
>> + if (!desc)
>> + return -ENOMSG;
>>
>> switch (fp->f_mode & (FMODE_WRITE | FMODE_READ)) {
>> case FMODE_WRITE:
>> @@ -385,7 +579,7 @@ static long hsmp_ioctl_msg(struct file *fp, unsigned long arg)
>> * Device is opened in O_WRONLY mode
>> * Execute only set/configure commands
>> */
>> - if (is_get_msg(&msg))
>> + if (is_get_msg(desc, &msg))
>> return -EPERM;
>> break;
>> case FMODE_READ:
>> @@ -393,7 +587,7 @@ static long hsmp_ioctl_msg(struct file *fp, unsigned long arg)
>> * Device is opened in O_RDONLY mode
>> * Execute only get/monitor commands
>> */
>> - if (!is_get_msg(&msg))
>> + if (!is_get_msg(desc, &msg))
>> return -EPERM;
>> break;
>> case FMODE_READ | FMODE_WRITE:
>> @@ -410,7 +604,7 @@ static long hsmp_ioctl_msg(struct file *fp, unsigned long arg)
>> if (ret)
>> return ret;
>>
>> - if (hsmp_msg_desc_table[msg.msg_id].response_sz > 0) {
>> + if (desc->response_sz > 0) {
>> /* Copy results back to user for get/monitor commands */
>> if (copy_to_user(arguser, &msg, sizeof(struct hsmp_message)))
>> return -EFAULT;
>> @@ -685,11 +879,16 @@ EXPORT_SYMBOL_NS_GPL(hsmp_get_tbl_dram_base, "AMD_HSMP");
>> int hsmp_cache_proto_ver(u16 sock_ind)
>> {
>> struct hsmp_message msg = { 0 };
>> + const struct hsmp_msg_desc *desc;
>> int ret;
>>
>> - msg.msg_id = HSMP_GET_PROTO_VER;
>> + msg.msg_id = hsmp_desc()->proto_ver_msg;
>> + desc = get_msg_desc(msg.msg_id);
>> + if (WARN_ON(!desc))
>> + return -ENOMSG;
>> +
>> msg.sock_ind = sock_ind;
>> - msg.response_sz = hsmp_msg_desc_table[HSMP_GET_PROTO_VER].response_sz;
>> + msg.response_sz = desc->response_sz;
>>
>> ret = hsmp_send_message_locked(&msg);
>> if (!ret)
>> diff --git a/drivers/platform/x86/amd/hsmp/hsmp.h b/drivers/platform/x86/amd/hsmp/hsmp.h
>> index 8dbff16a87b1..890cfb664829 100644
>> --- a/drivers/platform/x86/amd/hsmp/hsmp.h
>> +++ b/drivers/platform/x86/amd/hsmp/hsmp.h
>> @@ -10,6 +10,9 @@
>> #ifndef HSMP_H
>> #define HSMP_H
>>
>> +#include <asm/amd/hsmp.h>
>> +
>> +#include <linux/acpi.h>
>> #include <linux/compiler_types.h>
>> #include <linux/device.h>
>> #include <linux/hwmon.h>
>> @@ -17,6 +20,7 @@
>> #include <linux/miscdevice.h>
>> #include <linux/mutex.h>
>> #include <linux/pci.h>
>> +#include <linux/processor.h>
>> #include <linux/rwsem.h>
>> #include <linux/semaphore.h>
>> #include <linux/sysfs.h>
>> @@ -32,6 +36,29 @@
>>
>> #define DRIVER_VERSION "2.6"
>>
>> +/*
>> + * Family/model ranges need a driver update every generation and miss new
>> + * client parts until then. The ACPI-reported PM profile does not: it says
>> + * what kind of system this is regardless of which CPU is in it.
>> + */
>> +static inline bool is_client_platform(void)
>> +{
>> + if (!IS_ENABLED(CONFIG_ACPI))
>> + return false;
>> +
>> + if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
>> + return false;
>> +
>> + switch (acpi_gbl_FADT.preferred_profile) {
>> + case PM_DESKTOP:
>> + case PM_MOBILE:
>> + case PM_TABLET:
>> + return true;
>> + default:
>> + return false;
>> + }
>> +}
>> +
>> struct hsmp_mbaddr_info {
>> u32 base_addr;
>> u32 msg_id_off;
>>
>
> --
> i.
>
next prev parent reply other threads:[~2026-09-19 5:32 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-01 4:51 [PATCH v5 0/4] platform/x86/amd/hsmp: Family 1Ah client support Muralidhara M K
2026-09-01 4:51 ` [PATCH v5 1/4] platform/x86/amd/hsmp: Add HSMP client support for Family 1Ah Muralidhara M K
2026-09-18 11:34 ` Ilpo Järvinen
2026-09-19 5:32 ` M K, Muralidhara [this message]
2026-09-18 11:46 ` Ilpo Järvinen
2026-09-01 4:51 ` [PATCH v5 2/4] platform/x86/amd/hsmp: Route metric table through the client messages Muralidhara M K
2026-09-01 4:51 ` [PATCH v5 3/4] platform/x86/amd/hsmp: Add ACPI client support for Family 1Ah Muralidhara M K
2026-09-18 11:39 ` Ilpo Järvinen
2026-09-19 5:30 ` M K, Muralidhara
2026-09-18 11:43 ` Ilpo Järvinen
2026-09-01 4:51 ` [PATCH v5 4/4] platform/x86/amd/hsmp: Document and expose client telemetry table in UAPI Muralidhara M K
2026-09-01 12:24 ` [PATCH v5 0/4] platform/x86/amd/hsmp: Family 1Ah client support Mario Limonciello
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=d3e9e152-07b0-4672-aa97-018c7da236f3@amd.com \
--to=muralimk@amd.com \
--cc=Mario.Limonciello@amd.com \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=muralidhara.mk@amd.com \
--cc=platform-driver-x86@vger.kernel.org \
--cc=superm1@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.