public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v7 0/3] Fix get cpu steer-tag fail on ARM64 platform
@ 2026-03-13  2:21 Chengwen Feng
  2026-03-13  2:21 ` [PATCH v7 1/3] ACPI: Refactor get_acpi_id_for_cpu() to acpi_get_cpu_uid() on non-x86 Chengwen Feng
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Chengwen Feng @ 2026-03-13  2:21 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, Sohil Mehta, Ilkka Koskinen,
	Robin Murphy, James Clark, Besar Wicaksono, Ma Ke, Wei Huang,
	Andy Gospodarek, Somnath Kotur, kees, punit.agrawal, guohanjun,
	suzuki.poulose, ryan.roberts, chenl311, masahiroy, wangyuquan1236,
	anshuman.khandual, heinrich.schuchardt, Eric.VanTassell,
	jonathan.cameron, wangzhou1, wanghuiqiang, liuyonglong,
	fengchengwen, linux-pci, linux-doc, linux-kernel,
	linux-arm-kernel, loongarch, linux-riscv, xen-devel, linux-acpi,
	linux-perf-users, stable

This patchset fixes the failure of CPU steer tag retrieval on ARM64
platforms. The series is structured as follows:

1. First commit: Refactor the ACPI Processor UID retrieval interface
   (no functional changes when input valid) to align naming conventions
   across arm64/riscv/loongarch architectures;
2. Second commit: Implement acpi_get_cpu_uid() for the x86 platform to
   complete the unified ACPI Processor UID interface across all
   ACPI-enabled architectures;
3. Third commit: Implement the core fix for the CPU steer tag retrieval
   logic on ARM64 (the root cause of the retrieval failure).

The refactor and x86 implementation lay the groundwork for the unified
ACPI interface required by the ARM64 steer tag fix, ensuring consistent
CPU UID retrieval across architectures before addressing the functional
bug.

---
Changes in v7:
- Refine first commit which address Jonathan's reviews
- Fix x86 implement bug (not consider INVALID-ID) which address Peter's
  review
- Fix CI error of x86 implement by moving function to acpi/boot.c

Changes in v6:
- Rename existing get_acpi_id_for_cpu() to acpi_get_cpu_uid()
- Split x86's modify as one commit

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 (3):
  ACPI: Refactor get_acpi_id_for_cpu() to acpi_get_cpu_uid() on non-x86
  x86: Implement acpi_get_cpu_uid()
  PCI/TPH: Fix get cpu steer-tag fail on ARM64 platform

 Documentation/PCI/tph.rst          |  4 +--
 arch/arm64/include/asm/acpi.h      | 16 +---------
 arch/arm64/kernel/acpi.c           | 16 ++++++++++
 arch/arm64/kernel/acpi_numa.c      | 14 +++++++++
 arch/loongarch/include/asm/acpi.h  |  5 ---
 arch/loongarch/kernel/acpi.c       |  9 ++++++
 arch/riscv/include/asm/acpi.h      |  4 ---
 arch/riscv/kernel/acpi.c           | 16 ++++++++++
 arch/riscv/kernel/acpi_numa.c      |  9 ++++--
 arch/x86/include/asm/cpu.h         |  1 -
 arch/x86/include/asm/smp.h         |  1 -
 arch/x86/kernel/acpi/boot.c        | 20 ++++++++++++
 arch/x86/xen/enlighten_hvm.c       |  5 +--
 drivers/acpi/pptt.c                | 50 ++++++++++++++++++++++--------
 drivers/acpi/riscv/rhct.c          |  7 ++++-
 drivers/pci/tph.c                  | 16 +++++++---
 drivers/perf/arm_cspmu/arm_cspmu.c |  6 ++--
 include/linux/acpi.h               | 11 +++++++
 include/linux/pci-tph.h            |  4 +--
 19 files changed, 158 insertions(+), 56 deletions(-)

-- 
2.17.1


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

* [PATCH v7 1/3] ACPI: Refactor get_acpi_id_for_cpu() to acpi_get_cpu_uid() on non-x86
  2026-03-13  2:21 [PATCH v7 0/3] Fix get cpu steer-tag fail on ARM64 platform Chengwen Feng
@ 2026-03-13  2:21 ` Chengwen Feng
  2026-03-17 21:21   ` Jeremy Linton
  2026-03-17 21:38   ` Jeremy Linton
  2026-03-13  2:21 ` [PATCH v7 2/3] x86: Implement acpi_get_cpu_uid() Chengwen Feng
  2026-03-13  2:21 ` [PATCH v7 3/3] PCI/TPH: Fix get cpu steer-tag fail on ARM64 platform Chengwen Feng
  2 siblings, 2 replies; 8+ messages in thread
From: Chengwen Feng @ 2026-03-13  2:21 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, Sohil Mehta, Ilkka Koskinen,
	Robin Murphy, James Clark, Besar Wicaksono, Ma Ke, Wei Huang,
	Andy Gospodarek, Somnath Kotur, kees, punit.agrawal, guohanjun,
	suzuki.poulose, ryan.roberts, chenl311, masahiroy, wangyuquan1236,
	anshuman.khandual, heinrich.schuchardt, Eric.VanTassell,
	jonathan.cameron, wangzhou1, wanghuiqiang, liuyonglong,
	fengchengwen, linux-pci, linux-doc, linux-kernel,
	linux-arm-kernel, loongarch, linux-riscv, xen-devel, linux-acpi,
	linux-perf-users, stable

Unify CPU ACPI ID retrieval interface across architectures by
refactoring get_acpi_id_for_cpu() to acpi_get_cpu_uid() on
arm64/riscv/loongarch:
- Add input parameter validation
- Adjust interface to int acpi_get_cpu_uid(unsigned int cpu, u32 *uid)
  (old: u32 get_acpi_id_for_cpu(unsigned int cpu), no input check)

This refactoring (not a pure rename) enhances interface robustness while
preparing for consistent ACPI Processor UID retrieval across all
ACPI-enabled platforms. Valid inputs retain original behavior.

Note: Move the ARM64-specific get_cpu_for_acpi_id() implementation to
      arch/arm64/kernel/acpi_numa.c to fix compilation errors from
      circular header dependencies introduced by the rename.

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      | 16 +---------
 arch/arm64/kernel/acpi.c           | 16 ++++++++++
 arch/arm64/kernel/acpi_numa.c      | 14 +++++++++
 arch/loongarch/include/asm/acpi.h  |  5 ---
 arch/loongarch/kernel/acpi.c       |  9 ++++++
 arch/riscv/include/asm/acpi.h      |  4 ---
 arch/riscv/kernel/acpi.c           | 16 ++++++++++
 arch/riscv/kernel/acpi_numa.c      |  9 ++++--
 drivers/acpi/pptt.c                | 50 ++++++++++++++++++++++--------
 drivers/acpi/riscv/rhct.c          |  7 ++++-
 drivers/perf/arm_cspmu/arm_cspmu.c |  6 ++--
 include/linux/acpi.h               | 13 ++++++++
 12 files changed, 122 insertions(+), 43 deletions(-)

diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index c07a58b96329..106a08556cbf 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -114,22 +114,8 @@ 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)
-{
-	return	acpi_cpu_get_madt_gicc(cpu)->uid;
-}
-
-static inline int get_cpu_for_acpi_id(u32 uid)
-{
-	int cpu;
-
-	for (cpu = 0; cpu < nr_cpu_ids; cpu++)
-		if (acpi_cpu_get_madt_gicc(cpu) &&
-		    uid == get_acpi_id_for_cpu(cpu))
-			return cpu;
 
-	return -EINVAL;
-}
+int get_cpu_for_acpi_id(u32 uid);
 
 static inline void arch_fix_phys_package_id(int num, u32 slot) { }
 void __init acpi_init_cpus(void);
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index af90128cfed5..f3866606fc46 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -458,3 +458,19 @@ int acpi_unmap_cpu(int cpu)
 }
 EXPORT_SYMBOL(acpi_unmap_cpu);
 #endif /* CONFIG_ACPI_HOTPLUG_CPU */
+
+int acpi_get_cpu_uid(unsigned int cpu, u32 *uid)
+{
+	struct acpi_madt_generic_interrupt *gicc;
+
+	if (cpu >= nr_cpu_ids)
+		return -EINVAL;
+
+	gicc = acpi_cpu_get_madt_gicc(cpu);
+	if (!gicc)
+		return -ENODEV;
+
+	*uid = gicc->uid;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(acpi_get_cpu_uid);
diff --git a/arch/arm64/kernel/acpi_numa.c b/arch/arm64/kernel/acpi_numa.c
index 2465f291c7e1..41d1e46a4338 100644
--- a/arch/arm64/kernel/acpi_numa.c
+++ b/arch/arm64/kernel/acpi_numa.c
@@ -34,6 +34,20 @@ int __init acpi_numa_get_nid(unsigned int cpu)
 	return acpi_early_node_map[cpu];
 }
 
