Linux Hardware Monitor development
 help / color / mirror / Atom feed
* [PATCH v8 0/7] x86/hygon: Add Family 0x18 DF node enumeration and SMN access
@ 2026-10-22  7:42 Lin Wang
  2026-10-22  7:42 ` [PATCH v8 1/7] x86/hygon: Add Family 0x18 DF node enumeration Lin Wang
                   ` (6 more replies)
  0 siblings, 7 replies; 16+ messages in thread
From: Lin Wang @ 2026-10-22  7:42 UTC (permalink / raw)
  To: Borislav Petkov, Yazen Ghannam, Mario Limonciello
  Cc: Pu Wen, Thomas Gleixner, Ingo Molnar, Dave Hansen, H. Peter Anvin,
	Tony Luck, Guenter Roeck, x86, linux-edac, linux-hwmon,
	linux-kernel

v8 addresses Yazen's comments on v7. The node and SMN helpers remain
local to hygon_node.c until Hygon consumers are added upstream. The
cache-build warning for -ENODEV is suppressed in guests; other errors
and bare-metal warnings are unchanged.

Patch 6 depends on "hwmon: (k10temp) Stop matching Hygon devices",
which Guenter has applied to hwmon-next. It is not in mainline yet and
must be merged before patch 6; otherwise k10temp still binds on Hygon
and its SMN reads fail.

The scope is unchanged. The series adds Hygon Data Fabric (DF) node
enumeration and SMN access. AMD NB/SMN initialization and EDAC/ATL
matching are restricted to AMD CPUs. Hygon EDAC and ATL support will
be submitted separately.

Tested v8 on a Family 0x18 Model 0x07 system with 2 sockets, 12 Core
and DDR Dies (CDDs) and 4 I/O Dies (IODs).

Changes in v8:

  - Keep unused node and SMN interfaces local. (Yazen)
  - Avoid the -ENODEV cache-build warning in guests. (Yazen)
  - Align the CPU-to-DF assignments. (Yazen)
  - Simplify the AMD SMN commit message. (Yazen)
  - Add a separate HYGON NODE DRIVER entry instead of changing
    HYGON PROCESSOR SUPPORT.

Link: https://lore.kernel.org/20261009090111.151878-1-wanglin@open-hieco.net # v7
Link: https://lore.kernel.org/20261017145226.GA359037@yaz-khff2.amd.com # v7 1/7 review
Link: https://lore.kernel.org/20261017153308.GE359037@yaz-khff2.amd.com # v7 6/7 review
Link: https://lore.kernel.org/b292d054-f0cf-4695-94a2-40f0d71563f8@roeck-us.net # k10temp applied

Lin Wang (7):
  x86/hygon: Add Family 0x18 DF node enumeration
  x86/hygon: Map CPU NodeIds to DF nodes
  EDAC/amd64: Stop matching Hygon CPUs
  RAS/AMD/ATL: Match AMD CPUs only
  x86/amd_nb: Restrict the northbridge framework to AMD CPUs
  x86/amd_node: Restrict SMN setup to AMD CPUs
  x86/hygon: Add Family 0x18 SMN access

 MAINTAINERS                       |   7 +
 arch/x86/Kconfig                  |   4 +
 arch/x86/include/asm/hygon/node.h |  41 ++
 arch/x86/kernel/Makefile          |   1 +
 arch/x86/kernel/amd_nb.c          |   6 +-
 arch/x86/kernel/amd_node.c        |   6 +-
 arch/x86/kernel/hygon_node.c      | 882 ++++++++++++++++++++++++++++++
 drivers/edac/amd64_edac.c         |   4 -
 drivers/ras/amd/atl/core.c        |   9 +-
 9 files changed, 945 insertions(+), 15 deletions(-)
 create mode 100644 arch/x86/include/asm/hygon/node.h
 create mode 100644 arch/x86/kernel/hygon_node.c

base-commit: 7be4bc52fd9e0e55dc9a2e0232b89427d2c4b614
-- 
2.43.0


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v8 1/7] x86/hygon: Add Family 0x18 DF node enumeration
  2026-10-22  7:42 [PATCH v8 0/7] x86/hygon: Add Family 0x18 DF node enumeration and SMN access Lin Wang
@ 2026-10-22  7:42 ` Lin Wang
  2026-10-22  7:49   ` sashiko-bot
  2026-10-24 15:15   ` Yazen Ghannam
  2026-10-22  7:42 ` [PATCH v8 2/7] x86/hygon: Map CPU NodeIds to DF nodes Lin Wang
                   ` (5 subsequent siblings)
  6 siblings, 2 replies; 16+ messages in thread
From: Lin Wang @ 2026-10-22  7:42 UTC (permalink / raw)
  To: Borislav Petkov, Yazen Ghannam, Mario Limonciello
  Cc: Pu Wen, Thomas Gleixner, Ingo Molnar, Dave Hansen, H. Peter Anvin,
	Tony Luck, Guenter Roeck, x86, linux-edac, linux-hwmon,
	linux-kernel

The AMD node code locates function 3 for node N at PCI slot 0x18 + N.
Hygon has no equivalent node-index-to-slot mapping: DF F3 devices are
discovered by PCI ID and the PCI BDF is only an access point.

Enumerate Hygon DF devices by PCI ID and read their identities from DF
registers. Build a dense node cache with Core and DDR Dies (CDDs) before
I/O Dies (IODs), providing node counts, identity and PCI function lookups.

Guests may expose a supported CPU model without DF devices. Suppress
the cache-build warning for -ENODEV in guests; keep other initialization
errors visible.

The node lookup helpers remain local until Hygon consumers are added.

Signed-off-by: Lin Wang <wanglin@open-hieco.net>
---
 MAINTAINERS                       |   7 +
 arch/x86/Kconfig                  |   4 +
 arch/x86/include/asm/hygon/node.h |  41 ++
 arch/x86/kernel/Makefile          |   1 +
 arch/x86/kernel/hygon_node.c      | 599 ++++++++++++++++++++++++++++++
 5 files changed, 652 insertions(+)
 create mode 100644 arch/x86/include/asm/hygon/node.h
 create mode 100644 arch/x86/kernel/hygon_node.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 0e9fe9c2a39b..76df7669972e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12182,6 +12182,13 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/input/touchscreen/hycon,hy46xx.yaml
 F:	drivers/input/touchscreen/hycon-hy46xx.c
 
+HYGON NODE DRIVER
+M:	Lin Wang <wanglin@open-hieco.net>
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+F:	arch/x86/include/asm/hygon/node.h
+F:	arch/x86/kernel/hygon_node.c
+
 HYGON PROCESSOR SUPPORT
 M:	Pu Wen <puwen@hygon.cn>
 L:	linux-kernel@vger.kernel.org
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 644ad02f7c9c..c08a9f052d9e 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -3085,6 +3085,10 @@ config AMD_NODE
 	def_bool y
 	depends on CPU_SUP_AMD && PCI
 
+config HYGON_NODE
+	def_bool y
+	depends on CPU_SUP_HYGON && PCI
+
 endmenu
 
 menu "Binary Emulations"
diff --git a/arch/x86/include/asm/hygon/node.h b/arch/x86/include/asm/hygon/node.h
new file mode 100644
index 000000000000..8cabbbdcf96a
--- /dev/null
+++ b/arch/x86/include/asm/hygon/node.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Hygon Family 0x18 Data Fabric (DF) node interfaces */
+#ifndef _ASM_X86_HYGON_NODE_H
+#define _ASM_X86_HYGON_NODE_H
+
+#include <linux/types.h>
+
+/* DF function indices supported by hygon_node_get_func(). */
+#define HYGON_DF_F3	3
+#define HYGON_DF_F4	4
+
+/*
+ * Hygon Core and DDR Dies (CDDs) start at DFID 4. Each CDD contains
+ * CPU cores and UMCs. I/O Dies (IODs) occupy DFIDs 0-3.
+ */
+#define HYGON_CDD_DFID_BASE	4
+
+/**
+ * enum hygon_node_type - DF node type, derived from DFID
+ * @HYGON_NODE_IOD: I/O die (DFID < HYGON_CDD_DFID_BASE); no UMC.
+ * @HYGON_NODE_CDD: Core and DDR Die (DFID >= HYGON_CDD_DFID_BASE);
+ *                  contains CPU cores and UMC controllers.
+ */
+enum hygon_node_type {
+	HYGON_NODE_IOD = 0,
+	HYGON_NODE_CDD = 1,
+};
+
+/**
+ * struct hygon_node_info - DF node information
+ * @socket_id: Physical socket ID, F1x200[30:28]
+ * @dfid:      Data Fabric ID, model-dependent source
+ * @type:      HYGON_NODE_CDD or HYGON_NODE_IOD
+ */
+struct hygon_node_info {
+	u8			socket_id;
+	u8			dfid;
+	enum hygon_node_type	type;
+};
+
+#endif /* _ASM_X86_HYGON_NODE_H */
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 31f46fd00527..b8430e5e53fb 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -136,6 +136,7 @@ obj-$(CONFIG_HPET_TIMER) 	+= hpet.o
 
 obj-$(CONFIG_AMD_NB)		+= amd_nb.o
 obj-$(CONFIG_AMD_NODE)		+= amd_node.o
+obj-$(CONFIG_HYGON_NODE)	+= hygon_node.o
 obj-$(CONFIG_DEBUG_NMI_SELFTEST) += nmi_selftest.o
 
 obj-$(CONFIG_KVM_GUEST)		+= kvm.o kvmclock.o
diff --git a/arch/x86/kernel/hygon_node.c b/arch/x86/kernel/hygon_node.c
new file mode 100644
index 000000000000..6a5278f8e5ca
--- /dev/null
+++ b/arch/x86/kernel/hygon_node.c
@@ -0,0 +1,599 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Hygon Family 0x18 Data Fabric node enumeration
+ *
+ * A DF instance exposes sibling PCI functions in one slot. Function 3
+ * is the misc device used for enumeration, function 4 is the link
+ * device, and functions 1 and 5 provide the socket and DF identity.
+ *
+ * Enumerate F3 devices by PCI ID, validate their F4 siblings, read each
+ * node's socket ID and DFID, and validate the enumerated socket set
+ * against SocketPresent. Sort the nodes into a dense cache with Core
+ * and DDR Dies (CDDs) before I/O Dies (IODs), then by socket ID and
+ * DFID.
+ */
+
+#define pr_fmt(fmt) "hygon_node: " fmt
+
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/cpufeature.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/processor.h>
+#include <linux/slab.h>
+#include <linux/sort.h>
+
+#include <asm/cpu_device_id.h>
+#include <asm/hygon/node.h>
+
+/*
+ * DF register offsets used for node identity discovery.
+ *
+ * F1x200 (SystemCfg) -- present on all supported models:
+ *   [30:28]  MySocketId    - hardware socket ID
+ *   [23:20]  MyDieId       - die ID (equals DFID on some models, see below)
+ *
+ * F5x180 (FabricBlockInstanceInformation3_CS) -- used on Model 06h-08h:
+ *   [19:16]  DFID          - Data Fabric ID for UMC/SMN addressing
+ *
+ * DFID source by model:
+ *   Model 04h/05h:  F1x200[23:20] (MyDieId == DFID)
+ *   Model 06h-08h:  F5x180[19:16] (MyDieId != DFID, different numbering)
+ */
+#define DF_F1_SYSTEM_CFG	0x200
+#define DF_F5_FABRIC_ID		0x180
+
+#define DF_F1_SOCKET_ID		GENMASK(30, 28)
+#define DF_F1_DIE_ID		GENMASK(23, 20)
+#define DF_F1_SOCKET_PRESENT	GENMASK(7, 0)
+#define DF_F5_DFID		GENMASK(19, 16)
+
+/* DF function numbers for sibling device access (internal use). */
+#define DF_F1	1
+#define DF_F5	5
+
+/* PCI device IDs used only by Hygon DF node discovery. */
+#define PCI_DEVICE_ID_HYGON_18H_DF_F3		0x1463
+#define PCI_DEVICE_ID_HYGON_18H_DF_F4		0x1464
+#define PCI_DEVICE_ID_HYGON_18H_M04H_DF_F1	0x1491
+#define PCI_DEVICE_ID_HYGON_18H_M04H_DF_F3	0x1493
+#define PCI_DEVICE_ID_HYGON_18H_M04H_DF_F4	0x1494
+#define PCI_DEVICE_ID_HYGON_18H_M05H_DF_F1	0x14b1
+#define PCI_DEVICE_ID_HYGON_18H_M05H_DF_F3	0x14b3
+#define PCI_DEVICE_ID_HYGON_18H_M05H_DF_F4	0x14b4
+#define PCI_DEVICE_ID_HYGON_18H_M06H_DF_F5	0x14b5
+
+/*
+ * Cached identity for one DF instance. After sorting, CDDs occupy
+ * nodes[0..num_cdd-1].
+ *
+ * The PCI BDF is the access point for a DF node, not its identity.
+ * The socket ID and DFID, read from DF registers, together identify
+ * the node in hardware.
+ */
+struct df_node {
+	struct pci_dev	*misc;
+	struct pci_dev	*link;
+	u8		socket_id;
+	u8		dfid;
+	bool		is_cdd;
+};
+
+struct df_node_cache {
+	struct df_node	*nodes;
+	u16		num_nodes;
+	u16		num_cdd;
+	u16		num_sockets;
+};
+
+struct df_id {
+	u8	socket_id;
+	u8	dfid;
+};
+
+/* DF sibling device IDs used to read node identity. */
+struct df_cfg {
+	u16	f1_id;
+	u16	f5_id;
+};
+
+/* DF misc (F3) device IDs for all supported Hygon Family 0x18 models. */
+static const struct pci_device_id df_misc_ids[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_HYGON_18H_DF_F3) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_HYGON_18H_M04H_DF_F3) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_HYGON_18H_M05H_DF_F3) },
+	{}
+};
+
+/* DF link (F4) device IDs for supported models. */
+static const struct pci_device_id df_link_ids[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_HYGON_18H_DF_F4) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_HYGON_18H_M04H_DF_F4) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_HYGON_18H_M05H_DF_F4) },
+	{}
+};
+
+static const struct df_cfg m04_df_cfg __initconst = {
+	.f1_id	= PCI_DEVICE_ID_HYGON_18H_M04H_DF_F1,
+};
+
+static const struct df_cfg m05_df_cfg __initconst = {
+	.f1_id	= PCI_DEVICE_ID_HYGON_18H_M05H_DF_F1,
+};
+
+static const struct df_cfg m06_m08_df_cfg __initconst = {
+	.f1_id	= PCI_DEVICE_ID_HYGON_18H_M05H_DF_F1,
+	.f5_id	= PCI_DEVICE_ID_HYGON_18H_M06H_DF_F5,
+};
+
+static const struct x86_cpu_id df_cpuids[] __initconst = {
+	X86_MATCH_VENDOR_FAM_MODEL(HYGON, 0x18, 0x04, &m04_df_cfg),
+	X86_MATCH_VENDOR_FAM_MODEL(HYGON, 0x18, 0x05, &m05_df_cfg),
+	X86_MATCH_VENDOR_FAM_MODEL(HYGON, 0x18, 0x06, &m06_m08_df_cfg),
+	X86_MATCH_VENDOR_FAM_MODEL(HYGON, 0x18, 0x07, &m06_m08_df_cfg),
+	X86_MATCH_VENDOR_FAM_MODEL(HYGON, 0x18, 0x08, &m06_m08_df_cfg),
+	{}
+};
+
+static struct df_node_cache df_cache;
+
+/*
+ * Iterate Hygon PCI devices, returning the next one that matches @ids.
+ * Follows the pci_get_device() convention: @from is consumed (its
+ * reference is dropped) and the returned device has an elevated
+ * reference count.
+ */
+static struct pci_dev * __init next_df_dev(struct pci_dev *from, const struct pci_device_id *ids)
+{
+	while ((from = pci_get_device(PCI_VENDOR_ID_HYGON, PCI_ANY_ID, from))) {
+		if (pci_match_id(ids, from))
+			return from;
+	}
+
+	return NULL;
+}
+
+/*
+ * Find the DF link (function 4) sibling of a DF misc (function 3)
+ * device. Both functions share the same PCI bus and slot.
+ */
+static struct pci_dev * __init get_link(struct pci_dev *misc)
+{
+	struct pci_dev *link;
+
+	link = pci_get_domain_bus_and_slot(pci_domain_nr(misc->bus),
+					   misc->bus->number,
+					   PCI_DEVFN(PCI_SLOT(misc->devfn),
+						     HYGON_DF_F4));
+	if (!link)
+		return NULL;
+
+	if (!pci_match_id(df_link_ids, link)) {
+		pci_dev_put(link);
+		return NULL;
+	}
+
+	return link;
+}
+
+static const struct df_cfg * __init get_df_cfg(void)
+{
+	const struct x86_cpu_id *id = x86_match_cpu(df_cpuids);
+
+	return id ? (const void *)id->driver_data : NULL;
+}
+
+/*
+ * Read a config register from a DF sibling function on the same PCI
+ * slot as @misc. Only functions 1 (F1, SystemCfg) and 5 (F5,
+ * FabricId) are supported.
+ */
+static int __init read_df_reg(struct pci_dev *misc, u8 func, int offset, u32 *value)
+{
+	const struct df_cfg *cfg;
+	struct pci_dev *sibling;
+	u16 expected_device;
+	int err;
+
+	cfg = get_df_cfg();
+	if (!cfg)
+		return -ENODEV;
+
+	if (func == DF_F1) {
+		expected_device = cfg->f1_id;
+
+		/*
+		 * Model 05h uses the M04H F1 device ID when F3 does not use
+		 * the M05H device ID.
+		 */
+		if (boot_cpu_data.x86_model == 0x5 &&
+		    misc->device != PCI_DEVICE_ID_HYGON_18H_M05H_DF_F3)
+			expected_device = PCI_DEVICE_ID_HYGON_18H_M04H_DF_F1;
+	} else if (func == DF_F5) {
+		expected_device = cfg->f5_id;
+	} else {
+		return -EINVAL;
+	}
+
+	if (!expected_device)
+		return -ENODEV;
+
+	sibling = pci_get_domain_bus_and_slot(pci_domain_nr(misc->bus),
+					      misc->bus->number,
+					      PCI_DEVFN(PCI_SLOT(misc->devfn),
+							func));
+	if (!sibling)
+		return -ENODEV;
+
+	if (sibling->vendor != PCI_VENDOR_ID_HYGON ||
+	    sibling->device != expected_device) {
+		pci_dev_put(sibling);
+		return -ENODEV;
+	}
+
+	err = pci_read_config_dword(sibling, offset, value);
+	pci_dev_put(sibling);
+
+	if (err) {
+		pr_warn("error reading %04x:%02x:%02x.%u offset 0x%x\n",
+			pci_domain_nr(misc->bus), misc->bus->number,
+			PCI_SLOT(misc->devfn), func, offset);
+		return pcibios_err_to_errno(err);
+	}
+
+	/* Do not parse a PCI error response as DF identity. */
+	if (PCI_POSSIBLE_ERROR(*value)) {
+		pr_warn("error response reading %04x:%02x:%02x.%u offset 0x%x\n",
+			pci_domain_nr(misc->bus), misc->bus->number,
+			PCI_SLOT(misc->devfn), func, offset);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+/*
+ * Read the hardware identity for one DF misc device from its sibling
+ * functions.
+ *
+ * Supported models expose F1x200 (SystemCfg): socket_id from [30:28] and a
+ * die identifier (MyDieId) from [23:20].
+ * On Model 06h-08h MyDieId differs from the DFID used by UMC and SMN
+ * addressing, so an additional F5x180 (FabricId) read obtains the DFID
+ * from [19:16].
+ *
+ * The boot CPU model selects the DF register layout for all instances.
+ */
+static int __init read_df_id(struct pci_dev *misc, struct df_id *id)
+{
+	const struct df_cfg *cfg = get_df_cfg();
+	u32 reg;
+	int ret;
+
+	if (!cfg)
+		return -ENODEV;
+
+	ret = read_df_reg(misc, DF_F1, DF_F1_SYSTEM_CFG, &reg);
+	if (ret)
+		return ret;
+
+	id->socket_id = FIELD_GET(DF_F1_SOCKET_ID, reg);
+	id->dfid = FIELD_GET(DF_F1_DIE_ID, reg);
+
+	/* Read DFID from F5x180 on models that provide an F5 sibling. */
+	if (cfg->f5_id) {
+		ret = read_df_reg(misc, DF_F5, DF_F5_FABRIC_ID, &reg);
+		if (ret)
+			return ret;
+		id->dfid = FIELD_GET(DF_F5_DFID, reg);
+	}
+
+	return 0;
+}
+
+/*
+ * Read the system-wide SocketPresent mask from F1x200[7:0].
+ *
+ * SocketPresent is system-wide rather than per-node. Read it once from
+ * the first DF misc device. A zero mask is invalid on supported models.
+ */
+static int __init read_socket_present(struct pci_dev *misc, u8 *socket_present)
+{
+	u32 reg;
+	int ret;
+
+	ret = read_df_reg(misc, DF_F1, DF_F1_SYSTEM_CFG, &reg);
+	if (ret)
+		return ret;
+
+	*socket_present = FIELD_GET(DF_F1_SOCKET_PRESENT, reg);
+	if (!*socket_present) {
+		pr_warn("SocketPresent is zero\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void __init release_nodes(struct df_node *nodes, u16 count)
+{
+	u16 i;
+
+	for (i = 0; i < count; i++) {
+		pci_dev_put(nodes[i].misc);
+		pci_dev_put(nodes[i].link);
+	}
+
+	kfree(nodes);
+}
+
+/*
+ * Walk all DF misc (F3) devices and read per-node identity (socket_id,
+ * dfid) from each, collecting them into a flat array. The system-wide
+ * SocketPresent mask is sampled once, and the enumerated socket set is
+ * validated against it; socket IDs must also be dense (0..N-1).
+ */
+static int __init collect_nodes(struct df_node_cache *cache)
+{
+	u8 observed_socket_mask = 0, socket_present_mask = 0;
+	struct pci_dev *misc = NULL, *link = NULL;
+	u16 capacity = 0, count = 0;
+	struct df_node *nodes;
+	int ret;
+
+	while ((misc = next_df_dev(misc, df_misc_ids)))
+		capacity++;
+
+	if (!capacity)
+		return -ENODEV;
+
+	nodes = kzalloc_objs(*nodes, capacity);
+	if (!nodes)
+		return -ENOMEM;
+
+	while ((misc = next_df_dev(misc, df_misc_ids))) {
+		struct df_id id;
+
+		link = get_link(misc);
+		if (!link) {
+			ret = -ENODEV;
+			goto fail_put_devs;
+		}
+
+		ret = read_df_id(misc, &id);
+		if (ret)
+			goto fail_put_devs;
+
+		/* SocketPresent is system-wide, so sample it once. */
+		if (!count) {
+			ret = read_socket_present(misc, &socket_present_mask);
+			if (ret)
+				goto fail_put_devs;
+		}
+
+		if (count >= capacity) {
+			ret = -ENODEV;
+			goto fail_put_devs;
+		}
+
+		nodes[count].misc = pci_dev_get(misc);
+		nodes[count].link = link;
+		link = NULL;
+		nodes[count].socket_id = id.socket_id;
+		nodes[count].dfid = id.dfid;
+		nodes[count].is_cdd = (id.dfid >= HYGON_CDD_DFID_BASE);
+		count++;
+
+		observed_socket_mask |= BIT(id.socket_id);
+	}
+
+	if (count != capacity) {
+		pr_warn("DF enumeration changed: expected %u nodes, got %u\n",
+			capacity, count);
+		ret = -ENODEV;
+		goto fail;
+	}
+
+	/*
+	 * Every populated socket must contribute at least one enumerated DF
+	 * misc device. SocketPresent is guaranteed to be non-zero.
+	 */
+	if (observed_socket_mask != socket_present_mask) {
+		pr_warn("SocketPresent mismatch: observed=0x%x present=0x%x\n",
+			observed_socket_mask, socket_present_mask);
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	cache->nodes = nodes;
+	cache->num_nodes = count;
+	cache->num_sockets = hweight8(socket_present_mask);
+
+	if (socket_present_mask != GENMASK(cache->num_sockets - 1, 0)) {
+		pr_warn("sparse socket IDs not supported (SocketPresent=0x%x)\n",
+			socket_present_mask);
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	return 0;
+
+fail_put_devs:
+	pci_dev_put(link);
+	pci_dev_put(misc);
+fail:
+	release_nodes(nodes, count);
+	cache->nodes = NULL;
+	cache->num_nodes = 0;
+	cache->num_sockets = 0;
+	return ret;
+}
+
+/*
+ * Sort CDD nodes before IOD nodes, then order by hardware
+ * (socket_id, dfid).
+ */
+static int __init node_cmp(const void *a, const void *b)
+{
+	const struct df_node *left = a, *right = b;
+
+	if (left->is_cdd != right->is_cdd)
+		return right->is_cdd - left->is_cdd;
+
+	if (left->socket_id != right->socket_id)
+		return (int)left->socket_id - right->socket_id;
+
+	return (int)left->dfid - (int)right->dfid;
+}
+
+static int __init sort_and_classify(struct df_node_cache *cache)
+{
+	u16 i;
+
+	sort(cache->nodes, cache->num_nodes, sizeof(*cache->nodes),
+	     node_cmp, NULL);
+
+	cache->num_cdd = 0;
+
+	for (i = 0; i < cache->num_nodes; i++) {
+		const struct df_node *node = &cache->nodes[i];
+
+		if (i) {
+			const struct df_node *prev = &cache->nodes[i - 1];
+
+			if (node->socket_id == prev->socket_id &&
+			    node->dfid == prev->dfid) {
+				pr_warn("duplicate DF node: socket=%u dfid=%u\n",
+					node->socket_id, node->dfid);
+				return -EINVAL;
+			}
+		}
+
+		if (node->is_cdd)
+			cache->num_cdd++;
+	}
+
+	if (!cache->num_cdd)
+		return -ENODEV;
+
+	return 0;
+}
+
+static int __init build_cache(void)
+{
+	struct df_node_cache cache = { };
+	int err;
+
+	err = collect_nodes(&cache);
+	if (err)
+		return err;
+
+	err = sort_and_classify(&cache);
+	if (err)
+		goto fail;
+
+	df_cache = cache;
+
+	return 0;
+
+fail:
+	release_nodes(cache.nodes, cache.num_nodes);
+	return err;
+}
+
+static u16 __maybe_unused hygon_node_num(void)
+{
+	return df_cache.num_nodes;
+}
+
+static u16 __maybe_unused hygon_cdd_num(void)
+{
+	return df_cache.num_cdd;
+}
+
+static int __maybe_unused hygon_node_get_info(u16 node, struct hygon_node_info *info)
+{
+	const struct df_node *n;
+
+	if (!info)
+		return -EINVAL;
+
+	if (!df_cache.nodes)
+		return -ENODEV;
+
+	if (node >= df_cache.num_nodes)
+		return -EINVAL;
+
+	n = &df_cache.nodes[node];
+	info->socket_id = n->socket_id;
+	info->dfid = n->dfid;
+	info->type = n->is_cdd ? HYGON_NODE_CDD : HYGON_NODE_IOD;
+	return 0;
+}
+
+/* Return a referenced DF device; the caller must call pci_dev_put(). */
+static __maybe_unused struct pci_dev *hygon_node_get_func(u16 node, u8 func)
+{
+	if (!df_cache.nodes)
+		return NULL;
+
+	if (node >= df_cache.num_nodes)
+		return NULL;
+
+	switch (func) {
+	case HYGON_DF_F3:
+		return pci_dev_get(df_cache.nodes[node].misc);
+	case HYGON_DF_F4:
+		return pci_dev_get(df_cache.nodes[node].link);
+	default:
+		return NULL;
+	}
+}
+
+/* Map any sibling PCI function to its dense DF node index. */
+static int __maybe_unused hygon_pci_dev_to_df_node(struct pci_dev *pdev)
+{
+	u16 i;
+
+	if (!pdev)
+		return -EINVAL;
+
+	if (!df_cache.nodes)
+		return -ENODEV;
+
+	for (i = 0; i < df_cache.num_nodes; i++) {
+		struct pci_dev *misc = df_cache.nodes[i].misc;
+
+		if (pci_domain_nr(misc->bus) == pci_domain_nr(pdev->bus) &&
+		    misc->bus->number == pdev->bus->number &&
+		    PCI_SLOT(misc->devfn) == PCI_SLOT(pdev->devfn))
+			return i;
+	}
+
+	return -ENODEV;
+}
+
+static int __init df_node_init(void)
+{
+	int ret;
+
+	if (!get_df_cfg())
+		return 0;
+
+	ret = build_cache();
+	if (ret) {
+		if (ret != -ENODEV || !cpu_feature_enabled(X86_FEATURE_HYPERVISOR))
+			pr_warn("DF node cache build failed: %d\n", ret);
+		return ret;
+	}
+
+	pr_info("%u DF nodes (%u CDDs, %u IODs) across %u sockets\n",
+		df_cache.num_nodes, df_cache.num_cdd,
+		df_cache.num_nodes - df_cache.num_cdd,
+		df_cache.num_sockets);
+
+	return 0;
+}
+fs_initcall(df_node_init);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v8 2/7] x86/hygon: Map CPU NodeIds to DF nodes
  2026-10-22  7:42 [PATCH v8 0/7] x86/hygon: Add Family 0x18 DF node enumeration and SMN access Lin Wang
  2026-10-22  7:42 ` [PATCH v8 1/7] x86/hygon: Add Family 0x18 DF node enumeration Lin Wang
@ 2026-10-22  7:42 ` Lin Wang
  2026-10-22  7:56   ` sashiko-bot
  2026-10-22  7:42 ` [PATCH v8 3/7] EDAC/amd64: Stop matching Hygon CPUs Lin Wang
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Lin Wang @ 2026-10-22  7:42 UTC (permalink / raw)
  To: Borislav Petkov, Yazen Ghannam, Mario Limonciello
  Cc: Pu Wen, Thomas Gleixner, Ingo Molnar, Dave Hansen, H. Peter Anvin,
	Tony Luck, Guenter Roeck, x86, linux-edac, linux-hwmon,
	linux-kernel

On bare-metal Hygon systems, CPUID 0x8000001E ECX[7:0] encodes a
CPU's socket and local CDD ordinal. The value is sparse across sockets
and cannot directly index the dense DF node cache.

Resolve the encoded socket and local ordinal against CDD entries in the
cache, which are ordered by socket and DFID. The NodeId reported by
CPUID in a guest may not describe the physical DF topology, so return
-ENODEV in guests or when it does not identify an enumerated CDD.

Hygon EDAC and ATL support will use this mapping. Keep it local until
that support is added.

Signed-off-by: Lin Wang <wanglin@open-hieco.net>
Reviewed-by: Yazen Ghannam <yazen.ghannam@amd.com>
---
 arch/x86/kernel/hygon_node.c | 54 ++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/arch/x86/kernel/hygon_node.c b/arch/x86/kernel/hygon_node.c
index 6a5278f8e5ca..03c723aab97e 100644
--- a/arch/x86/kernel/hygon_node.c
+++ b/arch/x86/kernel/hygon_node.c
@@ -24,6 +24,7 @@
 #include <linux/processor.h>
 #include <linux/slab.h>
 #include <linux/sort.h>
+#include <linux/topology.h>
 
 #include <asm/cpu_device_id.h>
 #include <asm/hygon/node.h>
@@ -481,6 +482,44 @@ static int __init sort_and_classify(struct df_node_cache *cache)
 	return 0;
 }
 
+#define NODE_ID_SOCKET	GENMASK(7, 4)
+#define NODE_ID_LOCAL	GENMASK(3, 0)
+
+/*
+ * Translate a Hygon Fam18h phys_node_id (CPUID 8000001E ECX[7:0]) to a
+ * dense DF CDD index. On supported models, CPUID reports this
+ * encoding:
+ *
+ *   phys_node_id = (socket_id << 4) | local_cdd_index_in_dfid_order
+ *
+ * The CDD region of df_cache.nodes[] is sorted by (socket_id, dfid), so
+ * return the index of the CDD whose socket_id matches and whose
+ * socket-local ordinal is @local.
+ *
+ * Return -ENODEV if the cache is unavailable or no CDD matches.
+ */
+static int phys_nid_to_df_node(unsigned int phys_nid)
+{
+	unsigned int socket, local, ordinal = 0;
+	u16 i;
+
+	socket = FIELD_GET(NODE_ID_SOCKET, phys_nid);
+	local  = FIELD_GET(NODE_ID_LOCAL, phys_nid);
+
+	if (!df_cache.nodes)
+		return -ENODEV;
+
+	for (i = 0; i < df_cache.num_cdd; i++) {
+		if (df_cache.nodes[i].socket_id != socket)
+			continue;
+
+		if (ordinal++ == local)
+			return i;
+	}
+
+	return -ENODEV;
+}
+
 static int __init build_cache(void)
 {
 	struct df_node_cache cache = { };
@@ -533,6 +572,21 @@ static int __maybe_unused hygon_node_get_info(u16 node, struct hygon_node_info *
 	return 0;
 }
 
+static int __maybe_unused cpu_to_df_node(unsigned int cpu)
+{
+	if (cpu >= nr_cpu_ids)
+		return -EINVAL;
+
+	/*
+	 * The NodeId reported by CPUID in a guest may not describe the
+	 * physical DF topology.
+	 */
+	if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR))
+		return -ENODEV;
+
+	return phys_nid_to_df_node(topology_amd_node_id(cpu));
+}
+
 /* Return a referenced DF device; the caller must call pci_dev_put(). */
 static __maybe_unused struct pci_dev *hygon_node_get_func(u16 node, u8 func)
 {
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v8 3/7] EDAC/amd64: Stop matching Hygon CPUs
  2026-10-22  7:42 [PATCH v8 0/7] x86/hygon: Add Family 0x18 DF node enumeration and SMN access Lin Wang
  2026-10-22  7:42 ` [PATCH v8 1/7] x86/hygon: Add Family 0x18 DF node enumeration Lin Wang
  2026-10-22  7:42 ` [PATCH v8 2/7] x86/hygon: Map CPU NodeIds to DF nodes Lin Wang
@ 2026-10-22  7:42 ` Lin Wang
  2026-10-22  7:45   ` sashiko-bot
  2026-10-22  7:42 ` [PATCH v8 4/7] RAS/AMD/ATL: Match AMD CPUs only Lin Wang
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Lin Wang @ 2026-10-22  7:42 UTC (permalink / raw)
  To: Borislav Petkov, Yazen Ghannam, Mario Limonciello
  Cc: Pu Wen, Thomas Gleixner, Ingo Molnar, Dave Hansen, H. Peter Anvin,
	Tony Luck, Guenter Roeck, x86, linux-edac, linux-hwmon,
	linux-kernel

