public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 0/2] Fix get cpu steer-tag fail on ARM64 platform
@ 2026-03-10  3:20 Chengwen Feng
  2026-03-10  3:20 ` [PATCH v5 1/2] ACPI: Rename get_acpi_id_for_cpu() to acpi_get_cpu_acpi_id() on non-x86 Chengwen Feng
  2026-03-10  3:20 ` [PATCH v5 2/2] PCI/TPH: Fix get cpu steer-tag fail on ARM64 platform Chengwen Feng
  0 siblings, 2 replies; 10+ messages in thread
From: Chengwen Feng @ 2026-03-10  3:20 UTC (permalink / raw)
  To: Bjorn Helgaas, Catalin Marinas, Will Deacon, Rafael J . Wysocki
  Cc: Jonathan Corbet, Shuah Khan, Huacai Chen, WANG Xuerui,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H . Peter Anvin, Juergen Gross, Boris Ostrovsky, Len Brown,
	Sunil V L, Mark Rutland, Chengwen Feng, Jonathan Cameron,
	Kees Cook, Yanteng Si, Sean Christopherson, Kai Huang,
	Tom Lendacky, Thomas Huth, Thorsten Blum, Kevin Loughlin,
	Zheyun Shen, Peter Zijlstra, Pawan Gupta, Xin Li,
	Ahmed S . Darwish, Sohil Mehta, Ilkka Koskinen, Robin Murphy,
	James Clark, Besar Wicaksono, Ma Ke, Ajit Khaparde, Wei Huang,
	Andy Gospodarek, Somnath Kotur, wangzhou1, wanghuiqiang,
	liuyonglong, linux-pci, linux-doc, linux-kernel, linux-arm-kernel,
	loongarch, linux-riscv, xen-devel, linux-acpi, linux-perf-users,
	stable

This patchset addresses the issue where retrieving the CPU steer-tag
fails on ARM64 platforms. The first commit is a pure renaming of the
ACPI CPU ID retrieval interface (no functional changes), which serves
as preparation for the second commit that implements the core fix for
the steer-tag retrieval logic.

---
Changes in v5:
- Refine commit-log of commit 2/2
- Replace cpu_acpi_id() by acpi_get_cpu_acpi_id() on x86

Changes in v4:
- Split the rename into a separate commit.

Changes in v3:
- Rename existing get_acpi_id_for_cpu() to acpi_get_cpu_acpi_id() other
  than add one new API.

Changes in v2:
- Add ECN _DSM reference doc name and its URL.
- Separate implement acpi_get_cpu_acpi_id() in each arch which supports
  ACPI.
- Refine commit-log.

Chengwen Feng (2):
  ACPI: Rename get_acpi_id_for_cpu() to acpi_get_cpu_acpi_id() on
    non-x86
  PCI/TPH: Fix get cpu steer-tag fail on ARM64 platform

 Documentation/PCI/tph.rst          |  4 ++--
 arch/arm64/include/asm/acpi.h      |  4 ++--
 arch/loongarch/include/asm/acpi.h  |  2 +-
 arch/riscv/include/asm/acpi.h      |  2 +-
 arch/riscv/kernel/acpi_numa.c      |  2 +-
 arch/x86/include/asm/acpi.h        |  2 ++
 arch/x86/include/asm/cpu.h         |  1 -
 arch/x86/include/asm/smp.h         |  1 -
 arch/x86/kernel/cpu/common.c       | 12 ++++++++++++
 arch/x86/xen/enlighten_hvm.c       |  4 ++--
 drivers/acpi/pptt.c                | 16 ++++++++--------
 drivers/acpi/riscv/rhct.c          |  2 +-
 drivers/pci/tph.c                  | 11 ++++++-----
 drivers/perf/arm_cspmu/arm_cspmu.c |  2 +-
 include/linux/pci-tph.h            |  4 ++--
 15 files changed, 41 insertions(+), 28 deletions(-)

-- 
2.17.1


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

* [PATCH v5 1/2] ACPI: Rename get_acpi_id_for_cpu() to acpi_get_cpu_acpi_id() on non-x86
  2026-03-10  3:20 [PATCH v5 0/2] Fix get cpu steer-tag fail on ARM64 platform Chengwen Feng
