linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 00/13] arm64: Add support for FEAT_E2H0, or lack thereof
@ 2023-11-27 11:45 Marc Zyngier
  2023-11-27 11:45 ` [PATCH v3 01/13] arm64: Add macro to compose a sysreg field value Marc Zyngier
                   ` (12 more replies)
  0 siblings, 13 replies; 20+ messages in thread
From: Marc Zyngier @ 2023-11-27 11:45 UTC (permalink / raw)
  To: linux-arm-kernel, kvmarm
  Cc: Catalin Marinas, Will Deacon, Mark Rutland, Ard Biesheuvel,
	James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu

Since ARMv8.1, the architecture has grown the VHE feature, which makes
EL2 a superset of EL1. With ARMv9.5 (and retroactively allowed from
ARMv8.1), the architecture allows implementations to have VHE as the
*only* implemented behaviour, meaning that HCR_EL2.E2H can be
implemented as RES1. As a follow-up, HCR_EL2.NV1 can also be
implemented as RES0, making the VHE-ness of the architecture
recursive.

This has a number of consequences, both at boot time and for KVM,
though the changes at that level are pretty minor.

The real meat of this series is on the cpufeature front, as FEAT_E2H0
is a *negative* feature, where 0b1111 (-1) represents E2H being RES1
and 0b1110 (-2) additionally indicates that NV1 is RES0. Fun, isn't
it?

As a bonus, a popular crop of non-compliant HW gets promoted as the
first batch of non-zero E2H0 users, making things easy for KVM.

This series is a prefix for the NV support. It also conflicts badly
with Ard's pre-LVA2 rework. FWIW, I've pushed out a resolution of the
conflict at [3].

* From v2 [2]:
  - Moved some SYS_FIELD_VALUE() usage to the correct patch
  - Fixed a couple of spelling mistakes
  - Picked RBs from Suzuki (thanks!)

* From v1 [1]:
  - Added a SYS_FIELD_VALUE() helper to handle the concatenation
    of various fields
  - Only test for the top bit of ID_AA64MMFR4_EL1.E2H0 to decide
    whether HCR_EL2.E2H is RES1.
  - Picked RBs from Oliver (thanks!)
  - Rebased on 6.7-rc2

[1] https://lore.kernel.org/r/20231113174244.3026520-1-maz@kernel.org
[2] https://lore.kernel.org/r/20231120123721.851738-1-maz@kernel.org
[3] https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/log/?h=arm64/pre-lva2

Marc Zyngier (13):
  arm64: Add macro to compose a sysreg field value
  arm64: cpufeatures: Correctly handle signed values
  arm64: cpufeature: Correctly display signed override values
  arm64: sysreg: Add layout for ID_AA64MMFR4_EL1
  arm64: cpufeature: Add ID_AA64MMFR4_EL1 handling
  arm64: cpufeature: Detect E2H0 not being implemented
  arm64: cpufeature: Detect HCR_EL2.NV1 being RES0
  arm64: Treat HCR_EL2.E2H as RES1 when ID_AA64MMFR4_EL1.E2H0 is
    negative
  arm64: Add override for ID_AA64MMFR4_EL1.E2H0
  arm64: Add MIDR-based override infrastructure
  arm64: Add MIDR-based overrides for ID_AA64MMFR4_EL1.E2H0
  KVM: arm64: Expose ID_AA64MMFR4_EL1 to guests
  KVM: arm64: Force guest's HCR_EL2.E2H RES1 when NV1 is not implemented

 arch/arm64/include/asm/cpu.h         |  1 +
 arch/arm64/include/asm/cpufeature.h  |  2 +
 arch/arm64/include/asm/kvm_emulate.h |  3 +-
 arch/arm64/include/asm/sysreg.h      |  5 +-
 arch/arm64/kernel/cpufeature.c       | 91 +++++++++++++++++++++++++---
 arch/arm64/kernel/cpuinfo.c          |  1 +
 arch/arm64/kernel/head.S             | 23 ++++---
 arch/arm64/kernel/idreg-override.c   | 65 ++++++++++++++++++++
 arch/arm64/kvm/nested.c              |  4 ++
 arch/arm64/kvm/sys_regs.c            | 17 +++++-
 arch/arm64/tools/cpucaps             |  2 +
 arch/arm64/tools/sysreg              | 37 +++++++++++
 12 files changed, 228 insertions(+), 23 deletions(-)

-- 
2.39.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 01/13] arm64: Add macro to compose a sysreg field value
  2023-11-27 11:45 [PATCH v3 00/13] arm64: Add support for FEAT_E2H0, or lack thereof Marc Zyngier
@ 2023-11-27 11:45 ` Marc Zyngier
  2023-11-27 11:45 ` [PATCH v3 02/13] arm64: cpufeatures: Correctly handle signed values Marc Zyngier
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 20+ messages in thread
From: Marc Zyngier @ 2023-11-27 11:45 UTC (permalink / raw)
  To: linux-arm-kernel, kvmarm
  Cc: Catalin Marinas, Will Deacon, Mark Rutland, Ard Biesheuvel,
	James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu

A common idiom is to compose a tupple (reg, field, val) into
a symbol matching an autogenerated definition.

Add a help performing the concatenation and replace it when
open-coded implementations exist.

Suggested-by: Oliver Upton <oliver.upton@linux.dev>
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/include/asm/sysreg.h | 5 ++++-
 arch/arm64/kvm/sys_regs.c       | 3 ++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 5e65f51c10d2..3cb18c7a1ef0 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -1156,6 +1156,8 @@
 	par;								\
 })
 
