db34f96
From edc7986d4d405daebaf2f66269b353da579fce5f Mon Sep 17 00:00:00 2001
db34f96
From: Christopher Covington <cov@codeaurora.org>
db34f96
Date: Tue, 31 May 2016 16:19:02 -0400
db34f96
Subject: arm64: Workaround for QDF2432 ID_AA64 SR accesses
db34f96
db34f96
The ARMv8.0 architecture reserves several system register encodings for
db34f96
future use. These encodings should behave as read-only and always return
db34f96
zero on a read. As described in Errata 94, the CPU cores in the QDF2432
db34f96
errantly cause an instruction abort if an AArch64 MRS instruction attempts
db34f96
to read any of the following system register encodings:
db34f96
db34f96
	Op0, Op1, CRn, CRm,        Op2
db34f96
	3,   0,   C0,  [C4-C7],    [2-3, 6-7]
db34f96
	3,   0,   C0,  C3,         [3-7]
db34f96
	3,   0,   C0,  [C4,C6,C7], [4-5]
db34f96
	3,   0,   C0,  C2,         [6-7]
db34f96
db34f96
Naively projecting ARMv8.0 names, this space includes:
db34f96
db34f96
	ID_AA64PFR[2-7]_EL1
db34f96
	ID_AA64DFR[2-3]_EL1
db34f96
	ID_AA64AFR[2-3]_EL1
db34f96
	ID_AA64ISAR[2-7]_EL1
db34f96
	ID_AA64MMFR[2-7]_EL1
db34f96
db34f96
As of v4.8-rc2, Linux only attempts to query one register in this space,
db34f96
ID_AA64MMFR2_EL1. As simple workaround, skip that access when the affected
db34f96
MIDR is detected.
db34f96
db34f96
Signed-off-by: Christopher Covington <cov@codeaurora.org>
db34f96
---
db34f96
 arch/arm64/kernel/cpuinfo.c | 4 +++-
db34f96
 1 file changed, 3 insertions(+), 1 deletion(-)
db34f96
db34f96
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
db34f96
index ed1b84f..790de6b 100644
db34f96
--- a/arch/arm64/kernel/cpuinfo.c
db34f96
+++ b/arch/arm64/kernel/cpuinfo.c
db34f96
@@ -325,6 +325,8 @@ static void cpuinfo_detect_icache_policy(struct cpuinfo_arm64 *info)
db34f96
 
db34f96
 static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
db34f96
 {
db34f96
+	bool qdf2432_cpu = read_cpuid_id() == 0x510f2811;
db34f96
+
db34f96
 	info->reg_cntfrq = arch_timer_get_cntfrq();
db34f96
 	info->reg_ctr = read_cpuid_cachetype();
db34f96
 	info->reg_dczid = read_cpuid(DCZID_EL0);
db34f96
@@ -337,7 +339,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
db34f96
 	info->reg_id_aa64isar1 = read_cpuid(ID_AA64ISAR1_EL1);
db34f96
 	info->reg_id_aa64mmfr0 = read_cpuid(ID_AA64MMFR0_EL1);
db34f96
 	info->reg_id_aa64mmfr1 = read_cpuid(ID_AA64MMFR1_EL1);
db34f96
-	info->reg_id_aa64mmfr2 = read_cpuid(ID_AA64MMFR2_EL1);
db34f96
+	info->reg_id_aa64mmfr2 = qdf2432_cpu ? 0 : read_cpuid(ID_AA64MMFR2_EL1);
db34f96
 	info->reg_id_aa64pfr0 = read_cpuid(ID_AA64PFR0_EL1);
db34f96
 	info->reg_id_aa64pfr1 = read_cpuid(ID_AA64PFR1_EL1);
db34f96
 
db34f96
-- 
db34f96
cgit v0.12
db34f96