linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/8] arm64: Support for systems without AArch32 state
@ 2016-02-25  9:52 Suzuki K Poulose
  2016-02-25  9:52 ` [PATCH v2 1/8] arm64: hwcaps: Cleanup naming Suzuki K Poulose
                   ` (8 more replies)
  0 siblings, 9 replies; 16+ messages in thread
From: Suzuki K Poulose @ 2016-02-25  9:52 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: marc.zyngier, christoffer.dall, will.deacon, ynorov,
	catalin.marinas, mark.rutland, linux-kernel, kvmarm,
	Suzuki K Poulose

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.

(Painfully) applies on top of 4.5-rc5 + [1] + [2].

Or it is available here :
  git://linux-arm.org/linux-skp.git noaarch32/v2-4.5-rc5

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2016-February/410556.html
[2] http://lists.infradead.org/pipermail/linux-arm-kernel/2016-January/401913.html

Changes since V1:
  - Prevent changing the personality to PER_LINUX32 by adding
    wrapper for personality() syscall.
  - Add the check to KVM before initialising a AArch32 vcpu
  - Tested on hardware.

Btw, linux32 doesn't complain when the personality() syscall fails to change
to PER_LINUX32. You can verify the personality by running 
 $ cat /proc/cpuinfo
 which would still list the 64bit features for the CPUs.


Suzuki K Poulose (7):
  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: Add a wrapper for personality() syscall
  arm64: kvm: Check support for AArch32 for 32bit guests

Yury Norov (1):
  arm64: compat: Check for AArch32 state

 arch/arm/include/asm/kvm_host.h     |    5 +
 arch/arm/kvm/arm.c                  |    3 +
 arch/arm64/include/asm/cpufeature.h |   15 ++-
 arch/arm64/include/asm/elf.h        |    3 +-
 arch/arm64/include/asm/kvm_host.h   |    8 ++
 arch/arm64/include/asm/sysreg.h     |    1 +
 arch/arm64/kernel/cpufeature.c      |  184 +++++++++++++++++++++--------------
 arch/arm64/kernel/cpuinfo.c         |   37 +++----
 arch/arm64/kernel/sys.c             |   10 ++
 9 files changed, 173 insertions(+), 93 deletions(-)

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v2 1/8] arm64: hwcaps: Cleanup naming
  2016-02-25  9:52 [PATCH v2 0/8] arm64: Support for systems without AArch32 state Suzuki K Poulose
@ 2016-02-25  9:52 ` Suzuki K Poulose
  2016-02-25  9:52 ` [PATCH v2 2/8] arm64: HWCAP: Split COMPAT HWCAP table entries Suzuki K Poulose
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: Suzuki K Poulose @ 2016-02-25  9:52 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: marc.zyngier, christoffer.dall, will.deacon, ynorov,
	catalin.marinas, mark.rutland, linux-kernel, kvmarm,
	Suzuki K Poulose

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] 16+ messages in thread

* [PATCH v2 2/8] arm64: HWCAP: Split COMPAT HWCAP table entries
  2016-02-25  9:52 [PATCH v2 0/8] arm64: Support for systems without AArch32 state Suzuki K Poulose
  2016-02-25  9:52 ` [PATCH v2 1/8] arm64: hwcaps: Cleanup naming Suzuki K Poulose
@ 2016-02-25  9:52 ` Suzuki K Poulose
  2016-02-25  9:52 ` [PATCH v2 3/8] arm64: Add helpers for detecting AArch32 support at EL0 Suzuki K Poulose
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: Suzuki K Poulose @ 2016-02-25  9:52 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: marc.zyngier, christoffer.dall, will.deacon, ynorov,
	catalin.marinas, mark.rutland, linux-kernel, kvmarm,
	Suzuki K Poulose

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] 16+ messages in thread

* [PATCH v2 3/8] arm64: Add helpers for detecting AArch32 support at EL0
  2016-02-25  9:52 [PATCH v2 0/8] arm64: Support for systems without AArch32 state Suzuki K Poulose
  2016-02-25  9:52 ` [PATCH v2 1/8] arm64: hwcaps: Cleanup naming Suzuki K Poulose
  2016-02-25  9:52 ` [PATCH v2 2/8] arm64: HWCAP: Split COMPAT HWCAP table entries Suzuki K Poulose
@ 2016-02-25  9:52 ` Suzuki K Poulose
  2016-02-25  9:52 ` [PATCH v2 4/8] arm64: cpufeature: Check availability of AArch32 Suzuki K Poulose
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: Suzuki K Poulose @ 2016-02-25  9:52 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: marc.zyngier, christoffer.dall, will.deacon, ynorov,
	catalin.marinas, mark.rutland, linux-kernel, kvmarm,
	Suzuki K Poulose

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] 16+ messages in thread

* [PATCH v2 4/8] arm64: cpufeature: Check availability of AArch32
  2016-02-25  9:52 [PATCH v2 0/8] arm64: Support for systems without AArch32 state Suzuki K Poulose
                   ` (2 preceding siblings ...)
  2016-02-25  9:52 ` [PATCH v2 3/8] arm64: Add helpers for detecting AArch32 support at EL0 Suzuki K Poulose
@ 2016-02-25  9:52 ` Suzuki K Poulose
  2016-02-25  9:52 ` [PATCH v2 5/8] arm64: cpufeature: Track 32bit EL0 support Suzuki K Poulose
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: Suzuki K Poulose @ 2016-02-25  9:52 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: marc.zyngier, christoffer.dall, will.deacon, ynorov,
	catalin.marinas, mark.rutland, linux-kernel, kvmarm,
	Suzuki K Poulose

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] 16+ messages in thread

* [PATCH v2 5/8] arm64: cpufeature: Track 32bit EL0 support
  2016-02-25  9:52 [PATCH v2 0/8] arm64: Support for systems without AArch32 state Suzuki K Poulose
                   ` (3 preceding siblings ...)
  2016-02-25  9:52 ` [PATCH v2 4/8] arm64: cpufeature: Check availability of AArch32 Suzuki K Poulose
@ 2016-02-25  9:52 ` Suzuki K Poulose
  2016-02-25  9:52 ` [PATCH v2 6/8] arm64: Add a wrapper for personality() syscall Suzuki K Poulose
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: Suzuki K Poulose @ 2016-02-25  9:52 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: marc.zyngier, christoffer.dall, will.deacon, ynorov,
	catalin.marinas, mark.rutland, linux-kernel, kvmarm,
	Suzuki K Poulose

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      |    9 +++++++++
 2 files changed, 16 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..8f6b674 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -675,6 +675,15 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.min_field_value = 2,
 	},
 #endif /* CONFIG_AS_LSE && CONFIG_ARM64_LSE_ATOMICS */
+	{
+		.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,
+	},
 	{},
 };
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 6/8] arm64: Add a wrapper for personality() syscall
  2016-02-25  9:52 [PATCH v2 0/8] arm64: Support for systems without AArch32 state Suzuki K Poulose
                   ` (4 preceding siblings ...)
  2016-02-25  9:52 ` [PATCH v2 5/8] arm64: cpufeature: Track 32bit EL0 support Suzuki K Poulose
@ 2016-02-25  9:52 ` Suzuki K Poulose
  2016-02-25  9:52 ` [PATCH v2 7/8] arm64: compat: Check for AArch32 state Suzuki K Poulose
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: Suzuki K Poulose @ 2016-02-25  9:52 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: marc.zyngier, christoffer.dall, will.deacon, ynorov,
	catalin.marinas, mark.rutland, linux-kernel, kvmarm,
	Suzuki K Poulose

In order to prevent setting PER_LINUX32 on systems without
32bit EL0 support, add a wrapper for personality() syscall.

Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 arch/arm64/kernel/sys.c |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/kernel/sys.c b/arch/arm64/kernel/sys.c
index 75151aa..817d860 100644
--- a/arch/arm64/kernel/sys.c
+++ b/arch/arm64/kernel/sys.c
@@ -36,11 +36,17 @@ asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
 	return sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
 }
 
+SYSCALL_DEFINE1(arm64_personality, unsigned int, personality)
+{
+	return sys_personality(personality);
+}
+
 /*
  * Wrappers to pass the pt_regs argument.
  */
 asmlinkage long sys_rt_sigreturn_wrapper(void);
 #define sys_rt_sigreturn	sys_rt_sigreturn_wrapper
+#define sys_personality		sys_arm64_personality
 
 #undef __SYSCALL
 #define __SYSCALL(nr, sym)	[nr] = sym,
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 7/8] arm64: compat: Check for AArch32 state
  2016-02-25  9:52 [PATCH v2 0/8] arm64: Support for systems without AArch32 state Suzuki K Poulose
                   ` (5 preceding siblings ...)
  2016-02-25  9:52 ` [PATCH v2 6/8] arm64: Add a wrapper for personality() syscall Suzuki K Poulose
@ 2016-02-25  9:52 ` Suzuki K Poulose
  2016-02-25  9:52 ` [PATCH v2 8/8] arm64: kvm: Check support for AArch32 for 32bit guests Suzuki K Poulose
  2016-03-01 21:19 ` [PATCH v2 0/8] arm64: Support for systems without AArch32 state Yury Norov
  8 siblings, 0 replies; 16+ messages in thread
From: Suzuki K Poulose @ 2016-02-25  9:52 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: marc.zyngier, christoffer.dall, will.deacon, ynorov,
	catalin.marinas, mark.rutland, linux-kernel, kvmarm,
	Suzuki K Poulose

From: Yury Norov <ynorov@caviumnetworks.com>

Make sure we have AArch32 state available for running COMPAT
binaries and also for switching the personality to PER_LINUX32.

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/sys.c        |    4 ++++
 3 files changed, 11 insertions(+), 3 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 8f6b674..1ae545e 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -929,7 +929,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)
@@ -946,7 +947,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/sys.c b/arch/arm64/kernel/sys.c
index 817d860..26fe8ea 100644
--- a/arch/arm64/kernel/sys.c
+++ b/arch/arm64/kernel/sys.c
@@ -25,6 +25,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/syscalls.h>
+#include <asm/cpufeature.h>
 
 asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
 			 unsigned long prot, unsigned long flags,
@@ -38,6 +39,9 @@ asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
 
 SYSCALL_DEFINE1(arm64_personality, unsigned int, personality)
 {
+	if (personality(personality) == PER_LINUX32 &&
+		!system_supports_32bit_el0())
+		return -EINVAL;
 	return sys_personality(personality);
 }
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 8/8] arm64: kvm: Check support for AArch32 for 32bit guests
  2016-02-25  9:52 [PATCH v2 0/8] arm64: Support for systems without AArch32 state Suzuki K Poulose
                   ` (6 preceding siblings ...)
  2016-02-25  9:52 ` [PATCH v2 7/8] arm64: compat: Check for AArch32 state Suzuki K Poulose
@ 2016-02-25  9:52 ` Suzuki K Poulose
  2016-03-02  9:08   ` Marc Zyngier
  2016-03-01 21:19 ` [PATCH v2 0/8] arm64: Support for systems without AArch32 state Yury Norov
  8 siblings, 1 reply; 16+ messages in thread
From: Suzuki K Poulose @ 2016-02-25  9:52 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: marc.zyngier, christoffer.dall, will.deacon, ynorov,
	catalin.marinas, mark.rutland, linux-kernel, kvmarm,
	Suzuki K Poulose

Add a check to make sure the system supports AArch32 state
before initialising a 32bit guest.

Cc: Christoffer Dall <christoffer.dall@linaro.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: kvmarm@lists.cs.columbia.edu
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>

---

I really wanted to pass kvm_vcpu down to the helpers. But then, I can't
define the arch specific helper in asm/kvm_host.h due to lack of kvm_vcpu's
definition yet:

 In file included from include/linux/kvm_host.h:35:0,
                  from arch/arm64/kernel/asm-offsets.c:24:
 ./arch/arm64/include/asm/kvm_host.h: In function ‘kvm_arch_vcpu_validate_features’:
 ./arch/arm64/include/asm/kvm_host.h:344:48: error: dereferencing pointer to incomplete type
   return  !test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features) ||
---
 arch/arm/include/asm/kvm_host.h   |    5 +++++
 arch/arm/kvm/arm.c                |    3 +++
 arch/arm64/include/asm/kvm_host.h |    8 ++++++++
 3 files changed, 16 insertions(+)

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index f9f2779..945c23a 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -238,6 +238,11 @@ static inline void kvm_arch_sync_events(struct kvm *kvm) {}
 static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
 
+static inline bool kvm_arch_vcpu_validate_features(struct kvm_vcpu_arch *arch_vcpu)
+{
+	return true;
+}
+
 static inline void kvm_arm_init_debug(void) {}
 static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index dda1959..fc4ea37 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -787,6 +787,9 @@ static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
 			set_bit(i, vcpu->arch.features);
 	}
 
+	if (!kvm_arch_vcpu_validate_features(&vcpu->arch))
+		return -EINVAL;
+
 	vcpu->arch.target = phys_target;
 
 	/* Now we know what it is, we can reset it. */
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 689d4c9..9d60a6c 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -24,6 +24,8 @@
 
 #include <linux/types.h>
 #include <linux/kvm_types.h>
+#include <asm/cpufeature.h>
+#include <asm/kvm_arm.h>
 #include <asm/kvm.h>
 #include <asm/kvm_mmio.h>
 
@@ -338,6 +340,12 @@ static inline void kvm_arch_sync_events(struct kvm *kvm) {}
 static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
 
+static inline bool kvm_arch_vcpu_validate_features(struct kvm_vcpu_arch *arch_vcpu)
+{
+	return  !test_bit(KVM_ARM_VCPU_EL1_32BIT, arch_vcpu->features) ||
+		system_supports_32bit_el0();
+}
+
 void kvm_arm_init_debug(void);
 void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
 void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 0/8] arm64: Support for systems without AArch32 state
  2016-02-25  9:52 [PATCH v2 0/8] arm64: Support for systems without AArch32 state Suzuki K Poulose
                   ` (7 preceding siblings ...)
  2016-02-25  9:52 ` [PATCH v2 8/8] arm64: kvm: Check support for AArch32 for 32bit guests Suzuki K Poulose
@ 2016-03-01 21:19 ` Yury Norov
  2016-03-02 15:07   ` Yury Norov
  8 siblings, 1 reply; 16+ messages in thread
From: Yury Norov @ 2016-03-01 21:19 UTC (permalink / raw)
  To: Suzuki K Poulose
  Cc: linux-arm-kernel, mark.rutland, marc.zyngier, catalin.marinas,
	will.deacon, linux-kernel, kvmarm, christoffer.dall

On Thu, Feb 25, 2016 at 09:52:40AM +0000, 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.
> 
> (Painfully) applies on top of 4.5-rc5 + [1] + [2].
> 
> Or it is available here :
>   git://linux-arm.org/linux-skp.git noaarch32/v2-4.5-rc5
> 
> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2016-February/410556.html
> [2] http://lists.infradead.org/pipermail/linux-arm-kernel/2016-January/401913.html
> 
> Changes since V1:
>   - Prevent changing the personality to PER_LINUX32 by adding
>     wrapper for personality() syscall.
>   - Add the check to KVM before initialising a AArch32 vcpu
>   - Tested on hardware.
> 
> Btw, linux32 doesn't complain when the personality() syscall fails to change
> to PER_LINUX32. You can verify the personality by running 
>  $ cat /proc/cpuinfo
>  which would still list the 64bit features for the CPUs.

Hi Suzuki,

I have some troubles with access to appropriate hardware to test
it, but I didn't forget.

Yury.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 8/8] arm64: kvm: Check support for AArch32 for 32bit guests
  2016-02-25  9:52 ` [PATCH v2 8/8] arm64: kvm: Check support for AArch32 for 32bit guests Suzuki K Poulose
@ 2016-03-02  9:08   ` Marc Zyngier
  2016-03-02 10:22     ` Suzuki K. Poulose
  2016-03-14 12:27     ` Suzuki K. Poulose
  0 siblings, 2 replies; 16+ messages in thread
From: Marc Zyngier @ 2016-03-02  9:08 UTC (permalink / raw)
  To: Suzuki K Poulose, linux-arm-kernel
  Cc: christoffer.dall, will.deacon, ynorov, catalin.marinas,
	mark.rutland, linux-kernel, kvmarm

On 25/02/16 09:52, Suzuki K Poulose wrote:
> Add a check to make sure the system supports AArch32 state
> before initialising a 32bit guest.
> 
> Cc: Christoffer Dall <christoffer.dall@linaro.org>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: kvmarm@lists.cs.columbia.edu
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> 
> ---
> 
> I really wanted to pass kvm_vcpu down to the helpers. But then, I can't
> define the arch specific helper in asm/kvm_host.h due to lack of kvm_vcpu's
> definition yet:
> 
>  In file included from include/linux/kvm_host.h:35:0,
>                   from arch/arm64/kernel/asm-offsets.c:24:
>  ./arch/arm64/include/asm/kvm_host.h: In function ‘kvm_arch_vcpu_validate_features’:
>  ./arch/arm64/include/asm/kvm_host.h:344:48: error: dereferencing pointer to incomplete type
>    return  !test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features) ||

Why don't you just have the prototype in kvm_host.h, and move the actual
implementation to something like guest.c? But I think there is a better
approach, see below.

> ---
>  arch/arm/include/asm/kvm_host.h   |    5 +++++
>  arch/arm/kvm/arm.c                |    3 +++
>  arch/arm64/include/asm/kvm_host.h |    8 ++++++++
>  3 files changed, 16 insertions(+)
> 
> diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
> index f9f2779..945c23a 100644
> --- a/arch/arm/include/asm/kvm_host.h
> +++ b/arch/arm/include/asm/kvm_host.h
> @@ -238,6 +238,11 @@ static inline void kvm_arch_sync_events(struct kvm *kvm) {}
>  static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
>  static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
>  
> +static inline bool kvm_arch_vcpu_validate_features(struct kvm_vcpu_arch *arch_vcpu)
> +{
> +	return true;
> +}
> +
>  static inline void kvm_arm_init_debug(void) {}
>  static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {}
>  static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index dda1959..fc4ea37 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -787,6 +787,9 @@ static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
>  			set_bit(i, vcpu->arch.features);
>  	}
>  
> +	if (!kvm_arch_vcpu_validate_features(&vcpu->arch))
> +		return -EINVAL;
> +
>  	vcpu->arch.target = phys_target;
>  
>  	/* Now we know what it is, we can reset it. */
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 689d4c9..9d60a6c 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -24,6 +24,8 @@
>  
>  #include <linux/types.h>
>  #include <linux/kvm_types.h>
> +#include <asm/cpufeature.h>
> +#include <asm/kvm_arm.h>
>  #include <asm/kvm.h>
>  #include <asm/kvm_mmio.h>
>  
> @@ -338,6 +340,12 @@ static inline void kvm_arch_sync_events(struct kvm *kvm) {}
>  static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
>  static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
>  
> +static inline bool kvm_arch_vcpu_validate_features(struct kvm_vcpu_arch *arch_vcpu)
> +{
> +	return  !test_bit(KVM_ARM_VCPU_EL1_32BIT, arch_vcpu->features) ||
> +		system_supports_32bit_el0();
> +}
> +

This is really convoluted (it took me 5 minutes staring at the
expression and remembering that AArch32 EL1 implies AArch32 EL0 to get it).

Now, we already have kvm_reset_vcpu() that validates AArch32 support. It
would probably be better to move things there. Thoughts?

>  void kvm_arm_init_debug(void);
>  void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
>  void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
> 

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 8/8] arm64: kvm: Check support for AArch32 for 32bit guests
  2016-03-02  9:08   ` Marc Zyngier
@ 2016-03-02 10:22     ` Suzuki K. Poulose
  2016-03-14 12:27     ` Suzuki K. Poulose
  1 sibling, 0 replies; 16+ messages in thread
From: Suzuki K. Poulose @ 2016-03-02 10:22 UTC (permalink / raw)
  To: Marc Zyngier, linux-arm-kernel
  Cc: christoffer.dall, will.deacon, ynorov, catalin.marinas,
	mark.rutland, linux-kernel, kvmarm

On 02/03/16 09:08, Marc Zyngier wrote:
> On 25/02/16 09:52, Suzuki K Poulose wrote:

>> I really wanted to pass kvm_vcpu down to the helpers. But then, I can't
>> define the arch specific helper in asm/kvm_host.h due to lack of kvm_vcpu's
>> definition yet:
>>
>>   In file included from include/linux/kvm_host.h:35:0,
>>                    from arch/arm64/kernel/asm-offsets.c:24:
>>   ./arch/arm64/include/asm/kvm_host.h: In function ‘kvm_arch_vcpu_validate_features’:
>>   ./arch/arm64/include/asm/kvm_host.h:344:48: error: dereferencing pointer to incomplete type
>>     return  !test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features) ||
>
> Why don't you just have the prototype in kvm_host.h, and move the actual
> implementation to something like guest.c? But I think there is a better
> approach, see below.

I thought it would better be a static inline. But, the GCC can do that, silly me :)

>
> This is really convoluted (it took me 5 minutes staring at the
> expression and remembering that AArch32 EL1 implies AArch32 EL0 to get it).
>
> Now, we already have kvm_reset_vcpu() that validates AArch32 support. It
> would probably be better to move things there. Thoughts?

Definitely. I overlooked the function name to do something
specific to resetting the CPU than doing some checks :(.
I will respin it.

Cheers
Suzuki

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 0/8] arm64: Support for systems without AArch32 state
  2016-03-01 21:19 ` [PATCH v2 0/8] arm64: Support for systems without AArch32 state Yury Norov
@ 2016-03-02 15:07   ` Yury Norov
  2016-03-02 15:24     ` Mark Rutland
  2016-03-02 15:25     ` Suzuki K. Poulose
  0 siblings, 2 replies; 16+ messages in thread
From: Yury Norov @ 2016-03-02 15:07 UTC (permalink / raw)
  To: Suzuki K Poulose
  Cc: linux-arm-kernel, mark.rutland, marc.zyngier, catalin.marinas,
	will.deacon, linux-kernel, kvmarm, christoffer.dall

On Wed, Mar 02, 2016 at 12:19:23AM +0300, Yury Norov wrote:
> On Thu, Feb 25, 2016 at 09:52:40AM +0000, 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.
> > 
> > (Painfully) applies on top of 4.5-rc5 + [1] + [2].
> > 
> > Or it is available here :
> >   git://linux-arm.org/linux-skp.git noaarch32/v2-4.5-rc5
> > 
> > [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2016-February/410556.html
> > [2] http://lists.infradead.org/pipermail/linux-arm-kernel/2016-January/401913.html
> > 
> > Changes since V1:
> >   - Prevent changing the personality to PER_LINUX32 by adding
> >     wrapper for personality() syscall.
> >   - Add the check to KVM before initialising a AArch32 vcpu
> >   - Tested on hardware.
> > 
> > Btw, linux32 doesn't complain when the personality() syscall fails to change
> > to PER_LINUX32. You can verify the personality by running 
> >  $ cat /proc/cpuinfo
> >  which would still list the 64bit features for the CPUs.
> 
> Hi Suzuki,
> 
> I have some troubles with access to appropriate hardware to test
> it, but I didn't forget.
> 
> Yury.

Hi Suzuki,

ubuntu@arm64:~$ uname -a
Linux arm64 4.5.0-rc5-00019-g3e330b9 #76 SMP PREEMPT Wed Mar 2 17:46:57 MSK 2016 aarch64 aarch64 aarch64 GNU/Linux

ubuntu@arm64:~$ cat /proc/cpuinfo
processor       : 0-47
BogoMIPS        : 200.00
Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
CPU implementer : 0x43
CPU architecture: 8
CPU variant     : 0x1
CPU part        : 0x0a1
CPU revision    : 0

ubuntu@arm64:~$ file readdir
readdir: ELF 32-bit LSB  executable, ARM, EABI5 version 1 (SYSV), statically linked, for GNU/Linux 2.6.32,
BuildID[sha1]=aeebc12494450b55a2ab0d39ebd2e121e9085d5c, not stripped

W/o 32_EL0:
ubuntu@arm64:~$ ./readdir 
-bash: ./readdir: cannot execute binary file: Exec format error

With 32_ELO but w/o your patchset: kernel just hangs (on 4.2 it
printed errors, but it was other machine);

With 32_EL0 and with your patchset:
ubuntu@arm64:~$ ./readdir 
-bash: ./readdir: cannot execute binary file: Exec format error

So, everything is looking OK. 

Tested-by: Yury Norov <ynorov@caviumnetworks.com>

Yury.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 0/8] arm64: Support for systems without AArch32 state
  2016-03-02 15:07   ` Yury Norov
@ 2016-03-02 15:24     ` Mark Rutland
  2016-03-02 15:25     ` Suzuki K. Poulose
  1 sibling, 0 replies; 16+ messages in thread
From: Mark Rutland @ 2016-03-02 15:24 UTC (permalink / raw)
  To: Yury Norov
  Cc: Suzuki K Poulose, linux-arm-kernel, marc.zyngier,
	catalin.marinas, will.deacon, linux-kernel, kvmarm,
	christoffer.dall

On Wed, Mar 02, 2016 at 06:07:21PM +0300, Yury Norov wrote:
> ubuntu@arm64:~$ uname -a
> Linux arm64 4.5.0-rc5-00019-g3e330b9 #76 SMP PREEMPT Wed Mar 2 17:46:57 MSK 2016 aarch64 aarch64 aarch64 GNU/Linux
> 
> ubuntu@arm64:~$ cat /proc/cpuinfo
> processor       : 0-47
> BogoMIPS        : 200.00
> Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant     : 0x1
> CPU part        : 0x0a1
> CPU revision    : 0

As an aside, please do not hack up custom /proc/cpuinfo formats.

It is a compatibility nightmare for everyone.

Mark.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 0/8] arm64: Support for systems without AArch32 state
  2016-03-02 15:07   ` Yury Norov
  2016-03-02 15:24     ` Mark Rutland
@ 2016-03-02 15:25     ` Suzuki K. Poulose
  1 sibling, 0 replies; 16+ messages in thread
From: Suzuki K. Poulose @ 2016-03-02 15:25 UTC (permalink / raw)
  To: Yury Norov
  Cc: linux-arm-kernel, mark.rutland, marc.zyngier, catalin.marinas,
	will.deacon, linux-kernel, kvmarm, christoffer.dall

On 02/03/16 15:07, Yury Norov wrote:
> On Wed, Mar 02, 2016 at 12:19:23AM +0300, Yury Norov wrote:
>> On Thu, Feb 25, 2016 at 09:52:40AM +0000, 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.

...

>
> So, everything is looking OK.
>
> Tested-by: Yury Norov <ynorov@caviumnetworks.com>

Thanks Yury.

Suzuki

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 8/8] arm64: kvm: Check support for AArch32 for 32bit guests
  2016-03-02  9:08   ` Marc Zyngier
  2016-03-02 10:22     ` Suzuki K. Poulose
@ 2016-03-14 12:27     ` Suzuki K. Poulose
  1 sibling, 0 replies; 16+ messages in thread
From: Suzuki K. Poulose @ 2016-03-14 12:27 UTC (permalink / raw)
  To: Marc Zyngier, linux-arm-kernel
  Cc: christoffer.dall, will.deacon, ynorov, catalin.marinas,
	mark.rutland, linux-kernel, kvmarm

On 02/03/16 09:08, Marc Zyngier wrote:
> On 25/02/16 09:52, Suzuki K Poulose wrote:
>> Add a check to make sure the system supports AArch32 state
>> before initialising a 32bit guest.
>>
>> Cc: Christoffer Dall <christoffer.dall@linaro.org>
>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>> Cc: kvmarm@lists.cs.columbia.edu
>> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>

...

>> @@ -338,6 +340,12 @@ static inline void kvm_arch_sync_events(struct kvm *kvm) {}
>>   static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
>>   static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
>>
>> +static inline bool kvm_arch_vcpu_validate_features(struct kvm_vcpu_arch *arch_vcpu)
>> +{
>> +	return  !test_bit(KVM_ARM_VCPU_EL1_32BIT, arch_vcpu->features) ||
>> +		system_supports_32bit_el0();
>> +}
>> +
>
> This is really convoluted (it took me 5 minutes staring at the
> expression and remembering that AArch32 EL1 implies AArch32 EL0 to get it).
>
> Now, we already have kvm_reset_vcpu() that validates AArch32 support. It
> would probably be better to move things there. Thoughts?

I think we can leave the kvm bits as it is now, discarding this patch, as
we already do the right thing. Also system_supports_32bit_el0() doesn't
guarantee system_supports_32bit_el1(). The negation and converse are
both true though.

i.e,

	!32bit_el0_support => !32bit_el1_support
		  &
	32bit_el1_support => 32bit_el0_support

Thanks
Suzuki

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2016-03-14 12:27 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-25  9:52 [PATCH v2 0/8] arm64: Support for systems without AArch32 state Suzuki K Poulose
2016-02-25  9:52 ` [PATCH v2 1/8] arm64: hwcaps: Cleanup naming Suzuki K Poulose
2016-02-25  9:52 ` [PATCH v2 2/8] arm64: HWCAP: Split COMPAT HWCAP table entries Suzuki K Poulose
2016-02-25  9:52 ` [PATCH v2 3/8] arm64: Add helpers for detecting AArch32 support at EL0 Suzuki K Poulose
2016-02-25  9:52 ` [PATCH v2 4/8] arm64: cpufeature: Check availability of AArch32 Suzuki K Poulose
2016-02-25  9:52 ` [PATCH v2 5/8] arm64: cpufeature: Track 32bit EL0 support Suzuki K Poulose
2016-02-25  9:52 ` [PATCH v2 6/8] arm64: Add a wrapper for personality() syscall Suzuki K Poulose
2016-02-25  9:52 ` [PATCH v2 7/8] arm64: compat: Check for AArch32 state Suzuki K Poulose
2016-02-25  9:52 ` [PATCH v2 8/8] arm64: kvm: Check support for AArch32 for 32bit guests Suzuki K Poulose
2016-03-02  9:08   ` Marc Zyngier
2016-03-02 10:22     ` Suzuki K. Poulose
2016-03-14 12:27     ` Suzuki K. Poulose
2016-03-01 21:19 ` [PATCH v2 0/8] arm64: Support for systems without AArch32 state Yury Norov
2016-03-02 15:07   ` Yury Norov
2016-03-02 15:24     ` Mark Rutland
2016-03-02 15:25     ` Suzuki K. Poulose

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).