@ 2026-03-10  3:20 ` Chengwen Feng
  2026-03-10 17:53   ` Bjorn Helgaas
  2026-03-10  3:20 ` [PATCH v5 2/2] PCI/TPH: Fix get cpu steer-tag fail on ARM64 platform Chengwen Feng
  1 sibling, 1 reply; 10+ messages in thread
From: Chengwen Feng @ 2026-03-10  3:20 UTC (permalink / raw)
  To: Bjorn Helgaas, Catalin Marinas, Will Deacon, Rafael J . Wysocki
  Cc: Jonathan Corbet, Shuah Khan, Huacai Chen, WANG Xuerui,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H . Peter Anvin, Juergen Gross, Boris Ostrovsky, Len Brown,
	Sunil V L, Mark Rutland, Chengwen Feng, Jonathan Cameron,
	Kees Cook, Yanteng Si, Sean Christopherson, Kai Huang,
	Tom Lendacky, Thomas Huth, Thorsten Blum, Kevin Loughlin,
	Zheyun Shen, Peter Zijlstra, Pawan Gupta, Xin Li,
	Ahmed S . Darwish, Sohil Mehta, Ilkka Koskinen, Robin Murphy,
	James Clark, Besar Wicaksono, Ma Ke, Ajit Khaparde, Wei Huang,
	Andy Gospodarek, Somnath Kotur, wangzhou1, wanghuiqiang,
	liuyonglong, linux-pci, linux-doc, linux-kernel, linux-arm-kernel,
	loongarch, linux-riscv, xen-devel, linux-acpi, linux-perf-users,
	stable

To unify the CPU ACPI ID retrieval interface across architectures,
rename the existing get_acpi_id_for_cpu() function to
acpi_get_cpu_acpi_id() on arm64/riscv/loongarch platforms.

This is a pure rename with no functional change, preparing for a
consistent ACPI Processor UID retrieval interface across all ACPI-enabled
platforms.

Cc: stable@vger.kernel.org
Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
---
 arch/arm64/include/asm/acpi.h      |  4 ++--
 arch/loongarch/include/asm/acpi.h  |  2 +-
 arch/riscv/include/asm/acpi.h      |  2 +-
 arch/riscv/kernel/acpi_numa.c      |  2 +-
 drivers/acpi/pptt.c                | 16 ++++++++--------
 drivers/acpi/riscv/rhct.c          |  2 +-
 drivers/perf/arm_cspmu/arm_cspmu.c |  2 +-
 7 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index c07a58b96329..202107aeb05b 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -114,7 +114,7 @@ static inline bool acpi_has_cpu_in_madt(void)
 }
 
 struct acpi_madt_generic_interrupt *acpi_cpu_get_madt_gicc(int cpu);
-static inline u32 get_acpi_id_for_cpu(unsigned int cpu)
+static inline u32 acpi_get_cpu_acpi_id(unsigned int cpu)
 {
 	return	acpi_cpu_get_madt_gicc(cpu)->uid;
 }
@@ -125,7 +125,7 @@ static inline int get_cpu_for_acpi_id(u32 uid)
 
 	for (cpu = 0; cpu < nr_cpu_ids; cpu++)
 		if (acpi_cpu_get_madt_gicc(cpu) &&
-		    uid == get_acpi_id_for_cpu(cpu))
+		    uid == acpi_get_cpu_acpi_id(cpu))
 			return cpu;
 
 	return -EINVAL;
diff --git a/arch/loongarch/include/asm/acpi.h b/arch/loongarch/include/asm/acpi.h
index 7376840fa9f7..89c6c8f52cc3 100644
--- a/arch/loongarch/include/asm/acpi.h
+++ b/arch/loongarch/include/asm/acpi.h
@@ -40,7 +40,7 @@ extern struct acpi_madt_core_pic acpi_core_pic[MAX_CORE_PIC];
 
 extern int __init parse_acpi_topology(void);
 
-static inline u32 get_acpi_id_for_cpu(unsigned int cpu)
+static inline u32 acpi_get_cpu_acpi_id(unsigned int cpu)
 {
 	return acpi_core_pic[cpu_logical_map(cpu)].processor_id;
 }
diff --git a/arch/riscv/include/asm/acpi.h b/arch/riscv/include/asm/acpi.h
index 6e13695120bc..1d23681b61b5 100644
--- a/arch/riscv/include/asm/acpi.h
+++ b/arch/riscv/include/asm/acpi.h
@@ -61,7 +61,7 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
 
 void acpi_init_rintc_map(void);
 struct acpi_madt_rintc *acpi_cpu_get_madt_rintc(int cpu);
-static inline u32 get_acpi_id_for_cpu(int cpu)
+static inline u32 acpi_get_cpu_acpi_id(int cpu)
 {
 	return acpi_cpu_get_madt_rintc(cpu)->uid;
 }
diff --git a/arch/riscv/kernel/acpi_numa.c b/arch/riscv/kernel/acpi_numa.c
index 130769e3a99c..c2eb4824d0f7 100644
--- a/arch/riscv/kernel/acpi_numa.c
+++ b/arch/riscv/kernel/acpi_numa.c
@@ -40,7 +40,7 @@ static inline int get_cpu_for_acpi_id(u32 uid)
 	int cpu;
 
 	for (cpu = 0; cpu < nr_cpu_ids; cpu++)
-		if (uid == get_acpi_id_for_cpu(cpu))
+		if (uid == acpi_get_cpu_acpi_id(cpu))
 			return cpu;
 
 	return -EINVAL;
diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c
index de5f8c018333..c1a8fba4c2b2 100644
--- a/drivers/acpi/pptt.c
+++ b/drivers/acpi/pptt.c
@@ -459,7 +459,7 @@ static void cache_setup_acpi_cpu(struct acpi_table_header *table,
 {
 	struct acpi_pptt_cache *found_cache;
 	struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
-	u32 acpi_cpu_id = get_acpi_id_for_cpu(cpu);
+	u32 acpi_cpu_id = acpi_get_cpu_acpi_id(cpu);
 	struct cacheinfo *this_leaf;
 	unsigned int index = 0;
 	struct acpi_pptt_processor *cpu_node = NULL;
@@ -546,7 +546,7 @@ static int topology_get_acpi_cpu_tag(struct acpi_table_header *table,
 				     unsigned int cpu, int level, int flag)
 {
 	struct acpi_pptt_processor *cpu_node;
-	u32 acpi_cpu_id = get_acpi_id_for_cpu(cpu);
+	u32 acpi_cpu_id = acpi_get_cpu_acpi_id(cpu);
 
 	cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
 	if (cpu_node) {
@@ -622,7 +622,7 @@ static int find_acpi_cpu_topology_tag(unsigned int cpu, int level, int flag)
 static int check_acpi_cpu_flag(unsigned int cpu, int rev, u32 flag)
 {
 	struct acpi_table_header *table;
-	u32 acpi_cpu_id = get_acpi_id_for_cpu(cpu);
+	u32 acpi_cpu_id = acpi_get_cpu_acpi_id(cpu);
 	struct acpi_pptt_processor *cpu_node = NULL;
 	int ret = -ENOENT;
 
@@ -671,7 +671,7 @@ int acpi_get_cache_info(unsigned int cpu, unsigned int *levels,
 
 	pr_debug("Cache Setup: find cache levels for CPU=%d\n", cpu);
 
-	acpi_cpu_id = get_acpi_id_for_cpu(cpu);
+	acpi_cpu_id = acpi_get_cpu_acpi_id(cpu);
 	cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
 	if (!cpu_node)
 		return -ENOENT;
@@ -797,7 +797,7 @@ int find_acpi_cpu_topology_cluster(unsigned int cpu)
 	if (!table)
 		return -ENOENT;
 
-	acpi_cpu_id = get_acpi_id_for_cpu(cpu);
+	acpi_cpu_id = acpi_get_cpu_acpi_id(cpu);
 	cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
 	if (!cpu_node || !cpu_node->parent)
 		return -ENOENT;
@@ -872,7 +872,7 @@ static void acpi_pptt_get_child_cpus(struct acpi_table_header *table_hdr,
 	cpumask_clear(cpus);
 
 	for_each_possible_cpu(cpu) {
-		acpi_id = get_acpi_id_for_cpu(cpu);
+		acpi_id = acpi_get_cpu_acpi_id(cpu);
 		cpu_node = acpi_find_processor_node(table_hdr, acpi_id);
 
 		while (cpu_node) {
@@ -966,7 +966,7 @@ int find_acpi_cache_level_from_id(u32 cache_id)
 	for_each_possible_cpu(cpu) {
 		bool empty;
 		int level = 1;
-		u32 acpi_cpu_id = get_acpi_id_for_cpu(cpu);
+		u32 acpi_cpu_id = acpi_get_cpu_acpi_id(cpu);
 		struct acpi_pptt_cache *cache;
 		struct acpi_pptt_processor *cpu_node;
 
@@ -1030,7 +1030,7 @@ int acpi_pptt_get_cpumask_from_cache_id(u32 cache_id, cpumask_t *cpus)
 	for_each_possible_cpu(cpu) {
 		bool empty;
 		int level = 1;
-		u32 acpi_cpu_id = get_acpi_id_for_cpu(cpu);
+		u32 acpi_cpu_id = acpi_get_cpu_acpi_id(cpu);
 		struct acpi_pptt_cache *cache;
 		struct acpi_pptt_processor *cpu_node;
 
diff --git a/drivers/acpi/riscv/rhct.c b/drivers/acpi/riscv/rhct.c
index caa2c16e1697..c15ce8c13136 100644
--- a/drivers/acpi/riscv/rhct.c
+++ b/drivers/acpi/riscv/rhct.c
@@ -44,7 +44,7 @@ int acpi_get_riscv_isa(struct acpi_table_header *table, unsigned int cpu, const
 	struct acpi_rhct_isa_string *isa_node;
 	struct acpi_table_rhct *rhct;
 	u32 *hart_info_node_offset;
-	u32 acpi_cpu_id = get_acpi_id_for_cpu(cpu);
+	u32 acpi_cpu_id = acpi_get_cpu_acpi_id(cpu);
 
 	BUG_ON(acpi_disabled);
 
diff --git a/drivers/perf/arm_cspmu/arm_cspmu.c b/drivers/perf/arm_cspmu/arm_cspmu.c
index 34430b68f602..506b661c60fd 100644
--- a/drivers/perf/arm_cspmu/arm_cspmu.c
+++ b/drivers/perf/arm_cspmu/arm_cspmu.c
@@ -1115,7 +1115,7 @@ static int arm_cspmu_acpi_get_cpus(struct arm_cspmu *cspmu)
 	if (affinity_flag == ACPI_APMT_FLAGS_AFFINITY_PROC) {
 		for_each_possible_cpu(cpu) {
 			if (apmt_node->proc_affinity ==
-			    get_acpi_id_for_cpu(cpu)) {
+			    acpi_get_cpu_acpi_id(cpu)) {
 				cpumask_set_cpu(cpu, &cspmu->associated_cpus);
 				break;
 			}
-- 
2.17.1


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

* [PATCH v5 2/2] PCI/TPH: Fix get cpu steer-tag fail on ARM64 platform
  2026-03-10  3:20 [PATCH v5 0/2] Fix get cpu steer-tag fail on ARM64 platform Chengwen Feng
  2026-03-10  3:20 ` [PATCH v5 1/2] ACPI: Rename get_acpi_id_for_cpu() to acpi_get_cpu_acpi_id() on non-x86 Chengwen Feng
@ 2026-03-10  3:20 ` Chengwen Feng
  2026-03-10 15:58   ` Jeremy Linton
  1 sibling, 1 reply; 10+ messages in thread
From: Chengwen Feng @ 2026-03-10  3:20 UTC (permalink / raw)
  To: Bjorn Helgaas, Catalin Marinas, Will Deacon, Rafael J . Wysocki
  Cc: Jonathan Corbet, Shuah Khan, Huacai Chen, WANG Xuerui,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H . Peter Anvin, Juergen Gross, Boris Ostrovsky, Len Brown,
	Sunil V L, Mark Rutland, Chengwen Feng, Jonathan Cameron,
	Kees Cook, Yanteng Si, Sean Christopherson, Kai Huang,
	Tom Lendacky, Thomas Huth, Thorsten Blum, Kevin Loughlin,
	Zheyun Shen, Peter Zijlstra, Pawan Gupta, Xin Li,
	Ahmed S . Darwish, Sohil Mehta, Ilkka Koskinen, Robin Murphy,
	James Clark, Besar Wicaksono, Ma Ke, Ajit Khaparde, Wei Huang,
	Andy Gospodarek, Somnath Kotur, wangzhou1, wanghuiqiang,
	liuyonglong, linux-pci, linux-doc, linux-kernel, linux-arm-kernel,
	loongarch, linux-riscv, xen-devel, linux-acpi, linux-perf-users,
	stable

