* [PATCH 0/6] Support for systems without AArch32 state
@ 2016-01-28 11:32 Suzuki K Poulose
2016-01-28 11:32 ` [PATCH 1/6] arm64: hwcaps: Cleanup naming Suzuki K Poulose
` (6 more replies)
0 siblings, 7 replies; 11+ messages in thread
From: Suzuki K Poulose @ 2016-01-28 11:32 UTC (permalink / raw)
To: linux-arm-kernel
This series add checks to make sure that the AArch32 state is
supported before we process the 32bit ID registers. Also
checks the same for COMPAT binary execution.
This series applies on top of 4.5-rc1 + Early CPU feature verification [1] +
Handle sign bit for CPU Features [2], even though review
doesn't require going through [1] & [2].
[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2016-January/401727.html
[2] http://lists.infradead.org/pipermail/linux-arm-kernel/2016-January/401913.html
Suzuki K Poulose (6):
arm64: hwcaps: Cleanup naming
arm64: HWCAP: Split COMPAT HWCAP table entries
arm64: Add helpers for detecting AArch32 support at EL0
arm64: cpufeature: Check availability of AArch32
arm64: cpufeature: Track 32bit EL0 support
arm64: compat: Check for AArch32 state
arch/arm64/include/asm/cpufeature.h | 15 ++-
arch/arm64/include/asm/elf.h | 3 +-
arch/arm64/include/asm/sysreg.h | 1 +
arch/arm64/kernel/cpufeature.c | 186 +++++++++++++++++++++--------------
arch/arm64/kernel/cpuinfo.c | 40 ++++----
5 files changed, 151 insertions(+), 94 deletions(-)
--
1.7.9.5
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/6] arm64: hwcaps: Cleanup naming
2016-01-28 11:32 [PATCH 0/6] Support for systems without AArch32 state Suzuki K Poulose
@ 2016-01-28 11:32 ` Suzuki K Poulose
2016-01-28 11:32 ` [PATCH 2/6] arm64: HWCAP: Split COMPAT HWCAP table entries Suzuki K Poulose
` (5 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Suzuki K Poulose @ 2016-01-28 11:32 UTC (permalink / raw)
To: linux-arm-kernel
We use hwcaps for referring to ELF hwcaps capability information.
However this can be confusing with 'cpu_hwcaps' which stands for the
CPU capability bit field. This patch cleans up the names to make it
a bit more readable.
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
arch/arm64/kernel/cpufeature.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index f29d63c..a3c254b 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -682,7 +682,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.hwcap = cap, \
}
-static const struct arm64_cpu_capabilities arm64_hwcaps[] = {
+static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, HWCAP_PMULL),
HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_AES),
HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA1_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_SHA1),
@@ -701,7 +701,7 @@ static const struct arm64_cpu_capabilities arm64_hwcaps[] = {
{},
};
-static void __init cap_set_hwcap(const struct arm64_cpu_capabilities *cap)
+static void __init cap_set_elf_hwcap(const struct arm64_cpu_capabilities *cap)
{
switch (cap->hwcap_type) {
case CAP_HWCAP:
@@ -722,7 +722,7 @@ static void __init cap_set_hwcap(const struct arm64_cpu_capabilities *cap)
}
/* Check if we have a particular HWCAP enabled */
-static bool __maybe_unused cpus_have_hwcap(const struct arm64_cpu_capabilities *cap)
+static bool cpus_have_elf_hwcap(const struct arm64_cpu_capabilities *cap)
{
bool rc;
@@ -746,14 +746,14 @@ static bool __maybe_unused cpus_have_hwcap(const struct arm64_cpu_capabilities *
return rc;
}
-static void __init setup_cpu_hwcaps(void)
+static void __init setup_elf_hwcaps(void)
{
int i;
- const struct arm64_cpu_capabilities *hwcaps = arm64_hwcaps;
+ const struct arm64_cpu_capabilities *hwcaps = arm64_elf_hwcaps;
for (i = 0; hwcaps[i].desc; i++)
if (hwcaps[i].matches(&hwcaps[i]))
- cap_set_hwcap(&hwcaps[i]);
+ cap_set_elf_hwcap(&hwcaps[i]);
}
void update_cpu_capabilities(const struct arm64_cpu_capabilities *caps,
@@ -889,8 +889,8 @@ void verify_local_cpu_capabilities(void)
caps[i].enable(NULL);
}
- for (i = 0, caps = arm64_hwcaps; caps[i].desc; i++) {
- if (!cpus_have_hwcap(&caps[i]))
+ for (i = 0, caps = arm64_elf_hwcaps; caps[i].desc; i++) {
+ if (!cpus_have_elf_hwcap(&caps[i]))
continue;
if (!feature_matches(__raw_read_system_reg(caps[i].sys_reg), &caps[i])) {
pr_crit("CPU%d: missing HWCAP: %s\n",
@@ -913,7 +913,7 @@ void __init setup_cpu_features(void)
/* Set the CPU feature capabilies */
setup_feature_capabilities();
- setup_cpu_hwcaps();
+ setup_elf_hwcaps();
/* Advertise that we have computed the system capabilities */
set_sys_caps_initialised();
--
1.7.9.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 2/6] arm64: HWCAP: Split COMPAT HWCAP table entries
2016-01-28 11:32 [PATCH 0/6] Support for systems without AArch32 state Suzuki K Poulose
2016-01-28 11:32 ` [PATCH 1/6] arm64: hwcaps: Cleanup naming Suzuki K Poulose
@ 2016-01-28 11:32 ` Suzuki K Poulose
2016-01-28 11:32 ` [PATCH 3/6] arm64: Add helpers for detecting AArch32 support at EL0 Suzuki K Poulose
` (4 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Suzuki K Poulose @ 2016-01-28 11:32 UTC (permalink / raw)
To: linux-arm-kernel
In order to handle systems which do not support 32bit at EL0,
split the COMPAT HWCAP entries into a separate table which can
be processed, only if the support is available.
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
arch/arm64/kernel/cpufeature.c | 78 ++++++++++++++++++++++++----------------
1 file changed, 47 insertions(+), 31 deletions(-)
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index a3c254b..b88cbef 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -691,6 +691,10 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_ATOMICS_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, HWCAP_ATOMICS),
HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, FTR_SIGNED, 0, CAP_HWCAP, HWCAP_FP),
HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, FTR_SIGNED, 0, CAP_HWCAP, HWCAP_ASIMD),
+ {},
+};
+
+static const struct arm64_cpu_capabilities compat_elf_hwcaps[] = {
#ifdef CONFIG_COMPAT
HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_PMULL),
HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_AES),
@@ -746,10 +750,9 @@ static bool cpus_have_elf_hwcap(const struct arm64_cpu_capabilities *cap)
return rc;
}
-static void __init setup_elf_hwcaps(void)
+static void __init setup_elf_hwcaps(const struct arm64_cpu_capabilities *hwcaps)
{
int i;
- const struct arm64_cpu_capabilities *hwcaps = arm64_elf_hwcaps;
for (i = 0; hwcaps[i].desc; i++)
if (hwcaps[i].matches(&hwcaps[i]))
@@ -850,29 +853,26 @@ static void check_early_cpu_features(void)
verify_cpu_asid_bits();
}
-/*
- * Run through the enabled system capabilities and enable() it on this CPU.
- * The capabilities were decided based on the available CPUs at the boot time.
- * Any new CPU should match the system wide status of the capability. If the
- * new CPU doesn't have a capability which the system now has enabled, we
- * cannot do anything to fix it up and could cause unexpected failures. So
- * we park the CPU.
- */
-void verify_local_cpu_capabilities(void)
+static void
+verify_local_elf_hwcaps(const struct arm64_cpu_capabilities *caps)
{
int i;
- const struct arm64_cpu_capabilities *caps;
- check_early_cpu_features();
-
- /*
- * If we haven't computed the system capabilities, there is nothing
- * to verify.
- */
- if (!sys_caps_initialised)
- return;
+ for (i = 0; caps[i].desc; i++) {
+ if (!cpus_have_elf_hwcap(&caps[i]))
+ continue;
+ if (!feature_matches(__raw_read_system_reg(caps[i].sys_reg), &caps[i])) {
+ pr_crit("CPU%d: missing HWCAP: %s\n",
+ smp_processor_id(), caps[i].desc);
+ cpu_die_early();
+ }
+ }
+}
- caps = arm64_features;
+static void
+verify_local_cpu_features(const struct arm64_cpu_capabilities *caps)
+{
+ int i;
for (i = 0; caps[i].desc; i++) {
if (!cpus_have_cap(caps[i].capability) || !caps[i].sys_reg)
continue;
@@ -888,16 +888,31 @@ void verify_local_cpu_capabilities(void)
if (caps[i].enable)
caps[i].enable(NULL);
}
+}
- for (i = 0, caps = arm64_elf_hwcaps; caps[i].desc; i++) {
- if (!cpus_have_elf_hwcap(&caps[i]))
- continue;
- if (!feature_matches(__raw_read_system_reg(caps[i].sys_reg), &caps[i])) {
- pr_crit("CPU%d: missing HWCAP: %s\n",
- smp_processor_id(), caps[i].desc);
- cpu_die_early();
- }
- }
+/*
+ * Run through the enabled system capabilities and enable() it on this CPU.
+ * The capabilities were decided based on the available CPUs at the boot time.
+ * Any new CPU should match the system wide status of the capability. If the
+ * new CPU doesn't have a capability which the system now has enabled, we
+ * cannot do anything to fix it up and could cause unexpected failures. So
+ * we park the CPU.
+ */
+void verify_local_cpu_capabilities(void)
+{
+
+ check_early_cpu_features();
+
+ /*
+ * If we haven't computed the system capabilities, there is nothing
+ * to verify.
+ */
+ if (!sys_caps_initialised)
+ return;
+
+ verify_local_cpu_features(arm64_features);
+ verify_local_elf_hwcaps(arm64_elf_hwcaps);
+ verify_local_elf_hwcaps(compat_elf_hwcaps);
}
static void __init setup_feature_capabilities(void)
@@ -913,7 +928,8 @@ void __init setup_cpu_features(void)
/* Set the CPU feature capabilies */
setup_feature_capabilities();
- setup_elf_hwcaps();
+ setup_elf_hwcaps(arm64_elf_hwcaps);
+ setup_elf_hwcaps(compat_elf_hwcaps);
/* Advertise that we have computed the system capabilities */
set_sys_caps_initialised();
--
1.7.9.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 3/6] arm64: Add helpers for detecting AArch32 support at EL0
2016-01-28 11:32 [PATCH 0/6] Support for systems without AArch32 state Suzuki K Poulose
2016-01-28 11:32 ` [PATCH 1/6] arm64: hwcaps: Cleanup naming Suzuki K Poulose
2016-01-28 11:32 ` [PATCH 2/6] arm64: HWCAP: Split COMPAT HWCAP table entries Suzuki K Poulose
@ 2016-01-28 11:32 ` Suzuki K Poulose
2016-01-28 11:32 ` [PATCH 4/6] arm64: cpufeature: Check availability of AArch32 Suzuki K Poulose
` (3 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Suzuki K Poulose @ 2016-01-28 11:32 UTC (permalink / raw)
To: linux-arm-kernel
Adds a helper to extract the support for AArch32 at EL0
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
arch/arm64/include/asm/cpufeature.h | 7 +++++++
arch/arm64/include/asm/sysreg.h | 1 +
2 files changed, 8 insertions(+)
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 5444a77..98f83d7 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -165,6 +165,13 @@ static inline bool id_aa64mmfr0_mixed_endian_el0(u64 mmfr0)
cpuid_feature_extract_unsigned_field(mmfr0, ID_AA64MMFR0_BIGENDEL0_SHIFT) == 0x1;
}
+static inline bool id_aa64pfr0_32bit_el0(u64 pfr0)
+{
+ u32 val = cpuid_feature_extract_unsigned_field(pfr0, ID_AA64PFR0_EL0_SHIFT);
+
+ return val == ID_AA64PFR0_EL0_32BIT_64BIT;
+}
+
void __init setup_cpu_features(void);
void update_cpu_capabilities(const struct arm64_cpu_capabilities *caps,
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 4aeebec..76d2f3e 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -111,6 +111,7 @@
#define ID_AA64PFR0_ASIMD_SUPPORTED 0x0
#define ID_AA64PFR0_EL1_64BIT_ONLY 0x1
#define ID_AA64PFR0_EL0_64BIT_ONLY 0x1
+#define ID_AA64PFR0_EL0_32BIT_64BIT 0x2
/* id_aa64mmfr0 */
#define ID_AA64MMFR0_TGRAN4_SHIFT 28
--
1.7.9.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 4/6] arm64: cpufeature: Check availability of AArch32
2016-01-28 11:32 [PATCH 0/6] Support for systems without AArch32 state Suzuki K Poulose
` (2 preceding siblings ...)
2016-01-28 11:32 ` [PATCH 3/6] arm64: Add helpers for detecting AArch32 support at EL0 Suzuki K Poulose
@ 2016-01-28 11:32 ` Suzuki K Poulose
2016-01-28 11:32 ` [PATCH 5/6] arm64: cpufeature: Track 32bit EL0 support Suzuki K Poulose
` (2 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Suzuki K Poulose @ 2016-01-28 11:32 UTC (permalink / raw)
To: linux-arm-kernel
On ARMv8 support for AArch32 state is optional. Hence it is
not safe to check the AArch32 ID registers for sanity, which
could lead to false warnings. This patch makes sure that the
AArch32 state is implemented before we keep track of the 32bit
ID registers.
As per ARM ARM (D.1.21.2 - Support for Exception Levels and
Execution States, DDI0487A.h), checking the support for AArch32
at EL0 is good enough to check the support for AArch32 (i.e,
AArch32 at EL1 => AArch32 at EL0, but not vice versa).
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
arch/arm64/kernel/cpufeature.c | 86 ++++++++++++++++++++++------------------
arch/arm64/kernel/cpuinfo.c | 37 +++++++++--------
2 files changed, 67 insertions(+), 56 deletions(-)
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index b88cbef..853e575 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -423,22 +423,26 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
init_cpu_ftr_reg(SYS_ID_AA64MMFR1_EL1, info->reg_id_aa64mmfr1);
init_cpu_ftr_reg(SYS_ID_AA64PFR0_EL1, info->reg_id_aa64pfr0);
init_cpu_ftr_reg(SYS_ID_AA64PFR1_EL1, info->reg_id_aa64pfr1);
- init_cpu_ftr_reg(SYS_ID_DFR0_EL1, info->reg_id_dfr0);
- init_cpu_ftr_reg(SYS_ID_ISAR0_EL1, info->reg_id_isar0);
- init_cpu_ftr_reg(SYS_ID_ISAR1_EL1, info->reg_id_isar1);
- init_cpu_ftr_reg(SYS_ID_ISAR2_EL1, info->reg_id_isar2);
- init_cpu_ftr_reg(SYS_ID_ISAR3_EL1, info->reg_id_isar3);
- init_cpu_ftr_reg(SYS_ID_ISAR4_EL1, info->reg_id_isar4);
- init_cpu_ftr_reg(SYS_ID_ISAR5_EL1, info->reg_id_isar5);
- init_cpu_ftr_reg(SYS_ID_MMFR0_EL1, info->reg_id_mmfr0);
- init_cpu_ftr_reg(SYS_ID_MMFR1_EL1, info->reg_id_mmfr1);
- init_cpu_ftr_reg(SYS_ID_MMFR2_EL1, info->reg_id_mmfr2);
- init_cpu_ftr_reg(SYS_ID_MMFR3_EL1, info->reg_id_mmfr3);
- init_cpu_ftr_reg(SYS_ID_PFR0_EL1, info->reg_id_pfr0);
- init_cpu_ftr_reg(SYS_ID_PFR1_EL1, info->reg_id_pfr1);
- init_cpu_ftr_reg(SYS_MVFR0_EL1, info->reg_mvfr0);
- init_cpu_ftr_reg(SYS_MVFR1_EL1, info->reg_mvfr1);
- init_cpu_ftr_reg(SYS_MVFR2_EL1, info->reg_mvfr2);
+
+ if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0)) {
+ init_cpu_ftr_reg(SYS_ID_DFR0_EL1, info->reg_id_dfr0);
+ init_cpu_ftr_reg(SYS_ID_ISAR0_EL1, info->reg_id_isar0);
+ init_cpu_ftr_reg(SYS_ID_ISAR1_EL1, info->reg_id_isar1);
+ init_cpu_ftr_reg(SYS_ID_ISAR2_EL1, info->reg_id_isar2);
+ init_cpu_ftr_reg(SYS_ID_ISAR3_EL1, info->reg_id_isar3);
+ init_cpu_ftr_reg(SYS_ID_ISAR4_EL1, info->reg_id_isar4);
+ init_cpu_ftr_reg(SYS_ID_ISAR5_EL1, info->reg_id_isar5);
+ init_cpu_ftr_reg(SYS_ID_MMFR0_EL1, info->reg_id_mmfr0);
+ init_cpu_ftr_reg(SYS_ID_MMFR1_EL1, info->reg_id_mmfr1);
+ init_cpu_ftr_reg(SYS_ID_MMFR2_EL1, info->reg_id_mmfr2);
+ init_cpu_ftr_reg(SYS_ID_MMFR3_EL1, info->reg_id_mmfr3);
+ init_cpu_ftr_reg(SYS_ID_PFR0_EL1, info->reg_id_pfr0);
+ init_cpu_ftr_reg(SYS_ID_PFR1_EL1, info->reg_id_pfr1);
+ init_cpu_ftr_reg(SYS_MVFR0_EL1, info->reg_mvfr0);
+ init_cpu_ftr_reg(SYS_MVFR1_EL1, info->reg_mvfr1);
+ init_cpu_ftr_reg(SYS_MVFR2_EL1, info->reg_mvfr2);
+ }
+
}
static void update_cpu_ftr_reg(struct arm64_ftr_reg *reg, u64 new)
@@ -541,47 +545,51 @@ void update_cpu_features(int cpu,
info->reg_id_aa64pfr1, boot->reg_id_aa64pfr1);
/*
- * If we have AArch32, we care about 32-bit features for compat. These
- * registers should be RES0 otherwise.
+ * If we have AArch32, we care about 32-bit features for compat.
+ * If the system doesn't support AArch32, don't update them.
*/
- taint |= check_update_ftr_reg(SYS_ID_DFR0_EL1, cpu,
+ if (id_aa64pfr0_32bit_el0(read_system_reg(SYS_ID_AA64PFR0_EL1)) &&
+ id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0)) {
+
+ taint |= check_update_ftr_reg(SYS_ID_DFR0_EL1, cpu,
info->reg_id_dfr0, boot->reg_id_dfr0);
- taint |= check_update_ftr_reg(SYS_ID_ISAR0_EL1, cpu,
+ taint |= check_update_ftr_reg(SYS_ID_ISAR0_EL1, cpu,
info->reg_id_isar0, boot->reg_id_isar0);
- taint |= check_update_ftr_reg(SYS_ID_ISAR1_EL1, cpu,
+ taint |= check_update_ftr_reg(SYS_ID_ISAR1_EL1, cpu,
info->reg_id_isar1, boot->reg_id_isar1);
- taint |= check_update_ftr_reg(SYS_ID_ISAR2_EL1, cpu,
+ taint |= check_update_ftr_reg(SYS_ID_ISAR2_EL1, cpu,
info->reg_id_isar2, boot->reg_id_isar2);
- taint |= check_update_ftr_reg(SYS_ID_ISAR3_EL1, cpu,
+ taint |= check_update_ftr_reg(SYS_ID_ISAR3_EL1, cpu,
info->reg_id_isar3, boot->reg_id_isar3);
- taint |= check_update_ftr_reg(SYS_ID_ISAR4_EL1, cpu,
+ taint |= check_update_ftr_reg(SYS_ID_ISAR4_EL1, cpu,
info->reg_id_isar4, boot->reg_id_isar4);
- taint |= check_update_ftr_reg(SYS_ID_ISAR5_EL1, cpu,
+ taint |= check_update_ftr_reg(SYS_ID_ISAR5_EL1, cpu,
info->reg_id_isar5, boot->reg_id_isar5);
- /*
- * Regardless of the value of the AuxReg field, the AIFSR, ADFSR, and
- * ACTLR formats could differ across CPUs and therefore would have to
- * be trapped for virtualization anyway.
- */
- taint |= check_update_ftr_reg(SYS_ID_MMFR0_EL1, cpu,
+ /*
+ * Regardless of the value of the AuxReg field, the AIFSR, ADFSR, and
+ * ACTLR formats could differ across CPUs and therefore would have to
+ * be trapped for virtualization anyway.
+ */
+ taint |= check_update_ftr_reg(SYS_ID_MMFR0_EL1, cpu,
info->reg_id_mmfr0, boot->reg_id_mmfr0);
- taint |= check_update_ftr_reg(SYS_ID_MMFR1_EL1, cpu,
+ taint |= check_update_ftr_reg(SYS_ID_MMFR1_EL1, cpu,
info->reg_id_mmfr1, boot->reg_id_mmfr1);
- taint |= check_update_ftr_reg(SYS_ID_MMFR2_EL1, cpu,
+ taint |= check_update_ftr_reg(SYS_ID_MMFR2_EL1, cpu,
info->reg_id_mmfr2, boot->reg_id_mmfr2);
- taint |= check_update_ftr_reg(SYS_ID_MMFR3_EL1, cpu,
+ taint |= check_update_ftr_reg(SYS_ID_MMFR3_EL1, cpu,
info->reg_id_mmfr3, boot->reg_id_mmfr3);
- taint |= check_update_ftr_reg(SYS_ID_PFR0_EL1, cpu,
+ taint |= check_update_ftr_reg(SYS_ID_PFR0_EL1, cpu,
info->reg_id_pfr0, boot->reg_id_pfr0);
- taint |= check_update_ftr_reg(SYS_ID_PFR1_EL1, cpu,
+ taint |= check_update_ftr_reg(SYS_ID_PFR1_EL1, cpu,
info->reg_id_pfr1, boot->reg_id_pfr1);
- taint |= check_update_ftr_reg(SYS_MVFR0_EL1, cpu,
+ taint |= check_update_ftr_reg(SYS_MVFR0_EL1, cpu,
info->reg_mvfr0, boot->reg_mvfr0);
- taint |= check_update_ftr_reg(SYS_MVFR1_EL1, cpu,
+ taint |= check_update_ftr_reg(SYS_MVFR1_EL1, cpu,
info->reg_mvfr1, boot->reg_mvfr1);
- taint |= check_update_ftr_reg(SYS_MVFR2_EL1, cpu,
+ taint |= check_update_ftr_reg(SYS_MVFR2_EL1, cpu,
info->reg_mvfr2, boot->reg_mvfr2);
+ }
/*
* Mismatched CPU features are a recipe for disaster. Don't even
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 212ae63..8cc2a86 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -213,23 +213,26 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
info->reg_id_aa64pfr0 = read_cpuid(ID_AA64PFR0_EL1);
info->reg_id_aa64pfr1 = read_cpuid(ID_AA64PFR1_EL1);
- info->reg_id_dfr0 = read_cpuid(ID_DFR0_EL1);
- info->reg_id_isar0 = read_cpuid(ID_ISAR0_EL1);
- info->reg_id_isar1 = read_cpuid(ID_ISAR1_EL1);
- info->reg_id_isar2 = read_cpuid(ID_ISAR2_EL1);
- info->reg_id_isar3 = read_cpuid(ID_ISAR3_EL1);
- info->reg_id_isar4 = read_cpuid(ID_ISAR4_EL1);
- info->reg_id_isar5 = read_cpuid(ID_ISAR5_EL1);
- info->reg_id_mmfr0 = read_cpuid(ID_MMFR0_EL1);
- info->reg_id_mmfr1 = read_cpuid(ID_MMFR1_EL1);
- info->reg_id_mmfr2 = read_cpuid(ID_MMFR2_EL1);
- info->reg_id_mmfr3 = read_cpuid(ID_MMFR3_EL1);
- info->reg_id_pfr0 = read_cpuid(ID_PFR0_EL1);
- info->reg_id_pfr1 = read_cpuid(ID_PFR1_EL1);
-
- info->reg_mvfr0 = read_cpuid(MVFR0_EL1);
- info->reg_mvfr1 = read_cpuid(MVFR1_EL1);
- info->reg_mvfr2 = read_cpuid(MVFR2_EL1);
+ /* Update the 32bit ID registers only if AArch32 is implemented */
+ if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0)) {
+ info->reg_id_dfr0 = read_cpuid(ID_DFR0_EL1);
+ info->reg_id_isar0 = read_cpuid(ID_ISAR0_EL1);
+ info->reg_id_isar1 = read_cpuid(ID_ISAR1_EL1);
+ info->reg_id_isar2 = read_cpuid(ID_ISAR2_EL1);
+ info->reg_id_isar3 = read_cpuid(ID_ISAR3_EL1);
+ info->reg_id_isar4 = read_cpuid(ID_ISAR4_EL1);
+ info->reg_id_isar5 = read_cpuid(ID_ISAR5_EL1);
+ info->reg_id_mmfr0 = read_cpuid(ID_MMFR0_EL1);
+ info->reg_id_mmfr1 = read_cpuid(ID_MMFR1_EL1);
+ info->reg_id_mmfr2 = read_cpuid(ID_MMFR2_EL1);
+ info->reg_id_mmfr3 = read_cpuid(ID_MMFR3_EL1);
+ info->reg_id_pfr0 = read_cpuid(ID_PFR0_EL1);
+ info->reg_id_pfr1 = read_cpuid(ID_PFR1_EL1);
+
+ info->reg_mvfr0 = read_cpuid(MVFR0_EL1);
+ info->reg_mvfr1 = read_cpuid(MVFR1_EL1);
+ info->reg_mvfr2 = read_cpuid(MVFR2_EL1);
+ }
cpuinfo_detect_icache_policy(info);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 5/6] arm64: cpufeature: Track 32bit EL0 support
2016-01-28 11:32 [PATCH 0/6] Support for systems without AArch32 state Suzuki K Poulose
` (3 preceding siblings ...)
2016-01-28 11:32 ` [PATCH 4/6] arm64: cpufeature: Check availability of AArch32 Suzuki K Poulose
@ 2016-01-28 11:32 ` Suzuki K Poulose
2016-01-28 11:32 ` [PATCH 6/6] arm64: compat: Check for AArch32 state Suzuki K Poulose
2016-02-22 14:03 ` [PATCH 0/6] Support for systems without " Suzuki K. Poulose
6 siblings, 0 replies; 11+ messages in thread
From: Suzuki K Poulose @ 2016-01-28 11:32 UTC (permalink / raw)
To: linux-arm-kernel
Keep track of the support for 32bit EL0.
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
arch/arm64/include/asm/cpufeature.h | 8 +++++++-
arch/arm64/kernel/cpufeature.c | 11 +++++++++++
2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 98f83d7..46c6f4c 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -30,8 +30,9 @@
#define ARM64_HAS_LSE_ATOMICS 5
#define ARM64_WORKAROUND_CAVIUM_23154 6
#define ARM64_WORKAROUND_834220 7
+#define ARM64_HAS_32BIT_EL0 8
-#define ARM64_NCAPS 8
+#define ARM64_NCAPS 9
#ifndef __ASSEMBLY__
@@ -187,6 +188,11 @@ static inline bool cpu_supports_mixed_endian_el0(void)
return id_aa64mmfr0_mixed_endian_el0(read_cpuid(ID_AA64MMFR0_EL1));
}
+static inline bool system_supports_32bit_el0(void)
+{
+ return cpus_have_cap(ARM64_HAS_32BIT_EL0);
+}
+
static inline bool system_supports_mixed_endian_el0(void)
{
return id_aa64mmfr0_mixed_endian_el0(read_system_reg(SYS_ID_AA64MMFR0_EL1));
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 853e575..8deaa20 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -675,6 +675,17 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.min_field_value = 2,
},
#endif /* CONFIG_AS_LSE && CONFIG_ARM64_LSE_ATOMICS */
+#ifdef CONFIG_COMPAT
+ {
+ .desc = "32 bit EL0",
+ .capability = ARM64_HAS_32BIT_EL0,
+ .matches = has_cpuid_feature,
+ .sys_reg = SYS_ID_AA64PFR0_EL1,
+ .field_pos = ID_AA64PFR0_EL0_SHIFT,
+ .sign = FTR_UNSIGNED,
+ .min_field_value = ID_AA64PFR0_EL0_32BIT_64BIT,
+ },
+#endif
{},
};
--
1.7.9.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 6/6] arm64: compat: Check for AArch32 state
2016-01-28 11:32 [PATCH 0/6] Support for systems without AArch32 state Suzuki K Poulose
` (4 preceding siblings ...)
2016-01-28 11:32 ` [PATCH 5/6] arm64: cpufeature: Track 32bit EL0 support Suzuki K Poulose
@ 2016-01-28 11:32 ` Suzuki K Poulose
2016-02-09 17:36 ` Will Deacon
2016-02-22 14:03 ` [PATCH 0/6] Support for systems without " Suzuki K. Poulose
6 siblings, 1 reply; 11+ messages in thread
From: Suzuki K Poulose @ 2016-01-28 11:32 UTC (permalink / raw)
To: linux-arm-kernel
Make sure we have AArch32 state available for running COMPAT binaries.
Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
[ Added checks for ELF HWCAP, Use cap bit in cap_hwcaps ]
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
arch/arm64/include/asm/elf.h | 3 ++-
arch/arm64/kernel/cpufeature.c | 7 +++++--
arch/arm64/kernel/cpuinfo.c | 3 ++-
3 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index faad6df..a1946f2 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -173,7 +173,8 @@ typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG];
/* AArch32 EABI. */
#define EF_ARM_EABI_MASK 0xff000000
-#define compat_elf_check_arch(x) (((x)->e_machine == EM_ARM) && \
+#define compat_elf_check_arch(x) (system_supports_32bit_el0() && \
+ ((x)->e_machine == EM_ARM) && \
((x)->e_flags & EF_ARM_EABI_MASK))
#define compat_start_thread compat_start_thread
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 8deaa20..cccc7ce 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -931,7 +931,8 @@ void verify_local_cpu_capabilities(void)
verify_local_cpu_features(arm64_features);
verify_local_elf_hwcaps(arm64_elf_hwcaps);
- verify_local_elf_hwcaps(compat_elf_hwcaps);
+ if (system_supports_32bit_el0())
+ verify_local_elf_hwcaps(compat_elf_hwcaps);
}
static void __init setup_feature_capabilities(void)
@@ -948,7 +949,9 @@ void __init setup_cpu_features(void)
/* Set the CPU feature capabilies */
setup_feature_capabilities();
setup_elf_hwcaps(arm64_elf_hwcaps);
- setup_elf_hwcaps(compat_elf_hwcaps);
+
+ if (system_supports_32bit_el0())
+ setup_elf_hwcaps(compat_elf_hwcaps);
/* Advertise that we have computed the system capabilities */
set_sys_caps_initialised();
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 8cc2a86..2890b74 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -124,7 +124,8 @@ static int c_show(struct seq_file *m, void *v)
* software which does already (at least for 32-bit).
*/
seq_puts(m, "Features\t:");
- if (personality(current->personality) == PER_LINUX32) {
+ if (system_supports_32bit_el0() &&
+ personality(current->personality) == PER_LINUX32) {
#ifdef CONFIG_COMPAT
for (j = 0; compat_hwcap_str[j]; j++)
if (compat_elf_hwcap & (1 << j))
--
1.7.9.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 6/6] arm64: compat: Check for AArch32 state
2016-01-28 11:32 ` [PATCH 6/6] arm64: compat: Check for AArch32 state Suzuki K Poulose
@ 2016-02-09 17:36 ` Will Deacon
2016-02-22 11:37 ` Suzuki K. Poulose
0 siblings, 1 reply; 11+ messages in thread
From: Will Deacon @ 2016-02-09 17:36 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Jan 28, 2016 at 11:32:17AM +0000, Suzuki K Poulose wrote:
> Make sure we have AArch32 state available for running COMPAT binaries.
>
> Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
> [ Added checks for ELF HWCAP, Use cap bit in cap_hwcaps ]
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
[...]
> diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
> index 8cc2a86..2890b74 100644
> --- a/arch/arm64/kernel/cpuinfo.c
> +++ b/arch/arm64/kernel/cpuinfo.c
> @@ -124,7 +124,8 @@ static int c_show(struct seq_file *m, void *v)
> * software which does already (at least for 32-bit).
> */
> seq_puts(m, "Features\t:");
> - if (personality(current->personality) == PER_LINUX32) {
> + if (system_supports_32bit_el0() &&
> + personality(current->personality) == PER_LINUX32) {
Wouldn't it be better to prevent tasks changing to the PER_LINUX32
personality on systems that don't support AArch32 at EL0?
Will
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 6/6] arm64: compat: Check for AArch32 state
2016-02-09 17:36 ` Will Deacon
@ 2016-02-22 11:37 ` Suzuki K. Poulose
0 siblings, 0 replies; 11+ messages in thread
From: Suzuki K. Poulose @ 2016-02-22 11:37 UTC (permalink / raw)
To: linux-arm-kernel
On 09/02/16 17:36, Will Deacon wrote:
> On Thu, Jan 28, 2016 at 11:32:17AM +0000, Suzuki K Poulose wrote:
>> Make sure we have AArch32 state available for running COMPAT binaries.
>> */
>> seq_puts(m, "Features\t:");
>> - if (personality(current->personality) == PER_LINUX32) {
>> + if (system_supports_32bit_el0() &&
>> + personality(current->personality) == PER_LINUX32) {
>
> Wouldn't it be better to prevent tasks changing to the PER_LINUX32
> personality on systems that don't support AArch32 at EL0?
Yes, thats the ideal solution. I took a look at it and it requires us to
hook in arm64 wrapper for the personality syscall. I will take a look.
Thanks
Suzuki
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 0/6] Support for systems without AArch32 state
2016-01-28 11:32 [PATCH 0/6] Support for systems without AArch32 state Suzuki K Poulose
` (5 preceding siblings ...)
2016-01-28 11:32 ` [PATCH 6/6] arm64: compat: Check for AArch32 state Suzuki K Poulose
@ 2016-02-22 14:03 ` Suzuki K. Poulose
2016-02-22 14:38 ` Yury Norov
6 siblings, 1 reply; 11+ messages in thread
From: Suzuki K. Poulose @ 2016-02-22 14:03 UTC (permalink / raw)
To: linux-arm-kernel
On 28/01/16 11:32, Suzuki K Poulose wrote:
> This series add checks to make sure that the AArch32 state is
> supported before we process the 32bit ID registers. Also
> checks the same for COMPAT binary execution.
Yuri,
Could you please give this series a spin on your hardware ?
I don't have access to system where I can test this.
Thanks
Suzuki
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 0/6] Support for systems without AArch32 state
2016-02-22 14:03 ` [PATCH 0/6] Support for systems without " Suzuki K. Poulose
@ 2016-02-22 14:38 ` Yury Norov
0 siblings, 0 replies; 11+ messages in thread
From: Yury Norov @ 2016-02-22 14:38 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 22, 2016 at 02:03:12PM +0000, Suzuki K. Poulose wrote:
> On 28/01/16 11:32, Suzuki K Poulose wrote:
> >This series add checks to make sure that the AArch32 state is
> >supported before we process the 32bit ID registers. Also
> >checks the same for COMPAT binary execution.
>
> Yuri,
>
> Could you please give this series a spin on your hardware ?
> I don't have access to system where I can test this.
>
> Thanks
> Suzuki
Hi Suzuki,
I can test it in 3-4 days.
Yury
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2016-02-22 14:38 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-01-28 11:32 [PATCH 0/6] Support for systems without AArch32 state Suzuki K Poulose
2016-01-28 11:32 ` [PATCH 1/6] arm64: hwcaps: Cleanup naming Suzuki K Poulose
2016-01-28 11:32 ` [PATCH 2/6] arm64: HWCAP: Split COMPAT HWCAP table entries Suzuki K Poulose
2016-01-28 11:32 ` [PATCH 3/6] arm64: Add helpers for detecting AArch32 support at EL0 Suzuki K Poulose
2016-01-28 11:32 ` [PATCH 4/6] arm64: cpufeature: Check availability of AArch32 Suzuki K Poulose
2016-01-28 11:32 ` [PATCH 5/6] arm64: cpufeature: Track 32bit EL0 support Suzuki K Poulose
2016-01-28 11:32 ` [PATCH 6/6] arm64: compat: Check for AArch32 state Suzuki K Poulose
2016-02-09 17:36 ` Will Deacon
2016-02-22 11:37 ` Suzuki K. Poulose
2016-02-22 14:03 ` [PATCH 0/6] Support for systems without " Suzuki K. Poulose
2016-02-22 14:38 ` Yury Norov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).