amd64_edac gets its node count and DF devices from the AMD northbridge
cache. Since commit 49b96fc0dddc ("x86/amd_nb: Simplify function 3
search"), the cache finds function 3 only at the fixed PCI slots
0x18 + N. Hygon DF devices are not at those slots, so the cache is
discarded on Hygon and amd64_edac_init() returns -ENODEV at its
amd_nb_num() check.

Remove the Hygon match and the empty Family 0x18 case. MCE decoding
in mce_amd.c is separate and unchanged. Hygon memory controller support
will use the Hygon node interfaces in a separate series.

Signed-off-by: Lin Wang <wanglin@open-hieco.net>
Reviewed-by: Yazen Ghannam <yazen.ghannam@amd.com>
---
 drivers/edac/amd64_edac.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 0c0d11c72925..d10043a2d35f 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -3840,9 +3840,6 @@ static int per_family_init(struct amd64_pvt *pvt)
 		}
 		break;
 
-	case 0x18:
-		break;
-
 	case 0x19:
 		switch (pvt->model) {
 		case 0x00 ... 0x0f:
@@ -4120,7 +4117,6 @@ static const struct x86_cpu_id amd64_cpuids[] = {
 	X86_MATCH_VENDOR_FAM(AMD,	0x15, NULL),
 	X86_MATCH_VENDOR_FAM(AMD,	0x16, NULL),
 	X86_MATCH_VENDOR_FAM(AMD,	0x17, NULL),
-	X86_MATCH_VENDOR_FAM(HYGON,	0x18, NULL),
 	X86_MATCH_VENDOR_FAM(AMD,	0x19, NULL),
 	X86_MATCH_VENDOR_FAM(AMD,	0x1A, NULL),
 	{ }
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v8 4/7] RAS/AMD/ATL: Match AMD CPUs only
  2026-10-22  7:42 [PATCH v8 0/7] x86/hygon: Add Family 0x18 DF node enumeration and SMN access Lin Wang
                   ` (2 preceding siblings ...)
  2026-10-22  7:42 ` [PATCH v8 3/7] EDAC/amd64: Stop matching Hygon CPUs Lin Wang
@ 2026-10-22  7:42 ` Lin Wang
  2026-10-22  7:46   ` sashiko-bot
  2026-10-22  7:42 ` [PATCH v8 5/7] x86/amd_nb: Restrict the northbridge framework to AMD CPUs Lin Wang
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Lin Wang @ 2026-10-22  7:42 UTC (permalink / raw)
  To: Borislav Petkov, Yazen Ghannam, Mario Limonciello
  Cc: Pu Wen, Thomas Gleixner, Ingo Molnar, Dave Hansen, H. Peter Anvin,
	Tony Luck, Guenter Roeck, x86, linux-edac, linux-hwmon,
	linux-kernel

ATL matches Hygon through X86_FEATURE_SMCA and X86_FEATURE_ZEN, but
relies on the AMD northbridge cache for its node count and F4 devices.
The cache uses fixed PCI slots that do not represent the Hygon topology.

The cache is therefore discarded before ATL can register its decoder,
so excluding Hygon from these feature matches does not disable a
working address translation path.

Qualify both feature matches with the AMD vendor. Hygon address
translation will use the Hygon node interfaces in a separate series.

Signed-off-by: Lin Wang <wanglin@open-hieco.net>
Reviewed-by: Yazen Ghannam <yazen.ghannam@amd.com>
---
 drivers/ras/amd/atl/core.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/ras/amd/atl/core.c b/drivers/ras/amd/atl/core.c
index d77dacdd4f56..fe84fc52c657 100644
--- a/drivers/ras/amd/atl/core.c
+++ b/drivers/ras/amd/atl/core.c
@@ -176,18 +176,17 @@ static void check_for_legacy_df_access(void)
 }
 
 /*
- * This library provides functionality for AMD-based systems with a Data Fabric.
+ * This library provides functionality for AMD systems with a Data Fabric.
  * The set of systems with a Data Fabric is equivalent to the set of Zen-based systems
  * and the set of systems with the Scalable MCA feature at this time. However, these
  * are technically independent things.
  *
  * It's possible to match on the PCI IDs of the Data Fabric devices, but this will be
- * an ever expanding list. Instead, match on the SMCA and Zen features to cover all
- * relevant systems.
+ * an ever expanding list. Instead, match AMD CPUs with the SMCA and Zen features.
  */
 static const struct x86_cpu_id amd_atl_cpuids[] = {
-	X86_MATCH_FEATURE(X86_FEATURE_SMCA, NULL),
-	X86_MATCH_FEATURE(X86_FEATURE_ZEN, NULL),
+	X86_MATCH_VENDOR_FEATURE(AMD, X86_FEATURE_SMCA, NULL),
+	X86_MATCH_VENDOR_FEATURE(AMD, X86_FEATURE_ZEN, NULL),
 	{ }
 };
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v8 5/7] x86/amd_nb: Restrict the northbridge framework to AMD CPUs
  2026-10-22  7:42 [PATCH v8 0/7] x86/hygon: Add Family 0x18 DF node enumeration and SMN access Lin Wang
                   ` (3 preceding siblings ...)
  2026-10-22  7:42 ` [PATCH v8 4/7] RAS/AMD/ATL: Match AMD CPUs only Lin Wang
@ 2026-10-22  7:42 ` Lin Wang
  2026-10-22  7:48   ` sashiko-bot
  2026-10-22  7:42 ` [PATCH v8 6/7] x86/amd_node: Restrict SMN setup " Lin Wang
  2026-10-22  7:42 ` [PATCH v8 7/7] x86/hygon: Add Family 0x18 SMN access Lin Wang
  6 siblings, 1 reply; 16+ messages in thread
From: Lin Wang @ 2026-10-22  7:42 UTC (permalink / raw)
  To: Borislav Petkov, Yazen Ghannam, Mario Limonciello
  Cc: Pu Wen, Thomas Gleixner, Ingo Molnar, Dave Hansen, H. Peter Anvin,
	Tony Luck, Guenter Roeck, x86, linux-edac, linux-hwmon,
	linux-kernel

The AMD northbridge cache previously discovered Hygon F3 devices by PCI
ID. It now derives the node count from CPU topology and locates node
functions at fixed PCI slots. Hygon DF devices do not follow that
layout, so the Hygon branch no longer builds a usable cache.

amd64_edac and ATL no longer use this cache on Hygon. Restrict
northbridge initialization and the early northbridge check to AMD CPUs.
Keep amd_get_mmconfig_range() available on Hygon because it reads the
MMCONFIG MSR without using the northbridge cache.

Signed-off-by: Lin Wang <wanglin@open-hieco.net>
Reviewed-by: Yazen Ghannam <yazen.ghannam@amd.com>
---
 arch/x86/kernel/amd_nb.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c
index 5d364540673d..848ed2ca17c3 100644
--- a/arch/x86/kernel/amd_nb.c
+++ b/arch/x86/kernel/amd_nb.c
@@ -125,8 +125,7 @@ bool __init early_is_amd_nb(u32 device)
 	const struct pci_device_id *id;
 	u32 vendor = device & 0xffff;
 
-	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
-	    boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
 		return false;
 
 	if (cpu_feature_enabled(X86_FEATURE_ZEN))
@@ -315,8 +314,7 @@ static __init void fix_erratum_688(void)
 
 static __init int init_amd_nbs(void)
 {
-	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
-	    boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
 		return 0;
 
 	amd_cache_northbridges();
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v8 6/7] x86/amd_node: Restrict SMN setup to AMD CPUs
  2026-10-22  7:42 [PATCH v8 0/7] x86/hygon: Add Family 0x18 DF node enumeration and SMN access Lin Wang
                   ` (4 preceding siblings ...)
  2026-10-22  7:42 ` [PATCH v8 5/7] x86/amd_nb: Restrict the northbridge framework to AMD CPUs Lin Wang
@ 2026-10-22  7:42 ` Lin Wang
  2026-10-22  7:49   ` sashiko-bot
  2026-10-22  7:42 ` [PATCH v8 7/7] x86/hygon: Add Family 0x18 SMN access Lin Wang
  6 siblings, 1 reply; 16+ messages in thread
From: Lin Wang @ 2026-10-22  7:42 UTC (permalink / raw)
  To: Borislav Petkov, Yazen Ghannam, Mario Limonciello
  Cc: Pu Wen, Thomas Gleixner, Ingo Molnar, Dave Hansen, H. Peter Anvin,
	Tony Luck, Guenter Roeck, x86, linux-edac, linux-hwmon,
	linux-kernel

amd_smn_init() also runs on Hygon because Hygon sets X86_FEATURE_ZEN.
It reserves config space on the matching host-bridge roots and groups
them by the CPU-derived node count. Hygon DF nodes are enumerated by
PCI ID, CPU NodeIds are sparse, and the nodes in a socket share one SMN
ingress, so the resulting root map is wrong on Hygon. These reservations
also prevent the Hygon node layer from claiming roots for its own
node-to-root mapping.

Hygon vendor matching has been removed from amd64_edac, amd_atl, and
k10temp modules. The remaining users match AMD PCI IDs or check for an
AMD CPU. With these changes in place, no in-tree Hygon driver uses the
AMD SMN accessors.

Restrict SMN setup and root discovery to AMD CPUs.

Signed-off-by: Lin Wang <wanglin@open-hieco.net>
Reviewed-by: Yazen Ghannam <yazen.ghannam@amd.com>
---

Notes (hygon-node-deps):
    Depends on commit 08e6615c909b ("hwmon: (k10temp) Stop matching Hygon
    devices") in hwmon-next, which is not in mainline yet. It must be merged
    before this patch.

 arch/x86/kernel/amd_node.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/amd_node.c b/arch/x86/kernel/amd_node.c
index b7926ba3610a..c36b410d04a4 100644
--- a/arch/x86/kernel/amd_node.c
+++ b/arch/x86/kernel/amd_node.c
@@ -229,8 +229,7 @@ static struct pci_dev *get_next_root(struct pci_dev *root)
 		if (root->devfn)
 			continue;
 
-		if (root->vendor != PCI_VENDOR_ID_AMD &&
-		    root->vendor != PCI_VENDOR_ID_HYGON)
+		if (root->vendor != PCI_VENDOR_ID_AMD)
 			continue;
 
 		break;
@@ -253,6 +252,9 @@ static int __init amd_smn_init(void)
 	u16 count, num_roots, roots_per_node, node, num_nodes;
 	struct pci_dev *root __free(pci_dev_put) = NULL;
 
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
+		return 0;
+
 	if (!cpu_feature_enabled(X86_FEATURE_ZEN))
 		return 0;
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v8 7/7] x86/hygon: Add Family 0x18 SMN access
  2026-10-22  7:42 [PATCH v8 0/7] x86/hygon: Add Family 0x18 DF node enumeration and SMN access Lin Wang
                   ` (5 preceding siblings ...)
  2026-10-22  7:42 ` [PATCH v8 6/7] x86/amd_node: Restrict SMN setup " Lin Wang
@ 2026-10-22  7:42 ` Lin Wang
  2026-10-22  7:52   ` sashiko-bot
  6 siblings, 1 reply; 16+ messages in thread
From: Lin Wang @ 2026-10-22  7:42 UTC (permalink / raw)
  To: Borislav Petkov, Yazen Ghannam, Mario Limonciello
  Cc: Pu Wen, Thomas Gleixner, Ingo Molnar, Dave Hansen, H. Peter Anvin,
	Tony Luck, Guenter Roeck, x86, linux-edac, linux-hwmon,
	linux-kernel

All DF nodes in a Hygon socket share one SMN ingress, so SMN accesses
for a node have to go through a root of the node's socket rather than a
root per node.

After DF enumeration, map each DF node to the first root of its socket.
The roots do not expose their socket IDs, so group them by socket
in PCI enumeration order. Hold a reference to every root, reserve its
config space, and serialize each index/data transaction. Enable SMN
access only after setup succeeds; on failure the DF node cache remains
usable without it.

Hygon drivers such as EDAC need SMN access. Keep the SMN read and write
helpers local to hygon_node.c until such drivers are added.

Signed-off-by: Lin Wang <wanglin@open-hieco.net>
Reviewed-by: Yazen Ghannam <yazen.ghannam@amd.com>
---
 arch/x86/kernel/hygon_node.c | 231 ++++++++++++++++++++++++++++++++++-
 1 file changed, 230 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/hygon_node.c b/arch/x86/kernel/hygon_node.c
index 03c723aab97e..7b0a18cd7027 100644
--- a/arch/x86/kernel/hygon_node.c
+++ b/arch/x86/kernel/hygon_node.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Hygon Family 0x18 Data Fabric node enumeration
+ * Hygon Family 0x18 Data Fabric node enumeration and SMN access
  *
  * A DF instance exposes sibling PCI functions in one slot. Function 3
  * is the misc device used for enumeration, function 4 is the link
@@ -17,8 +17,10 @@
 
 #include <linux/bitfield.h>
 #include <linux/bitops.h>
+#include <linux/cleanup.h>
 #include <linux/cpufeature.h>
 #include <linux/init.h>
+#include <linux/mutex.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
 #include <linux/processor.h>
@@ -629,6 +631,229 @@ static int __maybe_unused hygon_pci_dev_to_df_node(struct pci_dev *pdev)
 	return -ENODEV;
 }
 