pcie_tph_get_cpu_st() is broken on ARM64:
1. pcie_tph_get_cpu_st() passes cpu_uid to the PCI ACPI DSM method.
   cpu_uid should be the ACPI Processor UID [1].
2. In BNXT, pcie_tph_get_cpu_st() is passed a cpu_uid obtained via
   cpumask_first(irq->cpu_mask) - the logical CPU ID of a CPU core,
   generated and managed by kernel (e.g., [0,255] for a system  with 256
   logical CPU cores).
3. On ARM64 platforms, ACPI assigns Processor UID to cores listed in the
   MADT table, and this UID may not match the kernel's logical CPU ID.
   When this occurs, the mismatch results in the wrong CPU steer-tag.
4. On AMD x86 the logical CPU ID is identical to the ACPI Processor UID
   so the mismatch is not seen.

Resolution:
1. Implement acpi_get_cpu_acpi_id() for x86, which replaces
   cpu_acpi_id(). All ACPI platforms now have an implementation.
2. Use acpi_get_cpu_acpi_id() in pcie_tph_get_cpu_st() to translate from
   logical CPU ID to ACPI Processor UID needed for the DSM call.
3. Rename pcie_tpu_get_cpu_st() parameter from cpu_uid to cpu to
   reflect that it is a logical CPU_ID.

[1] According to ECN_TPH-ST_Revision_20200924
    (https://members.pcisig.com/wg/PCI-SIG/document/15470), the input
    is defined as: "If the target is a processor, then this field
    represents the ACPI Processor UID of the processor as specified in
    the MADT. If the target is a processor container, then this field
    represents the ACPI Processor UID of the processor container as
    specified in the PPTT."

Fixes: d2e8a34876ce ("PCI/TPH: Add Steering Tag support")
Cc: stable@vger.kernel.org
Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
---
 Documentation/PCI/tph.rst    |  4 ++--
 arch/x86/include/asm/acpi.h  |  2 ++
 arch/x86/include/asm/cpu.h   |  1 -
 arch/x86/include/asm/smp.h   |  1 -
 arch/x86/kernel/cpu/common.c | 12 ++++++++++++
 arch/x86/xen/enlighten_hvm.c |  4 ++--
 drivers/pci/tph.c            | 11 ++++++-----
 include/linux/pci-tph.h      |  4 ++--
 8 files changed, 26 insertions(+), 13 deletions(-)

diff --git a/Documentation/PCI/tph.rst b/Documentation/PCI/tph.rst
index e8993be64fd6..b6cf22b9bd90 100644
--- a/Documentation/PCI/tph.rst
+++ b/Documentation/PCI/tph.rst
@@ -79,10 +79,10 @@ To retrieve a Steering Tag for a target memory associated with a specific
 CPU, use the following function::
 
   int pcie_tph_get_cpu_st(struct pci_dev *pdev, enum tph_mem_type type,
-                          unsigned int cpu_uid, u16 *tag);
+                          unsigned int cpu, u16 *tag);
 
 The `type` argument is used to specify the memory type, either volatile
-or persistent, of the target memory. The `cpu_uid` argument specifies the
+or persistent, of the target memory. The `cpu` argument specifies the
 CPU where the memory is associated to.
 
 After the ST value is retrieved, the device driver can use the following
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h
index a03aa6f999d1..b968369715c1 100644
--- a/arch/x86/include/asm/acpi.h
+++ b/arch/x86/include/asm/acpi.h
@@ -157,6 +157,8 @@ static inline bool acpi_has_cpu_in_madt(void)
 	return !!acpi_lapic;
 }
 
+u32 acpi_get_cpu_acpi_id(unsigned int cpu);
+
 #define ACPI_HAVE_ARCH_SET_ROOT_POINTER
 static __always_inline void acpi_arch_set_root_pointer(u64 addr)
 {
diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
index ad235dda1ded..57a0786dfd75 100644
--- a/arch/x86/include/asm/cpu.h
+++ b/arch/x86/include/asm/cpu.h
@@ -11,7 +11,6 @@
 
 #ifndef CONFIG_SMP
 #define cpu_physical_id(cpu)			boot_cpu_physical_apicid
-#define cpu_acpi_id(cpu)			0
 #endif /* CONFIG_SMP */
 
 #ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
index 84951572ab81..05d1d479b4cf 100644
--- a/arch/x86/include/asm/smp.h
+++ b/arch/x86/include/asm/smp.h
@@ -130,7 +130,6 @@ __visible void smp_call_function_interrupt(struct pt_regs *regs);
 __visible void smp_call_function_single_interrupt(struct pt_regs *r);
 
 #define cpu_physical_id(cpu)	per_cpu(x86_cpu_to_apicid, cpu)
-#define cpu_acpi_id(cpu)	per_cpu(x86_cpu_to_acpiid, cpu)
 
 /*
  * This function is needed by all SMP systems. It must _always_ be valid
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 1c3261cae40c..93f4f3283c81 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -29,6 +29,7 @@
 #include <linux/utsname.h>
 #include <linux/efi.h>
 
+#include <asm/acpi.h>
 #include <asm/alternative.h>
 #include <asm/cmdline.h>
 #include <asm/cpuid/api.h>
@@ -57,6 +58,7 @@
 #include <asm/asm.h>
 #include <asm/bugs.h>
 #include <asm/cpu.h>
+#include <asm/smp.h>
 #include <asm/mce.h>
 #include <asm/msr.h>
 #include <asm/cacheinfo.h>
@@ -2643,3 +2645,13 @@ void __init arch_cpu_finalize_init(void)
 	 */
 	mem_encrypt_init();
 }
+
+u32 acpi_get_cpu_acpi_id(unsigned int cpu)
+{
+#ifndef CONFIG_SMP
+	return 0;
+#else
+	return per_cpu(x86_cpu_to_acpiid, cpu);
+#endif
+}
+EXPORT_SYMBOL_GPL(acpi_get_cpu_acpi_id);
diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c
index fe57ff85d004..0a5cde7865b2 100644
--- a/arch/x86/xen/enlighten_hvm.c
+++ b/arch/x86/xen/enlighten_hvm.c
@@ -161,8 +161,8 @@ static int xen_cpu_up_prepare_hvm(unsigned int cpu)
 	 */
 	xen_uninit_lock_cpu(cpu);
 
-	if (cpu_acpi_id(cpu) != CPU_ACPIID_INVALID)
-		per_cpu(xen_vcpu_id, cpu) = cpu_acpi_id(cpu);
+	if (acpi_get_cpu_acpi_id(cpu) != CPU_ACPIID_INVALID)
+		per_cpu(xen_vcpu_id, cpu) = acpi_get_cpu_acpi_id(cpu);
 	else
 		per_cpu(xen_vcpu_id, cpu) = cpu;
 	xen_vcpu_setup(cpu);
diff --git a/drivers/pci/tph.c b/drivers/pci/tph.c
index ca4f97be7538..c1bd60637b5a 100644
--- a/drivers/pci/tph.c
+++ b/drivers/pci/tph.c
@@ -236,18 +236,19 @@ static int write_tag_to_st_table(struct pci_dev *pdev, int index, u16 tag)
  * with a specific CPU
  * @pdev: PCI device
  * @mem_type: target memory type (volatile or persistent RAM)
- * @cpu_uid: associated CPU id
+ * @cpu: associated CPU id
  * @tag: Steering Tag to be returned
  *
  * Return the Steering Tag for a target memory that is associated with a
- * specific CPU as indicated by cpu_uid.
+ * specific CPU as indicated by cpu.
  *
  * Return: 0 if success, otherwise negative value (-errno)
  */
 int pcie_tph_get_cpu_st(struct pci_dev *pdev, enum tph_mem_type mem_type,
-			unsigned int cpu_uid, u16 *tag)
+			unsigned int cpu, u16 *tag)
 {
 #ifdef CONFIG_ACPI
+	u32 cpu_uid = acpi_get_cpu_acpi_id(cpu);
 	struct pci_dev *rp;
 	acpi_handle rp_acpi_handle;
 	union st_info info;
@@ -265,9 +266,9 @@ int pcie_tph_get_cpu_st(struct pci_dev *pdev, enum tph_mem_type mem_type,
 
 	*tag = tph_extract_tag(mem_type, pdev->tph_req_type, &info);
 
-	pci_dbg(pdev, "get steering tag: mem_type=%s, cpu_uid=%d, tag=%#04x\n",
+	pci_dbg(pdev, "get steering tag: mem_type=%s, cpu=%d, tag=%#04x\n",
 		(mem_type == TPH_MEM_TYPE_VM) ? "volatile" : "persistent",
-		cpu_uid, *tag);
+		cpu, *tag);
 
 	return 0;
 #else
diff --git a/include/linux/pci-tph.h b/include/linux/pci-tph.h
index ba28140ce670..be68cd17f2f8 100644
--- a/include/linux/pci-tph.h
+++ b/include/linux/pci-tph.h
@@ -25,7 +25,7 @@ int pcie_tph_set_st_entry(struct pci_dev *pdev,
 			  unsigned int index, u16 tag);
 int pcie_tph_get_cpu_st(struct pci_dev *dev,
 			enum tph_mem_type mem_type,
-			unsigned int cpu_uid, u16 *tag);
+			unsigned int cpu, u16 *tag);
 void pcie_disable_tph(struct pci_dev *pdev);
 int pcie_enable_tph(struct pci_dev *pdev, int mode);
 u16 pcie_tph_get_st_table_size(struct pci_dev *pdev);
@@ -36,7 +36,7 @@ static inline int pcie_tph_set_st_entry(struct pci_dev *pdev,
 { return -EINVAL; }
 static inline int pcie_tph_get_cpu_st(struct pci_dev *dev,
 				      enum tph_mem_type mem_type,
-				      unsigned int cpu_uid, u16 *tag)
+				      unsigned int cpu, u16 *tag)
 { return -EINVAL; }
 static inline void pcie_disable_tph(struct pci_dev *pdev) { }
 static inline int pcie_enable_tph(struct pci_dev *pdev, int mode)
-- 
2.17.1


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

* Re: [PATCH v5 2/2] PCI/TPH: Fix get cpu steer-tag fail on ARM64 platform
  2026-03-10  3:20 ` [PATCH v5 2/2] PCI/TPH: Fix get cpu steer-tag fail on ARM64 platform Chengwen Feng
@ 2026-03-10 15:58   ` Jeremy Linton
  2026-03-10 22:09     ` Bjorn Helgaas
  0 siblings, 1 reply; 10+ messages in thread
From: Jeremy Linton @ 2026-03-10 15:58 UTC (permalink / raw)
  To: Chengwen Feng, Bjorn Helgaas, Catalin Marinas, Will Deacon,
	Rafael J . Wysocki
  Cc: Jonathan Corbet, Shuah Khan, Huacai Chen, WANG Xuerui,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H . Peter Anvin, Juergen Gross, Boris Ostrovsky, Len Brown,
	Sunil V L, Mark Rutland, Jonathan Cameron, Kees Cook, Yanteng Si,
	Sean Christopherson, Kai Huang, Tom Lendacky, Thomas Huth,
	Thorsten Blum, Kevin Loughlin, Zheyun Shen, Peter Zijlstra,
	Pawan Gupta, Xin Li, Ahmed S . Darwish, Sohil Mehta,
	Ilkka Koskinen, Robin Murphy, James Clark, Besar Wicaksono, Ma Ke,
	Ajit Khaparde, Wei Huang, Andy Gospodarek, Somnath Kotur,
	wangzhou1, wanghuiqiang, liuyonglong, linux-pci, linux-doc,
	linux-kernel, linux-arm-kernel, loongarch, linux-riscv, xen-devel,
	linux-acpi, linux-perf-users, stable, Wathsala Vithanage

Hi,

+Wathsala who has been looking at TPH too.

On 3/9/26 10:20 PM, Chengwen Feng wrote:
> pcie_tph_get_cpu_st() is broken on ARM64:
> 1. pcie_tph_get_cpu_st() passes cpu_uid to the PCI ACPI DSM method.
>     cpu_uid should be the ACPI Processor UID [1].
> 2. In BNXT, pcie_tph_get_cpu_st() is passed a cpu_uid obtained via
>     cpumask_first(irq->cpu_mask) - the logical CPU ID of a CPU core,
>     generated and managed by kernel (e.g., [0,255] for a system  with 256
>     logical CPU cores).
> 3. On ARM64 platforms, ACPI assigns Processor UID to cores listed in the
>     MADT table, and this UID may not match the kernel's logical CPU ID.
>     When this occurs, the mismatch results in the wrong CPU steer-tag.
> 4. On AMD x86 the logical CPU ID is identical to the ACPI Processor UID
>     so the mismatch is not seen.
> 
> Resolution:
> 1. Implement acpi_get_cpu_acpi_id() for x86, which replaces
>     cpu_acpi_id(). All ACPI platforms now have an implementation.
> 2. Use acpi_get_cpu_acpi_id() in pcie_tph_get_cpu_st() to translate from
>     logical CPU ID to ACPI Processor UID needed for the DSM call.
> 3. Rename pcie_tpu_get_cpu_st() parameter from cpu_uid to cpu to
>     reflect that it is a logical CPU_ID.
> 
> [1] According to ECN_TPH-ST_Revision_20200924
>      (https://members.pcisig.com/wg/PCI-SIG/document/15470), the input
>      is defined as: "If the target is a processor, then this field
>      represents the ACPI Processor UID of the processor as specified in
>      the MADT. If the target is a processor container, then this field
>      represents the ACPI Processor UID of the processor container as
>      specified in the PPTT."

The bit about "processor containers" is not supported by linux yet, and 
is potentially a problem worth considering.

The original rename comments from the previous patch versions are on 
point, but since they have grown large, i'm going to suggest the x86 
rename/shuffle here is also in its own patch seperate from the TPH 
specific changes like the arm ones now are.

Thanks for looking after this.

> 
> Fixes: d2e8a34876ce ("PCI/TPH: Add Steering Tag support")
> Cc: stable@vger.kernel.org
> Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
> ---
>   Documentation/PCI/tph.rst    |  4 ++--
>   arch/x86/include/asm/acpi.h  |  2 ++
>   arch/x86/include/asm/cpu.h   |  1 -
>   arch/x86/include/asm/smp.h   |  1 -
>   arch/x86/kernel/cpu/common.c | 12 ++++++++++++
>   arch/x86/xen/enlighten_hvm.c |  4 ++--
>   drivers/pci/tph.c            | 11 ++++++-----
>   include/linux/pci-tph.h      |  4 ++--
>   8 files changed, 26 insertions(+), 13 deletions(-)
> 
> diff --git a/Documentation/PCI/tph.rst b/Documentation/PCI/tph.rst
> index e8993be64fd6..b6cf22b9bd90 100644
> --- a/Documentation/PCI/tph.rst
> +++ b/Documentation/PCI/tph.rst
> @@ -79,10 +79,10 @@ To retrieve a Steering Tag for a target memory associated with a specific
>   CPU, use the following function::
>   
>     int pcie_tph_get_cpu_st(struct pci_dev *pdev, enum tph_mem_type type,
> -                          unsigned int cpu_uid, u16 *tag);
> +                          unsigned int cpu, u16 *tag);
>   
>   The `type` argument is used to specify the memory type, either volatile
> -or persistent, of the target memory. The `cpu_uid` argument specifies the
> +or persistent, of the target memory. The `cpu` argument specifies the
>   CPU where the memory is associated to.
>   
>   After the ST value is retrieved, the device driver can use the following
> diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h
> index a03aa6f999d1..b968369715c1 100644
> --- a/arch/x86/include/asm/acpi.h
> +++ b/arch/x86/include/asm/acpi.h
> @@ -157,6 +157,8 @@ static inline bool acpi_has_cpu_in_madt(void)
>   	return !!acpi_lapic;
>   }
>   
> +u32 acpi_get_cpu_acpi_id(unsigned int cpu);
> +
>   #define ACPI_HAVE_ARCH_SET_ROOT_POINTER
>   static __always_inline void acpi_arch_set_root_pointer(u64 addr)
>   {
> diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
> index ad235dda1ded..57a0786dfd75 100644
> --- a/arch/x86/include/asm/cpu.h
> +++ b/arch/x86/include/asm/cpu.h
> @@ -11,7 +11,6 @@
>   
>   #ifndef CONFIG_SMP
>   #define cpu_physical_id(cpu)			boot_cpu_physical_apicid
> -#define cpu_acpi_id(cpu)			0
>   #endif /* CONFIG_SMP */
>   
>   #ifdef CONFIG_HOTPLUG_CPU
> diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
> index 84951572ab81..05d1d479b4cf 100644
> --- a/arch/x86/include/asm/smp.h
> +++ b/arch/x86/include/asm/smp.h
> @@ -130,7 +130,6 @@ __visible void smp_call_function_interrupt(struct pt_regs *regs);
>   __visible void smp_call_function_single_interrupt(struct pt_regs *r);
>   
>   #define cpu_physical_id(cpu)	per_cpu(x86_cpu_to_apicid, cpu)
> -#define cpu_acpi_id(cpu)	per_cpu(x86_cpu_to_acpiid, cpu)
>   
>   /*
>    * This function is needed by all SMP systems. It must _always_ be valid
> diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
> index 1c3261cae40c..93f4f3283c81 100644
> --- a/arch/x86/kernel/cpu/common.c
> +++ b/arch/x86/kernel/cpu/common.c
> @@ -29,6 +29,7 @@
>   #include <linux/utsname.h>
>   #include <linux/efi.h>
>   
> +#include <asm/acpi.h>
>   #include <asm/alternative.h>
>   #include <asm/cmdline.h>
>   #include <asm/cpuid/api.h>
> @@ -57,6 +58,7 @@
>   #include <asm/asm.h>
>   #include <asm/bugs.h>
>   #include <asm/cpu.h>
> +#include <asm/smp.h>
>   #include <asm/mce.h>
>   #include <asm/msr.h>
>   #include <asm/cacheinfo.h>
> @@ -2643,3 +2645,13 @@ void __init arch_cpu_finalize_init(void)
>   	 */
>   	mem_encrypt_init();
>   }
> +
> +u32 acpi_get_cpu_acpi_id(unsigned int cpu)
> +{
> +#ifndef CONFIG_SMP
> +	return 0;
> +#else
> +	return per_cpu(x86_cpu_to_acpiid, cpu);
> +#endif
> +}
> +EXPORT_SYMBOL_GPL(acpi_get_cpu_acpi_id);
> diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c
> index fe57ff85d004..0a5cde7865b2 100644
> --- a/arch/x86/xen/enlighten_hvm.c
> +++ b/arch/x86/xen/enlighten_hvm.c
> @@ -161,8 +161,8 @@ static int xen_cpu_up_prepare_hvm(unsigned int cpu)
>   	 */
>   	xen_uninit_lock_cpu(cpu);
>   
> -	if (cpu_acpi_id(cpu) != CPU_ACPIID_INVALID)
> -		per_cpu(xen_vcpu_id, cpu) = cpu_acpi_id(cpu);
> +	if (acpi_get_cpu_acpi_id(cpu) != CPU_ACPIID_INVALID)
> +		per_cpu(xen_vcpu_id, cpu) = acpi_get_cpu_acpi_id(cpu);
>   	else
>   		per_cpu(xen_vcpu_id, cpu) = cpu;
>   	xen_vcpu_setup(cpu);
> diff --git a/drivers/pci/tph.c b/drivers/pci/tph.c
> index ca4f97be7538..c1bd60637b5a 100644
> --- a/drivers/pci/tph.c
> +++ b/drivers/pci/tph.c
> @@ -236,18 +236,19 @@ static int write_tag_to_st_table(struct pci_dev *pdev, int index, u16 tag)
>    * with a specific CPU
>    * @pdev: PCI device
>    * @mem_type: target memory type (volatile or persistent RAM)
> - * @cpu_uid: associated CPU id
> + * @cpu: associated CPU id
>    * @tag: Steering Tag to be returned
>    *
>    * Return the Steering Tag for a target memory that is associated with a
> - * specific CPU as indicated by cpu_uid.
> + * specific CPU as indicated by cpu.
>    *
>    * Return: 0 if success, otherwise negative value (-errno)
>    */
>   int pcie_tph_get_cpu_st(struct pci_dev *pdev, enum tph_mem_type mem_type,
> -			unsigned int cpu_uid, u16 *tag)
> +			unsigned int cpu, u16 *tag)
>   {
>   #ifdef CONFIG_ACPI
> +	u32 cpu_uid = acpi_get_cpu_acpi_id(cpu);
>   	struct pci_dev *rp;
>   	acpi_handle rp_acpi_handle;
>   	union st_info info;
> @@ -265,9 +266,9 @@ int pcie_tph_get_cpu_st(struct pci_dev *pdev, enum tph_mem_type mem_type,
>   
>   	*tag = tph_extract_tag(mem_type, pdev->tph_req_type, &info);
>   
> -	pci_dbg(pdev, "get steering tag: mem_type=%s, cpu_uid=%d, tag=%#04x\n",
> +	pci_dbg(pdev, "get steering tag: mem_type=%s, cpu=%d, tag=%#04x\n",
>   		(mem_type == TPH_MEM_TYPE_VM) ? "volatile" : "persistent",
> -		cpu_uid, *tag);
> +		cpu, *tag);
>   
>   	return 0;
>   #else
> diff --git a/include/linux/pci-tph.h b/include/linux/pci-tph.h
> index ba28140ce670..be68cd17f2f8 100644
> --- a/include/linux/pci-tph.h
> +++ b/include/linux/pci-tph.h
> @@ -25,7 +25,7 @@ int pcie_tph_set_st_entry(struct pci_dev *pdev,
>   			  unsigned int index, u16 tag);
>   int pcie_tph_get_cpu_st(struct pci_dev *dev,
>   			enum tph_mem_type mem_type,
> -			unsigned int cpu_uid, u16 *tag);
> +			unsigned int cpu, u16 *tag);
>   void pcie_disable_tph(struct pci_dev *pdev);
>   int pcie_enable_tph(struct pci_dev *pdev, int mode);
>   u16 pcie_tph_get_st_table_size(struct pci_dev *pdev);
> @@ -36,7 +36,7 @@ static inline int pcie_tph_set_st_entry(struct pci_dev *pdev,
>   { return -EINVAL; }
>   static inline int pcie_tph_get_cpu_st(struct pci_dev *dev,
>   				      enum tph_mem_type mem_type,
> -				      unsigned int cpu_uid, u16 *tag)
> +				      unsigned int cpu, u16 *tag)
>   { return -EINVAL; }
>   static inline void pcie_disable_tph(struct pci_dev *pdev) { }
>   static inline int pcie_enable_tph(struct pci_dev *pdev, int mode)


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

* Re: [PATCH v5 1/2] ACPI: Rename get_acpi_id_for_cpu() to acpi_get_cpu_acpi_id() on non-x86
  2026-03-10  3:20 ` [PATCH v5 1/2] ACPI: Rename get_acpi_id_for_cpu() to acpi_get_cpu_acpi_id() on non-x86 Chengwen Feng
@ 2026-03-10 17:53   ` Bjorn Helgaas
  2026-03-10 22:39     ` Andrew Cooper
  2026-03-11  2:57     ` fengchengwen
  0 siblings, 2 replies; 10+ messages in thread
From: Bjorn Helgaas @ 2026-03-10 17:53 UTC (permalink / raw)
  To: Chengwen Feng
  Cc: Bjorn Helgaas, Catalin Marinas, Will Deacon, Rafael J . Wysocki,
	Jonathan Corbet, Shuah Khan, Huacai Chen, WANG Xuerui,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H . Peter Anvin, Juergen Gross, Boris Ostrovsky, Len Brown,
	Sunil V L, Mark Rutland, Jonathan Cameron, Kees Cook, Yanteng Si,
	Sean Christopherson, Kai Huang, Tom Lendacky, Thomas Huth,
	Thorsten Blum, Kevin Loughlin, Zheyun Shen, Peter Zijlstra,
	Pawan Gupta, Xin Li, Ahmed S . Darwish, Sohil Mehta,
	Ilkka Koskinen, Robin Murphy, James Clark, Besar Wicaksono, Ma Ke,
	Ajit Khaparde, Wei Huang, Andy Gospodarek, Somnath Kotur,
	wangzhou1, wanghuiqiang, liuyonglong, linux-pci, linux-doc,
	linux-kernel, linux-arm-kernel, loongarch, linux-riscv, xen-devel,
	linux-acpi, linux-perf-users, stable

On Tue, Mar 10, 2026 at 11:20:48AM +0800, Chengwen Feng wrote:
> To unify the CPU ACPI ID retrieval interface across architectures,
> rename the existing get_acpi_id_for_cpu() function to
> acpi_get_cpu_acpi_id() on arm64/riscv/loongarch platforms.
> 
> This is a pure rename with no functional change, preparing for a
> consistent ACPI Processor UID retrieval interface across all ACPI-enabled
> platforms.

Really a question for the ACPI folks, but my preferences would be:

  - Simpler name for the interface, e.g., "acpi_get_cpu_id()"

  - Single prototype in generic header, e.g., include/linux/acpi.h

  - Split the x86 part to a separate patch and maybe (a tangent, but
    looks dubious to me) figure out whether/why xen needs xen_vcpu_id
    to be ACPI CPU IDs

> Cc: stable@vger.kernel.org
> Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
> ---
>  arch/arm64/include/asm/acpi.h      |  4 ++--
>  arch/loongarch/include/asm/acpi.h  |  2 +-
>  arch/riscv/include/asm/acpi.h      |  2 +-
>  arch/riscv/kernel/acpi_numa.c      |  2 +-
>  drivers/acpi/pptt.c                | 16 ++++++++--------
>  drivers/acpi/riscv/rhct.c          |  2 +-
>  drivers/perf/arm_cspmu/arm_cspmu.c |  2 +-
>  7 files changed, 15 insertions(+), 15 deletions(-)

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

* Re: [PATCH v5 2/2] PCI/TPH: Fix get cpu steer-tag fail on ARM64 platform
  2026-03-10 15:58   ` Jeremy Linton
@ 2026-03-10 22:09     ` Bjorn Helgaas
  2026-03-11  3:00       ` fengchengwen
  0 siblings, 1 reply; 10+ messages in thread
From: Bjorn Helgaas @ 2026-03-10 22:09 UTC (permalink / raw)
  To: Jeremy Linton
  Cc: Chengwen Feng, Bjorn Helgaas, Catalin Marinas, Will Deacon,
	Rafael J . Wysocki, Jonathan Corbet, Shuah Khan, Huacai Chen,
	WANG Xuerui, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, x86, H . Peter Anvin, Juergen Gross, Boris Ostrovsky,
	Len Brown, Sunil V L, Mark Rutland, Jonathan Cameron, Kees Cook,
	Yanteng Si, Sean Christopherson, Kai Huang, Tom Lendacky,
	Thomas Huth, Thorsten Blum, Kevin Loughlin, Zheyun Shen,
	Peter Zijlstra, Pawan Gupta, Xin Li, Ahmed S . Darwish,
	Sohil Mehta, Ilkka Koskinen, Robin Murphy, James Clark,
	Besar Wicaksono, Ma Ke, Ajit Khaparde, Wei Huang, Andy Gospodarek,
	Somnath Kotur, wangzhou1, wanghuiqiang, liuyonglong, linux-pci,
	linux-doc, linux-kernel, linux-arm-kernel, loongarch, linux-riscv,
	xen-devel, linux-acpi, linux-perf-users, stable,
	Wathsala Vithanage

On Tue, Mar 10, 2026 at 10:58:49AM -0500, Jeremy Linton wrote:
> On 3/9/26 10:20 PM, Chengwen Feng wrote:
> > pcie_tph_get_cpu_st() is broken on ARM64:
> > 1. pcie_tph_get_cpu_st() passes cpu_uid to the PCI ACPI DSM method.
> >     cpu_uid should be the ACPI Processor UID [1].
> > 2. In BNXT, pcie_tph_get_cpu_st() is passed a cpu_uid obtained via
> >     cpumask_first(irq->cpu_mask) - the logical CPU ID of a CPU core,
> >     generated and managed by kernel (e.g., [0,255] for a system  with 256
> >     logical CPU cores).
> > 3. On ARM64 platforms, ACPI assigns Processor UID to cores listed in the
> >     MADT table, and this UID may not match the kernel's logical CPU ID.
> >     When this occurs, the mismatch results in the wrong CPU steer-tag.
> > 4. On AMD x86 the logical CPU ID is identical to the ACPI Processor UID
> >     so the mismatch is not seen.

> >   int pcie_tph_get_cpu_st(struct pci_dev *pdev, enum tph_mem_type mem_type,
> > -			unsigned int cpu_uid, u16 *tag)
> > +			unsigned int cpu, u16 *tag)
> >   {
> >   #ifdef CONFIG_ACPI
> > +	u32 cpu_uid = acpi_get_cpu_acpi_id(cpu);

From AI review (gemini/gemini-3.1-pro-preview):

  Does this code need to validate that `cpu` is within bounds before
  using it?  Before this change, the `cpu_uid` parameter was passed
  opaquely to the ACPI firmware via `tph_invoke_dsm()`, which would
  gracefully handle invalid values.

  Now, `cpu` is treated as a logical CPU index and passed to
  `acpi_get_cpu_acpi_id(cpu)`. On architectures like arm64 and riscv,
  `acpi_get_cpu_acpi_id()` uses `cpu` directly as an array index
  (`&cpu_madt_gicc[cpu]` and `&cpu_madt_rintc[cpu]`). On x86, it uses
  `per_cpu(x86_cpu_to_acpiid, cpu)`.

  If a caller passes an out-of-bounds `cpu` index (for example, if an
  IRQ affinity mask is empty and `cpumask_first()` returns
  `nr_cpu_ids`, or if userspace passes an arbitrary ID via
  `mlx5_st_alloc_index()`), this will result in an out-of-bounds
  memory read.

  Consider adding a bounds check:

    if (cpu >= nr_cpu_ids)
      return -EINVAL;

I agree that this is an issue, and I think implementations of
acpi_get_cpu_acpi_id() should validate their inputs.

I don't know if there's a value that can never be a valid ACPI CPU UID
and could be used as an error value from acpi_get_cpu_acpi_id().  I do
see a few mentions of a ~0 value meaning "all processors" (ACPI r6.6,
sec 5.2.12.13).  

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

* Re: [PATCH v5 1/2] ACPI: Rename get_acpi_id_for_cpu() to acpi_get_cpu_acpi_id() on non-x86
  2026-03-10 17:53   ` Bjorn Helgaas
@ 2026-03-10 22:39     ` Andrew Cooper
  2026-03-11  2:57     ` fengchengwen
  1 sibling, 0 replies; 10+ messages in thread
From: Andrew Cooper @ 2026-03-10 22:39 UTC (permalink / raw)
  To: Bjorn Helgaas, Chengwen Feng
  Cc: Andrew Cooper, Bjorn Helgaas, Catalin Marinas, Will Deacon,
	Rafael J . Wysocki, Jonathan Corbet, Shuah Khan, Huacai Chen,
	WANG Xuerui, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, x86, H . Peter Anvin, Juergen Gross, Boris Ostrovsky,
	Len Brown, Sunil V L, Mark Rutland, Jonathan Cameron, Kees Cook,
	Yanteng Si, Sean Christopherson, Kai Huang, Tom Lendacky,
	Thomas Huth, Thorsten Blum, Kevin Loughlin, Zheyun Shen,
	Peter Zijlstra, Pawan Gupta, Xin Li, Ahmed S . Darwish,
	Sohil Mehta, Ilkka Koskinen, Robin Murphy, James Clark,
	Besar Wicaksono, Ma Ke, Ajit Khaparde, Wei Huang, Andy Gospodarek,
	Somnath Kotur, wangzhou1, wanghuiqiang, liuyonglong, linux-pci,
	linux-doc, linux-kernel, linux-arm-kernel, loongarch, linux-riscv,
	xen-devel, linux-acpi, linux-perf-users, stable

On 10/03/2026 5:53 pm, Bjorn Helgaas wrote:
>   - Split the x86 part to a separate patch and maybe (a tangent, but
>     looks dubious to me) figure out whether/why xen needs xen_vcpu_id
>     to be ACPI CPU IDs

This is an unfortunate mess made decades ago with no good solution. 
It's to do with how Xen and dom0 share responsibility for the system.

Xen PV dom0 (only, but still widely in use; ring-deprivileging and
predates hardware virt) is OSPM for the whole system, seeing the real
ACPI tables but with a number of vCPUs generally less than the whole system.

This causes Linux to have a split idea of what CPUs are, held together
by hope and duct tape.

Xen PVH dom0 (hardware virt) is OSPM, but has an MADT matching it's vCPU
layout.  It still sees the system DSDT/etc, so while this is better from
Linux's point of view, it's still not great.

Regular unprivileged VMs get a fully coherent set of CPUID + ACPI tables.

~Andrew

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

* Re: [PATCH v5 1/2] ACPI: Rename get_acpi_id_for_cpu() to acpi_get_cpu_acpi_id() on non-x86
  2026-03-10 17:53   ` Bjorn Helgaas
  2026-03-10 22:39     ` Andrew Cooper
@ 2026-03-11  2:57     ` fengchengwen
  1 sibling, 0 replies; 10+ messages in thread
From: fengchengwen @ 2026-03-11  2:57 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Bjorn Helgaas, Catalin Marinas, Will Deacon, Rafael J . Wysocki,
	Jonathan Corbet, Shuah Khan, Huacai Chen, WANG Xuerui,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H . Peter Anvin, Juergen Gross, Boris Ostrovsky, Len Brown,
	Sunil V L, Mark Rutland, Jonathan Cameron, Kees Cook, Yanteng Si,
	Sean Christopherson, Kai Huang, Tom Lendacky, Thomas Huth,
	Thorsten Blum, Kevin Loughlin, Zheyun Shen, Peter Zijlstra,
	Pawan Gupta, Xin Li, Ahmed S . Darwish, Sohil Mehta,
	Ilkka Koskinen, Robin Murphy, James Clark, Besar Wicaksono, Ma Ke,
	Ajit Khaparde, Wei Huang, Andy Gospodarek, Somnath Kotur,
	wangzhou1, wanghuiqiang, liuyonglong, linux-pci, linux-doc,
	linux-kernel, linux-arm-kernel, loongarch, linux-riscv, xen-devel,
	linux-acpi, linux-perf-users, stable

On 3/11/2026 1:53 AM, Bjorn Helgaas wrote:
> On Tue, Mar 10, 2026 at 11:20:48AM +0800, Chengwen Feng wrote:
>> To unify the CPU ACPI ID retrieval interface across architectures,
>> rename the existing get_acpi_id_for_cpu() function to
>> acpi_get_cpu_acpi_id() on arm64/riscv/loongarch platforms.
>>
>> This is a pure rename with no functional change, preparing for a
>> consistent ACPI Processor UID retrieval interface across all ACPI-enabled
>> platforms.
> 
> Really a question for the ACPI folks, but my preferences would be:
> 
>   - Simpler name for the interface, e.g., "acpi_get_cpu_id()"

OK, and how about add u-, like: acpi_get_cpu_uid()

> 
>   - Single prototype in generic header, e.g., include/linux/acpi.h

OK

> 
>   - Split the x86 part to a separate patch and maybe (a tangent, but
>     looks dubious to me) figure out whether/why xen needs xen_vcpu_id
>     to be ACPI CPU IDs

OK for a separate patch for x86.

Btw: the x86 implementation in 2/2 commit may has problem, please see the reply in 2/2 for detail.

> 
>> Cc: stable@vger.kernel.org
>> Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
>> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
>> ---
>>  arch/arm64/include/asm/acpi.h      |  4 ++--
>>  arch/loongarch/include/asm/acpi.h  |  2 +-
>>  arch/riscv/include/asm/acpi.h      |  2 +-
>>  arch/riscv/kernel/acpi_numa.c      |  2 +-
>>  drivers/acpi/pptt.c                | 16 ++++++++--------
>>  drivers/acpi/riscv/rhct.c          |  2 +-
>>  drivers/perf/arm_cspmu/arm_cspmu.c |  2 +-
>>  7 files changed, 15 insertions(+), 15 deletions(-)
> 


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

* Re: [PATCH v5 2/2] PCI/TPH: Fix get cpu steer-tag fail on ARM64 platform
  2026-03-10 22:09     ` Bjorn Helgaas
@ 2026-03-11  3:00       ` fengchengwen
  2026-03-11 17:02         ` Bjorn Helgaas
  0 siblings, 1 reply; 10+ messages in thread
From: fengchengwen @ 2026-03-11  3:00 UTC (permalink / raw)
  To: Bjorn Helgaas, Jeremy Linton
  Cc: Bjorn Helgaas, Catalin Marinas, Will Deacon, Rafael J . Wysocki,
	Jonathan Corbet, Shuah Khan, Huacai Chen, WANG Xuerui,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H . Peter Anvin, Juergen Gross, Boris Ostrovsky, Len Brown,
	Sunil V L, Mark Rutland, Jonathan Cameron, Kees Cook, Yanteng Si,
	Sean Christopherson, Kai Huang, Tom Lendacky, Thomas Huth,
	Thorsten Blum, Kevin Loughlin, Zheyun Shen, Peter Zijlstra,
	Pawan Gupta, Xin Li, Ahmed S . Darwish, Sohil Mehta,
	Ilkka Koskinen, Robin Murphy, James Clark, Besar Wicaksono, Ma Ke,
	Ajit Khaparde, Wei Huang, Andy Gospodarek, Somnath Kotur,
	wangzhou1, wanghuiqiang, liuyonglong, linux-pci, linux-doc,
	linux-kernel, linux-arm-kernel, loongarch, linux-riscv, xen-devel,
	linux-acpi, linux-perf-users, stable, Wathsala Vithanage

On 3/11/2026 6:09 AM, Bjorn Helgaas wrote:
> On Tue, Mar 10, 2026 at 10:58:49AM -0500, Jeremy Linton wrote:
>> On 3/9/26 10:20 PM, Chengwen Feng wrote:
>>> pcie_tph_get_cpu_st() is broken on ARM64:
>>> 1. pcie_tph_get_cpu_st() passes cpu_uid to the PCI ACPI DSM method.
>>>     cpu_uid should be the ACPI Processor UID [1].
>>> 2. In BNXT, pcie_tph_get_cpu_st() is passed a cpu_uid obtained via
>>>     cpumask_first(irq->cpu_mask) - the logical CPU ID of a CPU core,
>>>     generated and managed by kernel (e.g., [0,255] for a system  with 256
>>>     logical CPU cores).
>>> 3. On ARM64 platforms, ACPI assigns Processor UID to cores listed in the
>>>     MADT table, and this UID may not match the kernel's logical CPU ID.
>>>     When this occurs, the mismatch results in the wrong CPU steer-tag.
>>> 4. On AMD x86 the logical CPU ID is identical to the ACPI Processor UID
>>>     so the mismatch is not seen.
> 
>>>   int pcie_tph_get_cpu_st(struct pci_dev *pdev, enum tph_mem_type mem_type,
>>> -			unsigned int cpu_uid, u16 *tag)
>>> +			unsigned int cpu, u16 *tag)
>>>   {
>>>   #ifdef CONFIG_ACPI
>>> +	u32 cpu_uid = acpi_get_cpu_acpi_id(cpu);
> 
> From AI review (gemini/gemini-3.1-pro-preview):
> 
>   Does this code need to validate that `cpu` is within bounds before
>   using it?  Before this change, the `cpu_uid` parameter was passed
>   opaquely to the ACPI firmware via `tph_invoke_dsm()`, which would
>   gracefully handle invalid values.
> 
>   Now, `cpu` is treated as a logical CPU index and passed to
>   `acpi_get_cpu_acpi_id(cpu)`. On architectures like arm64 and riscv,
>   `acpi_get_cpu_acpi_id()` uses `cpu` directly as an array index
>   (`&cpu_madt_gicc[cpu]` and `&cpu_madt_rintc[cpu]`). On x86, it uses
>   `per_cpu(x86_cpu_to_acpiid, cpu)`.
> 
>   If a caller passes an out-of-bounds `cpu` index (for example, if an
>   IRQ affinity mask is empty and `cpumask_first()` returns
>   `nr_cpu_ids`, or if userspace passes an arbitrary ID via
>   `mlx5_st_alloc_index()`), this will result in an out-of-bounds
>   memory read.
> 
>   Consider adding a bounds check:
> 
>     if (cpu >= nr_cpu_ids)
>       return -EINVAL;
> 
> I agree that this is an issue, and I think implementations of
> acpi_get_cpu_acpi_id() should validate their inputs.
> 
> I don't know if there's a value that can never be a valid ACPI CPU UID
> and could be used as an error value from acpi_get_cpu_acpi_id().  I do
> see a few mentions of a ~0 value meaning "all processors" (ACPI r6.6,
> sec 5.2.12.13).  

I only have the ACPI Specification Version 6.5, so I will use v6.5 as an example.

The ACPI specification does not define invalid value ranges for the ACPI UID.
For the arm64 platform (Section 5.2.12.14):
  ACPI Processor UID: The OS associates this GICC Structure with a processor device
                      object in the namespace when the _UID child object of the
                      processor device evaluates to a numeric value that matches
                      the numeric value in this field.

I am concerned that we cannot implement it like this:
	int acpi_get_cpu_uid(unsigned int cpu) {
		if (cpu >= nr_cpu_ids)
			return -EINVAL;
		...
	}
or:
	u32 acpi_get_cpu_uid(unsigned int cpu) {
		if (cpu >= nr_cpu_ids)
			return U32_MAX;
		...
	}

How about implementing it as follows:
	s64 acpi_get_cpu_uid(unsigned int cpu) {
		if (cpu >= nr_cpu_ids)
			return -EINVAL;
		...
	}
or
	int acpi_get_cpu_uid(unsigned int cpu, u32 *uid) {
		if (cpu >= nr_cpu_ids)
			return -EINVAL;
		*uid = xxx;
		return 0;
	}



Another issue: This commit also provides an implementation for the x86 platform.
However, further code analysis revealed a potential problem in the implementation:

The acpi_get_cpu_acpi_id() retrieves uid from x86_cpu_to_acpiid in SMP, and
x86_cpu_to_acpiid is set through the call chain: acpi_parse_lapic() ->
topology_register_apic() -> topo_register_apic() -> topo_set_cpuids() ->
x86_cpu_to_acpiid. It appears to retrieve the "ACPI Processor UID" from
ACPI Section 5.2.12.2, but the problem is that this field is only one byte in length,
which may cause issues in huge-core systems.

Therefore, I suggest re-implementing the acpi_get_cpu_uid function for the x86
platform. Either I provide a default implementation (shown below), or x86 guys
contribute to the implementation:

	s64 acpi_get_cpu_uid(unsigned int cpu) {
		if (cpu >= nr_cpu_ids)
			return -EINVAL;
		return cpu;
	}

Thanks

> 


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

* Re: [PATCH v5 2/2] PCI/TPH: Fix get cpu steer-tag fail on ARM64 platform
  2026-03-11  3:00       ` fengchengwen
@ 2026-03-11 17:02         ` Bjorn Helgaas
  0 siblings, 0 replies; 10+ messages in thread
From: Bjorn Helgaas @ 2026-03-11 17:02 UTC (permalink / raw)
  To: fengchengwen
  Cc: Jeremy Linton, Bjorn Helgaas, Catalin Marinas, Will Deacon,
	Rafael J . Wysocki, Jonathan Corbet, Shuah Khan, Huacai Chen,
	WANG Xuerui, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, x86, H . Peter Anvin, Juergen Gross, Boris Ostrovsky,
	Len Brown, Sunil V L, Mark Rutland, Jonathan Cameron, Kees Cook,
	Yanteng Si, Sean Christopherson, Kai Huang, Tom Lendacky,
	Thomas Huth, Thorsten Blum, Kevin Loughlin, Zheyun Shen,
	Peter Zijlstra, Pawan Gupta, Xin Li, Ahmed S . Darwish,
	Sohil Mehta, Ilkka Koskinen, Robin Murphy, James Clark,
	Besar Wicaksono, Ma Ke, Ajit Khaparde, Wei Huang, Andy Gospodarek,
	Somnath Kotur, wangzhou1, wanghuiqiang, liuyonglong, linux-pci,
	linux-doc, linux-kernel, linux-arm-kernel, loongarch, linux-riscv,
	xen-devel, linux-acpi, linux-perf-users, stable,
	Wathsala Vithanage

On Wed, Mar 11, 2026 at 11:00:02AM +0800, fengchengwen wrote:
> On 3/11/2026 6:09 AM, Bjorn Helgaas wrote:
> > On Tue, Mar 10, 2026 at 10:58:49AM -0500, Jeremy Linton wrote:
> >> On 3/9/26 10:20 PM, Chengwen Feng wrote:
> >>> pcie_tph_get_cpu_st() is broken on ARM64:
> >>> 1. pcie_tph_get_cpu_st() passes cpu_uid to the PCI ACPI DSM method.
> >>>     cpu_uid should be the ACPI Processor UID [1].
> >>> 2. In BNXT, pcie_tph_get_cpu_st() is passed a cpu_uid obtained via
> >>>     cpumask_first(irq->cpu_mask) - the logical CPU ID of a CPU core,
> >>>     generated and managed by kernel (e.g., [0,255] for a system  with 256
> >>>     logical CPU cores).
> >>> 3. On ARM64 platforms, ACPI assigns Processor UID to cores listed in the
> >>>     MADT table, and this UID may not match the kernel's logical CPU ID.
> >>>     When this occurs, the mismatch results in the wrong CPU steer-tag.
> >>> 4. On AMD x86 the logical CPU ID is identical to the ACPI Processor UID
> >>>     so the mismatch is not seen.
> > 
> >>>   int pcie_tph_get_cpu_st(struct pci_dev *pdev, enum tph_mem_type mem_type,
> >>> -			unsigned int cpu_uid, u16 *tag)
> >>> +			unsigned int cpu, u16 *tag)
> >>>   {
> >>>   #ifdef CONFIG_ACPI
> >>> +	u32 cpu_uid = acpi_get_cpu_acpi_id(cpu);
> > 
> > From AI review (gemini/gemini-3.1-pro-preview):
> > 
> >   Does this code need to validate that `cpu` is within bounds before
> >   using it?  Before this change, the `cpu_uid` parameter was passed
> >   opaquely to the ACPI firmware via `tph_invoke_dsm()`, which would
> >   gracefully handle invalid values.
> > 
> >   Now, `cpu` is treated as a logical CPU index and passed to
> >   `acpi_get_cpu_acpi_id(cpu)`. On architectures like arm64 and riscv,
> >   `acpi_get_cpu_acpi_id()` uses `cpu` directly as an array index
> >   (`&cpu_madt_gicc[cpu]` and `&cpu_madt_rintc[cpu]`). On x86, it uses
> >   `per_cpu(x86_cpu_to_acpiid, cpu)`.
> > 
> >   If a caller passes an out-of-bounds `cpu` index (for example, if an
> >   IRQ affinity mask is empty and `cpumask_first()` returns
> >   `nr_cpu_ids`, or if userspace passes an arbitrary ID via
> >   `mlx5_st_alloc_index()`), this will result in an out-of-bounds
> >   memory read.
> > 
> >   Consider adding a bounds check:
> > 
> >     if (cpu >= nr_cpu_ids)
> >       return -EINVAL;
> > 
> > I agree that this is an issue, and I think implementations of
> > acpi_get_cpu_acpi_id() should validate their inputs.
> > 
> > I don't know if there's a value that can never be a valid ACPI CPU UID
> > and could be used as an error value from acpi_get_cpu_acpi_id().  I do
> > see a few mentions of a ~0 value meaning "all processors" (ACPI r6.6,
> > sec 5.2.12.13).  
> 
> I only have the ACPI Specification Version 6.5, so I will use v6.5
> as an example.

https://uefi.org/sites/default/files/resources/ACPI_Spec_6.6.pdf

> 	int acpi_get_cpu_uid(unsigned int cpu, u32 *uid) {
> 		if (cpu >= nr_cpu_ids)
> 			return -EINVAL;
> 		*uid = xxx;
> 		return 0;
> 	}

This looks good to me.

> Another issue: This commit also provides an implementation for the
> x86 platform.  However, further code analysis revealed a potential
> problem in the implementation:
> 
> The acpi_get_cpu_acpi_id() retrieves uid from x86_cpu_to_acpiid in
> SMP, and x86_cpu_to_acpiid is set through the call chain:
> acpi_parse_lapic() -> topology_register_apic() ->
> topo_register_apic() -> topo_set_cpuids() -> x86_cpu_to_acpiid. It
> appears to retrieve the "ACPI Processor UID" from ACPI Section
> 5.2.12.2, but the problem is that this field is only one byte in
> length, which may cause issues in huge-core systems.
> 
> Therefore, I suggest re-implementing the acpi_get_cpu_uid function
> for the x86 platform. Either I provide a default implementation
> (shown below), or x86 guys contribute to the implementation:
> 
> 	s64 acpi_get_cpu_uid(unsigned int cpu) {
> 		if (cpu >= nr_cpu_ids)
> 			return -EINVAL;
> 		return cpu;
> 	}

I don't think this is your problem to solve, so don't worry about it.
If you implement acpi_get_cpu_uid() to return the same values as
cpu_acpi_id(), it's up to the x86 folks to deal with any one-byte ID
issues.

Bjorn

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

end of thread, other threads:[~2026-03-11 17:02 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-10  3:20 [PATCH v5 0/2] Fix get cpu steer-tag fail on ARM64 platform Chengwen Feng
2026-03-10  3:20 ` [PATCH v5 1/2] ACPI: Rename get_acpi_id_for_cpu() to acpi_get_cpu_acpi_id() on non-x86 Chengwen Feng
2026-03-10 17:53   ` Bjorn Helgaas
2026-03-10 22:39     ` Andrew Cooper
2026-03-11  2:57     ` fengchengwen
2026-03-10  3:20 ` [PATCH v5 2/2] PCI/TPH: Fix get cpu steer-tag fail on ARM64 platform Chengwen Feng
2026-03-10 15:58   ` Jeremy Linton
2026-03-10 22:09     ` Bjorn Helgaas
2026-03-11  3:00       ` fengchengwen
2026-03-11 17:02         ` Bjorn Helgaas

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