From: James Morse <james.morse(a)arm.com>
commit cf2bbc7e5bb6be1096bd31cedc7bf6c6f135ded8 openEuler-1.0
hulk inclusion
category: feature
bugzilla: 28055
CVE: NA
------------------------------
The alpha MPAM table contains a pointer to the PPTT cache, which it
expects to be unique, which isn't guaranteed.
Ideally we'd take a cache-id, but the hardware doesn't have a
suitable property, instead arm64 will generate an id from the cpu
affinity ids.
To find the cache id we need to find the cacheinfo structure, which
we can do if we have a pptt cpu_node (different to the cache node),
as this is the fw_token used to match the Processor Container that
contains all the CPUs that share this cache.
How can we find the expected-to-be-unique cpu_node from the cache_node?
... add acpi_pptt_find_cache_backwards() to find a PPTT processor node
given a PPTT cache node. This is totally broken as many processor nodes
may point at the same PPTT cache indicating different instances of the
cache. (e.g. all the L1 caches are the same shape, but they aren't the
same cache).
This only works if you cooked your PPTT table to look like this.
Signed-off-by: James Morse <james.morse(a)arm.com> # ... but its still GPLv2
Signed-off-by: Wang ShaoBo <bobo.shaobowang(a)huawei.com>
Reviewed-By: Xie XiuQi <xiexiuqi(a)huawei.com>
Signed-off-by: Yang Yingliang <yangyingliang(a)huawei.com>
Signed-off-by: Xin Hao <haoxing990(a)gmail.com>
---
drivers/acpi/pptt.c | 50 ++++++++++++++++++++++++++++++++++++++++++++
include/linux/acpi.h | 4 ++++
2 files changed, 54 insertions(+)
diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c
index f0aa0b4d721a..190765300349 100644
--- a/drivers/acpi/pptt.c
+++ b/drivers/acpi/pptt.c
@@ -280,6 +280,56 @@ static struct acpi_pptt_processor *acpi_find_processor_node(struct
acpi_table_he
return NULL;
}
+
+
+/*
+ * acpi_pptt_find_cache_backwards() - Given a PPTT cache find a processor node
+ * that points to it. This lets us find a cacheinfo node by fw_token, but
+ * is totally broken as many processor node may point at the same PPTT
+ * cache indicating different instances of the cache. (e.g. all the L1
+ * caches are the same shape, but they aren't the same cache).
+ * This only works if you cooked your PPTT table to look like this.
+ */
+struct acpi_pptt_processor *
+acpi_pptt_find_cache_backwards(struct acpi_table_header *table_hdr,
+ struct acpi_pptt_cache *cache)
+{
+ struct acpi_pptt_processor *cpu_node;
+ struct acpi_subtable_header *entry;
+ struct acpi_subtable_header *res;
+ unsigned long table_end;
+ u32 proc_sz;
+ int i;
+
+ table_end = (unsigned long)table_hdr + table_hdr->length;
+ entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr,
+ sizeof(struct acpi_table_pptt));
+ proc_sz = sizeof(struct acpi_pptt_processor *);
+
+ /* find the processor structure which points at with this cpuid */
+ while ((unsigned long)entry + proc_sz < table_end) {
+ if (entry->length == 0) {
+ pr_warn("Invalid zero length subtable\n");
+ break;
+ }
+
+ cpu_node = (struct acpi_pptt_processor *)entry;
+ entry = ACPI_ADD_PTR(struct acpi_subtable_header, entry,
+ entry->length);
+
+ if (cpu_node->header.type != ACPI_PPTT_TYPE_PROCESSOR)
+ continue;
+
+ for (i = 0; i < cpu_node->number_of_priv_resources; i++) {
+ res = acpi_get_pptt_resource(table_hdr, cpu_node, i);
+ if (&cache->header == res)
+ return cpu_node;
+ }
+ }
+
+ return NULL;
+}
+
/**
* acpi_validate_cache_node() - Given an offset in the table, check this is
* a cache node.
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 63fb5bcb1a65..1cba6251c42b 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -1349,4 +1349,8 @@ static inline int find_acpi_cpu_cache_topology(unsigned int cpu, int
level)
}
#endif
+struct acpi_pptt_processor *
+acpi_pptt_find_cache_backwards(struct acpi_table_header *table_hdr,
+ struct acpi_pptt_cache *cache);
+
#endif /*_LINUX_ACPI_H*/
--
2.31.0