+/*
+ * SMN index/data register pair offsets in the host-bridge PCI config
+ * space. Reads and writes to a (node, address) pair are issued as a
+ * two-step transaction: write the SMN address to the index register,
+ * then read or write the value at the data register.
+ */
+#define SMN_INDEX_OFFSET	0x60
+#define SMN_DATA_OFFSET		0x64
+
+/*
+ * Runtime SMN state.
+ *
+ * The smn_reserved_roots array owns the independent PCI references and
+ * config-space reservations for the lifetime of the built-in node layer. The
+ * smn_roots array contains per-node aliases and is published only after
+ * setup succeeds.
+ */
+static struct pci_dev	**smn_roots;
+static struct pci_dev	**smn_reserved_roots;
+static u16		smn_num_nodes;
+static DEFINE_MUTEX(smn_mutex);
+
+/*
+ * Walk PCI host-bridge devices matching the Hygon vendor. The SMN
+ * index/data registers live in function 0 of each root complex. This
+ * follows pci_get_class() iterator semantics: @root is consumed and the
+ * returned device has an iterator reference. A retained device needs an
+ * independent reference before the iterator advances.
+ */
+static struct pci_dev * __init get_next_root(struct pci_dev *root)
+{
+	while ((root = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, root))) {
+		if (root->devfn)
+			continue;
+		if (root->vendor != PCI_VENDOR_ID_HYGON)
+			continue;
+		break;
+	}
+	return root;
+}
+
+/* Release each config region before dropping its owning device reference. */
+static void __init release_reserved_roots(struct pci_dev **roots, u16 count)
+{
+	u16 i;
+
+	for (i = 0; i < count; i++) {
+		pci_release_config_region(roots[i], 0, PCI_CFG_SPACE_SIZE);
+		pci_dev_put(roots[i]);
+	}
+}
+
+/*
+ * Select one root from each contiguous per-socket enumeration group,
+ * then map every DF node to the root for its socket. The roots do not
+ * expose their socket IDs, so the grouping follows PCI enumeration order.
+ *
+ * The smn_reserved_roots array owns the PCI references and config
+ * regions. The smn_roots array contains per-node aliases. Enable SMN
+ * access only after both arrays are complete.
+ */
+static int __init smn_setup(void)
+{
+	u16 num_roots, roots_per_socket, node, num_nodes, num_sockets, reserved;
+	struct pci_dev **reserved_roots, **roots;
+	struct pci_dev *root = NULL;
+	u8 socket_id;
+	int ret;
+
+	num_roots = 0;
+	while ((root = get_next_root(root)))
+		num_roots++;
+
+	pr_debug("Found %u Hygon SMN root devices\n", num_roots);
+
+	if (!num_roots)
+		return -ENODEV;
+
+	num_nodes = df_cache.num_nodes;
+	if (!num_nodes)
+		return -ENODEV;
+
+	num_sockets = df_cache.num_sockets;
+	if (!num_sockets)
+		return -ENODEV;
+
+	if (num_roots % num_sockets) {
+		pr_err("Root count %u not divisible by socket count %u\n",
+		       num_roots, num_sockets);
+		return -ENODEV;
+	}
+
+	roots = kzalloc_objs(*roots, num_nodes);
+	if (!roots)
+		return -ENOMEM;
+
+	reserved_roots = kzalloc_objs(*reserved_roots, num_roots);
+	if (!reserved_roots) {
+		kfree(roots);
+		return -ENOMEM;
+	}
+
+	/* Reserve every root before publishing the node-to-root mapping. */
+	roots_per_socket = num_roots / num_sockets;
+	reserved = 0;
+	while ((root = get_next_root(root))) {
+		if (reserved >= num_roots) {
+			ret = -ENODEV;
+			goto err_release;
+		}
+
+		pci_dbg(root, "Reserving PCI config space\n");
+
+		/*
+		 * Mark the entire PCI config space kernel-exclusive because it
+		 * contains the SMN index/data registers.
+		 */
+		if (!pci_request_config_region_exclusive(root, 0,
+							 PCI_CFG_SPACE_SIZE,
+							 NULL)) {
+			pci_err(root, "Failed to reserve config space\n");
+			ret = -EEXIST;
+			goto err_release;
+		}
+
+		reserved_roots[reserved++] = pci_dev_get(root);
+	}
+
+	if (reserved != num_roots) {
+		pr_err("Root enumeration changed: expected %u roots, got %u\n",
+		       num_roots, reserved);
+		ret = -ENODEV;
+		goto err_release;
+	}
+
+	for (node = 0; node < num_nodes; node++) {
+		socket_id = df_cache.nodes[node].socket_id;
+
+		if (socket_id >= num_sockets) {
+			ret = -ENODEV;
+			goto err_release;
+		}
+
+		roots[node] = reserved_roots[socket_id * roots_per_socket];
+
+		pci_dbg(roots[node],
+			"is root for Hygon node %u (socket %u)\n",
+			node, socket_id);
+	}
+
+	smn_reserved_roots = reserved_roots;
+	smn_num_nodes = num_nodes;
+	smn_roots = roots;
+	return 0;
+
+err_release:
+	pci_dev_put(root);
+	release_reserved_roots(reserved_roots, reserved);
+	kfree(reserved_roots);
+	kfree(roots);
+	return ret;
+}
+
+/*
+ * Serialize the PCI index/data pair between in-kernel SMN users.
+ * The access sequence follows amd_smn_read() and amd_smn_write().
+ * The Hygon node-to-root mapping comes from smn_setup().
+ */
+static int smn_rw(u16 node, u32 address, u32 *value, bool write)
+{
+	struct pci_dev *root;
+	int err;
+
+	if (!smn_roots || node >= smn_num_nodes)
+		return -ENODEV;
+
+	root = smn_roots[node];
+	if (!root)
+		return -ENODEV;
+
+	guard(mutex)(&smn_mutex);
+
+	err = pci_write_config_dword(root, SMN_INDEX_OFFSET, address);
+	if (err) {
+		pr_warn("SMN index write failed (addr 0x%x)\n", address);
+		return pcibios_err_to_errno(err);
+	}
+
+	err = write ? pci_write_config_dword(root, SMN_DATA_OFFSET, *value)
+		    : pci_read_config_dword(root, SMN_DATA_OFFSET, value);
+
+	return pcibios_err_to_errno(err);
+}
+
+static int __must_check __maybe_unused hygon_smn_read(u16 node, u32 address, u32 *value)
+{
+	int err;
+
+	if (!value)
+		return -EINVAL;
+
+	err = smn_rw(node, address, value, false);
+
+	/* Clear the output so callers do not consume a stale value. */
+	if (err) {
+		*value = 0;
+		return err;
+	}
+
+	/* Treat the PCI all-ones value as a missing device. */
+	if (PCI_POSSIBLE_ERROR(*value)) {
+		*value = 0;
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int __must_check __maybe_unused hygon_smn_write(u16 node, u32 address, u32 value)
+{
+	return smn_rw(node, address, &value, true);
+}
+
 static int __init df_node_init(void)
 {
 	int ret;
@@ -648,6 +873,10 @@ static int __init df_node_init(void)
 		df_cache.num_nodes - df_cache.num_cdd,
 		df_cache.num_sockets);
 
+	ret = smn_setup();
+	if (ret)
+		pr_warn("SMN setup failed: %d\n", ret);
+
 	return 0;
 }
 fs_initcall(df_node_init);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH v8 3/7] EDAC/amd64: Stop matching Hygon CPUs
  2026-10-22  7:42 ` [PATCH v8 3/7] EDAC/amd64: Stop matching Hygon CPUs Lin Wang
@ 2026-10-22  7:45   ` sashiko-bot
  0 siblings, 0 replies; 16+ messages in thread