+#define SYS_FIELD_VALUE(reg, field, val)	reg##_##field##_##val
+
 #define SYS_FIELD_GET(reg, field, val)		\
 		 FIELD_GET(reg##_##field##_MASK, val)
 
@@ -1163,7 +1165,8 @@
 		 FIELD_PREP(reg##_##field##_MASK, val)
 
 #define SYS_FIELD_PREP_ENUM(reg, field, val)		\
-		 FIELD_PREP(reg##_##field##_MASK, reg##_##field##_##val)
+		 FIELD_PREP(reg##_##field##_MASK,	\
+			    SYS_FIELD_VALUE(reg, field, val))
 
 #endif
 
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 4735e1b37fb3..9f76f24b96f8 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1561,7 +1561,8 @@ static u64 read_sanitised_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
 	u64 __f_val = FIELD_GET(reg##_##field##_MASK, val);		       \
 	(val) &= ~reg##_##field##_MASK;					       \
 	(val) |= FIELD_PREP(reg##_##field##_MASK,			       \
-			min(__f_val, (u64)reg##_##field##_##limit));	       \
+			    min(__f_val,				       \
+				(u64)SYS_FIELD_VALUE(reg, field, limit)));     \
 	(val);								       \
 })
 
-- 
2.39.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 02/13] arm64: cpufeatures: Correctly handle signed values
  2023-11-27 11:45 [PATCH v3 00/13] arm64: Add support for FEAT_E2H0, or lack thereof Marc Zyngier
  2023-11-27 11:45 ` [PATCH v3 01/13] arm64: Add macro to compose a sysreg field value Marc Zyngier
@ 2023-11-27 11:45 ` Marc Zyngier
  2023-12-11 12:24   ` Will Deacon
  2023-11-27 11:45 ` [PATCH v3 03/13] arm64: cpufeature: Correctly display signed override values Marc Zyngier
                   ` (10 subsequent siblings)
  12 siblings, 1 reply; 20+ messages in thread
From: Marc Zyngier @ 2023-11-27 11:45 UTC (permalink / raw)
  To: linux-arm-kernel, kvmarm
  Cc: Catalin Marinas, Will Deacon, Mark Rutland, Ard Biesheuvel,
	James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu

Although we've had signed values for some features such as PMUv3
and FP, the code that handles the comparaison with some limit
has a couple of annoying issues:

- the min_field_value is always unsigned, meaning that we cannot
  easily compare it with a negative value

- it is not possible to have a range of values, let alone a range
  of negative values

Fix this by:

- adding an upper limit to the comparison, defaulting to all bits
  being set to the maximum positive value

- ensuring that the signess of the min and max values are taken into
  account

A ARM64_CPUID_FIELDS_NEG() macro is provided for signed features, but
nothing is using it yet.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/include/asm/cpufeature.h |  1 +
 arch/arm64/kernel/cpufeature.c      | 65 +++++++++++++++++++++++++----
 2 files changed, 57 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index f6d416fe49b0..5f3f62efebd5 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -363,6 +363,7 @@ struct arm64_cpu_capabilities {
 			u8 field_pos;
 			u8 field_width;
 			u8 min_field_value;
+			u8 max_field_value;
 			u8 hwcap_type;
 			bool sign;
 			unsigned long hwcap;
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 646591c67e7a..bc8787f28ffd 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -140,12 +140,42 @@ void dump_cpu_features(void)
 	pr_emerg("0x%*pb\n", ARM64_NCAPS, &system_cpucaps);
 }
 
+#define __ARM64_MAX_POSITIVE(reg, field)				\
+		((reg##_##field##_SIGNED ?				\
+		  BIT(reg##_##field##_WIDTH - 1) :			\
+		  BIT(reg##_##field##_WIDTH)) - 1)
+
+#define __ARM64_MIN_NEGATIVE(reg, field)  BIT(reg##_##field##_WIDTH - 1)
+
+#define __ARM64_CPUID_FIELDS(reg, field, min_value, max_value)		\
+		.sys_reg = SYS_##reg,					\
+		.field_pos = reg##_##field##_SHIFT,			\
+		.field_width = reg##_##field##_WIDTH,			\
+		.sign = reg##_##field##_SIGNED,				\
+		.min_field_value = min_value,				\
+		.max_field_value = max_value,
+
+/*
+ * ARM64_CPUID_FIELDS() encodes a field with a range from min_value to
+ * an implicit maximum that depends on the sign-ess of the field.
+ *
+ * An unsigned field will be capped at all ones, while a signed field
+ * will be limited to the positive half only.
+ */
 #define ARM64_CPUID_FIELDS(reg, field, min_value)			\
-		.sys_reg = SYS_##reg,							\
-		.field_pos = reg##_##field##_SHIFT,						\
-		.field_width = reg##_##field##_WIDTH,						\
-		.sign = reg##_##field##_SIGNED,							\
-		.min_field_value = reg##_##field##_##min_value,
+	__ARM64_CPUID_FIELDS(reg, field,				\
+			     SYS_FIELD_VALUE(reg, field, min_value),	\
+			     __ARM64_MAX_POSITIVE(reg, field))
+
+/*
+ * ARM64_CPUID_FIELDS_NEG() encodes a field with a range from an
+ * implicit minimal value to max_value. This should be used when
+ * matching a non-implemented property.
+ */
+#define ARM64_CPUID_FIELDS_NEG(reg, field, max_value)			\
+	__ARM64_CPUID_FIELDS(reg, field,				\
+			     __ARM64_MIN_NEGATIVE(reg, field),		\
+			     SYS_FIELD_VALUE(reg, field, max_value))
 
 #define __ARM64_FTR_BITS(SIGNED, VISIBLE, STRICT, TYPE, SHIFT, WIDTH, SAFE_VAL) \
 	{						\
@@ -1470,11 +1500,28 @@ has_always(const struct arm64_cpu_capabilities *entry, int scope)
 static bool
 feature_matches(u64 reg, const struct arm64_cpu_capabilities *entry)
 {
-	int val = cpuid_feature_extract_field_width(reg, entry->field_pos,
-						    entry->field_width,
-						    entry->sign);
+	int val, min, max;
+	u64 tmp;
+
+	val = cpuid_feature_extract_field_width(reg, entry->field_pos,
+						entry->field_width,
+						entry->sign);
+
+	tmp = entry->min_field_value;
+	tmp <<= entry->field_pos;
+
+	min = cpuid_feature_extract_field_width(tmp, entry->field_pos,
+						entry->field_width,
+						entry->sign);
+
+	tmp = entry->max_field_value;
+	tmp <<= entry->field_pos;
+
+	max = cpuid_feature_extract_field_width(tmp, entry->field_pos,
+						entry->field_width,
+						entry->sign);
 
-	return val >= entry->min_field_value;
+	return val >= min && val <= max;
 }
 
 static u64
-- 
2.39.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 03/13] arm64: cpufeature: Correctly display signed override values
  2023-11-27 11:45 [PATCH v3 00/13] arm64: Add support for FEAT_E2H0, or lack thereof Marc Zyngier
  2023-11-27 11:45 ` [PATCH v3 01/13] arm64: Add macro to compose a sysreg field value Marc Zyngier
  2023-11-27 11:45 ` [PATCH v3 02/13] arm64: cpufeatures: Correctly handle signed values Marc Zyngier
@ 2023-11-27 11:45 ` Marc Zyngier
  2023-11-27 11:45 ` [PATCH v3 04/13] arm64: sysreg: Add layout for ID_AA64MMFR4_EL1 Marc Zyngier
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 20+ messages in thread
From: Marc Zyngier @ 2023-11-27 11:45 UTC (permalink / raw)
  To: linux-arm-kernel, kvmarm
  Cc: Catalin Marinas, Will Deacon, Mark Rutland, Ard Biesheuvel,
	James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu

When a field gets overriden, the kernel indicates the result of
the override in dmesg. This works well with unsigned fields, but
results in a pretty ugly output when the field is signed.

Truncate the field to its width before displaying it.

Reviewed-by: Oliver Upton <oliver.upton@linux.dev>
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/kernel/cpufeature.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index bc8787f28ffd..9c3ded9635dd 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -949,7 +949,8 @@ static void init_cpu_ftr_reg(u32 sys_reg, u64 new)
 				pr_warn("%s[%d:%d]: %s to %llx\n",
 					reg->name,
 					ftrp->shift + ftrp->width - 1,
-					ftrp->shift, str, tmp);
+					ftrp->shift, str,
+					tmp & (BIT(ftrp->width) - 1));
 		} else if ((ftr_mask & reg->override->val) == ftr_mask) {
 			reg->override->val &= ~ftr_mask;
 			pr_warn("%s[%d:%d]: impossible override, ignored\n",
-- 
2.39.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 04/13] arm64: sysreg: Add layout for ID_AA64MMFR4_EL1
  2023-11-27 11:45 [PATCH v3 00/13] arm64: Add support for FEAT_E2H0, or lack thereof Marc Zyngier
                   ` (2 preceding siblings ...)
  2023-11-27 11:45 ` [PATCH v3 03/13] arm64: cpufeature: Correctly display signed override values Marc Zyngier
@ 2023-11-27 11:45 ` Marc Zyngier
  2023-11-27 11:45 ` [PATCH v3 05/13] arm64: cpufeature: Add ID_AA64MMFR4_EL1 handling Marc Zyngier
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 20+ messages in thread
From: Marc Zyngier @ 2023-11-27 11:45 UTC (permalink / raw)
  To: linux-arm-kernel, kvmarm
  Cc: Catalin Marinas, Will Deacon, Mark Rutland, Ard Biesheuvel,
	James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu

ARMv9.5 has infroduced ID_AA64MMFR4_EL1 with a bunch of new features.
Add the corresponding layout.

This is extracted from the public ARM SysReg_xml_A_profile-2023-09
delivery, timestamped d55f5af8e09052abe92a02adf820deea2eaed717.

Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/tools/sysreg | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 96cbeeab4eec..7fb3a4928256 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1675,6 +1675,43 @@ UnsignedEnum	3:0	TCRX
 EndEnum
 EndSysreg
 
+Sysreg	ID_AA64MMFR4_EL1	3	0	0	7	4
+Res0	63:40
+UnsignedEnum	39:36	E3DSE
+	0b0000	NI
+	0b0001	IMP
+EndEnum
+Res0	35:28
+SignedEnum	27:24	E2H0
+	0b0000	IMP
+	0b1110	NI_NV1
+	0b1111	NI
+EndEnum
+UnsignedEnum	23:20	NV_frac
+	0b0000	NV_NV2
+	0b0001	NV2_ONLY
+EndEnum
+UnsignedEnum	19:16	FGWTE3
+	0b0000	NI
+	0b0001	IMP
+EndEnum
+UnsignedEnum	15:12	HACDBS
+	0b0000	NI
+	0b0001	IMP
+EndEnum
+UnsignedEnum	11:8	ASID2
+	0b0000	NI
+	0b0001	IMP
+EndEnum
+SignedEnum	7:4	EIESB
+	0b0000	NI
+	0b0001	ToEL3
+	0b0010	ToELx
+	0b1111	ANY
+EndEnum
+Res0	3:0
+EndSysreg
+
 Sysreg	SCTLR_EL1	3	0	1	0	0
 Field	63	TIDCP
 Field	62	SPINTMASK
-- 
2.39.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 05/13] arm64: cpufeature: Add ID_AA64MMFR4_EL1 handling
  2023-11-27 11:45 [PATCH v3 00/13] arm64: Add support for FEAT_E2H0, or lack thereof Marc Zyngier
                   ` (3 preceding siblings ...)
  2023-11-27 11:45 ` [PATCH v3 04/13] arm64: sysreg: Add layout for ID_AA64MMFR4_EL1 Marc Zyngier
@ 2023-11-27 11:45 ` Marc Zyngier
  2023-11-27 11:45 ` [PATCH v3 06/13] arm64: cpufeature: Detect E2H0 not being implemented Marc Zyngier
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 20+ messages in thread
From: Marc Zyngier @ 2023-11-27 11:45 UTC (permalink / raw)
  To: linux-arm-kernel, kvmarm
  Cc: Catalin Marinas, Will Deacon, Mark Rutland, Ard Biesheuvel,
	James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu

Add ID_AA64MMFR4_EL1 to the list of idregs the kernel knows about,
and describe the E2H0 field.

Reviewed-by: Oliver Upton <oliver.upton@linux.dev>
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/include/asm/cpu.h   | 1 +
 arch/arm64/kernel/cpufeature.c | 7 +++++++
 arch/arm64/kernel/cpuinfo.c    | 1 +
 3 files changed, 9 insertions(+)

diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
index f3034099fd95..d5ba6ec9f711 100644
--- a/arch/arm64/include/asm/cpu.h
+++ b/arch/arm64/include/asm/cpu.h
@@ -57,6 +57,7 @@ struct cpuinfo_arm64 {
 	u64		reg_id_aa64mmfr1;
 	u64		reg_id_aa64mmfr2;
 	u64		reg_id_aa64mmfr3;
+	u64		reg_id_aa64mmfr4;
 	u64		reg_id_aa64pfr0;
 	u64		reg_id_aa64pfr1;
 	u64		reg_id_aa64zfr0;
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 9c3ded9635dd..4a72fb26daec 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -437,6 +437,11 @@ static const struct arm64_ftr_bits ftr_id_aa64mmfr3[] = {
 	ARM64_FTR_END,
 };
 
+static const struct arm64_ftr_bits ftr_id_aa64mmfr4[] = {
+	S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR4_EL1_E2H0_SHIFT, 4, 0),
+	ARM64_FTR_END,
+};
+
 static const struct arm64_ftr_bits ftr_ctr[] = {
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, 31, 1, 1), /* RES1 */
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, CTR_EL0_DIC_SHIFT, 1, 1),
@@ -754,6 +759,7 @@ static const struct __ftr_reg_entry {
 			       &id_aa64mmfr1_override),
 	ARM64_FTR_REG(SYS_ID_AA64MMFR2_EL1, ftr_id_aa64mmfr2),
 	ARM64_FTR_REG(SYS_ID_AA64MMFR3_EL1, ftr_id_aa64mmfr3),
+	ARM64_FTR_REG(SYS_ID_AA64MMFR4_EL1, ftr_id_aa64mmfr4),
 
 	/* Op1 = 1, CRn = 0, CRm = 0 */
 	ARM64_FTR_REG(SYS_GMID_EL1, ftr_gmid),
@@ -1078,6 +1084,7 @@ 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_AA64MMFR2_EL1, info->reg_id_aa64mmfr2);
 	init_cpu_ftr_reg(SYS_ID_AA64MMFR3_EL1, info->reg_id_aa64mmfr3);
+	init_cpu_ftr_reg(SYS_ID_AA64MMFR4_EL1, info->reg_id_aa64mmfr4);
 	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_AA64ZFR0_EL1, info->reg_id_aa64zfr0);
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index a257da7b56fe..a4205effca46 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -452,6 +452,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
 	info->reg_id_aa64mmfr1 = read_cpuid(ID_AA64MMFR1_EL1);
 	info->reg_id_aa64mmfr2 = read_cpuid(ID_AA64MMFR2_EL1);
 	info->reg_id_aa64mmfr3 = read_cpuid(ID_AA64MMFR3_EL1);
+	info->reg_id_aa64mmfr4 = read_cpuid(ID_AA64MMFR4_EL1);
 	info->reg_id_aa64pfr0 = read_cpuid(ID_AA64PFR0_EL1);
 	info->reg_id_aa64pfr1 = read_cpuid(ID_AA64PFR1_EL1);
 	info->reg_id_aa64zfr0 = read_cpuid(ID_AA64ZFR0_EL1);
-- 
2.39.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 06/13] arm64: cpufeature: Detect E2H0 not being implemented
  2023-11-27 11:45 [PATCH v3 00/13] arm64: Add support for FEAT_E2H0, or lack thereof Marc Zyngier
                   ` (4 preceding siblings ...)
  2023-11-27 11:45 ` [PATCH v3 05/13] arm64: cpufeature: Add ID_AA64MMFR4_EL1 handling Marc Zyngier
@ 2023-11-27 11:45 ` Marc Zyngier
  2023-12-11 12:42   ` Will Deacon
  2023-11-27 11:45 ` [PATCH v3 07/13] arm64: cpufeature: Detect HCR_EL2.NV1 being RES0 Marc Zyngier
                   ` (6 subsequent siblings)
  12 siblings, 1 reply; 20+ messages in thread
From: Marc Zyngier @ 2023-11-27 11:45 UTC (permalink / raw)
  To: linux-arm-kernel, kvmarm
  Cc: Catalin Marinas, Will Deacon, Mark Rutland, Ard Biesheuvel,
	James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu

FEAT_E2H0 is a new feature that indicates whether or not HCR_EL2.E2H
can be set to 0. Amusingly, this feature is set to 0 when implemented,
and otherwise negative.

Add a new capability and detection infrastructure to detect the
absence of FEAT_E2H0.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/kernel/cpufeature.c | 7 +++++++
 arch/arm64/tools/cpucaps       | 1 +
 2 files changed, 8 insertions(+)

diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 4a72fb26daec..6ef9811f7bb7 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2786,6 +2786,13 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		ARM64_CPUID_FIELDS(ID_AA64MMFR2_EL1, EVT, IMP)
 	},
+	{
+		.desc = "FEAT_E2H0 not implemented",
+		.capability = ARM64_HCR_E2H_RES1,
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.matches = has_cpuid_feature,
+		ARM64_CPUID_FIELDS_NEG(ID_AA64MMFR4_EL1, E2H0, NI)
+	},
 	{},
 };
 
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index b98c38288a9d..8866ea9bf995 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -52,6 +52,7 @@ HAS_TIDCP1
 HAS_TLB_RANGE
 HAS_VIRT_HOST_EXTN
 HAS_WFXT
+HCR_E2H_RES1
 HW_DBM
 KVM_HVHE
 KVM_PROTECTED_MODE
-- 
2.39.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 07/13] arm64: cpufeature: Detect HCR_EL2.NV1 being RES0
  2023-11-27 11:45 [PATCH v3 00/13] arm64: Add support for FEAT_E2H0, or lack thereof Marc Zyngier
                   ` (5 preceding siblings ...)
  2023-11-27 11:45 ` [PATCH v3 06/13] arm64: cpufeature: Detect E2H0 not being implemented Marc Zyngier
@ 2023-11-27 11:45 ` Marc Zyngier
  2023-11-27 11:45 ` [PATCH v3 08/13] arm64: Treat HCR_EL2.E2H as RES1 when ID_AA64MMFR4_EL1.E2H0 is negative Marc Zyngier
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 20+ messages in thread
From: Marc Zyngier @ 2023-11-27 11:45 UTC (permalink / raw)
  To: linux-arm-kernel, kvmarm
  Cc: Catalin Marinas, Will Deacon, Mark Rutland, Ard Biesheuvel,
	James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu

A variant of FEAT_E2H0 not being implemented exists in the form of
HCR_EL2.E2H being RES1 *and* HCR_EL2.NV1 being RES0 (indicating that
only VHE is supported on the host and nested guests).

Add the necessary infrastructure for this new CPU capability.

Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/kernel/cpufeature.c | 7 +++++++
 arch/arm64/tools/cpucaps       | 1 +
 2 files changed, 8 insertions(+)

diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 6ef9811f7bb7..64a026cc5cec 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2793,6 +2793,13 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		ARM64_CPUID_FIELDS_NEG(ID_AA64MMFR4_EL1, E2H0, NI)
 	},
+	{
+		.desc = "FEAT_E2H0 not implemented (NV1 RES0)",
+		.capability = ARM64_HCR_NV1_RES0,
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.matches = has_cpuid_feature,
+		ARM64_CPUID_FIELDS_NEG(ID_AA64MMFR4_EL1, E2H0, NI_NV1)
+	},
 	{},
 };
 
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 8866ea9bf995..fea24bcd6252 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -53,6 +53,7 @@ HAS_TLB_RANGE
 HAS_VIRT_HOST_EXTN
 HAS_WFXT
 HCR_E2H_RES1
+HCR_NV1_RES0
 HW_DBM
 KVM_HVHE
 KVM_PROTECTED_MODE
-- 
2.39.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 08/13] arm64: Treat HCR_EL2.E2H as RES1 when ID_AA64MMFR4_EL1.E2H0 is negative
  2023-11-27 11:45 [PATCH v3 00/13] arm64: Add support for FEAT_E2H0, or lack thereof Marc Zyngier
                   ` (6 preceding siblings ...)
  2023-11-27 11:45 ` [PATCH v3 07/13] arm64: cpufeature: Detect HCR_EL2.NV1 being RES0 Marc Zyngier
@ 2023-11-27 11:45 ` Marc Zyngier
  2023-11-27 11:45 ` [PATCH v3 09/13] arm64: Add override for ID_AA64MMFR4_EL1.E2H0 Marc Zyngier
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 20+ messages in thread
From: Marc Zyngier @ 2023-11-27 11:45 UTC (permalink / raw)
  To: linux-arm-kernel, kvmarm
  Cc: Catalin Marinas, Will Deacon, Mark Rutland, Ard Biesheuvel,
	James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu

For CPUs that have ID_AA64MMFR4_EL1.E2H0 as negative, it is important
to avoid the boot path that sets HCR_EL2.E2H=0. Fortunately, we
already have this path to cope with fruity CPUs.

Tweak init_el2 to look at ID_AA64MMFR4_EL1.E2H0 first.

Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/kernel/head.S | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 7b236994f0e1..57e39bc3b2b5 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -584,25 +584,32 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
 	mov_q	x1, INIT_SCTLR_EL1_MMU_OFF
 
 	/*
-	 * Fruity CPUs seem to have HCR_EL2.E2H set to RES1,
-	 * making it impossible to start in nVHE mode. Is that
-	 * compliant with the architecture? Absolutely not!
+	 * Compliant CPUs advertise their VHE-onlyness with
+	 * ID_AA64MMFR4_EL1.E2H0 < 0. HCR_EL2.E2H can be
+	 * RES1 in that case.
+	 *
+	 * Fruity CPUs seem to have HCR_EL2.E2H set to RES1, but
+	 * don't advertise it (they predate this relaxation).
 	 */
+	mrs_s	x0, SYS_ID_AA64MMFR4_EL1
+	ubfx	x0, x0, #ID_AA64MMFR4_EL1_E2H0_SHIFT, #ID_AA64MMFR4_EL1_E2H0_WIDTH
+	tbnz	x0, #(ID_AA64MMFR4_EL1_E2H0_SHIFT + ID_AA64MMFR4_EL1_E2H0_WIDTH - 1), 1f
+
 	mrs	x0, hcr_el2
 	and	x0, x0, #HCR_E2H
-	cbz	x0, 1f
-
+	cbz	x0, 2f
+1:
 	/* Set a sane SCTLR_EL1, the VHE way */
 	pre_disable_mmu_workaround
 	msr_s	SYS_SCTLR_EL12, x1
 	mov	x2, #BOOT_CPU_FLAG_E2H
-	b	2f
+	b	3f
 
-1:
+2:
 	pre_disable_mmu_workaround
 	msr	sctlr_el1, x1
 	mov	x2, xzr
-2:
+3:
 	__init_el2_nvhe_prepare_eret
 
 	mov	w0, #BOOT_CPU_MODE_EL2
-- 
2.39.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 09/13] arm64: Add override for ID_AA64MMFR4_EL1.E2H0
  2023-11-27 11:45 [PATCH v3 00/13] arm64: Add support for FEAT_E2H0, or lack thereof Marc Zyngier
                   ` (7 preceding siblings ...)
  2023-11-27 11:45 ` [PATCH v3 08/13] arm64: Treat HCR_EL2.E2H as RES1 when ID_AA64MMFR4_EL1.E2H0 is negative Marc Zyngier
@ 2023-11-27 11:45 ` Marc Zyngier
  2023-11-27 11:45 ` [PATCH v3 10/13] arm64: Add MIDR-based override infrastructure Marc Zyngier
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 20+ messages in thread
From: Marc Zyngier @ 2023-11-27 11:45 UTC (permalink / raw)
  To: linux-arm-kernel, kvmarm
  Cc: Catalin Marinas, Will Deacon, Mark Rutland, Ard Biesheuvel,
	James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu

Allow ID_AA64MMFR4_EL1.E2H0 to be overriden from the command-line.
This will subsequently be of use for non-compliant CPUs.

Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/include/asm/cpufeature.h |  1 +
 arch/arm64/kernel/cpufeature.c      |  4 +++-
 arch/arm64/kernel/idreg-override.c  | 10 ++++++++++
 3 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 5f3f62efebd5..d465db251939 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -901,6 +901,7 @@ s64 arm64_ftr_safe_value(const struct arm64_ftr_bits *ftrp, s64 new, s64 cur);
 struct arm64_ftr_reg *get_arm64_ftr_reg(u32 sys_id);
 
 extern struct arm64_ftr_override id_aa64mmfr1_override;
+extern struct arm64_ftr_override id_aa64mmfr4_override;
 extern struct arm64_ftr_override id_aa64pfr0_override;
 extern struct arm64_ftr_override id_aa64pfr1_override;
 extern struct arm64_ftr_override id_aa64zfr0_override;
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 64a026cc5cec..7dcda39537f8 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -691,6 +691,7 @@ static const struct arm64_ftr_bits ftr_raz[] = {
 	__ARM64_FTR_REG_OVERRIDE(#id, id, table, &no_override)
 
 struct arm64_ftr_override __ro_after_init id_aa64mmfr1_override;
+struct arm64_ftr_override __ro_after_init id_aa64mmfr4_override;
 struct arm64_ftr_override __ro_after_init id_aa64pfr0_override;
 struct arm64_ftr_override __ro_after_init id_aa64pfr1_override;
 struct arm64_ftr_override __ro_after_init id_aa64zfr0_override;
@@ -759,7 +760,8 @@ static const struct __ftr_reg_entry {
 			       &id_aa64mmfr1_override),
 	ARM64_FTR_REG(SYS_ID_AA64MMFR2_EL1, ftr_id_aa64mmfr2),
 	ARM64_FTR_REG(SYS_ID_AA64MMFR3_EL1, ftr_id_aa64mmfr3),
-	ARM64_FTR_REG(SYS_ID_AA64MMFR4_EL1, ftr_id_aa64mmfr4),
+	ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64MMFR4_EL1, ftr_id_aa64mmfr4,
+			       &id_aa64mmfr4_override),
 
 	/* Op1 = 1, CRn = 0, CRm = 0 */
 	ARM64_FTR_REG(SYS_GMID_EL1, ftr_gmid),
diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/idreg-override.c
index 3addc09f8746..7b5b9dc20e6b 100644
--- a/arch/arm64/kernel/idreg-override.c
+++ b/arch/arm64/kernel/idreg-override.c
@@ -55,6 +55,15 @@ static const struct ftr_set_desc mmfr1 __initconst = {
 	},
 };
 
+static const struct ftr_set_desc mmfr4 __initconst = {
+	.name		= "id_aa64mmfr4",
+	.override	= &id_aa64mmfr4_override,
+	.fields		= {
+		FIELD("e2h0", ID_AA64MMFR4_EL1_E2H0_SHIFT, NULL ),
+		{}
+	},
+};
+
 static bool __init pfr0_sve_filter(u64 val)
 {
 	/*
@@ -161,6 +170,7 @@ static const struct ftr_set_desc sw_features __initconst = {
 
 static const struct ftr_set_desc * const regs[] __initconst = {
 	&mmfr1,
+	&mmfr4,
 	&pfr0,
 	&pfr1,
 	&isar1,
-- 
2.39.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 10/13] arm64: Add MIDR-based override infrastructure
  2023-11-27 11:45 [PATCH v3 00/13] arm64: Add support for FEAT_E2H0, or lack thereof Marc Zyngier
                   ` (8 preceding siblings ...)
  2023-11-27 11:45 ` [PATCH v3 09/13] arm64: Add override for ID_AA64MMFR4_EL1.E2H0 Marc Zyngier
@ 2023-11-27 11:45 ` Marc Zyngier
  2023-11-27 11:45 ` [PATCH v3 11/13] arm64: Add MIDR-based overrides for ID_AA64MMFR4_EL1.E2H0 Marc Zyngier
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 20+ messages in thread
From: Marc Zyngier @ 2023-11-27 11:45 UTC (permalink / raw)
  To: linux-arm-kernel, kvmarm
  Cc: Catalin Marinas, Will Deacon, Mark Rutland, Ard Biesheuvel,
	James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu

In order to be able to use the override infrastructure to "fix"
CPUs that have deviated from the architecture spec, add a new
pile of hacks on top of the existing one, allowing a feature
to be overriden based on matching a MIDR list.

Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/kernel/idreg-override.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/idreg-override.c
index 7b5b9dc20e6b..57c145bf50b7 100644
--- a/arch/arm64/kernel/idreg-override.c
+++ b/arch/arm64/kernel/idreg-override.c
@@ -321,6 +321,23 @@ static __init void parse_cmdline(void)
 		__parse_cmdline(prop, true);
 }
 
+struct midr_override_data {
+	const char		feature[FTR_ALIAS_OPTION_LEN];
+	const struct midr_range	ranges[];
+};
+
+static const struct midr_override_data * const midr_ovr_data[] __initconst = {
+};
+
+static void __init apply_midr_overrides(void)
+{
+	const u64 midr = read_cpuid_id();
+
+	for (int i = 0; i < ARRAY_SIZE(midr_ovr_data); i++)
+		if (is_midr_in_range_list(midr, midr_ovr_data[i]->ranges))
+			__parse_cmdline(midr_ovr_data[i]->feature, false);
+}
+
 /* Keep checkers quiet */
 void init_feature_override(u64 boot_status);
 
@@ -337,6 +354,8 @@ asmlinkage void __init init_feature_override(u64 boot_status)
 
 	__boot_status = boot_status;
 
+	apply_midr_overrides();
+
 	parse_cmdline();
 
 	for (i = 0; i < ARRAY_SIZE(regs); i++) {
-- 
2.39.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 11/13] arm64: Add MIDR-based overrides for ID_AA64MMFR4_EL1.E2H0
  2023-11-27 11:45 [PATCH v3 00/13] arm64: Add support for FEAT_E2H0, or lack thereof Marc Zyngier
                   ` (9 preceding siblings ...)
  2023-11-27 11:45 ` [PATCH v3 10/13] arm64: Add MIDR-based override infrastructure Marc Zyngier
@ 2023-11-27 11:45 ` Marc Zyngier
  2023-11-27 11:45 ` [PATCH v3 12/13] KVM: arm64: Expose ID_AA64MMFR4_EL1 to guests Marc Zyngier
  2023-11-27 11:45 ` [PATCH v3 13/13] KVM: arm64: Force guest's HCR_EL2.E2H RES1 when NV1 is not implemented Marc Zyngier
  12 siblings, 0 replies; 20+ messages in thread
From: Marc Zyngier @ 2023-11-27 11:45 UTC (permalink / raw)
  To: linux-arm-kernel, kvmarm
  Cc: Catalin Marinas, Will Deacon, Mark Rutland, Ard Biesheuvel,
	James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu

None the Apple M1/M2 CPUs effectively implement E2H=0, and M2
doesn't correctly implement NV1=1 (the EL2 S1 PTW seems to barf
on the nVHE format).

Override ID_AA64MMFR4_EL1.E2H0 for these CPUs to reflect what they
actually support.

Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/kernel/idreg-override.c | 36 ++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/idreg-override.c
index 57c145bf50b7..f7be459e5ff3 100644
--- a/arch/arm64/kernel/idreg-override.c
+++ b/arch/arm64/kernel/idreg-override.c
@@ -326,7 +326,43 @@ struct midr_override_data {
 	const struct midr_range	ranges[];
 };
 
+static const struct midr_override_data e2h0_ni __initconst = {
+	/*
+	 * These CPUs predate FEAT_E2H0, but have HCR_EL2.E2H RES1
+	 * anyway.
+	 */
+	.feature	= "id_aa64mmfr4.e2h0=0xf",
+	.ranges	= {
+		MIDR_ALL_VERSIONS(MIDR_APPLE_M1_ICESTORM),
+		MIDR_ALL_VERSIONS(MIDR_APPLE_M1_FIRESTORM),
+		MIDR_ALL_VERSIONS(MIDR_APPLE_M1_ICESTORM_PRO),
+		MIDR_ALL_VERSIONS(MIDR_APPLE_M1_FIRESTORM_PRO),
+		MIDR_ALL_VERSIONS(MIDR_APPLE_M1_ICESTORM_MAX),
+		MIDR_ALL_VERSIONS(MIDR_APPLE_M1_FIRESTORM_MAX),
+		{}
+	},
+};
+
+static const struct midr_override_data e2h0_nv1_ni __initconst = {
+	/*
+	 * These CPUs predate FEAT_E2H0, but have both HCR_EL2.E2H
+	 * RES1 and a non-functional HCR_EL2.NV1.
+	 */
+	.feature	= "id_aa64mmfr4.e2h0=0xe",
+	.ranges	= {
+		MIDR_ALL_VERSIONS(MIDR_APPLE_M2_BLIZZARD),
+		MIDR_ALL_VERSIONS(MIDR_APPLE_M2_AVALANCHE),
+		MIDR_ALL_VERSIONS(MIDR_APPLE_M2_BLIZZARD_PRO),
+		MIDR_ALL_VERSIONS(MIDR_APPLE_M2_AVALANCHE_PRO),
+		MIDR_ALL_VERSIONS(MIDR_APPLE_M2_BLIZZARD_MAX),
+		MIDR_ALL_VERSIONS(MIDR_APPLE_M2_AVALANCHE_MAX),
+		{}
+	},
+};
+
 static const struct midr_override_data * const midr_ovr_data[] __initconst = {
+	&e2h0_ni,
+	&e2h0_nv1_ni,
 };
 
 static void __init apply_midr_overrides(void)
-- 
2.39.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 12/13] KVM: arm64: Expose ID_AA64MMFR4_EL1 to guests
  2023-11-27 11:45 [PATCH v3 00/13] arm64: Add support for FEAT_E2H0, or lack thereof Marc Zyngier
                   ` (10 preceding siblings ...)
  2023-11-27 11:45 ` [PATCH v3 11/13] arm64: Add MIDR-based overrides for ID_AA64MMFR4_EL1.E2H0 Marc Zyngier
@ 2023-11-27 11:45 ` Marc Zyngier
  2023-11-27 11:45 ` [PATCH v3 13/13] KVM: arm64: Force guest's HCR_EL2.E2H RES1 when NV1 is not implemented Marc Zyngier
  12 siblings, 0 replies; 20+ messages in thread
From: Marc Zyngier @ 2023-11-27 11:45 UTC (permalink / raw)
  To: linux-arm-kernel, kvmarm
  Cc: Catalin Marinas, Will Deacon, Mark Rutland, Ard Biesheuvel,
	James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu

We can now expose ID_AA64MMFR4_EL1 to guests, and let NV guests
understand that they cannot really switch HCR_EL2.E2H to 0 on
some platforms.

Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/kvm/nested.c   | 4 ++++
 arch/arm64/kvm/sys_regs.c | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index 042695a210ce..3885f1c93979 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -137,6 +137,10 @@ void access_nested_id_reg(struct kvm_vcpu *v, struct sys_reg_params *p,
 		val |= FIELD_PREP(NV_FTR(MMFR2, TTL), 0b0001);
 		break;
 
+	case SYS_ID_AA64MMFR4_EL1:
+		val &= NV_FTR(MMFR4, E2H0);
+		break;
+
 	case SYS_ID_AA64DFR0_EL1:
 		/* Only limited support for PMU, Debug, BPs and WPs */
 		val &= (NV_FTR(DFR0, PMUVer)	|
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 9f76f24b96f8..ff2e66f0bda1 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -2197,7 +2197,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 					ID_AA64MMFR2_EL1_NV |
 					ID_AA64MMFR2_EL1_CCIDX)),
 	ID_SANITISED(ID_AA64MMFR3_EL1),
-	ID_UNALLOCATED(7,4),
+	ID_SANITISED(ID_AA64MMFR4_EL1),
 	ID_UNALLOCATED(7,5),
 	ID_UNALLOCATED(7,6),
 	ID_UNALLOCATED(7,7),
-- 
2.39.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 13/13] KVM: arm64: Force guest's HCR_EL2.E2H RES1 when NV1 is not implemented
  2023-11-27 11:45 [PATCH v3 00/13] arm64: Add support for FEAT_E2H0, or lack thereof Marc Zyngier
                   ` (11 preceding siblings ...)
  2023-11-27 11:45 ` [PATCH v3 12/13] KVM: arm64: Expose ID_AA64MMFR4_EL1 to guests Marc Zyngier
@ 2023-11-27 11:45 ` Marc Zyngier
  12 siblings, 0 replies; 20+ messages in thread
From: Marc Zyngier @ 2023-11-27 11:45 UTC (permalink / raw)
  To: linux-arm-kernel, kvmarm
  Cc: Catalin Marinas, Will Deacon, Mark Rutland, Ard Biesheuvel,
	James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu

If NV1 isn't supported on a system, make sure we always evaluate
the guest's HCR_EL2.E2H as RES1, irrespective of what the guest
may have written there.

Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/include/asm/kvm_emulate.h |  3 ++-
 arch/arm64/kvm/sys_regs.c            | 12 +++++++++++-
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index 78a550537b67..7b10a44189d0 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -213,7 +213,8 @@ static inline bool vcpu_is_el2(const struct kvm_vcpu *vcpu)
 
 static inline bool __vcpu_el2_e2h_is_set(const struct kvm_cpu_context *ctxt)
 {
-	return ctxt_sys_reg(ctxt, HCR_EL2) & HCR_E2H;
+	return (cpus_have_final_cap(ARM64_HCR_NV1_RES0) ||
+		(ctxt_sys_reg(ctxt, HCR_EL2) & HCR_E2H));
 }
 
 static inline bool vcpu_el2_e2h_is_set(const struct kvm_vcpu *vcpu)
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index ff2e66f0bda1..9e1e3da2ed4a 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -2022,6 +2022,16 @@ static bool access_spsr(struct kvm_vcpu *vcpu,
 	return true;
 }
 
+static u64 reset_hcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
+{
+	u64 val = r->val;
+
+	if (cpus_have_final_cap(ARM64_HCR_NV1_RES0))
+		val |= HCR_E2H;
+
+	return __vcpu_sys_reg(vcpu, r->reg) = val;
+}
+
 /*
  * Architected system registers.
  * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2
@@ -2513,7 +2523,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	EL2_REG(VMPIDR_EL2, access_rw, reset_unknown, 0),
 	EL2_REG(SCTLR_EL2, access_rw, reset_val, SCTLR_EL2_RES1),
 	EL2_REG(ACTLR_EL2, access_rw, reset_val, 0),
-	EL2_REG(HCR_EL2, access_rw, reset_val, 0),
+	EL2_REG(HCR_EL2, access_rw, reset_hcr, 0),
 	EL2_REG(MDCR_EL2, access_rw, reset_val, 0),
 	EL2_REG(CPTR_EL2, access_rw, reset_val, CPTR_NVHE_EL2_RES1),
 	EL2_REG(HSTR_EL2, access_rw, reset_val, 0),
-- 
2.39.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 02/13] arm64: cpufeatures: Correctly handle signed values
  2023-11-27 11:45 ` [PATCH v3 02/13] arm64: cpufeatures: Correctly handle signed values Marc Zyngier
@ 2023-12-11 12:24   ` Will Deacon
  2024-01-08 17:46     ` Marc Zyngier
  0 siblings, 1 reply; 20+ messages in thread
From: Will Deacon @ 2023-12-11 12:24 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-arm-kernel, kvmarm, Catalin Marinas, Mark Rutland,
	Ard Biesheuvel, James Morse, Suzuki K Poulose, Oliver Upton,
	Zenghui Yu

On Mon, Nov 27, 2023 at 11:45:48AM +0000, Marc Zyngier wrote:
> Although we've had signed values for some features such as PMUv3
> and FP, the code that handles the comparaison with some limit
> has a couple of annoying issues:
> 
> - the min_field_value is always unsigned, meaning that we cannot
>   easily compare it with a negative value
> 
> - it is not possible to have a range of values, let alone a range
>   of negative values
> 
> Fix this by:
> 
> - adding an upper limit to the comparison, defaulting to all bits
>   being set to the maximum positive value
> 
> - ensuring that the signess of the min and max values are taken into
>   account
> 
> A ARM64_CPUID_FIELDS_NEG() macro is provided for signed features, but
> nothing is using it yet.
> 
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
>  arch/arm64/include/asm/cpufeature.h |  1 +
>  arch/arm64/kernel/cpufeature.c      | 65 +++++++++++++++++++++++++----
>  2 files changed, 57 insertions(+), 9 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> index f6d416fe49b0..5f3f62efebd5 100644
> --- a/arch/arm64/include/asm/cpufeature.h
> +++ b/arch/arm64/include/asm/cpufeature.h
> @@ -363,6 +363,7 @@ struct arm64_cpu_capabilities {
>  			u8 field_pos;
>  			u8 field_width;
>  			u8 min_field_value;
> +			u8 max_field_value;
>  			u8 hwcap_type;
>  			bool sign;
>  			unsigned long hwcap;
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index 646591c67e7a..bc8787f28ffd 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -140,12 +140,42 @@ void dump_cpu_features(void)
>  	pr_emerg("0x%*pb\n", ARM64_NCAPS, &system_cpucaps);
>  }
>  
> +#define __ARM64_MAX_POSITIVE(reg, field)				\
> +		((reg##_##field##_SIGNED ?				\
> +		  BIT(reg##_##field##_WIDTH - 1) :			\
> +		  BIT(reg##_##field##_WIDTH)) - 1)
> +
> +#define __ARM64_MIN_NEGATIVE(reg, field)  BIT(reg##_##field##_WIDTH - 1)

I'm struggling to grok these two macros. For example, let's say I have a
4-bit signed field. In that case, the maximum positive value is 7 (0b0111)
and the minimum negative value is -8 (0b1000), but the macros above appear
to give 0b1000 for both.

Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 06/13] arm64: cpufeature: Detect E2H0 not being implemented
  2023-11-27 11:45 ` [PATCH v3 06/13] arm64: cpufeature: Detect E2H0 not being implemented Marc Zyngier
@ 2023-12-11 12:42   ` Will Deacon
  2024-01-09 15:16     ` Marc Zyngier
  0 siblings, 1 reply; 20+ messages in thread
From: Will Deacon @ 2023-12-11 12:42 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-arm-kernel, kvmarm, Catalin Marinas, Mark Rutland,
	Ard Biesheuvel, James Morse, Suzuki K Poulose, Oliver Upton,
	Zenghui Yu

On Mon, Nov 27, 2023 at 11:45:52AM +0000, Marc Zyngier wrote:
> FEAT_E2H0 is a new feature that indicates whether or not HCR_EL2.E2H
> can be set to 0. Amusingly, this feature is set to 0 when implemented,
> and otherwise negative.
> 
> Add a new capability and detection infrastructure to detect the
> absence of FEAT_E2H0.
> 
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
>  arch/arm64/kernel/cpufeature.c | 7 +++++++
>  arch/arm64/tools/cpucaps       | 1 +
>  2 files changed, 8 insertions(+)
> 
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index 4a72fb26daec..6ef9811f7bb7 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -2786,6 +2786,13 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
>  		.matches = has_cpuid_feature,
>  		ARM64_CPUID_FIELDS(ID_AA64MMFR2_EL1, EVT, IMP)
>  	},
> +	{
> +		.desc = "FEAT_E2H0 not implemented",
> +		.capability = ARM64_HCR_E2H_RES1,
> +		.type = ARM64_CPUCAP_SYSTEM_FEATURE,

Is ARM64_CPUCAP_SYSTEM_FEATURE the right thing to use here? For example,
if the boot CPUs have this feature but a late CPU doesn't, then I think
we should be ok as long as we're using VHE, but I don't think the above
takes that into account.

Maybe we shouldn't be adding new capabilities for this at all, and instead
just look at the sanitised register value when we need to?

Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 02/13] arm64: cpufeatures: Correctly handle signed values
  2023-12-11 12:24   ` Will Deacon
@ 2024-01-08 17:46     ` Marc Zyngier
  2024-01-09 11:40       ` Marc Zyngier
  0 siblings, 1 reply; 20+ messages in thread
From: Marc Zyngier @ 2024-01-08 17:46 UTC (permalink / raw)
  To: Will Deacon
  Cc: linux-arm-kernel, kvmarm, Catalin Marinas, Mark Rutland,
	Ard Biesheuvel, James Morse, Suzuki K Poulose, Oliver Upton,
	Zenghui Yu

On Mon, 11 Dec 2023 12:24:16 +0000,
Will Deacon <will@kernel.org> wrote:
> 
> On Mon, Nov 27, 2023 at 11:45:48AM +0000, Marc Zyngier wrote:
> > Although we've had signed values for some features such as PMUv3
> > and FP, the code that handles the comparaison with some limit
> > has a couple of annoying issues:
> > 
> > - the min_field_value is always unsigned, meaning that we cannot
> >   easily compare it with a negative value
> > 
> > - it is not possible to have a range of values, let alone a range
> >   of negative values
> > 
> > Fix this by:
> > 
> > - adding an upper limit to the comparison, defaulting to all bits
> >   being set to the maximum positive value
> > 
> > - ensuring that the signess of the min and max values are taken into
> >   account
> > 
> > A ARM64_CPUID_FIELDS_NEG() macro is provided for signed features, but
> > nothing is using it yet.
> > 
> > Signed-off-by: Marc Zyngier <maz@kernel.org>
> > ---
> >  arch/arm64/include/asm/cpufeature.h |  1 +
> >  arch/arm64/kernel/cpufeature.c      | 65 +++++++++++++++++++++++++----
> >  2 files changed, 57 insertions(+), 9 deletions(-)
> > 
> > diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> > index f6d416fe49b0..5f3f62efebd5 100644
> > --- a/arch/arm64/include/asm/cpufeature.h
> > +++ b/arch/arm64/include/asm/cpufeature.h
> > @@ -363,6 +363,7 @@ struct arm64_cpu_capabilities {
> >  			u8 field_pos;
> >  			u8 field_width;
> >  			u8 min_field_value;
> > +			u8 max_field_value;
> >  			u8 hwcap_type;
> >  			bool sign;
> >  			unsigned long hwcap;
> > diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> > index 646591c67e7a..bc8787f28ffd 100644
> > --- a/arch/arm64/kernel/cpufeature.c
> > +++ b/arch/arm64/kernel/cpufeature.c
> > @@ -140,12 +140,42 @@ void dump_cpu_features(void)
> >  	pr_emerg("0x%*pb\n", ARM64_NCAPS, &system_cpucaps);
> >  }
> >  
> > +#define __ARM64_MAX_POSITIVE(reg, field)				\
> > +		((reg##_##field##_SIGNED ?				\
> > +		  BIT(reg##_##field##_WIDTH - 1) :			\
> > +		  BIT(reg##_##field##_WIDTH)) - 1)
> > +
> > +#define __ARM64_MIN_NEGATIVE(reg, field)  BIT(reg##_##field##_WIDTH - 1)
> 
> I'm struggling to grok these two macros. For example, let's say I have a
> 4-bit signed field. In that case, the maximum positive value is 7 (0b0111)
> and the minimum negative value is -8 (0b1000), but the macros above appear
> to give 0b1000 for both.

Crap. Well spotted. The signed maximum needs to be further adjusted
like this:

#define __ARM64_MAX_POSITIVE(reg, field)				\
		((reg##_##field##_SIGNED ?				\
		  BIT(reg##_##field##_WIDTH - 1) - 1:			\
		  BIT(reg##_##field##_WIDTH)) - 1)

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 02/13] arm64: cpufeatures: Correctly handle signed values
  2024-01-08 17:46     ` Marc Zyngier
@ 2024-01-09 11:40       ` Marc Zyngier
  2024-01-30 11:34         ` Will Deacon
  0 siblings, 1 reply; 20+ messages in thread
From: Marc Zyngier @ 2024-01-09 11:40 UTC (permalink / raw)
  To: Will Deacon
  Cc: linux-arm-kernel, kvmarm, Catalin Marinas, Mark Rutland,
	Ard Biesheuvel, James Morse, Suzuki K Poulose, Oliver Upton,
	Zenghui Yu

On Mon, 08 Jan 2024 17:46:12 +0000,
Marc Zyngier <maz@kernel.org> wrote:
> 
> On Mon, 11 Dec 2023 12:24:16 +0000,
> Will Deacon <will@kernel.org> wrote:

[...]

> > > diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> > > index 646591c67e7a..bc8787f28ffd 100644
> > > --- a/arch/arm64/kernel/cpufeature.c
> > > +++ b/arch/arm64/kernel/cpufeature.c
> > > @@ -140,12 +140,42 @@ void dump_cpu_features(void)
> > >  	pr_emerg("0x%*pb\n", ARM64_NCAPS, &system_cpucaps);
> > >  }
> > >  
> > > +#define __ARM64_MAX_POSITIVE(reg, field)				\
> > > +		((reg##_##field##_SIGNED ?				\
> > > +		  BIT(reg##_##field##_WIDTH - 1) :			\
> > > +		  BIT(reg##_##field##_WIDTH)) - 1)
> > > +
> > > +#define __ARM64_MIN_NEGATIVE(reg, field)  BIT(reg##_##field##_WIDTH - 1)
> > 
> > I'm struggling to grok these two macros. For example, let's say I have a
> > 4-bit signed field. In that case, the maximum positive value is 7 (0b0111)
> > and the minimum negative value is -8 (0b1000), but the macros above appear
> > to give 0b1000 for both.
> 
> Crap. Well spotted. The signed maximum needs to be further adjusted
> like this:

Actually, scratch that. The original code is correct and does return
0b0111 for the max of a signed 4 bit value, and 0b1000 for the min.
The clue is in the bracketing (the '- 1' is applied to the result of
the conditional expression in the max case).

	M.

-- 
Without deviation from the norm, progress is not possible.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 06/13] arm64: cpufeature: Detect E2H0 not being implemented
  2023-12-11 12:42   ` Will Deacon
@ 2024-01-09 15:16     ` Marc Zyngier
  0 siblings, 0 replies; 20+ messages in thread
From: Marc Zyngier @ 2024-01-09 15:16 UTC (permalink / raw)
  To: Will Deacon
  Cc: linux-arm-kernel, kvmarm, Catalin Marinas, Mark Rutland,
	Ard Biesheuvel, James Morse, Suzuki K Poulose, Oliver Upton,
	Zenghui Yu

On Mon, 11 Dec 2023 12:42:38 +0000,
Will Deacon <will@kernel.org> wrote:
> 
> On Mon, Nov 27, 2023 at 11:45:52AM +0000, Marc Zyngier wrote:
> > FEAT_E2H0 is a new feature that indicates whether or not HCR_EL2.E2H
> > can be set to 0. Amusingly, this feature is set to 0 when implemented,
> > and otherwise negative.
> > 
> > Add a new capability and detection infrastructure to detect the
> > absence of FEAT_E2H0.
> > 
> > Signed-off-by: Marc Zyngier <maz@kernel.org>
> > ---
> >  arch/arm64/kernel/cpufeature.c | 7 +++++++
> >  arch/arm64/tools/cpucaps       | 1 +
> >  2 files changed, 8 insertions(+)
> > 
> > diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> > index 4a72fb26daec..6ef9811f7bb7 100644
> > --- a/arch/arm64/kernel/cpufeature.c
> > +++ b/arch/arm64/kernel/cpufeature.c
> > @@ -2786,6 +2786,13 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
> >  		.matches = has_cpuid_feature,
> >  		ARM64_CPUID_FIELDS(ID_AA64MMFR2_EL1, EVT, IMP)
> >  	},
> > +	{
> > +		.desc = "FEAT_E2H0 not implemented",
> > +		.capability = ARM64_HCR_E2H_RES1,
> > +		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
> 
> Is ARM64_CPUCAP_SYSTEM_FEATURE the right thing to use here? For example,
> if the boot CPUs have this feature but a late CPU doesn't, then I think
> we should be ok as long as we're using VHE, but I don't think the above
> takes that into account.
> 
> Maybe we shouldn't be adding new capabilities for this at all, and instead
> just look at the sanitised register value when we need to?

That's probably good enough for this particular use of E2H0, as this
is not used on any fast path.

However, when E2H0 is 0b1110 (NV1 being RES0, and thus the guest's own
HCR_EL2.E2H being RES1), we need to sanitise the guest's HCR_EL2 no
matter what the guest writes there.

With that in mind, __vcpu_el2_e2h_is_set() using the sanitised value
would result in a binary search on a lot of very hot paths, something
that I'm keen to avoid.

So while I'm happy to drop this particular cap, I'll keep the one
introduced in patch #6.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 02/13] arm64: cpufeatures: Correctly handle signed values
  2024-01-09 11:40       ` Marc Zyngier
@ 2024-01-30 11:34         ` Will Deacon
  0 siblings, 0 replies; 20+ messages in thread
From: Will Deacon @ 2024-01-30 11:34 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-arm-kernel, kvmarm, Catalin Marinas, Mark Rutland,
	Ard Biesheuvel, James Morse, Suzuki K Poulose, Oliver Upton,
	Zenghui Yu

On Tue, Jan 09, 2024 at 11:40:19AM +0000, Marc Zyngier wrote:
> On Mon, 08 Jan 2024 17:46:12 +0000,
> Marc Zyngier <maz@kernel.org> wrote:
> > 
> > On Mon, 11 Dec 2023 12:24:16 +0000,
> > Will Deacon <will@kernel.org> wrote:
> 
> [...]
> 
> > > > diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> > > > index 646591c67e7a..bc8787f28ffd 100644
> > > > --- a/arch/arm64/kernel/cpufeature.c
> > > > +++ b/arch/arm64/kernel/cpufeature.c
> > > > @@ -140,12 +140,42 @@ void dump_cpu_features(void)
> > > >  	pr_emerg("0x%*pb\n", ARM64_NCAPS, &system_cpucaps);
> > > >  }
> > > >  
> > > > +#define __ARM64_MAX_POSITIVE(reg, field)				\
> > > > +		((reg##_##field##_SIGNED ?				\
> > > > +		  BIT(reg##_##field##_WIDTH - 1) :			\
> > > > +		  BIT(reg##_##field##_WIDTH)) - 1)
> > > > +
> > > > +#define __ARM64_MIN_NEGATIVE(reg, field)  BIT(reg##_##field##_WIDTH - 1)
> > > 
> > > I'm struggling to grok these two macros. For example, let's say I have a
> > > 4-bit signed field. In that case, the maximum positive value is 7 (0b0111)
> > > and the minimum negative value is -8 (0b1000), but the macros above appear
> > > to give 0b1000 for both.
> > 
> > Crap. Well spotted. The signed maximum needs to be further adjusted
> > like this:
> 
> Actually, scratch that. The original code is correct and does return
> 0b0111 for the max of a signed 4 bit value, and 0b1000 for the min.
> The clue is in the bracketing (the '- 1' is applied to the result of
> the conditional expression in the max case).

Gah, sorry, that trailing '- 1' really caught me out with the formatting!

Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

end of thread, other threads:[~2024-01-30 11:34 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-27 11:45 [PATCH v3 00/13] arm64: Add support for FEAT_E2H0, or lack thereof Marc Zyngier
2023-11-27 11:45 ` [PATCH v3 01/13] arm64: Add macro to compose a sysreg field value Marc Zyngier
2023-11-27 11:45 ` [PATCH v3 02/13] arm64: cpufeatures: Correctly handle signed values Marc Zyngier
2023-12-11 12:24   ` Will Deacon
2024-01-08 17:46     ` Marc Zyngier
2024-01-09 11:40       ` Marc Zyngier
2024-01-30 11:34         ` Will Deacon
2023-11-27 11:45 ` [PATCH v3 03/13] arm64: cpufeature: Correctly display signed override values Marc Zyngier
2023-11-27 11:45 ` [PATCH v3 04/13] arm64: sysreg: Add layout for ID_AA64MMFR4_EL1 Marc Zyngier
2023-11-27 11:45 ` [PATCH v3 05/13] arm64: cpufeature: Add ID_AA64MMFR4_EL1 handling Marc Zyngier
2023-11-27 11:45 ` [PATCH v3 06/13] arm64: cpufeature: Detect E2H0 not being implemented Marc Zyngier
2023-12-11 12:42   ` Will Deacon
2024-01-09 15:16     ` Marc Zyngier
2023-11-27 11:45 ` [PATCH v3 07/13] arm64: cpufeature: Detect HCR_EL2.NV1 being RES0 Marc Zyngier
2023-11-27 11:45 ` [PATCH v3 08/13] arm64: Treat HCR_EL2.E2H as RES1 when ID_AA64MMFR4_EL1.E2H0 is negative Marc Zyngier
2023-11-27 11:45 ` [PATCH v3 09/13] arm64: Add override for ID_AA64MMFR4_EL1.E2H0 Marc Zyngier
2023-11-27 11:45 ` [PATCH v3 10/13] arm64: Add MIDR-based override infrastructure Marc Zyngier
2023-11-27 11:45 ` [PATCH v3 11/13] arm64: Add MIDR-based overrides for ID_AA64MMFR4_EL1.E2H0 Marc Zyngier
2023-11-27 11:45 ` [PATCH v3 12/13] KVM: arm64: Expose ID_AA64MMFR4_EL1 to guests Marc Zyngier
2023-11-27 11:45 ` [PATCH v3 13/13] KVM: arm64: Force guest's HCR_EL2.E2H RES1 when NV1 is not implemented Marc Zyngier

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