From da7196c98cc78639438556db3dbf94da936a9d6f Mon Sep 17 00:00:00 2001
From: Wang ShaoBo <bobo.shaobowang@huawei.com>
Date: Thu, 16 Apr 2020 11:05:07 +0800
Subject: [PATCH 2872/2944] openEuler: ACPI / PPTT: cacheinfo: Label caches
 based on fw_token

commit 96c482e9dffa956ef525277fb2f9035be4bcb432 openEuler-1.0

hulk inclusion
category: feature
bugzilla: 28055
CVE: NA

------------------------------

According to James's implementation: http://www.linux-arm.org/git?p=linux-
jm.git;a=commit;h=413eb4281b072e1ee60f88b814f2a418358f2155, "ACPI / PPTT:
cacheinfo: Label caches based on fw_token".

For resctrl ABI, cache node labeled by min_physid of leaf cpu node can
not be good recognized, for this, we use to label each cache node by
numa node id, it can be acquired by leaf cpu node with min_physid.

But there also has some problems when doing this, with current MPAM ACPI
Description 1.0, we haven't enough information to label those cache node
when using partition mode, we hope fixing that when getting unified des-
cription.

Signed-off-by: Wang ShaoBo <bobo.shaobowang@huawei.com>
Reviewed-By: Xie XiuQi <xiexiuqi@huawei.com>
Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
Signed-off-by: Xin Hao <haoxing990@gmail.com>
Reviewed-by: Baolin Wang <baolin.wang@openanolis.org>
---
 arch/arm64/include/asm/acpi.h |  4 ++++
 drivers/acpi/pptt.c           | 55 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+)

diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index ffe3c26..8433cfa 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -103,6 +103,10 @@ static inline u32 get_acpi_id_for_cpu(unsigned int cpu)
 
 static inline void arch_fix_phys_package_id(int num, u32 slot) { }
 void __init acpi_init_cpus(void);
+void acpi_pptt_find_min_physid_cpu_node(struct acpi_table_header *table_hdr,
+			struct acpi_pptt_processor *cpu_node,
+			phys_cpuid_t *min_physid,
+			struct acpi_pptt_processor **min_cpu_node);
 int apei_claim_sea(struct pt_regs *regs);
 #else
 static inline void acpi_init_cpus(void) { }
diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c
index 1907653..d99cfb5 100644
--- a/drivers/acpi/pptt.c
+++ b/drivers/acpi/pptt.c
@@ -431,6 +431,61 @@ static struct acpi_pptt_cache *acpi_find_cache_node(struct acpi_table_header *ta
 }
 
 /**
+ * acpi_pptt_min_physid_from_cpu_node() - Recursivly find @min_physid for all
+ * leaf CPUs below @cpu_node.
+ * @table_hdr:  Pointer to the head of the PPTT table
+ * @cpu_node:   The point in the toplogy to start the walk
+ * @min_physid: The min_physid to update with leaf CPUs.
+ * @min_cpu_node: The min_cpu_node to update with leaf CPUs.
+ */
+void acpi_pptt_find_min_physid_cpu_node(struct acpi_table_header *table_hdr,
+			struct acpi_pptt_processor *cpu_node,
+			phys_cpuid_t *min_physid,
+			struct acpi_pptt_processor **min_cpu_node)
+{
+	bool leaf = true;
+	u32 acpi_processor_id;
+	phys_cpuid_t cpu_node_phys_id;
+	struct acpi_subtable_header *iter;
+	struct acpi_pptt_processor *iter_node = NULL;
+	u32 target_node = ACPI_PTR_DIFF(cpu_node, table_hdr);
+	u32 proc_sz = sizeof(struct acpi_pptt_processor *);
+	unsigned long table_end = (unsigned long)table_hdr + table_hdr->length;
+
+	/*
+	 * Walk the PPTT, looking for nodes that reference cpu_node
+	 * as parent.
+	 */
+	iter = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr,
+				sizeof(struct acpi_table_pptt));
+
+	while ((unsigned long)iter + proc_sz < table_end) {
+		iter_node = (struct acpi_pptt_processor *)iter;
+
+		if (iter->type == ACPI_PPTT_TYPE_PROCESSOR &&
+			iter_node->parent == target_node) {
+			leaf = false;
+			acpi_pptt_find_min_physid_cpu_node(table_hdr, iter_node,
+						min_physid, min_cpu_node);
+		}
+
+		if (iter->length == 0)
+			return;
+		iter = ACPI_ADD_PTR(struct acpi_subtable_header, iter,
+					iter->length);
+	}
+
+	acpi_processor_id = cpu_node->acpi_processor_id;
+	cpu_node_phys_id = acpi_id_to_phys_cpuid(acpi_processor_id);
+	if (!invalid_phys_cpuid(cpu_node_phys_id) &&
+		*min_physid > cpu_node_phys_id &&
+		leaf == true) {
+		*min_physid = cpu_node_phys_id;
+		*min_cpu_node = cpu_node;
+	}
+}
+
+/**
  * update_cache_properties() - Update cacheinfo for the given processor
  * @this_leaf: Kernel cache info structure being updated
  * @found_cache: The PPTT node describing this cache instance
-- 
1.8.3.1

