X86 platform drivers
 help / color / mirror / Atom feed
From: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>
To: Suma Hegde <suma.hegde@amd.com>
Cc: platform-driver-x86@vger.kernel.org, hdegoede@redhat.com,
	 Muthusamy Ramalingam <muthusamy.ramalingam@amd.com>,
	 NaveenKrishna.Chatradhi@amd.com,
	Dhruv Gupta <dhruv.gupta@amd.com>,
	 Muthusamy Ramalingam <Muthusamy.Ramalingam@amd.com>
Subject: Re: [PATCH 07/11] platform/x86/amd/hsmp: Add per-platform bitmap to validate HSMP messages
Date: Wed, 21 Oct 2026 14:28:41 +0300 (EEST)	[thread overview]
Message-ID: <9d6591cb-1423-00cb-e87c-80d5a44a8fa7@linux.intel.com> (raw)
In-Reply-To: <5a6e8a43-ed7e-74fc-f83b-ec29352eaf92@linux.intel.com>

[-- Attachment #1: Type: text/plain, Size: 12462 bytes --]

On Wed, 21 Oct 2026, Ilpo Järvinen wrote:

> On Thu, 8 Oct 2026, Suma Hegde wrote:
> 
> > From: Suma Hegde <Suma.Hegde@amd.com>
> > 
> > The HSMP driver previously allowed sending any message defined in
> > amd_hsmp.h, including ones not supported on the running platform.
> > 
> > Add read and write bitmaps per socket to store which HSMP messages
> > are enabled on the platform. Add validation in validate_message()
> > to reject unsupported messages before they reach the SMU.
> > 
> > Key changes:
> > - Introduce enabled_read_msg_ids and enabled_write_msg_ids bitmaps in
> >   struct hsmp_socket.
> > - Add is_read_msg_enabled() and is_write_msg_enabled() helpers in
> >   hsmp.h.
> > - Use is_get_msg() to distinguish read and write HSMP messages.
> > - Mark HSMP_TEST, HSMP_GET_PROTO_VER, and HSMP_GET_SMU_VER as always
> >   enabled during bitmap initialization, as these cannot be masked by
> >   BIOS.
> > - Skip bitmap init, populate, and validation on client platforms; the
> >   client message set has no per-platform bitmaps yet.
> > 
> > Co-developed-by: Dhruv Gupta <dhruv.gupta@amd.com>
> > Signed-off-by: Dhruv Gupta <dhruv.gupta@amd.com>
> > Co-developed-by: Muthusamy Ramalingam <Muthusamy.Ramalingam@amd.com>
> > Signed-off-by: Muthusamy Ramalingam <Muthusamy.Ramalingam@amd.com>
> > Signed-off-by: Suma Hegde <Suma.Hegde@amd.com>
> > ---
> >  drivers/platform/x86/amd/hsmp/acpi.c | 13 ++++
> >  drivers/platform/x86/amd/hsmp/hsmp.c | 94 ++++++++++++++++++++++++++++
> >  drivers/platform/x86/amd/hsmp/hsmp.h | 27 ++++++++
> >  drivers/platform/x86/amd/hsmp/plat.c | 13 ++++
> >  4 files changed, 147 insertions(+)
> > 
> > diff --git a/drivers/platform/x86/amd/hsmp/acpi.c b/drivers/platform/x86/amd/hsmp/acpi.c
> > index b6f54e8b91663..0d3b324fe2244 100644
> > --- a/drivers/platform/x86/amd/hsmp/acpi.c
> > +++ b/drivers/platform/x86/amd/hsmp/acpi.c
> > @@ -566,6 +566,11 @@ static int init_acpi(struct device *dev)
> >  
> >  	sock = &hsmp_pdev->sock[sock_ind];
> >  
> > +	if (!is_client_platform()) {
> > +		init_read_enabled_msg_bitmap(sock);
> > +		init_write_enabled_msg_bitmap(sock);
> > +	}
> > +
> >  	/* Test the hsmp interface */
> >  	ret = hsmp_test(sock_ind, 0xDEADBEEF);
> >  	if (ret) {
> > @@ -581,6 +586,14 @@ static int init_acpi(struct device *dev)
> >  		return ret;
> >  	}
> >  
> > +	if (!is_client_platform()) {
> > +		ret = hsmp_populate_msg_bitmaps(sock_ind);
> > +		if (ret) {
> > +			dev_err(dev, "Failed to get enabled HSMP messages on this platform\n");
> > +			return ret;
> > +		}
> > +	}
> > +
> >  	if ((is_client_platform() &&
> >  	     sock->proto_ver >= RYZEN_MASTER_PROTO_VER1) ||
> >  	    (!is_client_platform() &&
> > diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c
> > index 8dc1fc75bd9ba..89528632c9532 100644
> > --- a/drivers/platform/x86/amd/hsmp/hsmp.c
> > +++ b/drivers/platform/x86/amd/hsmp/hsmp.c
> > @@ -11,6 +11,7 @@
> >  
> >  #include <linux/acpi.h>
> >  #include <linux/array_size.h>
> > +#include <linux/bitmap.h>
> >  #include <linux/build_bug.h>
> >  #include <linux/cleanup.h>
> >  #include <linux/compiler.h>
> > @@ -285,6 +286,8 @@ static int validate_message(struct hsmp_message *msg)
> >  {
> >  	const struct hsmp_plat_desc *plat_desc = hsmp_desc();
> >  	const struct hsmp_msg_desc *desc;
> > +	struct hsmp_socket *sock;
> > +	unsigned int sock_ind;
> >  
> >  	if (!plat_desc->msg_desc) {
> >  		/*
> > @@ -294,6 +297,9 @@ static int validate_message(struct hsmp_message *msg)
> >  		 * supports in each direction and leave msg_id correctness,
> >  		 * such as an unsupported or out-of-range value, to the SMU
> >  		 * status code __hsmp_send_message() already translates.
> > +		 *
> > +		 * Client platforms also have no per-platform enabled-message
> > +		 * bitmaps yet, so skip that check here.
> 
> I'm unsure how to read this. This validation seems to be on driver side so 
> why cannot it be validated for client?
> 
> >  		 */
> >  		if (msg->num_args > HSMP_CLIENT_MAX_MSG_LEN ||
> >  		    msg->response_sz > HSMP_CLIENT_MAX_MSG_LEN)
> > @@ -307,6 +313,17 @@ static int validate_message(struct hsmp_message *msg)
> >  	if (!desc)
> >  		return -ENOMSG;
> >  
> > +	sock_ind = array_index_nospec(msg->sock_ind, hsmp_pdev.num_sockets);
> > +	sock = &hsmp_pdev.sock[sock_ind];
> > +
> > +	if (is_get_msg(desc, msg)) {
> > +		if (!is_read_msg_enabled(sock, msg->msg_id))
> > +			return -ENOMSG;
> > +	} else {
> > +		if (!is_write_msg_enabled(sock, msg->msg_id))
> > +			return -ENOMSG;
> > +	}
> > +
> >  	/*
> >  	 * num_args passed by user should match the num_args specified in
> >  	 * message description table.
> > @@ -822,6 +839,83 @@ int hsmp_cache_proto_ver(u16 sock_ind)
> >  }
> >  EXPORT_SYMBOL_NS_GPL(hsmp_cache_proto_ver, "AMD_HSMP");
> >  
> > +/*
> > + * Predefine read and write enabled message bitmaps for use on platforms where
> > + * HSMP_GET_ENABLED_HSMP_CMDS (37h) is not available.
> > + */
> > +static const u32 read_bitmap_f19h_m00h_0fh[] = {0x001b8cde, 0x00000000, 0x00000000};
> 
> These are just a combination of BIT(msg_id), right? If yes, these should 
> be constructed from the named defines by OR'ing them together instead of 
> using those obscure literals.
> 
> > +static const u32 write_bitmap_f19h_m00h_0fh[] = {0x00047320, 0x00000000, 0x00000000};
> > +
> > +static const u32 read_bitmap_zen4_variants[] = {0x7fdb8cde, 0x00000000, 0x00000000};
> > +static const u32 write_bitmap_zen4_variants[] = {0x80047320, 0x00000007, 0x00000000};
> > +
> > +static const u32 read_bitmap_f19h_m80h_9fh[] = {0x7e0b8cde, 0x00000038, 0x00000000};
> > +static const u32 write_bitmap_f19h_m80h_9fh[] = {0x00040320, 0x00000000, 0x00000000};
> > +
> > +static const u32 read_bitmap_f1ah_m00h_1fh[] = {0x7fdb8cde, 0x00070182, 0x00000000};
> > +static const u32 write_bitmap_f1ah_m00h_1fh[] = {0x80047320, 0x000001c6, 0x00000000};
> 
> What's the general plan with these? Do we have to keep adding to them when 
> more platforms appear?

Nevermind the question, I see the answer in patch 9.

Could you please add a note about the future platforms having automatic 
way to acquire this into changelog of this patch as well.

--
 i.

> > +/*
> > + * Family 0x1A model 0x50-0x5f, family 0x1A model 0xC0-0xCF,
> > + * family 0x1A model 0x90-0x9B and family 0x1A model 0xA0-0xAB
> > + * belong to 6th Gen AMD EPYC Server family.
> > + */
> > +static const u32 read_bitmap_zen6_variants[] = {0x7fdbbcde, 0x05ff07fe, 0x00000000};
> > +static const u32 write_bitmap_zen6_variants[] = {0x00047320, 0x070007c6, 0x00000000};
> > +
> > +#define set_read_enabled_msg_bitmap(sock, src)	\
> > +	bitmap_from_arr32((sock)->enabled_read_msg_ids, (src), HSMP_MAX_MSGS)
> > +#define set_write_enabled_msg_bitmap(sock, src)	\
> > +	bitmap_from_arr32((sock)->enabled_write_msg_ids, (src), HSMP_MAX_MSGS)
> > +
> > +int hsmp_populate_msg_bitmaps(u16 sock_ind)
> > +{
> > +	struct hsmp_socket *sock = &hsmp_pdev.sock[sock_ind];
> > +
> > +	switch (boot_cpu_data.x86) {
> > +	case 0x19:
> > +		switch (boot_cpu_data.x86_model) {
> > +		case 0x00 ... 0x0F:
> > +			set_read_enabled_msg_bitmap(sock, read_bitmap_f19h_m00h_0fh);
> > +			set_write_enabled_msg_bitmap(sock, write_bitmap_f19h_m00h_0fh);
> > +			return 0;
> > +		case 0x10 ... 0x1F:
> > +		case 0xA0 ... 0xAF:
> > +			set_read_enabled_msg_bitmap(sock, read_bitmap_zen4_variants);
> > +			set_write_enabled_msg_bitmap(sock, write_bitmap_zen4_variants);
> > +			return 0;
> > +		case 0x80 ... 0x9F:
> > +			set_read_enabled_msg_bitmap(sock, read_bitmap_f19h_m80h_9fh);
> > +			set_write_enabled_msg_bitmap(sock, write_bitmap_f19h_m80h_9fh);
> > +			return 0;
> > +		}
> > +		break;
> > +	case 0x1A:
> > +		switch (boot_cpu_data.x86_model) {
> > +		case 0x00 ... 0x1F:
> > +			set_read_enabled_msg_bitmap(sock, read_bitmap_f1ah_m00h_1fh);
> > +			set_write_enabled_msg_bitmap(sock, write_bitmap_f1ah_m00h_1fh);
> > +			return 0;
> > +		case 0x50 ... 0x5F:
> > +		case 0x90 ... 0x9B:
> > +		case 0xA0 ... 0xAB:
> > +		case 0xC0 ... 0xCF:
> > +			set_read_enabled_msg_bitmap(sock, read_bitmap_zen6_variants);
> > +			set_write_enabled_msg_bitmap(sock, write_bitmap_zen6_variants);
> > +			/*
> > +			 * PC6 control (msg 0x29) is not supported from
> > +			 * protocol 0x70002 onwards on these models.
> > +			 */
> > +			if (sock->proto_ver >= 0x70002) {
> > +				clear_bit(HSMP_PC6_ENABLE, sock->enabled_read_msg_ids);
> > +				clear_bit(HSMP_PC6_ENABLE, sock->enabled_write_msg_ids);
> > +			}
> > +			return 0;
> > +		}
> > +	}
> > +	return -ENODEV;
> > +}
> > +EXPORT_SYMBOL_NS_GPL(hsmp_populate_msg_bitmaps, "AMD_HSMP");
> > +
> >  static const struct file_operations hsmp_fops = {
> >  	.owner		= THIS_MODULE,
> >  	.unlocked_ioctl	= hsmp_ioctl,
> > diff --git a/drivers/platform/x86/amd/hsmp/hsmp.h b/drivers/platform/x86/amd/hsmp/hsmp.h
> > index 6c850c91a51b1..e67bbdd2b9bee 100644
> > --- a/drivers/platform/x86/amd/hsmp/hsmp.h
> > +++ b/drivers/platform/x86/amd/hsmp/hsmp.h
> > @@ -13,6 +13,8 @@
> >  #include <asm/amd/hsmp.h>
> >  
> >  #include <linux/acpi.h>
> > +#include <linux/bitmap.h>
> > +#include <linux/bitops.h>
> >  #include <linux/compiler_types.h>
> >  #include <linux/device.h>
> >  #include <linux/hwmon.h>
> > @@ -26,6 +28,8 @@
> >  #include <linux/sysfs.h>
> >  #include <linux/types.h>
> >  
> > +#define HSMP_MAX_MSGS			96
> > +
> >  #define HSMP_METRICS_TABLE_NAME	"metrics_bin"
> >  
> >  #define HSMP_ATTR_GRP_NAME_SIZE	10
> > @@ -77,6 +81,8 @@ struct hsmp_socket {
> >  	struct device *dev;
> >  	u16 sock_ind;
> >  	u32 proto_ver;
> > +	DECLARE_BITMAP(enabled_read_msg_ids, HSMP_MAX_MSGS);
> > +	DECLARE_BITMAP(enabled_write_msg_ids, HSMP_MAX_MSGS);
> >  	int (*amd_hsmp_rdwr)(struct hsmp_socket *sock, u32 off, u32 *val, bool rw);
> >  };
> >  
> > @@ -86,7 +92,28 @@ struct hsmp_plat_device {
> >  	u16 num_sockets;
> >  };
> >  
> > +/* HSMP_TEST, HSMP_GET_PROTO_VER, HSMP_GET_SMU_VER are always enabled in
> > + * all the platforms and can't be masked by BIOS. Set those bits in the
> > + * bitmap during bitmap initialization.
> > + */
> > +#define init_read_enabled_msg_bitmap(sock)					\
> > +	do {									\
> > +		bitmap_zero((sock)->enabled_read_msg_ids, HSMP_MAX_MSGS);	\
> > +		bitmap_set((sock)->enabled_read_msg_ids, HSMP_TEST, 1);		\
> > +		bitmap_set((sock)->enabled_read_msg_ids, HSMP_GET_PROTO_VER, 1);\
> > +		bitmap_set((sock)->enabled_read_msg_ids, HSMP_GET_SMU_VER, 1);	\
> > +	} while (0)
> > +
> > +#define init_write_enabled_msg_bitmap(sock)	\
> > +	bitmap_zero((sock)->enabled_write_msg_ids, HSMP_MAX_MSGS)
> > +
> > +#define is_read_msg_enabled(sock, msg_id)	\
> > +	test_bit((msg_id), (sock)->enabled_read_msg_ids)
> > +#define is_write_msg_enabled(sock, msg_id)	\
> > +	test_bit((msg_id), (sock)->enabled_write_msg_ids)
> > +
> >  int hsmp_cache_proto_ver(u16 sock_ind);
> > +int hsmp_populate_msg_bitmaps(u16 sock_ind);
> >  int hsmp_test(u16 sock_ind, u32 value);
> >  long hsmp_ioctl(struct file *fp, unsigned int cmd, unsigned long arg);
> >  void hsmp_misc_deregister(void);
> > diff --git a/drivers/platform/x86/amd/hsmp/plat.c b/drivers/platform/x86/amd/hsmp/plat.c
> > index 40c98d9c66d4f..310a776125961 100644
> > --- a/drivers/platform/x86/amd/hsmp/plat.c
> > +++ b/drivers/platform/x86/amd/hsmp/plat.c
> > @@ -178,6 +178,11 @@ static int init_platform_device(struct device *dev)
> >  		sock->mbinfo.msg_arg_off	= SMN_HSMP_MSG_DATA;
> >  		sema_init(&sock->hsmp_sem, 1);
> >  
> > +		if (!is_client_platform()) {
> > +			init_read_enabled_msg_bitmap(sock);
> > +			init_write_enabled_msg_bitmap(sock);
> > +		}
> > +
> >  		/* Test the hsmp interface on each socket */
> >  		ret = hsmp_test(i, 0xDEADBEEF);
> >  		if (ret) {
> > @@ -193,6 +198,14 @@ static int init_platform_device(struct device *dev)
> >  			return ret;
> >  		}
> >  
> > +		if (!is_client_platform()) {
> > +			ret = hsmp_populate_msg_bitmaps(i);
> > +			if (ret) {
> > +				dev_err(dev, "Failed to get enabled HSMP messages on this platform\n");
> > +				return ret;
> > +			}
> > +		}
> > +
> >  		if (sock->proto_ver == HSMP_PROTO_VER6) {
> >  			ret = hsmp_get_tbl_dram_base(i);
> >  			if (ret)
> > 
> 
> 

  reply	other threads:[~2026-10-21 11:28 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-08  9:29 [PATCH 00/11] platform/x86/amd/hsmp: Per-platform enabled-message bitmaps Suma Hegde
2026-10-08  9:29 ` [PATCH 01/11] platform/x86/amd/hsmp: Fix sock_ind bounds check in is_bin_visible Suma Hegde
2026-10-08  9:29 ` [PATCH 02/11] platform/x86/amd/hsmp: Move proto_ver to hsmp_socket structure Suma Hegde
2026-10-08  9:29 ` [PATCH 03/11] platform/x86/amd/hsmp: Null-check drvdata in hsmp_is_sock_attr_visible() Suma Hegde
2026-10-21 11:07   ` Ilpo Järvinen
2026-10-08  9:29 ` [PATCH 04/11] platform/x86/amd/hsmp: Move is_get_msg() before validate_message() Suma Hegde
2026-10-08  9:29 ` [PATCH 05/11] platform/x86/amd/hsmp: Use local sock pointer in init_acpi() Suma Hegde
2026-10-08  9:29 ` [PATCH 06/11] platform/x86/amd/hsmp: Move the sock_ind bound check before validate_message() Suma Hegde
2026-10-08  9:29 ` [PATCH 07/11] platform/x86/amd/hsmp: Add per-platform bitmap to validate HSMP messages Suma Hegde
2026-10-21 11:25   ` Ilpo Järvinen
2026-10-21 11:28     ` Ilpo Järvinen [this message]
2026-10-08  9:29 ` [PATCH 08/11] platform/x86/amd/hsmp: Populate the bitmaps dynamically on 6th Gen AMD EPYC Server Suma Hegde
2026-10-08  9:29 ` [PATCH 09/11] platform/x86/amd/hsmp: Populate the bitmaps dynamically for future platforms Suma Hegde
2026-10-08  9:29 ` [PATCH 10/11] platform/x86/amd/hsmp: Relocate to_hsmp_sys_attr() macro Suma Hegde
2026-10-08  9:29 ` [PATCH 11/11] platform/x86/amd/hsmp: Update sysfs and hwmon file modes based on platform capabilities Suma Hegde

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=9d6591cb-1423-00cb-e87c-80d5a44a8fa7@linux.intel.com \
    --to=ilpo.jarvinen@linux.intel.com \
    --cc=NaveenKrishna.Chatradhi@amd.com \
    --cc=dhruv.gupta@amd.com \
    --cc=hdegoede@redhat.com \
    --cc=muthusamy.ramalingam@amd.com \
    --cc=platform-driver-x86@vger.kernel.org \
    --cc=suma.hegde@amd.com \
    /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