diff --git a/Documentation/PCI/tph.rst b/Documentation/PCI/tph.rst index e8993be64fd64d..b6cf22b9bd90a5 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/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h index c07a58b96329d8..8a54ca6ba60282 100644 --- a/arch/arm64/include/asm/acpi.h +++ b/arch/arm64/include/asm/acpi.h @@ -114,22 +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) -{ - 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 af90128cfed56d..24b9d934be547c 100644 --- a/arch/arm64/kernel/acpi.c +++ b/arch/arm64/kernel/acpi.c @@ -458,3 +458,33 @@ 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); + +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; +} diff --git a/arch/loongarch/include/asm/acpi.h b/arch/loongarch/include/asm/acpi.h index 7376840fa9f78a..eda9d4d0a493c1 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 1367ca759468f9..058f0dbe8e8f97 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 6e13695120bc21..26ab37c171bcf6 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 26c018ebce03c5..12d22fab892bc6 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 130769e3a99c3b..6a2d4289f806e4 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/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h index ad235dda1ded0f..57a0786dfd75da 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 84951572ab8170..05d1d479b4cf3d 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 a3f2fb1fea1bc9..ceba24f65ae3a8 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 fe57ff85d004ba..2f9fa27e5a3c23 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/drivers/acpi/pptt.c b/drivers/acpi/pptt.c index de5f8c018333d7..7bd5bc1f225a41 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 caa2c16e16974a..8f3f38c64a88aa 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/pci/tph.c b/drivers/pci/tph.c index ca4f97be75389d..b67c9ad14bdaad 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/drivers/perf/arm_cspmu/arm_cspmu.c b/drivers/perf/arm_cspmu/arm_cspmu.c index 34430b68f60254..ed72c3d1f79678 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 3a412dcebc296d..da43177da4028f 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -324,6 +324,17 @@ int acpi_unmap_cpu(int cpu); acpi_handle acpi_get_processor_handle(int cpu); +/** + * acpi_get_cpu_uid() - Get ACPI Processor UID of from MADT table + * @cpu: Logical CPU number (0-based) + * @uid: Pointer to store ACPI Processor UID + * + * Return: 0 on success (ACPI Processor ID stored in *uid); + * -EINVAL if CPU number is invalid or out of range; + * -ENODEV if ACPI Processor UID for the CPU is not found. + */ +int acpi_get_cpu_uid(unsigned int cpu, u32 *uid); + #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 ba28140ce67076..be68cd17f2f833 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)