From: sashiko-bot @ 2026-10-22  7:45 UTC (permalink / raw)
  To: Lin Wang; +Cc: linux-hwmon

> amd64_edac gets its node count and DF devices from the AMD northbridge
> cache. Since commit 49b96fc0dddc ("x86/amd_nb: Simplify function 3
> search"), the cache finds function 3 only at the fixed PCI slots
> 0x18 + N. Hygon DF devices are not at those slots, so the cache is
> discarded on Hygon and amd64_edac_init() returns -ENODEV at its
> amd_nb_num() check.
> 
> Remove the Hygon match and the empty Family 0x18 case. MCE decoding
> in mce_amd.c is separate and unchanged. Hygon memory controller support
> will use the Hygon node interfaces in a separate series.
> 
> Signed-off-by: Lin Wang <wanglin@open-hieco.net>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261022074218.667049-1-wanglin@open-hieco.net?part=3


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v8 4/7] RAS/AMD/ATL: Match AMD CPUs only
  2026-10-22  7:42 ` [PATCH v8 4/7] RAS/AMD/ATL: Match AMD CPUs only Lin Wang
@ 2026-10-22  7:46   ` sashiko-bot
  0 siblings, 0 replies; 16+ messages in thread
From: sashiko-bot @ 2026-10-22  7:46 UTC (permalink / raw)
  To: Lin Wang; +Cc: linux-hwmon

