]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
x86/amd_node, platform/x86/amd/hsmp: Have HSMP use SMN through AMD_NODE
authorYazen Ghannam <yazen.ghannam@amd.com>
Thu, 30 Jan 2025 19:48:55 +0000 (19:48 +0000)
committerBorislav Petkov (AMD) <bp@alien8.de>
Mon, 17 Feb 2025 08:47:31 +0000 (09:47 +0100)
The HSMP interface is just an SMN interface with different offsets.

Define an HSMP wrapper in the SMN code and have the HSMP platform driver
use that rather than a local solution.

Also, remove the "root" member from AMD_NB, since there are no more
users of it.

Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Carlos Bilbao <carlos.bilbao@kernel.org>
Acked-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Link: https://lore.kernel.org/r/20250130-wip-x86-amd-nb-cleanup-v4-1-b5cc997e471b@amd.com
arch/x86/include/asm/amd_nb.h
arch/x86/include/asm/amd_node.h
arch/x86/kernel/amd_nb.c
arch/x86/kernel/amd_node.c
drivers/platform/x86/amd/hsmp/Kconfig
drivers/platform/x86/amd/hsmp/acpi.c
drivers/platform/x86/amd/hsmp/hsmp.c
drivers/platform/x86/amd/hsmp/hsmp.h
drivers/platform/x86/amd/hsmp/plat.c

index 4c4efb93045ed54b01663866a955ab30f810b6bd..adfa0854cf2dade5f2451be120767e8e8f3cfa4b 100644 (file)
@@ -27,7 +27,6 @@ struct amd_l3_cache {
 };
 
 struct amd_northbridge {
-       struct pci_dev *root;
        struct pci_dev *misc;
        struct pci_dev *link;
        struct amd_l3_cache l3_cache;
index 113ad3e8ee40ae8f6966eebfdb5b7b2e638ee7d8..002c3afbd30f9ba3b47a3e86b269e0425754e965 100644 (file)
@@ -30,7 +30,20 @@ static inline u16 amd_num_nodes(void)
        return topology_amd_nodes_per_pkg() * topology_max_packages();
 }
 
+#ifdef CONFIG_AMD_NODE
 int __must_check amd_smn_read(u16 node, u32 address, u32 *value);
 int __must_check amd_smn_write(u16 node, u32 address, u32 value);
 
+/* Should only be used by the HSMP driver. */
+int __must_check amd_smn_hsmp_rdwr(u16 node, u32 address, u32 *value, bool write);
+#else
+static inline int __must_check amd_smn_read(u16 node, u32 address, u32 *value) { return -ENODEV; }
+static inline int __must_check amd_smn_write(u16 node, u32 address, u32 value) { return -ENODEV; }
+
+static inline int __must_check amd_smn_hsmp_rdwr(u16 node, u32 address, u32 *value, bool write)
+{
+       return -ENODEV;
+}
+#endif /* CONFIG_AMD_NODE */
+
 #endif /*_ASM_X86_AMD_NODE_H_*/
index 11fac09e3a8cb55e082764e6c5aa706c02df7d4d..24d7a87edf9c053afdcfe43d8d0d459f2d55fbc0 100644 (file)
@@ -73,7 +73,6 @@ static int amd_cache_northbridges(void)
        amd_northbridges.nb = nb;
 
        for (i = 0; i < amd_northbridges.num; i++) {
-               node_to_amd_nb(i)->root = amd_node_get_root(i);
                node_to_amd_nb(i)->misc = amd_node_get_func(i, 3);
 
                /*
index d2ec7fd555c515eb1fa67f55f014598bb8160950..65045f223c10a25920dfbfbf1e1936be49c036dd 100644 (file)
@@ -97,6 +97,9 @@ static DEFINE_MUTEX(smn_mutex);
 #define SMN_INDEX_OFFSET       0x60
 #define SMN_DATA_OFFSET                0x64
 
+#define HSMP_INDEX_OFFSET      0xc4
+#define HSMP_DATA_OFFSET       0xc8
+
 /*
  * SMN accesses may fail in ways that are difficult to detect here in the called
  * functions amd_smn_read() and amd_smn_write(). Therefore, callers must do
@@ -179,6 +182,12 @@ int __must_check amd_smn_write(u16 node, u32 address, u32 value)
 }
 EXPORT_SYMBOL_GPL(amd_smn_write);
 
+int __must_check amd_smn_hsmp_rdwr(u16 node, u32 address, u32 *value, bool write)
+{
+       return __amd_smn_rw(HSMP_INDEX_OFFSET, HSMP_DATA_OFFSET, node, address, value, write);
+}
+EXPORT_SYMBOL_GPL(amd_smn_hsmp_rdwr);
+
 static int amd_cache_roots(void)
 {
        u16 node, num_nodes = amd_num_nodes();
index 7d10d4462a453df00ae8c2af237d5bfbdc40ddf2..d6f7a62d55b5e467df8350f3d6eb99b23c02f5c1 100644 (file)
@@ -7,7 +7,7 @@ config AMD_HSMP
        tristate
 
 menu "AMD HSMP Driver"
-       depends on AMD_NB || COMPILE_TEST
+       depends on AMD_NODE || COMPILE_TEST
 
 config AMD_HSMP_ACPI
        tristate "AMD HSMP ACPI device driver"
index 444b43be35a256f2f1b06c87b36747cc51faf4ea..c1eccb3c80c5c99394a207c6896e72f7c6d14944 100644 (file)
@@ -10,7 +10,6 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <asm/amd_hsmp.h>
-#include <asm/amd_nb.h>
 
 #include <linux/acpi.h>
 #include <linux/device.h>
@@ -24,6 +23,8 @@
 
 #include <uapi/asm-generic/errno-base.h>
 
+#include <asm/amd_node.h>
+
 #include "hsmp.h"
 
 #define DRIVER_NAME            "amd_hsmp"
@@ -321,8 +322,8 @@ static int hsmp_acpi_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        if (!hsmp_pdev->is_probed) {
-               hsmp_pdev->num_sockets = amd_nb_num();
-               if (hsmp_pdev->num_sockets == 0 || hsmp_pdev->num_sockets > MAX_AMD_SOCKETS)
+               hsmp_pdev->num_sockets = amd_num_nodes();
+               if (hsmp_pdev->num_sockets == 0 || hsmp_pdev->num_sockets > MAX_AMD_NUM_NODES)
                        return -ENODEV;
 
                hsmp_pdev->sock = devm_kcalloc(&pdev->dev, hsmp_pdev->num_sockets,
index 03164e30b3a502a0e2aa36d2ef93281e36c8d032..a3ac09a90de4566c95c3243d73e4e1b2ac1eeab7 100644 (file)
@@ -8,7 +8,6 @@
  */
 
 #include <asm/amd_hsmp.h>
-#include <asm/amd_nb.h>
 
 #include <linux/acpi.h>
 #include <linux/delay.h>
index e852f0a947e4f8215c11710a957d3e92b2367674..af8b21f821d668e43bf6cbfa18ec8409fb9267d5 100644 (file)
@@ -21,8 +21,6 @@
 
 #define HSMP_ATTR_GRP_NAME_SIZE        10
 
-#define MAX_AMD_SOCKETS 8
-
 #define HSMP_CDEV_NAME         "hsmp_cdev"
 #define HSMP_DEVNODE_NAME      "hsmp"
 
@@ -41,7 +39,6 @@ struct hsmp_socket {
        void __iomem *virt_base_addr;
        struct semaphore hsmp_sem;
        char name[HSMP_ATTR_GRP_NAME_SIZE];
-       struct pci_dev *root;
        struct device *dev;
        u16 sock_ind;
        int (*amd_hsmp_rdwr)(struct hsmp_socket *sock, u32 off, u32 *val, bool rw);
index 02ca85762b68660b36301f208c15d7609583d6b4..b9782a078dbd2fc67e1ad61ff9085a6da49dd7b9 100644 (file)
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <asm/amd_hsmp.h>
-#include <asm/amd_nb.h>
 
+#include <linux/build_bug.h>
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
 #include <linux/sysfs.h>
 
+#include <asm/amd_node.h>
+
 #include "hsmp.h"
 
 #define DRIVER_NAME            "amd_hsmp"
 #define SMN_HSMP_MSG_RESP      0x0010980
 #define SMN_HSMP_MSG_DATA      0x00109E0
 
-#define HSMP_INDEX_REG         0xc4
-#define HSMP_DATA_REG          0xc8
-
 static struct hsmp_plat_device *hsmp_pdev;
 
 static int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset,
                             u32 *value, bool write)
 {
-       int ret;
-
-       if (!sock->root)
-               return -ENODEV;
-
-       ret = pci_write_config_dword(sock->root, HSMP_INDEX_REG,
-                                    sock->mbinfo.base_addr + offset);
-       if (ret)
-               return ret;
-
-       ret = (write ? pci_write_config_dword(sock->root, HSMP_DATA_REG, *value)
-                    : pci_read_config_dword(sock->root, HSMP_DATA_REG, value));
-
-       return ret;
+       return amd_smn_hsmp_rdwr(sock->sock_ind, sock->mbinfo.base_addr + offset, value, write);
 }
 
 static ssize_t hsmp_metric_tbl_plat_read(struct file *filp, struct kobject *kobj,
@@ -95,7 +81,12 @@ static umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
  * Static array of 8 + 1(for NULL) elements is created below
  * to create sysfs groups for sockets.
  * is_bin_visible function is used to show / hide the necessary groups.
+ *
+ * Validate the maximum number against MAX_AMD_NUM_NODES. If this changes,
+ * then the attributes and groups below must be adjusted.
  */
+static_assert(MAX_AMD_NUM_NODES == 8);
+
 #define HSMP_BIN_ATTR(index, _list)                                    \
 static const struct bin_attribute attr##index = {                      \
        .attr = { .name = HSMP_METRICS_TABLE_NAME, .mode = 0444},       \
@@ -159,10 +150,7 @@ static int init_platform_device(struct device *dev)
        int ret, i;
 
        for (i = 0; i < hsmp_pdev->num_sockets; i++) {
-               if (!node_to_amd_nb(i))
-                       return -ENODEV;
                sock = &hsmp_pdev->sock[i];
-               sock->root                      = node_to_amd_nb(i)->root;
                sock->sock_ind                  = i;
                sock->dev                       = dev;
                sock->mbinfo.base_addr          = SMN_HSMP_BASE;
@@ -305,11 +293,11 @@ static int __init hsmp_plt_init(void)
                return -ENOMEM;
 
        /*
-        * amd_nb_num() returns number of SMN/DF interfaces present in the system
+        * amd_num_nodes() returns number of SMN/DF interfaces present in the system
         * if we have N SMN/DF interfaces that ideally means N sockets
         */
-       hsmp_pdev->num_sockets = amd_nb_num();
-       if (hsmp_pdev->num_sockets == 0 || hsmp_pdev->num_sockets > MAX_AMD_SOCKETS)
+       hsmp_pdev->num_sockets = amd_num_nodes();
+       if (hsmp_pdev->num_sockets == 0 || hsmp_pdev->num_sockets > MAX_AMD_NUM_NODES)
                return ret;
 
        ret = platform_driver_register(&amd_hsmp_driver);