+int get_cpu_for_acpi_id(u32 uid)
+{
+	u32 cpu_uid;
+	int ret;
+
+	for (int cpu = 0; cpu < nr_cpu_ids; cpu++) {
+		ret = acpi_get_cpu_uid(cpu, &cpu_uid);
+		if (ret == 0 && uid == cpu_uid)
+			return cpu;
+	}
+
+	return -EINVAL;
+}
+
 static int __init acpi_parse_gicc_pxm(union acpi_subtable_headers *header,
 				      const unsigned long end)
 {
diff --git a/arch/loongarch/include/asm/acpi.h b/arch/loongarch/include/asm/acpi.h
index 7376840fa9f7..eda9d4d0a493 100644
--- a/arch/loongarch/include/asm/acpi.h
+++ b/arch/loongarch/include/asm/acpi.h
@@ -40,11 +40,6 @@ 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)
-{
-	return acpi_core_pic[cpu_logical_map(cpu)].processor_id;
-}
-
 #endif /* !CONFIG_ACPI */
 
 #define ACPI_TABLE_UPGRADE_MAX_PHYS ARCH_LOW_ADDRESS_LIMIT
diff --git a/arch/loongarch/kernel/acpi.c b/arch/loongarch/kernel/acpi.c
index 1367ca759468..058f0dbe8e8f 100644
--- a/arch/loongarch/kernel/acpi.c
+++ b/arch/loongarch/kernel/acpi.c
@@ -385,3 +385,12 @@ int acpi_unmap_cpu(int cpu)
 EXPORT_SYMBOL(acpi_unmap_cpu);
 
 #endif /* CONFIG_ACPI_HOTPLUG_CPU */
+
+int acpi_get_cpu_uid(unsigned int cpu, u32 *uid)
+{
+	if (cpu >= nr_cpu_ids)
+		return -EINVAL;
+	*uid = acpi_core_pic[cpu_logical_map(cpu)].processor_id;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(acpi_get_cpu_uid);
diff --git a/arch/riscv/include/asm/acpi.h b/arch/riscv/include/asm/acpi.h
index 6e13695120bc..26ab37c171bc 100644
--- a/arch/riscv/include/asm/acpi.h
+++ b/arch/riscv/include/asm/acpi.h
@@ -61,10 +61,6 @@ 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)
-{
-	return acpi_cpu_get_madt_rintc(cpu)->uid;
-}
 
 int acpi_get_riscv_isa(struct acpi_table_header *table,
 		       unsigned int cpu, const char **isa);
diff --git a/arch/riscv/kernel/acpi.c b/arch/riscv/kernel/acpi.c
index 71698ee11621..322ea92aa39f 100644
--- a/arch/riscv/kernel/acpi.c
+++ b/arch/riscv/kernel/acpi.c
@@ -337,3 +337,19 @@ int raw_pci_write(unsigned int domain, unsigned int bus,
 }
 
 #endif	/* CONFIG_PCI */
