From 534ad2fc53af6da735b49732a7b8cdfb3540d6b3 Mon Sep 17 00:00:00 2001 From: Yu Liao Date: Fri, 9 Jun 2023 13:06:51 +0800 Subject: [PATCH] ACPI / PPTT: Find PPTT processor node by cache id openeuler inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I77UDW CVE: NA -------------------------------- The MPAM table identifies caches by id, but the driver also wants to know the processor node. Add a helper that walks every possible cache, until it finds the one identified by id, then return processor node. Signed-off-by: Yu Liao --- drivers/acpi/pptt.c | 55 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/acpi.h | 5 ++++ 2 files changed, 60 insertions(+) diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c index 3d9403ded527..c0f722ecb3c7 100644 --- a/drivers/acpi/pptt.c +++ b/drivers/acpi/pptt.c @@ -958,3 +958,58 @@ int __init acpi_pptt_init(void) return 0; } + +struct acpi_pptt_processor *find_acpi_processor_node_from_cache_id(u32 cache_id) +{ + u32 acpi_cpu_id; + acpi_status status; + int level, cpu, num_levels; + struct acpi_pptt_cache *cache; + struct acpi_table_header *table; + struct acpi_pptt_cache_v1 *cache_v1; + struct acpi_pptt_processor *cpu_node; + + status = acpi_get_table(ACPI_SIG_PPTT, 0, &table); + if (ACPI_FAILURE(status)) { + acpi_pptt_warn_missing(); + return NULL; + } + + if (table->revision < 3) { + acpi_put_table(table); + return NULL; + } + + /* + * If we found the cache first, we'd still need to walk from each CPU + * to find the level... + */ + for_each_possible_cpu(cpu) { + acpi_cpu_id = get_acpi_id_for_cpu(cpu); + cpu_node = acpi_find_processor_node(table, acpi_cpu_id); + if (!cpu_node) + break; + num_levels = acpi_count_levels(table, cpu_node); + + for (level = 0; level <= num_levels; level++) { + cache = acpi_find_cache_node(table, acpi_cpu_id, + ACPI_PPTT_CACHE_TYPE_UNIFIED, + level, &cpu_node); + if (!cache) + continue; + + cache_v1 = ACPI_ADD_PTR(struct acpi_pptt_cache_v1, + cache, + sizeof(struct acpi_pptt_cache)); + + if (cache->flags & ACPI_PPTT_CACHE_ID_VALID && + cache_v1->cache_id == cache_id) { + acpi_put_table(table); + return cpu_node; + } + } + } + + acpi_put_table(table); + return NULL; +} diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 7c14b71464df..ce073553510f 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -1367,6 +1367,7 @@ int find_acpi_cpu_topology_cluster(unsigned int cpu); int find_acpi_cpu_topology_package(unsigned int cpu); int find_acpi_cpu_topology_hetero_id(unsigned int cpu); int find_acpi_cpu_cache_topology(unsigned int cpu, int level); +struct acpi_pptt_processor *find_acpi_processor_node_from_cache_id(u32 cache_id); #else static inline int acpi_pptt_cpu_is_thread(unsigned int cpu) { @@ -1392,6 +1393,10 @@ static inline int find_acpi_cpu_cache_topology(unsigned int cpu, int level) { return -EINVAL; } +static inline struct acpi_pptt_processor *find_acpi_processor_node_from_cache_id(u32 cache_id) +{ + return NULL; +} #endif #ifdef CONFIG_ACPI -- GitLab