From: James Morse james.morse@arm.com
hulk inclusion category: feature bugzilla: 34278 CVE: NA
-------------------------------------------------
The MPAM ACPI table holds a PPTT-offset that describes a cache. Add a helper cacheinfo_shared_cpu_map_search() to search the cacheinfo structures for a cache that represents this firmware description.
The cacheinfo structures are freed and allocated over CPU online/offline, the caller of this helper must hold the cpu-hotplug read lock while the helper runs, and while it holds the return value.
Signed-off-by: James Morse james.morse@arm.com Link: http://www.linux-arm.org/git?p=linux-jm.git;a=patch;h=9e5b7ec7c145019f7160c5... Signed-off-by: Wang ShaoBo bobo.shaobowang@huawei.com Reviewed-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Cheng Jian cj.chengjian@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Signed-off-by: Cheng Jian cj.chengjian@huawei.com --- drivers/base/cacheinfo.c | 38 ++++++++++++++++++++++++++++++++++++++ include/linux/cacheinfo.h | 1 + 2 files changed, 39 insertions(+)
diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c index 7ada06f5d961..aee69d78c2e7 100644 --- a/drivers/base/cacheinfo.c +++ b/drivers/base/cacheinfo.c @@ -213,6 +213,44 @@ int __weak cache_setup_acpi(unsigned int cpu) return -ENOTSUPP; }
+/** + * cacheinfo_shared_cpu_map_search() - find an instance of struct cacheinfo + * from the provided firmware description. + * Caller must hold cpus_read_lock() until its finished with the cacheinfo. + * + * Return a CPUs cache leaf described @fw_desc, or NULL. + */ +struct cacheinfo *cacheinfo_shared_cpu_map_search(void *fw_token) +{ + struct cacheinfo *iter; + unsigned int cpu, index; + struct cpu_cacheinfo *cpu_ci; + + for_each_online_cpu(cpu) { + cpu_ci = get_cpu_cacheinfo(cpu); + + /* + * info_list of this cacheinfo instance + * may not be initialized because sometimes + * free_cache_attributes() may free this + * info_list but not set num_leaves to zero, + * for example when PPTT is not supported. + */ + if (!cpu_ci->info_list) + continue; + + for (index = 0; index < cache_leaves(cpu); index++) { + iter = cpu_ci->info_list + index; + + if (iter->fw_token == fw_token) { + return iter; + } + } + } + + return NULL; +} + unsigned int coherency_max_size;
static int cache_shared_cpu_map_setup(unsigned int cpu) diff --git a/include/linux/cacheinfo.h b/include/linux/cacheinfo.h index 6db3f7f8a7d6..2e5ab4cde3fe 100644 --- a/include/linux/cacheinfo.h +++ b/include/linux/cacheinfo.h @@ -97,6 +97,7 @@ int func(unsigned int cpu) \ }
struct cpu_cacheinfo *get_cpu_cacheinfo(unsigned int cpu); +struct cacheinfo *cacheinfo_shared_cpu_map_search(void *fw_desc); int init_cache_level(unsigned int cpu); int populate_cache_leaves(unsigned int cpu); int cache_setup_acpi(unsigned int cpu);