> ATL matches Hygon through X86_FEATURE_SMCA and X86_FEATURE_ZEN, but
> relies on the AMD northbridge cache for its node count and F4 devices.
> The cache uses fixed PCI slots that do not represent the Hygon topology.
> 
> The cache is therefore discarded before ATL can register its decoder,
> so excluding Hygon from these feature matches does not disable a
> working address translation path.
> 
> Qualify both feature matches with the AMD vendor. Hygon address
> translation will use the Hygon node interfaces in a separate series.
> 
> Signed-off-by: Lin Wang <wanglin@open-hieco.net>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261022074218.667049-1-wanglin@open-hieco.net?part=4


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v8 5/7] x86/amd_nb: Restrict the northbridge framework to AMD CPUs
  2026-10-22  7:42 ` [PATCH v8 5/7] x86/amd_nb: Restrict the northbridge framework to AMD CPUs Lin Wang
@ 2026-10-22  7:48   ` sashiko-bot
  0 siblings, 0 replies; 16+ messages in thread
From: sashiko-bot @ 2026-10-22  7:48 UTC (permalink / raw)
  To: Lin Wang; +Cc: linux-hwmon

> The AMD northbridge cache previously discovered Hygon F3 devices by PCI
> ID. It now derives the node count from CPU topology and locates node
> functions at fixed PCI slots. Hygon DF devices do not follow that
> layout, so the Hygon branch no longer builds a usable cache.
> 
> amd64_edac and ATL no longer use this cache on Hygon. Restrict
> northbridge initialization and the early northbridge check to AMD CPUs.
> Keep amd_get_mmconfig_range() available on Hygon because it reads the
> MMCONFIG MSR without using the northbridge cache.
> 
> Signed-off-by: Lin Wang <wanglin@open-hieco.net>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261022074218.667049-1-wanglin@open-hieco.net?part=5


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v8 1/7] x86/hygon: Add Family 0x18 DF node enumeration
  2026-10-22  7:42 ` [PATCH v8 1/7] x86/hygon: Add Family 0x18 DF node enumeration Lin Wang
@ 2026-10-22  7:49   ` sashiko-bot
  2026-10-24 15:15   ` Yazen Ghannam
  1 sibling, 0 replies; 16+ messages in thread
From: sashiko-bot @ 2026-10-22  7:49 UTC (permalink / raw)
  To: Lin Wang; +Cc: linux-hwmon

> The AMD node code locates function 3 for node N at PCI slot 0x18 + N.
> Hygon has no equivalent node-index-to-slot mapping: DF F3 devices are
> discovered by PCI ID and the PCI BDF is only an access point.
> 
> Enumerate Hygon DF devices by PCI ID and read their identities from DF
> registers. Build a dense node cache with Core and DDR Dies (CDDs) before
> I/O Dies (IODs), providing node counts, identity and PCI function lookups.
> 
> Guests may expose a supported CPU model without DF devices. Suppress
> the cache-build warning for -ENODEV in guests; keep other initialization
> errors visible.
> 
> The node lookup helpers remain local until Hygon consumers are added.
> 
> Signed-off-by: Lin Wang <wanglin@open-hieco.net>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261022074218.667049-1-wanglin@open-hieco.net?part=1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v8 6/7] x86/amd_node: Restrict SMN setup to AMD CPUs
  2026-10-22  7:42 ` [PATCH v8 6/7] x86/amd_node: Restrict SMN setup " Lin Wang
@ 2026-10-22  7:49   ` sashiko-bot
  0 siblings, 0 replies; 16+ messages in thread
From: sashiko-bot @ 2026-10-22  7:49 UTC (permalink / raw)
  To: Lin Wang; +Cc: linux-hwmon

> amd_smn_init() also runs on Hygon because Hygon sets X86_FEATURE_ZEN.
> It reserves config space on the matching host-bridge roots and groups
> them by the CPU-derived node count. Hygon DF nodes are enumerated by
> PCI ID, CPU NodeIds are sparse, and the nodes in a socket share one SMN
> ingress, so the resulting root map is wrong on Hygon. These reservations
> also prevent the Hygon node layer from claiming roots for its own
> node-to-root mapping.
> 
> Hygon vendor matching has been removed from amd64_edac, amd_atl, and
> k10temp modules. The remaining users match AMD PCI IDs or check for an
> AMD CPU. With these changes in place, no in-tree Hygon driver uses the
> AMD SMN accessors.
> 
> Restrict SMN setup and root discovery to AMD CPUs.
> 
> Signed-off-by: Lin Wang <wanglin@open-hieco.net>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261022074218.667049-1-wanglin@open-hieco.net?part=6


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v8 7/7] x86/hygon: Add Family 0x18 SMN access
  2026-10-22  7:42 ` [PATCH v8 7/7] x86/hygon: Add Family 0x18 SMN access Lin Wang
