Re: [PATCH 7/7] Documentation/arch/x86/amd_hsmp: Document the SMN and MSR IOCTLs
Mario Limonciello <[email protected]> Wed, 29 Jul 2026 16:41:09 -0500
| Newsgroups | org.kernel.vger.platform-driver-x86,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
On 7/29/26 11:40, Muralidhara M K wrote: > Describe HSMP_IOCTL_SMN_CMD and HSMP_IOCTL_MSR_CMD: the payload structs, > the CAP_SYS_RAWIO and open-mode requirements, and the rule that both are > read-only, so a request with @write set is refused with -EPERM even for a > fully privileged caller on an O_RDWR handle. > > Also note that reading the protocol_version attribute can fail on the > Fam1Ah client platforms, because some client SMU builds reject the > interface-version query, which is why the telemetry ioctl rather than > that attribute is the way to reach the client telemetry layout. I'm happy that these are (at least) defaulting to read-only, but I don't understand their purpose. We already have /dev/cpu/CPUNUM/msr, and we also have amd-node which provides access to SMN via /sys/kernel/debug/x86/. Can you better describe the needs of why these new messages must exist and we can't have structured data for them? Even if amd_hsmp needs to use SMN or MSR to fetch specific data data, this feels a lot safer to have a structured specific fetch method than such a wide (albeit permissioned) pipe. > > Signed-off-by: Muralidhara M K <[email protected]> > --- > Documentation/arch/x86/amd_hsmp.rst | 44 +++++++++++++++++++++++++++++ > 1 file changed, 44 insertions(+) > > diff --git a/Documentation/arch/x86/amd_hsmp.rst b/Documentation/arch/x86/amd_hsmp.rst > index 8a9d6fe7d4cf..0f03201a9f68 100644 > --- a/Documentation/arch/x86/amd_hsmp.rst > +++ b/Documentation/arch/x86/amd_hsmp.rst > @@ -229,6 +229,50 @@ The following IOCTLs are defined: > ``sizeof(struct hsmp_metric_table)``. Later version metrics table > layout is documented in the Public PPR. > > + On the Fam1Ah client platforms reading ``protocol_version`` can fail, > + because some client SMU builds reject the interface-version query. > + Those parts have their own telemetry layout and this ioctl is the way > + to read it. It seems to me you don't actually describe the telemetry layout or what should be done with SMN. > + > +``ioctl(file, HSMP_IOCTL_SMN_CMD, struct hsmp_smn_message *smn)`` > + Read a 32-bit SMN register on the socket given by ``sock_ind``. This > + reaches registers outside the HSMP message ABI, so it requires > + ``CAP_SYS_RAWIO`` as well as a handle opened for reading, the latter > + because the value read is written back into the request struct. > + > + The ioctl is read-only. ``write`` must be zero, and a request that > + sets it is rejected with ``-EPERM`` even with ``CAP_SYS_RAWIO`` and an > + ``O_RDWR`` handle; the field exists only so that write support could be > + added later without changing the layout. ``reserved`` must be zero. > + Argument:: > + > + struct hsmp_smn_message { > + __u32 smn_address; /* SMN address to read */ > + __u32 value; /* Value read, filled in by the kernel */ > + __u16 sock_ind; /* Socket index */ > + __u8 write; /* Must be zero */ > + __u8 reserved; /* Reserved, must be zero */ > + }; > + > +``ioctl(file, HSMP_IOCTL_MSR_CMD, struct hsmp_msr_message *msr)`` > + Read a 64-bit MSR on the logical CPU given by ``core_id``, or on > + whichever CPU the ioctl runs on when ``core_id`` is > + ``HSMP_MSR_ANY_CPU`` (``(__u32)-1``). Any other ``core_id`` must refer > + to an online CPU, otherwise the call fails with ``-EINVAL``. Requires > + ``CAP_SYS_RAWIO`` and a handle opened for reading. > + > + Read-only on the same terms as ``HSMP_IOCTL_SMN_CMD``: a non-zero > + ``write`` is rejected with ``-EPERM``, and every byte of ``reserved`` > + must be zero. Argument:: > + > + struct hsmp_msr_message { > + __u32 msr_address; /* MSR index to read */ > + __u32 core_id; /* Logical CPU, or HSMP_MSR_ANY_CPU */ > + __u64 value; /* Value read, filled in by the kernel */ > + __u8 write; /* Must be zero */ > + __u8 reserved[3]; /* Reserved, must be zero */ > + }; > + > The ioctl would return a non-zero on failure; you can read errno to see > what happened. The transaction returns 0 on success. >