+
+int acpi_get_cpu_uid(unsigned int cpu, u32 *uid)
+{
+	struct acpi_madt_rintc *rintc;
+
+	if (cpu >= nr_cpu_ids)
+		return -EINVAL;
+
+	rintc = acpi_cpu_get_madt_rintc(cpu);
+	if (!rintc)
+		return -ENODEV;
+
+	*uid = rintc->uid;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(acpi_get_cpu_uid);
diff --git a/arch/riscv/kernel/acpi_numa.c b/arch/riscv/kernel/acpi_numa.c
index 130769e3a99c..6a2d4289f806 100644
--- a/arch/riscv/kernel/acpi_numa.c
+++ b/arch/riscv/kernel/acpi_numa.c
@@ -37,11 +37,14 @@ static int __init acpi_numa_get_nid(unsigned int cpu)
 
 static inline int get_cpu_for_acpi_id(u32 uid)
 {
-	int cpu;
+	u32 cpu_uid;
+	int ret;
 
-	for (cpu = 0; cpu < nr_cpu_ids; cpu++)
-		if (uid == get_acpi_id_for_cpu(cpu))
+	for (int cpu = 0; cpu < nr_cpu_ids; cpu++) {
+		ret = acpi_get_cpu_uid(cpu, &cpu_uid);
+		if (ret == 0 && uid == cpu_uid)
 			return cpu;
+	}
 
 	return -EINVAL;
 }
diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c
index de5f8c018333..7bd5bc1f225a 100644
--- a/drivers/acpi/pptt.c
+++ b/drivers/acpi/pptt.c
@@ -459,11 +459,14 @@ 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;
 	struct cacheinfo *this_leaf;
 	unsigned int index = 0;
 	struct acpi_pptt_processor *cpu_node = NULL;
 
+	if (acpi_get_cpu_uid(cpu, &acpi_cpu_id) != 0)
+		return;
+
 	while (index < get_cpu_cacheinfo(cpu)->num_leaves) {
 		this_leaf = this_cpu_ci->info_list + index;
 		found_cache = acpi_find_cache_node(table, acpi_cpu_id,
@@ -546,7 +549,10 @@ 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;
+
+	if (acpi_get_cpu_uid(cpu, &acpi_cpu_id) != 0)
+		return -ENOENT;
 
 	cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
 	if (cpu_node) {
@@ -614,18 +620,22 @@ static int find_acpi_cpu_topology_tag(unsigned int cpu, int level, int flag)
  *
  * Check the node representing a CPU for a given flag.
  *
- * Return: -ENOENT if the PPTT doesn't exist, the CPU cannot be found or
- *	   the table revision isn't new enough.
+ * Return: -ENOENT if can't get CPU's ACPI Processor UID, the PPTT doesn't
+ *	   exist, the CPU cannot be found or the table revision isn't new
+ *	   enough.
  *	   1, any passed flag set
  *	   0, flag unset
  */
 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;
 	struct acpi_pptt_processor *cpu_node = NULL;
 	int ret = -ENOENT;
 
+	if (acpi_get_cpu_uid(cpu, &acpi_cpu_id) != 0)
+		return -ENOENT;
+
 	table = acpi_get_pptt();
 	if (!table)
 		return -ENOENT;
@@ -651,7 +661,8 @@ static int check_acpi_cpu_flag(unsigned int cpu, int rev, u32 flag)
  * in the PPTT. Errors caused by lack of a PPTT table, or otherwise, return 0
  * indicating we didn't find any cache levels.
  *
- * Return: -ENOENT if no PPTT table or no PPTT processor struct found.
+ * Return: -ENOENT if no PPTT table, can't get CPU's ACPI Process UID or no PPTT
+ *	   processor struct found.
  *	   0 on success.
  */
 int acpi_get_cache_info(unsigned int cpu, unsigned int *levels,
@@ -671,7 +682,9 @@ 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);
+	if (acpi_get_cpu_uid(cpu, &acpi_cpu_id))
+		return -ENOENT;
+
 	cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
 	if (!cpu_node)
 		return -ENOENT;
@@ -780,8 +793,9 @@ int find_acpi_cpu_topology_package(unsigned int cpu)
  * It may not exist in single CPU systems. In simple multi-CPU systems,
  * it may be equal to the package topology level.
  *
- * Return: -ENOENT if the PPTT doesn't exist, the CPU cannot be found
- * or there is no toplogy level above the CPU..
+ * Return: -ENOENT if the PPTT doesn't exist, can't get CPU's ACPI
+ * Processor UID, the CPU cannot be found or there is no toplogy level
+ * above the CPU.
  * Otherwise returns a value which represents the package for this CPU.
  */
 
@@ -797,7 +811,9 @@ int find_acpi_cpu_topology_cluster(unsigned int cpu)
 	if (!table)
 		return -ENOENT;
 
-	acpi_cpu_id = get_acpi_id_for_cpu(cpu);
+	if (acpi_get_cpu_uid(cpu, &acpi_cpu_id) != 0)
+		return -ENOENT;
+
 	cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
 	if (!cpu_node || !cpu_node->parent)
 		return -ENOENT;
@@ -872,7 +888,9 @@ 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);
+		if (acpi_get_cpu_uid(cpu, &acpi_id) != 0)
+			continue;
+
 		cpu_node = acpi_find_processor_node(table_hdr, acpi_id);
 
 		while (cpu_node) {
@@ -966,10 +984,13 @@ 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;
 		struct acpi_pptt_cache *cache;
 		struct acpi_pptt_processor *cpu_node;
 
+		if (acpi_get_cpu_uid(cpu, &acpi_cpu_id) != 0)
+			continue;
+
 		cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
 		if (!cpu_node)
 			continue;
@@ -1030,10 +1051,13 @@ 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;
 		struct acpi_pptt_cache *cache;
 		struct acpi_pptt_processor *cpu_node;
 
+		if (acpi_get_cpu_uid(cpu, &acpi_cpu_id) != 0)
+			continue;
+
 		cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
 		if (!cpu_node)
 			continue;
diff --git a/drivers/acpi/riscv/rhct.c b/drivers/acpi/riscv/rhct.c
index caa2c16e1697..8f3f38c64a88 100644
--- a/drivers/acpi/riscv/rhct.c
+++ b/drivers/acpi/riscv/rhct.c
@@ -44,10 +44,15 @@ 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;
+	int ret;
 
 	BUG_ON(acpi_disabled);
 
+	ret = acpi_get_cpu_uid(cpu, &acpi_cpu_id);
+	if (ret != 0)
+		return ret;
+
 	if (!table) {
 		rhct = acpi_get_rhct();
 		if (!rhct)
diff --git a/drivers/perf/arm_cspmu/arm_cspmu.c b/drivers/perf/arm_cspmu/arm_cspmu.c
index 34430b68f602..ed72c3d1f796 100644
--- a/drivers/perf/arm_cspmu/arm_cspmu.c
+++ b/drivers/perf/arm_cspmu/arm_cspmu.c
@@ -1107,15 +1107,17 @@ static int arm_cspmu_acpi_get_cpus(struct arm_cspmu *cspmu)
 {
 	struct acpi_apmt_node *apmt_node;
 	int affinity_flag;
+	u32 cpu_uid;
 	int cpu;
+	int ret;
 
 	apmt_node = arm_cspmu_apmt_node(cspmu->dev);
 	affinity_flag = apmt_node->flags & ACPI_APMT_FLAGS_AFFINITY;
 
 	if (affinity_flag == ACPI_APMT_FLAGS_AFFINITY_PROC) {
 		for_each_possible_cpu(cpu) {
-			if (apmt_node->proc_affinity ==
-			    get_acpi_id_for_cpu(cpu)) {
+			ret = acpi_get_cpu_uid(cpu, &cpu_uid);
+			if (ret == 0 && apmt_node->proc_affinity == cpu_uid) {
 				cpumask_set_cpu(cpu, &cspmu->associated_cpus);
 				break;
 			}
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 4d2f0bed7a06..035094a55f18 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -324,6 +324,19 @@ int acpi_unmap_cpu(int cpu);
 
 acpi_handle acpi_get_processor_handle(int cpu);
 
+#ifndef CONFIG_X86
+/*
+ * acpi_get_cpu_uid() - Get ACPI Processor UID of a specified CPU from MADT table
+ * @cpu: Logical CPU number (0-based)
+ * @uid: Pointer to store the ACPI Processor UID (valid only on successful return)
+ *
+ * Return: 0 on successful retrieval (the ACPI Processor ID is stored in *uid);
+ *         -EINVAL if the CPU number is invalid or out of range;
+ *         -ENODEV if the ACPI Processor UID for the specified CPU is not found.
+ */
+int acpi_get_cpu_uid(unsigned int cpu, u32 *uid);
+#endif
+
 #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
 int acpi_get_ioapic_id(acpi_handle handle, u32 gsi_base, u64 *phys_addr);
 #endif
-- 
2.17.1


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

* [PATCH v7 2/3] x86: Implement acpi_get_cpu_uid()
  2026-03-13  2:21 [PATCH v7 0/3] Fix get cpu steer-tag fail on ARM64 platform Chengwen Feng
  2026-03-13  2:21 ` [PATCH v7 1/3] ACPI: Refactor get_acpi_id_for_cpu() to acpi_get_cpu_uid() on non-x86 Chengwen Feng
@ 2026-03-13  2:21 ` Chengwen Feng
  2026-03-13  2:21 ` [PATCH v7 3/3] PCI/TPH: Fix get cpu steer-tag fail on ARM64 platform Chengwen Feng
  2 siblings, 0 replies; 8+ messages in thread
From: Chengwen Feng @ 2026-03-13  2:21 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, Sohil Mehta, Ilkka Koskinen,
	Robin Murphy, James Clark, Besar Wicaksono, Ma Ke, Wei Huang,
	Andy Gospodarek, Somnath Kotur, kees, punit.agrawal, guohanjun,
	suzuki.poulose, ryan.roberts, chenl311, masahiroy, wangyuquan1236,
	anshuman.khandual, heinrich.schuchardt, Eric.VanTassell,
	jonathan.cameron, wangzhou1, wanghuiqiang, liuyonglong,
	fengchengwen, linux-pci, linux-doc, linux-kernel,
	linux-arm-kernel, loongarch, linux-riscv, xen-devel, linux-acpi,
	linux-perf-users, stable

Add acpi_get_cpu_uid() implementation for x86, replacing the existing
cpu_acpi_id() function. This completes the unified ACPI Processor UID
retrieval interface across all ACPI-enabled architectures.

Cc: stable@vger.kernel.org
Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
---
 arch/x86/include/asm/cpu.h   |  1 -
 arch/x86/include/asm/smp.h   |  1 -
 arch/x86/kernel/acpi/boot.c  | 20 ++++++++++++++++++++
 arch/x86/xen/enlighten_hvm.c |  5 +++--
 include/linux/acpi.h         |  2 --
 5 files changed, 23 insertions(+), 6 deletions(-)

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/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index a3f2fb1fea1b..ceba24f65ae3 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -1848,3 +1848,23 @@ void __iomem * (*acpi_os_ioremap)(acpi_physical_address phys, acpi_size size) =
 	x86_acpi_os_ioremap;
 EXPORT_SYMBOL_GPL(acpi_os_ioremap);
 #endif
+
+int acpi_get_cpu_uid(unsigned int cpu, u32 *uid)
+{
+	u32 acpi_id;
+
+	if (cpu >= nr_cpu_ids)
+		return -EINVAL;
+
+#ifdef CONFIG_SMP
+	acpi_id = per_cpu(x86_cpu_to_acpiid, cpu);
+	if (acpi_id == CPU_ACPIID_INVALID)
+		return -ENODEV;
+#else
+	acpi_id = 0;
+#endif
+
+	*uid = acpi_id;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(acpi_get_cpu_uid);
diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c
index fe57ff85d004..2f9fa27e5a3c 100644
--- a/arch/x86/xen/enlighten_hvm.c
+++ b/arch/x86/xen/enlighten_hvm.c
@@ -151,6 +151,7 @@ static void xen_hvm_crash_shutdown(struct pt_regs *regs)
 
 static int xen_cpu_up_prepare_hvm(unsigned int cpu)
 {
+	u32 cpu_uid;
 	int rc = 0;
 
 	/*
@@ -161,8 +162,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_uid(cpu, &cpu_uid) == 0)
+		per_cpu(xen_vcpu_id, cpu) = cpu_uid;
 	else
 		per_cpu(xen_vcpu_id, cpu) = cpu;
 	xen_vcpu_setup(cpu);
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 035094a55f18..90a1fdcb7eb9 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -324,7 +324,6 @@ int acpi_unmap_cpu(int cpu);
 
 acpi_handle acpi_get_processor_handle(int cpu);
 
-#ifndef CONFIG_X86
 /*
  * acpi_get_cpu_uid() - Get ACPI Processor UID of a specified CPU from MADT table
  * @cpu: Logical CPU number (0-based)
@@ -335,7 +334,6 @@ acpi_handle acpi_get_processor_handle(int cpu);
  *         -ENODEV if the ACPI Processor UID for the specified CPU is not found.
  */
 int acpi_get_cpu_uid(unsigned int cpu, u32 *uid);
-#endif
 
 #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
 int acpi_get_ioapic_id(acpi_handle handle, u32 gsi_base, u64 *phys_addr);
-- 
2.17.1


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

* [PATCH v7 3/3] PCI/TPH: Fix get cpu steer-tag fail on ARM64 platform
  2026-03-13  2:21 [PATCH v7 0/3] Fix get cpu steer-tag fail on ARM64 platform Chengwen Feng
  2026-03-13  2:21 ` [PATCH v7 1/3] ACPI: Refactor get_acpi_id_for_cpu() to acpi_get_cpu_uid() on non-x86 Chengwen Feng
  2026-03-13  2:21 ` [PATCH v7 2/3] x86: Implement acpi_get_cpu_uid() Chengwen Feng
@ 2026-03-13  2:21 ` Chengwen Feng
  2 siblings, 0 replies; 8+ messages in thread
From: Chengwen Feng @ 2026-03-13  2:21 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, Sohil Mehta, Ilkka Koskinen,
	Robin Murphy, James Clark, Besar Wicaksono, Ma Ke, Wei Huang,
	Andy Gospodarek, Somnath Kotur, kees, punit.agrawal, guohanjun,
	suzuki.poulose, ryan.roberts, chenl311, masahiroy, wangyuquan1236,
	anshuman.khandual, heinrich.schuchardt, Eric.VanTassell,
	jonathan.cameron, wangzhou1, wanghuiqiang, liuyonglong,
	fengchengwen, 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. Use acpi_get_cpu_uid() in pcie_tph_get_cpu_st() to translate from
   logical CPU ID to ACPI Processor UID needed for the DSM call.
2. 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 ++--
 drivers/pci/tph.c         | 16 +++++++++++-----
 include/linux/pci-tph.h   |  4 ++--
 3 files changed, 15 insertions(+), 9 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/drivers/pci/tph.c b/drivers/pci/tph.c
index ca4f97be7538..b67c9ad14bda 100644
--- a/drivers/pci/tph.c
+++ b/drivers/pci/tph.c
@@ -236,21 +236,27 @@ 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
 	struct pci_dev *rp;
 	acpi_handle rp_acpi_handle;
 	union st_info info;
+	u32 cpu_uid;
+	int ret;
+
+	ret = acpi_get_cpu_uid(cpu, &cpu_uid);
+	if (ret != 0)
+		return ret;
 
 	rp = pcie_find_root_port(pdev);
 	if (!rp || !rp->bus || !rp->bus->bridge)
@@ -265,9 +271,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] 8+ messages in thread

* Re: [PATCH v7 1/3] ACPI: Refactor get_acpi_id_for_cpu() to acpi_get_cpu_uid() on non-x86
  2026-03-13  2:21 ` [PATCH v7 1/3] ACPI: Refactor get_acpi_id_for_cpu() to acpi_get_cpu_uid() on non-x86 Chengwen Feng
@ 2026-03-17 21:21   ` Jeremy Linton
  2026-03-17 21:38   ` Jeremy Linton
  1 sibling, 0 replies; 8+ messages in thread
From: Jeremy Linton @ 2026-03-17 21:21 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, Sohil Mehta, Ilkka Koskinen,
	Robin Murphy, James Clark, Besar Wicaksono, Ma Ke, Wei Huang,
	Andy Gospodarek, Somnath Kotur, kees, punit.agrawal, guohanjun,
	suzuki.poulose, ryan.roberts, chenl311, masahiroy, wangyuquan1236,
	anshuman.khandual, heinrich.schuchardt, Eric.VanTassell,
	jonathan.cameron, wangzhou1, wanghuiqiang, liuyonglong, linux-pci,
	linux-doc, linux-kernel, linux-arm-kernel, loongarch, linux-riscv,
	xen-devel, linux-acpi, linux-perf-users, stable

Hi,

On 3/12/26 9:21 PM, Chengwen Feng wrote:
> Unify CPU ACPI ID retrieval interface across architectures by
> refactoring get_acpi_id_for_cpu() to acpi_get_cpu_uid() on
> arm64/riscv/loongarch:
> - Add input parameter validation
> - Adjust interface to int acpi_get_cpu_uid(unsigned int cpu, u32 *uid)
>    (old: u32 get_acpi_id_for_cpu(unsigned int cpu), no input check)
> 
> This refactoring (not a pure rename) enhances interface robustness while
> preparing for consistent ACPI Processor UID retrieval across all
> ACPI-enabled platforms. Valid inputs retain original behavior.
> 
> Note: Move the ARM64-specific get_cpu_for_acpi_id() implementation to
>        arch/arm64/kernel/acpi_numa.c to fix compilation errors from
>        circular header dependencies introduced by the rename.

I moved get_cpu_for_acpi_id() into arm64/kernel/acpi.c, and granted 
didn't test a wide range of configs, but i'm not seeing the circular 
dependency, what is causing that?

> 
> 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      | 16 +---------
>   arch/arm64/kernel/acpi.c           | 16 ++++++++++
>   arch/arm64/kernel/acpi_numa.c      | 14 +++++++++
>   arch/loongarch/include/asm/acpi.h  |  5 ---
>   arch/loongarch/kernel/acpi.c       |  9 ++++++
>   arch/riscv/include/asm/acpi.h      |  4 ---
>   arch/riscv/kernel/acpi.c           | 16 ++++++++++
>   arch/riscv/kernel/acpi_numa.c      |  9 ++++--
>   drivers/acpi/pptt.c                | 50 ++++++++++++++++++++++--------
>   drivers/acpi/riscv/rhct.c          |  7 ++++-
>   drivers/perf/arm_cspmu/arm_cspmu.c |  6 ++--
>   include/linux/acpi.h               | 13 ++++++++
>   12 files changed, 122 insertions(+), 43 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
> index c07a58b96329..106a08556cbf 100644
> --- a/arch/arm64/include/asm/acpi.h
> +++ b/arch/arm64/include/asm/acpi.h
> @@ -114,22 +114,8 @@ 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)
> -{
> -	return	acpi_cpu_get_madt_gicc(cpu)->uid;
> -}
> -
> -static inline int get_cpu_for_acpi_id(u32 uid)
> -{
> -	int cpu;
> -
> -	for (cpu = 0; cpu < nr_cpu_ids; cpu++)
> -		if (acpi_cpu_get_madt_gicc(cpu) &&
> -		    uid == get_acpi_id_for_cpu(cpu))
> -			return cpu;
>   
> -	return -EINVAL;
> -}
> +int get_cpu_for_acpi_id(u32 uid);
>   
>   static inline void arch_fix_phys_package_id(int num, u32 slot) { }
>   void __init acpi_init_cpus(void);
> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
> index af90128cfed5..f3866606fc46 100644
> --- a/arch/arm64/kernel/acpi.c
> +++ b/arch/arm64/kernel/acpi.c
> @@ -458,3 +458,19 @@ int acpi_unmap_cpu(int cpu)
>   }
>   EXPORT_SYMBOL(acpi_unmap_cpu);
>   #endif /* CONFIG_ACPI_HOTPLUG_CPU */
> +
> +int acpi_get_cpu_uid(unsigned int cpu, u32 *uid)
> +{
> +	struct acpi_madt_generic_interrupt *gicc;
> +
> +	if (cpu >= nr_cpu_ids)
> +		return -EINVAL;
I think this should be cpu_possible() because we have a number of 
for_each_possible() calls that end up in here and AFAIK nr_cpu_ids can 
be more restrictive than the possible list.> +
> +	gicc = acpi_cpu_get_madt_gicc(cpu);
> +	if (!gicc)
> +		return -ENODEV;
So, on arm64, I didn't think it was possible to have a logical cpu 
lookup that didn't map to a gicc uid, because the logical core couldn't 
exist otherwise and (AFAIK) we don't have holes in the possible cpu 
mask. Once you know the logical core is less than nr_cpu_ids it must 
have a MADT mapping. So check this is redundant too, no?

But, if its possible to call this with an invalid logical cpu then we 
probably want to know that, so nr_cpu_ids/cpu_possible() check should 
have pr_warn_once() because there is a bug somewhere, particularly from 
all the pptt calls below where I guess there is an implication there is 
an ID mismatch between the MADT and the PPTT or simply that the user has 
clamped max cpus less than the for_each_possible() calls in the pptt/etc 
code.


> +
> +	*uid = gicc->uid;
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(acpi_get_cpu_uid);
> diff --git a/arch/arm64/kernel/acpi_numa.c b/arch/arm64/kernel/acpi_numa.c
> index 2465f291c7e1..41d1e46a4338 100644
> --- a/arch/arm64/kernel/acpi_numa.c
> +++ b/arch/arm64/kernel/acpi_numa.c
> @@ -34,6 +34,20 @@ int __init acpi_numa_get_nid(unsigned int cpu)
>   	return acpi_early_node_map[cpu];
>   }
>   
> +int get_cpu_for_acpi_id(u32 uid)
> +{
> +	u32 cpu_uid;
> +	int ret;
> +
> +	for (int cpu = 0; cpu < nr_cpu_ids; cpu++) {
> +		ret = acpi_get_cpu_uid(cpu, &cpu_uid);
This change is redundant, no? Your walking a limited list of possible 
CPUs that have GICC entries and checking to see if one of the known 
logical cores has a matching ACPI id. AKA you can't have an invalid 
logical core here, so the previous call must have a valid acpi id. But 
at the same time so was the acpi_cpu_get_madt_gicc() check in there 
before, which was probably left over from when the tables were being 
mapped rather than cached.

> +		if (ret == 0 && uid == cpu_uid)
> +			return cpu;
> +	}
> +
> +	return -EINVAL;
> +}
> +
I didn't actually manage to hit the case here that keeps this from 
compiling cleanly in acpi.c above if its placed immediately following 
acpi_get_cpu_uid(). IMHO, these two functions are kept close to each 
other since they are so conceptually related.

>   static int __init acpi_parse_gicc_pxm(union acpi_subtable_headers *header,
>   				      const unsigned long end)
>   {
> diff --git a/arch/loongarch/include/asm/acpi.h b/arch/loongarch/include/asm/acpi.h
> index 7376840fa9f7..eda9d4d0a493 100644
> --- a/arch/loongarch/include/asm/acpi.h
> +++ b/arch/loongarch/include/asm/acpi.h
> @@ -40,11 +40,6 @@ 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)
> -{
> -	return acpi_core_pic[cpu_logical_map(cpu)].processor_id;
> -}
> -
>   #endif /* !CONFIG_ACPI */
>   
>   #define ACPI_TABLE_UPGRADE_MAX_PHYS ARCH_LOW_ADDRESS_LIMIT
> diff --git a/arch/loongarch/kernel/acpi.c b/arch/loongarch/kernel/acpi.c
> index 1367ca759468..058f0dbe8e8f 100644
> --- a/arch/loongarch/kernel/acpi.c
> +++ b/arch/loongarch/kernel/acpi.c
> @@ -385,3 +385,12 @@ int acpi_unmap_cpu(int cpu)
>   EXPORT_SYMBOL(acpi_unmap_cpu);
>   
>   #endif /* CONFIG_ACPI_HOTPLUG_CPU */
> +
> +int acpi_get_cpu_uid(unsigned int cpu, u32 *uid)
> +{
> +	if (cpu >= nr_cpu_ids)
> +		return -EINVAL;
> +	*uid = acpi_core_pic[cpu_logical_map(cpu)].processor_id;
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(acpi_get_cpu_uid);
> diff --git a/arch/riscv/include/asm/acpi.h b/arch/riscv/include/asm/acpi.h
> index 6e13695120bc..26ab37c171bc 100644
> --- a/arch/riscv/include/asm/acpi.h
> +++ b/arch/riscv/include/asm/acpi.h
> @@ -61,10 +61,6 @@ 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)
> -{
> -	return acpi_cpu_get_madt_rintc(cpu)->uid;
> -}
>   
>   int acpi_get_riscv_isa(struct acpi_table_header *table,
>   		       unsigned int cpu, const char **isa);
> diff --git a/arch/riscv/kernel/acpi.c b/arch/riscv/kernel/acpi.c
> index 71698ee11621..322ea92aa39f 100644
> --- a/arch/riscv/kernel/acpi.c
> +++ b/arch/riscv/kernel/acpi.c
> @@ -337,3 +337,19 @@ int raw_pci_write(unsigned int domain, unsigned int bus,
>   }
>   
>   #endif	/* CONFIG_PCI */
> +
> +int acpi_get_cpu_uid(unsigned int cpu, u32 *uid)
> +{
> +	struct acpi_madt_rintc *rintc;
> +
> +	if (cpu >= nr_cpu_ids)
> +		return -EINVAL;
> +
> +	rintc = acpi_cpu_get_madt_rintc(cpu);
> +	if (!rintc)
> +		return -ENODEV;
> +
> +	*uid = rintc->uid;
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(acpi_get_cpu_uid);
> diff --git a/arch/riscv/kernel/acpi_numa.c b/arch/riscv/kernel/acpi_numa.c
> index 130769e3a99c..6a2d4289f806 100644
> --- a/arch/riscv/kernel/acpi_numa.c
> +++ b/arch/riscv/kernel/acpi_numa.c
> @@ -37,11 +37,14 @@ static int __init acpi_numa_get_nid(unsigned int cpu)
>   
>   static inline int get_cpu_for_acpi_id(u32 uid)
>   {
> -	int cpu;
> +	u32 cpu_uid;
> +	int ret;
>   
> -	for (cpu = 0; cpu < nr_cpu_ids; cpu++)
> -		if (uid == get_acpi_id_for_cpu(cpu))
> +	for (int cpu = 0; cpu < nr_cpu_ids; cpu++) {
> +		ret = acpi_get_cpu_uid(cpu, &cpu_uid);
> +		if (ret == 0 && uid == cpu_uid)
>   			return cpu;
> +	}
>   
>   	return -EINVAL;
>   }
> diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c
> index de5f8c018333..7bd5bc1f225a 100644
> --- a/drivers/acpi/pptt.c
> +++ b/drivers/acpi/pptt.c
> @@ -459,11 +459,14 @@ 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;
>   	struct cacheinfo *this_leaf;
>   	unsigned int index = 0;
>   	struct acpi_pptt_processor *cpu_node = NULL;
>   
> +	if (acpi_get_cpu_uid(cpu, &acpi_cpu_id) != 0)
> +		return;
> +
>   	while (index < get_cpu_cacheinfo(cpu)->num_leaves) {
>   		this_leaf = this_cpu_ci->info_list + index;
>   		found_cache = acpi_find_cache_node(table, acpi_cpu_id,
> @@ -546,7 +549,10 @@ 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;
> +
> +	if (acpi_get_cpu_uid(cpu, &acpi_cpu_id) != 0)
> +		return -ENOENT;
>   
>   	cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
>   	if (cpu_node) {
> @@ -614,18 +620,22 @@ static int find_acpi_cpu_topology_tag(unsigned int cpu, int level, int flag)
>    *
>    * Check the node representing a CPU for a given flag.
>    *
> - * Return: -ENOENT if the PPTT doesn't exist, the CPU cannot be found or
> - *	   the table revision isn't new enough.
> + * Return: -ENOENT if can't get CPU's ACPI Processor UID, the PPTT doesn't
> + *	   exist, the CPU cannot be found or the table revision isn't new
> + *	   enough.
>    *	   1, any passed flag set
>    *	   0, flag unset
>    */
>   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;
>   	struct acpi_pptt_processor *cpu_node = NULL;
>   	int ret = -ENOENT;
>   
> +	if (acpi_get_cpu_uid(cpu, &acpi_cpu_id) != 0)
> +		return -ENOENT;
> +
>   	table = acpi_get_pptt();
>   	if (!table)
>   		return -ENOENT;
> @@ -651,7 +661,8 @@ static int check_acpi_cpu_flag(unsigned int cpu, int rev, u32 flag)
>    * in the PPTT. Errors caused by lack of a PPTT table, or otherwise, return 0
>    * indicating we didn't find any cache levels.
>    *
> - * Return: -ENOENT if no PPTT table or no PPTT processor struct found.
> + * Return: -ENOENT if no PPTT table, can't get CPU's ACPI Process UID or no PPTT
> + *	   processor struct found.
>    *	   0 on success.
>    */
>   int acpi_get_cache_info(unsigned int cpu, unsigned int *levels,
> @@ -671,7 +682,9 @@ 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);
> +	if (acpi_get_cpu_uid(cpu, &acpi_cpu_id))
> +		return -ENOENT;
> +
>   	cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
>   	if (!cpu_node)
>   		return -ENOENT;
> @@ -780,8 +793,9 @@ int find_acpi_cpu_topology_package(unsigned int cpu)
>    * It may not exist in single CPU systems. In simple multi-CPU systems,
>    * it may be equal to the package topology level.
>    *
> - * Return: -ENOENT if the PPTT doesn't exist, the CPU cannot be found
> - * or there is no toplogy level above the CPU..
> + * Return: -ENOENT if the PPTT doesn't exist, can't get CPU's ACPI
> + * Processor UID, the CPU cannot be found or there is no toplogy level
> + * above the CPU.
>    * Otherwise returns a value which represents the package for this CPU.
>    */
>   
> @@ -797,7 +811,9 @@ int find_acpi_cpu_topology_cluster(unsigned int cpu)
>   	if (!table)
>   		return -ENOENT;
>   
> -	acpi_cpu_id = get_acpi_id_for_cpu(cpu);
> +	if (acpi_get_cpu_uid(cpu, &acpi_cpu_id) != 0)
> +		return -ENOENT;
> +
>   	cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
>   	if (!cpu_node || !cpu_node->parent)
>   		return -ENOENT;
> @@ -872,7 +888,9 @@ 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);
> +		if (acpi_get_cpu_uid(cpu, &acpi_id) != 0)
> +			continue;
> +
>   		cpu_node = acpi_find_processor_node(table_hdr, acpi_id);
>   
>   		while (cpu_node) {
> @@ -966,10 +984,13 @@ 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;
>   		struct acpi_pptt_cache *cache;
>   		struct acpi_pptt_processor *cpu_node;
>   
> +		if (acpi_get_cpu_uid(cpu, &acpi_cpu_id) != 0)
> +			continue;
> +
>   		cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
>   		if (!cpu_node)
>   			continue;
> @@ -1030,10 +1051,13 @@ 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;
>   		struct acpi_pptt_cache *cache;
>   		struct acpi_pptt_processor *cpu_node;
>   
> +		if (acpi_get_cpu_uid(cpu, &acpi_cpu_id) != 0)
> +			continue;
> +
>   		cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
>   		if (!cpu_node)
>   			continue;
> diff --git a/drivers/acpi/riscv/rhct.c b/drivers/acpi/riscv/rhct.c
> index caa2c16e1697..8f3f38c64a88 100644
> --- a/drivers/acpi/riscv/rhct.c
> +++ b/drivers/acpi/riscv/rhct.c
> @@ -44,10 +44,15 @@ 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;
> +	int ret;
>   
>   	BUG_ON(acpi_disabled);
>   
> +	ret = acpi_get_cpu_uid(cpu, &acpi_cpu_id);
> +	if (ret != 0)
> +		return ret;
> +
>   	if (!table) {
>   		rhct = acpi_get_rhct();
>   		if (!rhct)
> diff --git a/drivers/perf/arm_cspmu/arm_cspmu.c b/drivers/perf/arm_cspmu/arm_cspmu.c
> index 34430b68f602..ed72c3d1f796 100644
> --- a/drivers/perf/arm_cspmu/arm_cspmu.c
> +++ b/drivers/perf/arm_cspmu/arm_cspmu.c
> @@ -1107,15 +1107,17 @@ static int arm_cspmu_acpi_get_cpus(struct arm_cspmu *cspmu)
>   {
>   	struct acpi_apmt_node *apmt_node;
>   	int affinity_flag;
> +	u32 cpu_uid;
>   	int cpu;
> +	int ret;
>   
>   	apmt_node = arm_cspmu_apmt_node(cspmu->dev);
>   	affinity_flag = apmt_node->flags & ACPI_APMT_FLAGS_AFFINITY;
>   
>   	if (affinity_flag == ACPI_APMT_FLAGS_AFFINITY_PROC) {
>   		for_each_possible_cpu(cpu) {
> -			if (apmt_node->proc_affinity ==
> -			    get_acpi_id_for_cpu(cpu)) {
> +			ret = acpi_get_cpu_uid(cpu, &cpu_uid);
> +			if (ret == 0 && apmt_node->proc_affinity == cpu_uid) {
>   				cpumask_set_cpu(cpu, &cspmu->associated_cpus);
>   				break;
>   			}
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index 4d2f0bed7a06..035094a55f18 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -324,6 +324,19 @@ int acpi_unmap_cpu(int cpu);
>   
>   acpi_handle acpi_get_processor_handle(int cpu);
>   
> +#ifndef CONFIG_X86
> +/*
> + * acpi_get_cpu_uid() - Get ACPI Processor UID of a specified CPU from MADT table
> + * @cpu: Logical CPU number (0-based)
> + * @uid: Pointer to store the ACPI Processor UID (valid only on successful return)
> + *
> + * Return: 0 on successful retrieval (the ACPI Processor ID is stored in *uid);
> + *         -EINVAL if the CPU number is invalid or out of range;
> + *         -ENODEV if the ACPI Processor UID for the specified CPU is not found.
> + */
> +int acpi_get_cpu_uid(unsigned int cpu, u32 *uid);
> +#endif
> +
>   #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
>   int acpi_get_ioapic_id(acpi_handle handle, u32 gsi_base, u64 *phys_addr);
>   #endif


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

* Re: [PATCH v7 1/3] ACPI: Refactor get_acpi_id_for_cpu() to acpi_get_cpu_uid() on non-x86
  2026-03-13  2:21 ` [PATCH v7 1/3] ACPI: Refactor get_acpi_id_for_cpu() to acpi_get_cpu_uid() on non-x86 Chengwen Feng
  2026-03-17 21:21   ` Jeremy Linton
@ 2026-03-17 21:38   ` Jeremy Linton
  2026-03-18  2:02     ` fengchengwen
  1 sibling, 1 reply; 8+ messages in thread
From: Jeremy Linton @ 2026-03-17 21:38 UTC (permalink / raw)
  To: Chengwen Feng, Bjorn Helgaas, Catalin Marinas, Will Deacon,
	Rafael J . Wysocki
  Cc: punit.agrawal, guohanjun, suzuki.poulose, ryan.roberts, chenl311,
	masahiroy, wangyuquan1236, anshuman.khandual, heinrich.schuchardt,
	Eric.VanTassell, jonathan.cameron, wangzhou1, wanghuiqiang,
	liuyonglong, linux-pci, linux-doc, linux-kernel, linux-arm-kernel,
	loongarch, linux-riscv, xen-devel, linux-acpi, linux-perf-users,
	stable

Hi,

Lets try this again, since the last one looks like it got caught in the 
moderation system and wasn't quite right anyway.

On 3/12/26 9:21 PM, Chengwen Feng wrote:
> Unify CPU ACPI ID retrieval interface across architectures by
> refactoring get_acpi_id_for_cpu() to acpi_get_cpu_uid() on
> arm64/riscv/loongarch:
> - Add input parameter validation
> - Adjust interface to int acpi_get_cpu_uid(unsigned int cpu, u32 *uid)
>    (old: u32 get_acpi_id_for_cpu(unsigned int cpu), no input check)
> 
> This refactoring (not a pure rename) enhances interface robustness while
> preparing for consistent ACPI Processor UID retrieval across all
> ACPI-enabled platforms. Valid inputs retain original behavior.
> 
> Note: Move the ARM64-specific get_cpu_for_acpi_id() implementation to
>        arch/arm64/kernel/acpi_numa.c to fix compilation errors from
>        circular header dependencies introduced by the rename.
> 
> 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      | 16 +---------
>   arch/arm64/kernel/acpi.c           | 16 ++++++++++
>   arch/arm64/kernel/acpi_numa.c      | 14 +++++++++
>   arch/loongarch/include/asm/acpi.h  |  5 ---
>   arch/loongarch/kernel/acpi.c       |  9 ++++++
>   arch/riscv/include/asm/acpi.h      |  4 ---
>   arch/riscv/kernel/acpi.c           | 16 ++++++++++
>   arch/riscv/kernel/acpi_numa.c      |  9 ++++--
>   drivers/acpi/pptt.c                | 50 ++++++++++++++++++++++--------
>   drivers/acpi/riscv/rhct.c          |  7 ++++-
>   drivers/perf/arm_cspmu/arm_cspmu.c |  6 ++--
>   include/linux/acpi.h               | 13 ++++++++
>   12 files changed, 122 insertions(+), 43 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
> index c07a58b96329..106a08556cbf 100644
> --- a/arch/arm64/include/asm/acpi.h
> +++ b/arch/arm64/include/asm/acpi.h
> @@ -114,22 +114,8 @@ 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)
> -{
> -	return	acpi_cpu_get_madt_gicc(cpu)->uid;
> -}
> -
> -static inline int get_cpu_for_acpi_id(u32 uid)
> -{
> -	int cpu;
> -
> -	for (cpu = 0; cpu < nr_cpu_ids; cpu++)
> -		if (acpi_cpu_get_madt_gicc(cpu) &&
> -		    uid == get_acpi_id_for_cpu(cpu))
> -			return cpu;
>   
> -	return -EINVAL;
> -}
> +int get_cpu_for_acpi_id(u32 uid);
>   
>   static inline void arch_fix_phys_package_id(int num, u32 slot) { }
>   void __init acpi_init_cpus(void);
> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
> index af90128cfed5..f3866606fc46 100644
> --- a/arch/arm64/kernel/acpi.c
> +++ b/arch/arm64/kernel/acpi.c
> @@ -458,3 +458,19 @@ int acpi_unmap_cpu(int cpu)
>   }
>   EXPORT_SYMBOL(acpi_unmap_cpu);
>   #endif /* CONFIG_ACPI_HOTPLUG_CPU */
> +
> +int acpi_get_cpu_uid(unsigned int cpu, u32 *uid)
> +{
> +	struct acpi_madt_generic_interrupt *gicc;
> +
> +	if (cpu >= nr_cpu_ids)
> +		return -EINVAL;
If this actually happens, its probably useful to know it with a 
pr_warn/pr_warn_once.> +
> +	gicc = acpi_cpu_get_madt_gicc(cpu);
> +	if (!gicc)
I think this check is redundant because we can't have logical cpu's that 
aren't in the cpu_possible() list, which on arm64 doesn't AFAIK have 
holes. In the past this might have made sense if we weren't maintaining 
a copy of the gicc structure from the MADT for each core.> +		return 
-ENODEV;
> +
> +	*uid = gicc->uid;
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(acpi_get_cpu_uid);
> diff --git a/arch/arm64/kernel/acpi_numa.c b/arch/arm64/kernel/acpi_numa.c
> index 2465f291c7e1..41d1e46a4338 100644
> --- a/arch/arm64/kernel/acpi_numa.c
> +++ b/arch/arm64/kernel/acpi_numa.c
> @@ -34,6 +34,20 @@ int __init acpi_numa_get_nid(unsigned int cpu)
>   	return acpi_early_node_map[cpu];
>   }
>   
> +int get_cpu_for_acpi_id(u32 uid)
> +{
> +	u32 cpu_uid;
> +	int ret;
> +
> +	for (int cpu = 0; cpu < nr_cpu_ids; cpu++) {
> +		ret = acpi_get_cpu_uid(cpu, &cpu_uid);
This might have been a simplification, but since we are basically doing 
a for_each_possible_cpu(cpu) and every possible cpu will have a GICC 
entry before it becomes 'possible' there will be a UID, so all the error 
checking AFAIK, is impossible here.> +		if (ret == 0 && uid == cpu_uid)
> +			return cpu;
> +	}
> +
> +	return -EINVAL;
> +}
> +
I also moved this below acpi_get_cpu_uid() in acpi.c and I don't see the 
a forward error issue you mentioned. It seems to me that they should be 
kept close to each other since they are basically inverses of each other.

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

* Re: [PATCH v7 1/3] ACPI: Refactor get_acpi_id_for_cpu() to acpi_get_cpu_uid() on non-x86
  2026-03-17 21:38   ` Jeremy Linton
@ 2026-03-18  2:02     ` fengchengwen
  2026-03-18  4:04       ` fengchengwen
  0 siblings, 1 reply; 8+ messages in thread
From: fengchengwen @ 2026-03-18  2:02 UTC (permalink / raw)
  To: Jeremy Linton, Bjorn Helgaas, Catalin Marinas, Will Deacon,
	Rafael J . Wysocki
  Cc: punit.agrawal, guohanjun, suzuki.poulose, ryan.roberts, chenl311,
	masahiroy, wangyuquan1236, anshuman.khandual, heinrich.schuchardt,
	Eric.VanTassell, jonathan.cameron, wangzhou1, wanghuiqiang,
	liuyonglong, linux-pci, linux-doc, linux-kernel, linux-arm-kernel,
	loongarch, linux-riscv, xen-devel, linux-acpi, linux-perf-users,
	stable

Hi,

On 3/18/2026 5:38 AM, Jeremy Linton wrote:
> Hi,
> 
> Lets try this again, since the last one looks like it got caught in the moderation system and wasn't quite right anyway.
> 
> On 3/12/26 9:21 PM, Chengwen Feng wrote:
>> Unify CPU ACPI ID retrieval interface across architectures by
>> refactoring get_acpi_id_for_cpu() to acpi_get_cpu_uid() on
>> arm64/riscv/loongarch:
>> - Add input parameter validation
>> - Adjust interface to int acpi_get_cpu_uid(unsigned int cpu, u32 *uid)
>>    (old: u32 get_acpi_id_for_cpu(unsigned int cpu), no input check)
>>
>> This refactoring (not a pure rename) enhances interface robustness while
>> preparing for consistent ACPI Processor UID retrieval across all
>> ACPI-enabled platforms. Valid inputs retain original behavior.
>>
>> Note: Move the ARM64-specific get_cpu_for_acpi_id() implementation to
>>        arch/arm64/kernel/acpi_numa.c to fix compilation errors from
>>        circular header dependencies introduced by the rename.
>>
>> 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      | 16 +---------
>>   arch/arm64/kernel/acpi.c           | 16 ++++++++++
>>   arch/arm64/kernel/acpi_numa.c      | 14 +++++++++
>>   arch/loongarch/include/asm/acpi.h  |  5 ---
>>   arch/loongarch/kernel/acpi.c       |  9 ++++++
>>   arch/riscv/include/asm/acpi.h      |  4 ---
>>   arch/riscv/kernel/acpi.c           | 16 ++++++++++
>>   arch/riscv/kernel/acpi_numa.c      |  9 ++++--
>>   drivers/acpi/pptt.c                | 50 ++++++++++++++++++++++--------
>>   drivers/acpi/riscv/rhct.c          |  7 ++++-
>>   drivers/perf/arm_cspmu/arm_cspmu.c |  6 ++--
>>   include/linux/acpi.h               | 13 ++++++++
>>   12 files changed, 122 insertions(+), 43 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
>> index c07a58b96329..106a08556cbf 100644
>> --- a/arch/arm64/include/asm/acpi.h
>> +++ b/arch/arm64/include/asm/acpi.h
>> @@ -114,22 +114,8 @@ 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)
>> -{
>> -    return    acpi_cpu_get_madt_gicc(cpu)->uid;
>> -}
>> -
>> -static inline int get_cpu_for_acpi_id(u32 uid)
>> -{
>> -    int cpu;
>> -
>> -    for (cpu = 0; cpu < nr_cpu_ids; cpu++)
>> -        if (acpi_cpu_get_madt_gicc(cpu) &&
>> -            uid == get_acpi_id_for_cpu(cpu))
>> -            return cpu;
>>   -    return -EINVAL;
>> -}
>> +int get_cpu_for_acpi_id(u32 uid);
>>     static inline void arch_fix_phys_package_id(int num, u32 slot) { }
>>   void __init acpi_init_cpus(void);
>> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
>> index af90128cfed5..f3866606fc46 100644
>> --- a/arch/arm64/kernel/acpi.c
>> +++ b/arch/arm64/kernel/acpi.c
>> @@ -458,3 +458,19 @@ int acpi_unmap_cpu(int cpu)
>>   }
>>   EXPORT_SYMBOL(acpi_unmap_cpu);
>>   #endif /* CONFIG_ACPI_HOTPLUG_CPU */
>> +
>> +int acpi_get_cpu_uid(unsigned int cpu, u32 *uid)
>> +{
>> +    struct acpi_madt_generic_interrupt *gicc;
>> +
>> +    if (cpu >= nr_cpu_ids)
>> +        return -EINVAL;
> If this actually happens, its probably useful to know it with a pr_warn/pr_warn_once.> +

The function maybe called from userspace which on later roadmap, so I prefer not add
warning or error here.
BTW: the function will return -EINVAL, so caller could know the case.

>> +    gicc = acpi_cpu_get_madt_gicc(cpu);
>> +    if (!gicc)
> I think this check is redundant because we can't have logical cpu's that aren't in the cpu_possible() list, which on arm64 doesn't AFAIK have holes. In the past this might have made sense if we weren't maintaining a copy of the gicc structure from the MADT for each core.> +        return -ENODEV;

This commit will backport to stable branch at least 6.6. So I think it's OK to keep it.

>> +
>> +    *uid = gicc->uid;
>> +    return 0;
>> +}
>> +EXPORT_SYMBOL_GPL(acpi_get_cpu_uid);
>> diff --git a/arch/arm64/kernel/acpi_numa.c b/arch/arm64/kernel/acpi_numa.c
>> index 2465f291c7e1..41d1e46a4338 100644
>> --- a/arch/arm64/kernel/acpi_numa.c
>> +++ b/arch/arm64/kernel/acpi_numa.c
>> @@ -34,6 +34,20 @@ int __init acpi_numa_get_nid(unsigned int cpu)
>>       return acpi_early_node_map[cpu];
>>   }
>>   +int get_cpu_for_acpi_id(u32 uid)
>> +{
>> +    u32 cpu_uid;
>> +    int ret;
>> +
>> +    for (int cpu = 0; cpu < nr_cpu_ids; cpu++) {
>> +        ret = acpi_get_cpu_uid(cpu, &cpu_uid);
> This might have been a simplification, but since we are basically doing a for_each_possible_cpu(cpu) and every possible cpu will have a GICC entry before it becomes 'possible' there will be a UID, so all the error checking AFAIK, is impossible here.> +        if (ret == 0 && uid == cpu_uid)

I prefer to keep the current impl, as it may catch future error.

>> +            return cpu;
>> +    }
>> +
>> +    return -EINVAL;
>> +}
>> +
> I also moved this below acpi_get_cpu_uid() in acpi.c and I don't see the a forward error issue you mentioned. It seems to me that they should be kept close to each other since they are basically inverses of each other.

As long as you ensure that it is not placed in asm/acpi.h, that's fine.
So it's OK to move this function to acpi.c

But I just checked the callers of this function again and found that there are
all in acpi_numa.c, so I will now add the static keyword to this function and
make it an internal function.

Thanks

> 


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

* Re: [PATCH v7 1/3] ACPI: Refactor get_acpi_id_for_cpu() to acpi_get_cpu_uid() on non-x86
  2026-03-18  2:02     ` fengchengwen
@ 2026-03-18  4:04       ` fengchengwen
  0 siblings, 0 replies; 8+ messages in thread
From: fengchengwen @ 2026-03-18  4:04 UTC (permalink / raw)
  To: Jeremy Linton, Bjorn Helgaas, Catalin Marinas, Will Deacon,
	Rafael J . Wysocki
  Cc: punit.agrawal, guohanjun, suzuki.poulose, ryan.roberts, chenl311,
	masahiroy, wangyuquan1236, anshuman.khandual, heinrich.schuchardt,
	Eric.VanTassell, jonathan.cameron, wangzhou1, wanghuiqiang,
	liuyonglong, linux-pci, linux-doc, linux-kernel, linux-arm-kernel,
	loongarch, linux-riscv, xen-devel, linux-acpi, linux-perf-users,
	stable

Sorry to self-reply

On 3/18/2026 10:02 AM, fengchengwen wrote:
> Hi,
> 
> On 3/18/2026 5:38 AM, Jeremy Linton wrote:
>> Hi,
>>
>> Lets try this again, since the last one looks like it got caught in the moderation system and wasn't quite right anyway.
>>
>> On 3/12/26 9:21 PM, Chengwen Feng wrote:
>>> Unify CPU ACPI ID retrieval interface across architectures by
>>> refactoring get_acpi_id_for_cpu() to acpi_get_cpu_uid() on
>>> arm64/riscv/loongarch:
>>> - Add input parameter validation
>>> - Adjust interface to int acpi_get_cpu_uid(unsigned int cpu, u32 *uid)
>>>    (old: u32 get_acpi_id_for_cpu(unsigned int cpu), no input check)
>>>
>>> This refactoring (not a pure rename) enhances interface robustness while
>>> preparing for consistent ACPI Processor UID retrieval across all
>>> ACPI-enabled platforms. Valid inputs retain original behavior.
>>>
>>> Note: Move the ARM64-specific get_cpu_for_acpi_id() implementation to
>>>        arch/arm64/kernel/acpi_numa.c to fix compilation errors from
>>>        circular header dependencies introduced by the rename.
>>>
>>> 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      | 16 +---------
>>>   arch/arm64/kernel/acpi.c           | 16 ++++++++++
>>>   arch/arm64/kernel/acpi_numa.c      | 14 +++++++++
>>>   arch/loongarch/include/asm/acpi.h  |  5 ---
>>>   arch/loongarch/kernel/acpi.c       |  9 ++++++
>>>   arch/riscv/include/asm/acpi.h      |  4 ---
>>>   arch/riscv/kernel/acpi.c           | 16 ++++++++++
>>>   arch/riscv/kernel/acpi_numa.c      |  9 ++++--
>>>   drivers/acpi/pptt.c                | 50 ++++++++++++++++++++++--------
>>>   drivers/acpi/riscv/rhct.c          |  7 ++++-
>>>   drivers/perf/arm_cspmu/arm_cspmu.c |  6 ++--
>>>   include/linux/acpi.h               | 13 ++++++++
>>>   12 files changed, 122 insertions(+), 43 deletions(-)
>>>
>>> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
>>> index c07a58b96329..106a08556cbf 100644
>>> --- a/arch/arm64/include/asm/acpi.h
>>> +++ b/arch/arm64/include/asm/acpi.h
>>> @@ -114,22 +114,8 @@ 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)
>>> -{
>>> -    return    acpi_cpu_get_madt_gicc(cpu)->uid;
>>> -}
>>> -
>>> -static inline int get_cpu_for_acpi_id(u32 uid)
>>> -{
>>> -    int cpu;
>>> -
>>> -    for (cpu = 0; cpu < nr_cpu_ids; cpu++)
>>> -        if (acpi_cpu_get_madt_gicc(cpu) &&
>>> -            uid == get_acpi_id_for_cpu(cpu))
>>> -            return cpu;
>>>   -    return -EINVAL;
>>> -}
>>> +int get_cpu_for_acpi_id(u32 uid);
>>>     static inline void arch_fix_phys_package_id(int num, u32 slot) { }
>>>   void __init acpi_init_cpus(void);
>>> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
>>> index af90128cfed5..f3866606fc46 100644
>>> --- a/arch/arm64/kernel/acpi.c
>>> +++ b/arch/arm64/kernel/acpi.c
>>> @@ -458,3 +458,19 @@ int acpi_unmap_cpu(int cpu)
>>>   }
>>>   EXPORT_SYMBOL(acpi_unmap_cpu);
>>>   #endif /* CONFIG_ACPI_HOTPLUG_CPU */
>>> +
>>> +int acpi_get_cpu_uid(unsigned int cpu, u32 *uid)
>>> +{
>>> +    struct acpi_madt_generic_interrupt *gicc;
>>> +
>>> +    if (cpu >= nr_cpu_ids)
>>> +        return -EINVAL;
>> If this actually happens, its probably useful to know it with a pr_warn/pr_warn_once.> +
> 
> The function maybe called from userspace which on later roadmap, so I prefer not add
> warning or error here.
> BTW: the function will return -EINVAL, so caller could know the case.
> 
>>> +    gicc = acpi_cpu_get_madt_gicc(cpu);
>>> +    if (!gicc)
>> I think this check is redundant because we can't have logical cpu's that aren't in the cpu_possible() list, which on arm64 doesn't AFAIK have holes. In the past this might have made sense if we weren't maintaining a copy of the gicc structure from the MADT for each core.> +        return -ENODEV;
> 
> This commit will backport to stable branch at least 6.6. So I think it's OK to keep it.
> 
>>> +
>>> +    *uid = gicc->uid;
>>> +    return 0;
>>> +}
>>> +EXPORT_SYMBOL_GPL(acpi_get_cpu_uid);
>>> diff --git a/arch/arm64/kernel/acpi_numa.c b/arch/arm64/kernel/acpi_numa.c
>>> index 2465f291c7e1..41d1e46a4338 100644
>>> --- a/arch/arm64/kernel/acpi_numa.c
>>> +++ b/arch/arm64/kernel/acpi_numa.c
>>> @@ -34,6 +34,20 @@ int __init acpi_numa_get_nid(unsigned int cpu)
>>>       return acpi_early_node_map[cpu];
>>>   }
>>>   +int get_cpu_for_acpi_id(u32 uid)
>>> +{
>>> +    u32 cpu_uid;
>>> +    int ret;
>>> +
>>> +    for (int cpu = 0; cpu < nr_cpu_ids; cpu++) {
>>> +        ret = acpi_get_cpu_uid(cpu, &cpu_uid);
>> This might have been a simplification, but since we are basically doing a for_each_possible_cpu(cpu) and every possible cpu will have a GICC entry before it becomes 'possible' there will be a UID, so all the error checking AFAIK, is impossible here.> +        if (ret == 0 && uid == cpu_uid)
> 
> I prefer to keep the current impl, as it may catch future error.
> 
>>> +            return cpu;
>>> +    }
>>> +
>>> +    return -EINVAL;
>>> +}
>>> +
>> I also moved this below acpi_get_cpu_uid() in acpi.c and I don't see the a forward error issue you mentioned. It seems to me that they should be kept close to each other since they are basically inverses of each other.
> 
> As long as you ensure that it is not placed in asm/acpi.h, that's fine.
> So it's OK to move this function to acpi.c
> 
> But I just checked the callers of this function again and found that there are
> all in acpi_numa.c, so I will now add the static keyword to this function and
> make it an internal function.

I just found drivers/irqchip/irq-gic-v3.c has a call for get_cpu_for_acpi_id,
so We should not marking as static.

According to your advise, I moved it in acpi.c in v8.

Thanks

> 
> Thanks
> 
>>
> 


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

end of thread, other threads:[~2026-03-18  4:04 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-13  2:21 [PATCH v7 0/3] Fix get cpu steer-tag fail on ARM64 platform Chengwen Feng
2026-03-13  2:21 ` [PATCH v7 1/3] ACPI: Refactor get_acpi_id_for_cpu() to acpi_get_cpu_uid() on non-x86 Chengwen Feng
2026-03-17 21:21   ` Jeremy Linton
2026-03-17 21:38   ` Jeremy Linton
2026-03-18  2:02     ` fengchengwen
2026-03-18  4:04       ` fengchengwen
2026-03-13  2:21 ` [PATCH v7 2/3] x86: Implement acpi_get_cpu_uid() Chengwen Feng
2026-03-13  2:21 ` [PATCH v7 3/3] PCI/TPH: Fix get cpu steer-tag fail on ARM64 platform Chengwen Feng

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