@ 2026-10-22  7:52   ` sashiko-bot
  0 siblings, 0 replies; 16+ messages in thread
From: sashiko-bot @ 2026-10-22  7:52 UTC (permalink / raw)
  To: Lin Wang; +Cc: linux-hwmon

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] x86/hygon: unreferenced reserved_roots allocation in smn_setup()
--

commit 9932a3551c6b7f805f9889c0454dbe666f4f46a0
Author: Lin Wang <wanglin@open-hieco.net>

x86/hygon: Add Family 0x18 SMN access

This commit adds system management network access support for Hygon
Family 0x18 processors by mapping data fabric nodes to per-socket root
complexes and providing serialized read and write helpers.

> diff --git a/arch/x86/kernel/hygon_node.c b/arch/x86/kernel/hygon_node.c
> index 03c723aab97e3..7b0a18cd7027a 100644
> --- a/arch/x86/kernel/hygon_node.c
> +++ b/arch/x86/kernel/hygon_node.c
[ ... ]
> @@ -629,6 +631,229 @@ static int __maybe_unused hygon_pci_dev_to_df_node(struct pci_dev *pdev)
[ ... ]
> +static struct pci_dev	**smn_roots;
> +static struct pci_dev	**smn_reserved_roots;
> +static u16		smn_num_nodes;
> +static DEFINE_MUTEX(smn_mutex);
[ ... ]
> +static int __init smn_setup(void)
> +{
> +	u16 num_roots, roots_per_socket, node, num_nodes, num_sockets, reserved;
> +	struct pci_dev **reserved_roots, **roots;
> +	struct pci_dev *root = NULL;
> +	u8 socket_id;
> +	int ret;
[ ... ]
> +	roots = kzalloc_objs(*roots, num_nodes);
> +	if (!roots)
> +		return -ENOMEM;
> +
> +	reserved_roots = kzalloc_objs(*reserved_roots, num_roots);
> +	if (!reserved_roots) {
> +		kfree(roots);
> +		return -ENOMEM;
> +	}
[ ... ]
> +	for (node = 0; node < num_nodes; node++) {
> +		socket_id = df_cache.nodes[node].socket_id;
> +
> +		if (socket_id >= num_sockets) {
> +			ret = -ENODEV;
> +			goto err_release;
> +		}
> +
> +		roots[node] = reserved_roots[socket_id * roots_per_socket];
> +
> +		pci_dbg(roots[node],
> +			"is root for Hygon node %u (socket %u)\n",
> +			node, socket_id);
> +	}
> +
> +	smn_reserved_roots = reserved_roots;
> +	smn_num_nodes = num_nodes;
> +	smn_roots = roots;
> +	return 0;

[Severity: Medium]
Does df_node_init() -> smn_setup() in arch/x86/kernel/hygon_node.c leak the
reserved_roots array once initialization completes?

In smn_setup(), reserved_roots is allocated with kzalloc_objs() to track
reserved root devices for error rollback via release_reserved_roots() and
to populate roots[node]. At the end of smn_setup(), reserved_roots is
assigned to the file-scope static variable smn_reserved_roots, which is
never read anywhere in arch/x86/kernel/hygon_node.c.

Because smn_reserved_roots is a write-only static variable with internal
linkage, the compiler optimizes away both the variable and the store to it.
Once smn_setup() returns, no reference to the reserved_roots allocation
remains in memory (as smn_roots only holds pointers to the individual
pci_dev objects), which leaves the array leaked and triggers a kmemleak
report.

Since the device references from pci_dev_get() and the config space
reservations from pci_request_config_region_exclusive() are held by the
pci_dev objects themselves, could smn_reserved_roots be removed and
reserved_roots freed with kfree(reserved_roots) before smn_setup() returns
0?

[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261022074218.667049-1-wanglin@open-hieco.net?part=7

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v8 2/7] x86/hygon: Map CPU NodeIds to DF nodes
  2026-10-22  7:42 ` [PATCH v8 2/7] x86/hygon: Map CPU NodeIds to DF nodes Lin Wang
@ 2026-10-22  7:56   ` sashiko-bot
  0 siblings, 0 replies; 16+ messages in thread
From: sashiko-bot @ 2026-10-22  7:56 UTC (permalink / raw)
  To: Lin Wang; +Cc: linux-hwmon

> On bare-metal Hygon systems, CPUID 0x8000001E ECX[7:0] encodes a
> CPU's socket and local CDD ordinal. The value is sparse across sockets
> and cannot directly index the dense DF node cache.
> 
> Resolve the encoded socket and local ordinal against CDD entries in the
> cache, which are ordered by socket and DFID. The NodeId reported by
> CPUID in a guest may not describe the physical DF topology, so return
> -ENODEV in guests or when it does not identify an enumerated CDD.
> 
> Hygon EDAC and ATL support will use this mapping. Keep it local until
> that support is added.
> 
> Signed-off-by: Lin Wang <wanglin@open-hieco.net>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261022074218.667049-1-wanglin@open-hieco.net?part=2


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v8 1/7] x86/hygon: Add Family 0x18 DF node enumeration
  2026-10-22  7:42 ` [PATCH v8 1/7] x86/hygon: Add Family 0x18 DF node enumeration Lin Wang
  2026-10-22  7:49   ` sashiko-bot
@ 2026-10-24 15:15   ` Yazen Ghannam
  1 sibling, 0 replies; 16+ messages in thread
From: Yazen Ghannam @ 2026-10-24 15:15 UTC (permalink / raw)
  To: Lin Wang
  Cc: Borislav Petkov, Mario Limonciello, Pu Wen, Thomas Gleixner,
	Ingo Molnar, Dave Hansen, H. Peter Anvin, Tony Luck,
	Guenter Roeck, x86, linux-edac, linux-hwmon, linux-kernel

On Thu, Oct 22, 2026 at 03:42:11PM +0800, Lin Wang wrote:
> The AMD node code locates function 3 for node N at PCI slot 0x18 + N.
> Hygon has no equivalent node-index-to-slot mapping: DF F3 devices are
> discovered by PCI ID and the PCI BDF is only an access point.
> 
> Enumerate Hygon DF devices by PCI ID and read their identities from DF
> registers. Build a dense node cache with Core and DDR Dies (CDDs) before
> I/O Dies (IODs), providing node counts, identity and PCI function lookups.
> 
> Guests may expose a supported CPU model without DF devices. Suppress
> the cache-build warning for -ENODEV in guests; keep other initialization
> errors visible.
> 
> The node lookup helpers remain local until Hygon consumers are added.
> 
> Signed-off-by: Lin Wang <wanglin@open-hieco.net>
> ---

Reviewed-by: Yazen Ghannam <yazen.ghannam@amd.com>

Thanks,
Yazen

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2026-10-24 15:15 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-22  7:42 [PATCH v8 0/7] x86/hygon: Add Family 0x18 DF node enumeration and SMN access Lin Wang
2026-10-22  7:42 ` [PATCH v8 1/7] x86/hygon: Add Family 0x18 DF node enumeration Lin Wang
2026-10-22  7:49   ` sashiko-bot
2026-10-24 15:15   ` Yazen Ghannam
2026-10-22  7:42 ` [PATCH v8 2/7] x86/hygon: Map CPU NodeIds to DF nodes Lin Wang
2026-10-22  7:56   ` sashiko-bot
2026-10-22  7:42 ` [PATCH v8 3/7] EDAC/amd64: Stop matching Hygon CPUs Lin Wang
2026-10-22  7:45   ` sashiko-bot
2026-10-22  7:42 ` [PATCH v8 4/7] RAS/AMD/ATL: Match AMD CPUs only Lin Wang
2026-10-22  7:46   ` sashiko-bot
2026-10-22  7:42 ` [PATCH v8 5/7] x86/amd_nb: Restrict the northbridge framework to AMD CPUs Lin Wang
2026-10-22  7:48   ` sashiko-bot
2026-10-22  7:42 ` [PATCH v8 6/7] x86/amd_node: Restrict SMN setup " Lin Wang
2026-10-22  7:49   ` sashiko-bot
2026-10-22  7:42 ` [PATCH v8 7/7] x86/hygon: Add Family 0x18 SMN access Lin Wang
2026-10-22  7:52   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox