From: Bjorn Helgaas <helgaas@kernel.org>
To: Chengwen Feng <fengchengwen@huawei.com>
Cc: linux-pci@vger.kernel.org, bhelgaas@google.com,
linux-acpi@vger.kernel.org, rafael@kernel.org, lenb@kernel.org,
wei.huang2@amd.com, Eric.VanTassell@amd.com,
jonathan.cameron@huawei.com, wangzhou1@hisilicon.com,
wanghuiqiang@huawei.com, liuyonglong@huawei.com,
stable@vger.kernel.org, Jeremy Linton <jeremy.linton@arm.com>,
Sunil V L <sunilvl@ventanamicro.com>,
Sunil V L <sunilvl@oss.qualcomm.com>,
Huacai Chen <chenhuacai@loongson.cn>,
Liupu Wang <wangliupu@loongson.cn>
Subject: Re: [PATCH] PCI/TPH: Fix get cpu steer-tag fail on ARM64 platform
Date: Tue, 3 Mar 2026 13:02:11 -0600 [thread overview]
Message-ID: <20260303190211.GA4059782@bhelgaas> (raw)
In-Reply-To: <20260303003625.39035-1-fengchengwen@huawei.com>
[+cc Jeremy, Sunil, Huacai, Liupu, authors of get_acpi_id_for_cpu()
for arm64, riscv, loongson]
On Tue, Mar 03, 2026 at 08:36:25AM +0800, Chengwen Feng wrote:
> Currently the pcie_tph_get_cpu_st() has a problem on ARM64 platform:
> 1. The pcie_tph_get_cpu_st() function directly uses cpu_uid as the input
> parameter to call the PCI ACPI DSM method. According to the DSM
> definition, the input value should be the ACPI Processor UID. For
> details, please see [1].
>
> 2. In the Broadcom driver implementation [2] (which invoke
> pcie_tph_get_cpu_st()), cpu_uid is obtained based on
> cpumask_first(irq->cpu_mask), that is the logical ID of a CPU core,
> which is generated and managed by the kernel. For example, [0,255]
> if the system has 256 logical CPU cores.
> 3. Unfortunately, on ARM64 platform, ACPI assigns Processor UID to the
> core which listed in the MADT table, the Processor UID may not equal
> the logical ID of a CPU core in the kernel. So the current
> implementation cannot obtain the cpu's real steer-tag in such case.
> 4. The reason why it can run on the AMD platform is that the mapping
> between the logical ID and ACPI Processor UID is similar.
>
> This commit fixes it by:
> 1. Introduce config ARCH_HAS_GET_CPU_ACPI_ID_API and its corresponding
> API acpi_get_cpu_acpi_id() to obtain the ACPI Processor UID of a CPU
> core. This API invokes get_acpi_id_for_cpu() to obtain the UID on
> ARM64 platform.
> 2. Because using the logical ID as the ACPI Processor UID directly on
> X86 platform is not standard. This commit uses cpu_acpi_id() to
> obtain the UID.
> 3. At the same time, the input parameter cpu_uid of
> pcie_tph_get_cpu_st() is renamed to cpu for clarity.
Thanks for raising this issue!
TLP Processing Hints (TPH) and Steering Tags are generic PCIe features
that we should support for both ACPI and non-ACPI systems.
The current implementation of pcie_tph_get_cpu_st() only supports
ACPI, and it assumes the cpu_uid parameter is an ACPI CPU UID that can
be passed directly to the _DSM. But since we want this to be a
generic interface, I think the "cpu" parameter should be the Linux
logical CPU ID, not an ACPI UID, as you point out.
> [1] According to the _DSM ECN, 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."
This needs a specific spec citation for the _DSM function. Ideally it
would be "PCI Firmware spec r3.3, sec xx", but I don't think there's a
revision of the spec that includes this ECN. But we can at least
include the actual name and URL for the approved ECN.
> [2] commit c214410c47d6e ("bnxt_en: Add TPH support in BNXT driver")
>
> Fixes: d2e8a34876ce ("PCI/TPH: Add Steering Tag support")
> Cc: stable@vger.kernel.org
> Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
> ---
> Documentation/PCI/tph.rst | 4 ++--
> drivers/acpi/Kconfig | 8 ++++++++
> drivers/acpi/processor_core.c | 13 +++++++++++++
> drivers/pci/tph.c | 13 +++++++------
> include/linux/acpi.h | 4 ++++
> include/linux/pci-tph.h | 4 ++--
> 6 files changed, 36 insertions(+), 10 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/acpi/Kconfig b/drivers/acpi/Kconfig
> index df0ff0764d0d..9d851a017cd1 100644
> --- a/drivers/acpi/Kconfig
> +++ b/drivers/acpi/Kconfig
> @@ -606,6 +606,14 @@ config ACPI_PRMT
> substantially increase computational overhead related to the
> initialization of some server systems.
>
> +config ARCH_HAS_GET_CPU_ACPI_ID_API
> + bool "Architecture supports get cpu's ACPI Processor UID"
> + depends on (X86 || ARM64)
> + default y
> + help
> + This config indicates whether the architecture provides a standard
> + API to get ACPI Processor UID of a cpu from MADT table.
> +
> endif # ACPI
>
> config X86_PM_TIMER
> diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
> index a4498357bd16..6150f5bdb62e 100644
> --- a/drivers/acpi/processor_core.c
> +++ b/drivers/acpi/processor_core.c
> @@ -335,6 +335,19 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id)
> }
> EXPORT_SYMBOL_GPL(acpi_get_cpuid);
>
> +#ifdef CONFIG_ARCH_HAS_GET_CPU_ACPI_ID_API
> +unsigned int acpi_get_cpu_acpi_id(unsigned int cpu)
> +{
> + if (cpu >= nr_cpu_ids)
> + return 0;
> +#ifdef CONFIG_X86
> + return cpu_acpi_id(cpu);
> +#elif CONFIG_ARM64
> + return get_acpi_id_for_cpu(cpu);
> +#endif
> +}
> +#endif /* CONFIG_ARCH_HAS_GET_CPU_ACPI_ID_API */
> +
> #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
> static int get_ioapic_id(struct acpi_subtable_header *entry, u32 gsi_base,
> u64 *phys_addr, int *ioapic_id)
> diff --git a/drivers/pci/tph.c b/drivers/pci/tph.c
> index ca4f97be7538..a47c2fbb6148 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
> +#ifdef CONFIG_ARCH_HAS_GET_CPU_ACPI_ID_API
> + unsigned int cpu_uid = acpi_get_cpu_acpi_id(cpu);
Any required conversion between Linux logical CPU and ACPI CPU UID
should be internal to pcie_tph_get_cpu_st(), as you're doing here.
But rather than adding CONFIG_ARCH_HAS_GET_CPU_ACPI_ID_API and the
ifdefs in acpi_get_cpu_acpi_id(), I think there should be a generic
ACPI interface that converts logical CPU ID to ACPI UID, and every
arch supporting ACPI should have to implement it.
We already have get_acpi_id_for_cpu(), implemented for arm64, riscv,
and loongarch:
30d87bfacbee ("arm64/acpi: Create arch specific cpu to acpi id helper")
f99561199470 ("RISC-V: ACPI: Cache and retrieve the RINTC structure")
f6f0c9a74a48 ("LoongArch: Add SMT (Simultaneous Multi-Threading) support")
What if we just implemented it for x86 as well and moved it to
include/linux/acpi.h or similar?
> 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/acpi.h b/include/linux/acpi.h
> index 4d2f0bed7a06..789bfcb8e0f3 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -324,6 +324,10 @@ int acpi_unmap_cpu(int cpu);
>
> acpi_handle acpi_get_processor_handle(int cpu);
>
> +#ifdef CONFIG_ARCH_HAS_GET_CPU_ACPI_ID_API
> +unsigned int acpi_get_cpu_acpi_id(unsigned int cpu);
> +#endif
> +
> #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
> int acpi_get_ioapic_id(acpi_handle handle, u32 gsi_base, u64 *phys_addr);
> #endif
> 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
>
next prev parent reply other threads:[~2026-03-03 19:02 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-03 0:36 [PATCH] PCI/TPH: Fix get cpu steer-tag fail on ARM64 platform Chengwen Feng
2026-03-03 19:02 ` Bjorn Helgaas [this message]
2026-03-04 9:28 ` fengchengwen
2026-03-04 15:38 ` Bjorn Helgaas
2026-03-05 8:40 ` fengchengwen
2026-03-04 13:50 ` kernel test robot
2026-03-04 23:18 ` kernel test robot
2026-03-05 0:02 ` kernel test robot
2026-03-05 1:29 ` kernel test robot
2026-03-05 8:36 ` [PATCH v2] " Chengwen Feng
2026-03-05 8:53 ` Huacai Chen
2026-03-05 9:07 ` fengchengwen
2026-03-05 14:54 ` Jonathan Cameron
2026-03-06 2:20 ` fengchengwen
2026-03-06 2:19 ` [PATCH v3] " Chengwen Feng
2026-03-06 10:01 ` Jonathan Cameron
2026-03-09 4:18 ` fengchengwen
2026-03-09 4:16 ` [PATCH v4 0/2] " Chengwen Feng
2026-03-09 4:16 ` [PATCH v4 1/2] ACPI: Rename get_acpi_id_for_cpu() to acpi_get_cpu_acpi_id() on non-x86 Chengwen Feng
2026-03-09 10:30 ` Jonathan Cameron
2026-03-09 13:29 ` Huacai Chen
2026-03-10 3:29 ` fengchengwen
2026-03-09 4:16 ` [PATCH v4 2/2] PCI/TPH: Fix get cpu steer-tag fail on ARM64 platform Chengwen Feng
2026-03-09 10:59 ` Jonathan Cameron
2026-03-09 10:28 ` [PATCH v4 0/2] " Jonathan Cameron
2026-03-10 3:26 ` fengchengwen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260303190211.GA4059782@bhelgaas \
--to=helgaas@kernel.org \
--cc=Eric.VanTassell@amd.com \
--cc=bhelgaas@google.com \
--cc=chenhuacai@loongson.cn \
--cc=fengchengwen@huawei.com \
--cc=jeremy.linton@arm.com \
--cc=jonathan.cameron@huawei.com \
--cc=lenb@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=liuyonglong@huawei.com \
--cc=rafael@kernel.org \
--cc=stable@vger.kernel.org \
--cc=sunilvl@oss.qualcomm.com \
--cc=sunilvl@ventanamicro.com \
--cc=wanghuiqiang@huawei.com \
--cc=wangliupu@loongson.cn \
--cc=wangzhou1@hisilicon.com \
--cc=wei.huang2@amd.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox