* [PATCH 01/12] arm64: cpufeatures: Correctly handle signed values
2023-11-13 17:42 [PATCH 00/12] arm64: Add support for FEAT_E2H0, or lack thereof Marc Zyngier
@ 2023-11-13 17:42 ` Marc Zyngier
2023-11-17 0:45 ` Oliver Upton
2023-11-13 17:42 ` [PATCH 02/12] arm64: cpufeature: Correctly display signed override values Marc Zyngier
` (10 subsequent siblings)
11 siblings, 1 reply; 21+ messages in thread
From: Marc Zyngier @ 2023-11-13 17:42 UTC (permalink / raw)
To: linux-arm-kernel, kvmarm
Cc: Catalin Marinas, Will Deacon, Mark Rutland, 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 | 66 +++++++++++++++++++++++++----
2 files changed, 58 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..e52d2c2b757f 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -140,12 +140,43 @@ void dump_cpu_features(void)
pr_emerg("0x%*pb\n", ARM64_NCAPS, &system_cpucaps);
}
+#define __ARM64_EXPAND_RFV(reg, field, val) reg##_##field##_##val
+#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, \
+ __ARM64_EXPAND_RFV(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), \
+ __ARM64_EXPAND_RFV(reg, field, max_value))
#define __ARM64_FTR_BITS(SIGNED, VISIBLE, STRICT, TYPE, SHIFT, WIDTH, SAFE_VAL) \
{ \
@@ -1470,11 +1501,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] 21+ messages in thread* Re: [PATCH 01/12] arm64: cpufeatures: Correctly handle signed values
2023-11-13 17:42 ` [PATCH 01/12] arm64: cpufeatures: Correctly handle signed values Marc Zyngier
@ 2023-11-17 0:45 ` Oliver Upton
0 siblings, 0 replies; 21+ messages in thread
From: Oliver Upton @ 2023-11-17 0:45 UTC (permalink / raw)
To: Marc Zyngier
Cc: linux-arm-kernel, kvmarm, Catalin Marinas, Will Deacon,
Mark Rutland, James Morse, Suzuki K Poulose, Zenghui Yu
On Mon, Nov 13, 2023 at 05:42:33PM +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 | 66 +++++++++++++++++++++++++----
> 2 files changed, 58 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..e52d2c2b757f 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -140,12 +140,43 @@ void dump_cpu_features(void)
> pr_emerg("0x%*pb\n", ARM64_NCAPS, &system_cpucaps);
> }
>
> +#define __ARM64_EXPAND_RFV(reg, field, val) reg##_##field##_##val
It might be a good idea to move this to sysreg.h and share it with other
callsites that manually concatenate at the moment. I added one instance
of this to ID_REG_LIMIT_FIELD_ENUM() in sys_regs.c, for example.
Kind of a nitpick, but it'd be nice to avoid churn if the underlying
naming scheme changes in the future. Otherwise this looks reasonable
to me.
--
Thanks,
Oliver
_______________________________________________
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] 21+ messages in thread
* [PATCH 02/12] arm64: cpufeature: Correctly display signed override values
2023-11-13 17:42 [PATCH 00/12] arm64: Add support for FEAT_E2H0, or lack thereof Marc Zyngier
2023-11-13 17:42 ` [PATCH 01/12] arm64: cpufeatures: Correctly handle signed values Marc Zyngier
@ 2023-11-13 17:42 ` Marc Zyngier
2023-11-17 0:46 ` Oliver Upton
2023-11-13 17:42 ` [PATCH 03/12] arm64: sysreg: Add layout for ID_AA64MMFR4_EL1 Marc Zyngier
` (9 subsequent siblings)
11 siblings, 1 reply; 21+ messages in thread
From: Marc Zyngier @ 2023-11-13 17:42 UTC (permalink / raw)
To: linux-arm-kernel, kvmarm
Cc: Catalin Marinas, Will Deacon, Mark Rutland, 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.
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 e52d2c2b757f..767a6f288755 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -950,7 +950,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] 21+ messages in thread* Re: [PATCH 02/12] arm64: cpufeature: Correctly display signed override values
2023-11-13 17:42 ` [PATCH 02/12] arm64: cpufeature: Correctly display signed override values Marc Zyngier
@ 2023-11-17 0:46 ` Oliver Upton
0 siblings, 0 replies; 21+ messages in thread
From: Oliver Upton @ 2023-11-17 0:46 UTC (permalink / raw)
To: Marc Zyngier
Cc: linux-arm-kernel, kvmarm, Catalin Marinas, Will Deacon,
Mark Rutland, James Morse, Suzuki K Poulose, Zenghui Yu
On Mon, Nov 13, 2023 at 05:42:34PM +0000, Marc Zyngier wrote:
> 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.
>
> Signed-off-by: Marc Zyngier <maz@kernel.org>
Reviewed-by: Oliver Upton <oliver.upton@linux.dev>
--
Thanks,
Oliver
_______________________________________________
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] 21+ messages in thread
* [PATCH 03/12] arm64: sysreg: Add layout for ID_AA64MMFR4_EL1
2023-11-13 17:42 [PATCH 00/12] arm64: Add support for FEAT_E2H0, or lack thereof Marc Zyngier
2023-11-13 17:42 ` [PATCH 01/12] arm64: cpufeatures: Correctly handle signed values Marc Zyngier
2023-11-13 17:42 ` [PATCH 02/12] arm64: cpufeature: Correctly display signed override values Marc Zyngier
@ 2023-11-13 17:42 ` Marc Zyngier
2023-11-13 17:42 ` [PATCH 04/12] arm64: cpufeature: Add ID_AA64MMFR4_EL1 handling Marc Zyngier
` (8 subsequent siblings)
11 siblings, 0 replies; 21+ messages in thread
From: Marc Zyngier @ 2023-11-13 17:42 UTC (permalink / raw)
To: linux-arm-kernel, kvmarm
Cc: Catalin Marinas, Will Deacon, Mark Rutland, 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.
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] 21+ messages in thread* [PATCH 04/12] arm64: cpufeature: Add ID_AA64MMFR4_EL1 handling
2023-11-13 17:42 [PATCH 00/12] arm64: Add support for FEAT_E2H0, or lack thereof Marc Zyngier
` (2 preceding siblings ...)
2023-11-13 17:42 ` [PATCH 03/12] arm64: sysreg: Add layout for ID_AA64MMFR4_EL1 Marc Zyngier
@ 2023-11-13 17:42 ` Marc Zyngier
2023-11-17 0:48 ` Oliver Upton
2023-11-13 17:42 ` [PATCH 05/12] arm64: cpufeature: Detect E2H0 not being implemented Marc Zyngier
` (7 subsequent siblings)
11 siblings, 1 reply; 21+ messages in thread
From: Marc Zyngier @ 2023-11-13 17:42 UTC (permalink / raw)
To: linux-arm-kernel, kvmarm
Cc: Catalin Marinas, Will Deacon, Mark Rutland, 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.
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 767a6f288755..41db7f993eef 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -438,6 +438,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),
@@ -755,6 +760,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),
@@ -1079,6 +1085,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] 21+ messages in thread* Re: [PATCH 04/12] arm64: cpufeature: Add ID_AA64MMFR4_EL1 handling
2023-11-13 17:42 ` [PATCH 04/12] arm64: cpufeature: Add ID_AA64MMFR4_EL1 handling Marc Zyngier
@ 2023-11-17 0:48 ` Oliver Upton
0 siblings, 0 replies; 21+ messages in thread
From: Oliver Upton @ 2023-11-17 0:48 UTC (permalink / raw)
To: Marc Zyngier
Cc: linux-arm-kernel, kvmarm, Catalin Marinas, Will Deacon,
Mark Rutland, James Morse, Suzuki K Poulose, Zenghui Yu
On Mon, Nov 13, 2023 at 05:42:36PM +0000, Marc Zyngier wrote:
> Add ID_AA64MMFR4_EL1 to the list of idregs the kernel knows about,
> and describe the E2H0 field.
>
> Signed-off-by: Marc Zyngier <maz@kernel.org>
Reviewed-by: Oliver Upton <oliver.upton@linux.dev>
--
Thanks,
Oliver
_______________________________________________
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] 21+ messages in thread
* [PATCH 05/12] arm64: cpufeature: Detect E2H0 not being implemented
2023-11-13 17:42 [PATCH 00/12] arm64: Add support for FEAT_E2H0, or lack thereof Marc Zyngier
` (3 preceding siblings ...)
2023-11-13 17:42 ` [PATCH 04/12] arm64: cpufeature: Add ID_AA64MMFR4_EL1 handling Marc Zyngier
@ 2023-11-13 17:42 ` Marc Zyngier
2023-11-17 0:56 ` Oliver Upton
2023-11-13 17:42 ` [PATCH 06/12] arm64: cpufeature: Detect HCR_EL2.NV1 being RES0 Marc Zyngier
` (6 subsequent siblings)
11 siblings, 1 reply; 21+ messages in thread
From: Marc Zyngier @ 2023-11-13 17:42 UTC (permalink / raw)
To: linux-arm-kernel, kvmarm
Cc: Catalin Marinas, Will Deacon, Mark Rutland, 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 41db7f993eef..e0d64e8b4851 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2787,6 +2787,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] 21+ messages in thread* Re: [PATCH 05/12] arm64: cpufeature: Detect E2H0 not being implemented
2023-11-13 17:42 ` [PATCH 05/12] arm64: cpufeature: Detect E2H0 not being implemented Marc Zyngier
@ 2023-11-17 0:56 ` Oliver Upton
2023-11-17 12:21 ` Marc Zyngier
0 siblings, 1 reply; 21+ messages in thread
From: Oliver Upton @ 2023-11-17 0:56 UTC (permalink / raw)
To: Marc Zyngier
Cc: linux-arm-kernel, kvmarm, Catalin Marinas, Will Deacon,
Mark Rutland, James Morse, Suzuki K Poulose, Zenghui Yu
On Mon, Nov 13, 2023 at 05:42:37PM +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>
Reviewed-by: Oliver Upton <oliver.upton@linux.dev>
> ---
> 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 41db7f993eef..e0d64e8b4851 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -2787,6 +2787,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,
I did read this a couple times before the neurons that interpret "0 not
implemented" and "RES1" fired together, heh.
--
Thanks,
Oliver
_______________________________________________
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] 21+ messages in thread* Re: [PATCH 05/12] arm64: cpufeature: Detect E2H0 not being implemented
2023-11-17 0:56 ` Oliver Upton
@ 2023-11-17 12:21 ` Marc Zyngier
0 siblings, 0 replies; 21+ messages in thread
From: Marc Zyngier @ 2023-11-17 12:21 UTC (permalink / raw)
To: Oliver Upton
Cc: linux-arm-kernel, kvmarm, Catalin Marinas, Will Deacon,
Mark Rutland, James Morse, Suzuki K Poulose, Zenghui Yu
On Fri, 17 Nov 2023 00:56:36 +0000,
Oliver Upton <oliver.upton@linux.dev> wrote:
>
> On Mon, Nov 13, 2023 at 05:42:37PM +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>
>
> Reviewed-by: Oliver Upton <oliver.upton@linux.dev>
>
> > ---
> > 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 41db7f993eef..e0d64e8b4851 100644
> > --- a/arch/arm64/kernel/cpufeature.c
> > +++ b/arch/arm64/kernel/cpufeature.c
> > @@ -2787,6 +2787,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,
>
> I did read this a couple times before the neurons that interpret "0 not
> implemented" and "RES1" fired together, heh.
Yeah, the whole thing is upside down, in order to preserve backward
compatibility. I guess that as the architecture deprecates old cruft,
we may see more of this sort of constructs.
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] 21+ messages in thread
* [PATCH 06/12] arm64: cpufeature: Detect HCR_EL2.NV1 being RES0
2023-11-13 17:42 [PATCH 00/12] arm64: Add support for FEAT_E2H0, or lack thereof Marc Zyngier
` (4 preceding siblings ...)
2023-11-13 17:42 ` [PATCH 05/12] arm64: cpufeature: Detect E2H0 not being implemented Marc Zyngier
@ 2023-11-13 17:42 ` Marc Zyngier
2023-11-13 17:42 ` [PATCH 07/12] arm64: Treat HCR_EL2.E2H as RES1 when ID_AA64MMFR4_EL1.E2H0 is non-zero Marc Zyngier
` (5 subsequent siblings)
11 siblings, 0 replies; 21+ messages in thread
From: Marc Zyngier @ 2023-11-13 17:42 UTC (permalink / raw)
To: linux-arm-kernel, kvmarm
Cc: Catalin Marinas, Will Deacon, Mark Rutland, 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.
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 e0d64e8b4851..a733c9a83f83 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2794,6 +2794,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] 21+ messages in thread* [PATCH 07/12] arm64: Treat HCR_EL2.E2H as RES1 when ID_AA64MMFR4_EL1.E2H0 is non-zero
2023-11-13 17:42 [PATCH 00/12] arm64: Add support for FEAT_E2H0, or lack thereof Marc Zyngier
` (5 preceding siblings ...)
2023-11-13 17:42 ` [PATCH 06/12] arm64: cpufeature: Detect HCR_EL2.NV1 being RES0 Marc Zyngier
@ 2023-11-13 17:42 ` Marc Zyngier
2023-11-17 0:23 ` Oliver Upton
2023-11-13 17:42 ` [PATCH 08/12] arm64: Add override for ID_AA64MMFR4_EL1.E2H0 Marc Zyngier
` (4 subsequent siblings)
11 siblings, 1 reply; 21+ messages in thread
From: Marc Zyngier @ 2023-11-13 17:42 UTC (permalink / raw)
To: linux-arm-kernel, kvmarm
Cc: Catalin Marinas, Will Deacon, Mark Rutland, James Morse,
Suzuki K Poulose, Oliver Upton, Zenghui Yu
For CPUs that have ID_AA64MMFR4_EL1.E2H0 as non-zero, 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.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/kernel/head.S | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 7b236994f0e1..5853540f7809 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -584,25 +584,34 @@ 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=0b111x. 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
+ and x0, x0, #0b1110
+ cmp x0, #0b1110
+ b.eq 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] 21+ messages in thread* Re: [PATCH 07/12] arm64: Treat HCR_EL2.E2H as RES1 when ID_AA64MMFR4_EL1.E2H0 is non-zero
2023-11-13 17:42 ` [PATCH 07/12] arm64: Treat HCR_EL2.E2H as RES1 when ID_AA64MMFR4_EL1.E2H0 is non-zero Marc Zyngier
@ 2023-11-17 0:23 ` Oliver Upton
2023-11-17 12:17 ` Marc Zyngier
0 siblings, 1 reply; 21+ messages in thread
From: Oliver Upton @ 2023-11-17 0:23 UTC (permalink / raw)
To: Marc Zyngier
Cc: linux-arm-kernel, kvmarm, Catalin Marinas, Will Deacon,
Mark Rutland, James Morse, Suzuki K Poulose, Zenghui Yu
Hey Marc,
On Mon, Nov 13, 2023 at 05:42:39PM +0000, Marc Zyngier wrote:
> For CPUs that have ID_AA64MMFR4_EL1.E2H0 as non-zero, 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.
>
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
> arch/arm64/kernel/head.S | 25 +++++++++++++++++--------
> 1 file changed, 17 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> index 7b236994f0e1..5853540f7809 100644
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -584,25 +584,34 @@ 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=0b111x. 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
> + and x0, x0, #0b1110
> + cmp x0, #0b1110
> + b.eq 1f
Wouldn't it be more consistent with the architectural definition of
signed feature fields to just test the sign bit in this case?
Maybe like:
ubfx x0, x0, #ID_AA64MMFR4_EL1_E2H0_SHIFT, #ID_AA64MMFR4_EL1_E2H0_WIDTH
tbnz x0, #3, 1f
You'll also save 8 measly bytes of text while you're at it :)
--
Thanks,
Oliver
_______________________________________________
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] 21+ messages in thread
* Re: [PATCH 07/12] arm64: Treat HCR_EL2.E2H as RES1 when ID_AA64MMFR4_EL1.E2H0 is non-zero
2023-11-17 0:23 ` Oliver Upton
@ 2023-11-17 12:17 ` Marc Zyngier
2023-11-17 18:01 ` Oliver Upton
0 siblings, 1 reply; 21+ messages in thread
From: Marc Zyngier @ 2023-11-17 12:17 UTC (permalink / raw)
To: Oliver Upton
Cc: linux-arm-kernel, kvmarm, Catalin Marinas, Will Deacon,
Mark Rutland, James Morse, Suzuki K Poulose, Zenghui Yu
On Fri, 17 Nov 2023 00:23:13 +0000,
Oliver Upton <oliver.upton@linux.dev> wrote:
>
> Hey Marc,
>
> On Mon, Nov 13, 2023 at 05:42:39PM +0000, Marc Zyngier wrote:
> > For CPUs that have ID_AA64MMFR4_EL1.E2H0 as non-zero, 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.
> >
> > Signed-off-by: Marc Zyngier <maz@kernel.org>
> > ---
> > arch/arm64/kernel/head.S | 25 +++++++++++++++++--------
> > 1 file changed, 17 insertions(+), 8 deletions(-)
> >
> > diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> > index 7b236994f0e1..5853540f7809 100644
> > --- a/arch/arm64/kernel/head.S
> > +++ b/arch/arm64/kernel/head.S
> > @@ -584,25 +584,34 @@ 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=0b111x. 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
> > + and x0, x0, #0b1110
> > + cmp x0, #0b1110
> > + b.eq 1f
>
> Wouldn't it be more consistent with the architectural definition of
> signed feature fields to just test the sign bit in this case?
>
> Maybe like:
>
> ubfx x0, x0, #ID_AA64MMFR4_EL1_E2H0_SHIFT, #ID_AA64MMFR4_EL1_E2H0_WIDTH
> tbnz x0, #3, 1f
>
> You'll also save 8 measly bytes of text while you're at it :)
At this stage, why not try this:
tbnz x0, #(ID_AA64MMFR4_EL1_E2H0_SHIFT + ID_AA64MMFR4_EL1_E2H0_WIDTH - 1), 1f
and we save a total of 12 bytes!
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] 21+ messages in thread
* Re: [PATCH 07/12] arm64: Treat HCR_EL2.E2H as RES1 when ID_AA64MMFR4_EL1.E2H0 is non-zero
2023-11-17 12:17 ` Marc Zyngier
@ 2023-11-17 18:01 ` Oliver Upton
0 siblings, 0 replies; 21+ messages in thread
From: Oliver Upton @ 2023-11-17 18:01 UTC (permalink / raw)
To: Marc Zyngier
Cc: linux-arm-kernel, kvmarm, Catalin Marinas, Will Deacon,
Mark Rutland, James Morse, Suzuki K Poulose, Zenghui Yu
On Fri, Nov 17, 2023 at 12:17:25PM +0000, Marc Zyngier wrote:
> On Fri, 17 Nov 2023 00:23:13 +0000, Oliver Upton <oliver.upton@linux.dev> wrote:
> > Wouldn't it be more consistent with the architectural definition of
> > signed feature fields to just test the sign bit in this case?
> >
> > Maybe like:
> >
> > ubfx x0, x0, #ID_AA64MMFR4_EL1_E2H0_SHIFT, #ID_AA64MMFR4_EL1_E2H0_WIDTH
> > tbnz x0, #3, 1f
> >
> > You'll also save 8 measly bytes of text while you're at it :)
>
> At this stage, why not try this:
>
> tbnz x0, #(ID_AA64MMFR4_EL1_E2H0_SHIFT + ID_AA64MMFR4_EL1_E2H0_WIDTH - 1), 1f
>
> and we save a total of 12 bytes!
Ship it :)
--
Thanks,
Oliver
_______________________________________________
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] 21+ messages in thread
* [PATCH 08/12] arm64: Add override for ID_AA64MMFR4_EL1.E2H0
2023-11-13 17:42 [PATCH 00/12] arm64: Add support for FEAT_E2H0, or lack thereof Marc Zyngier
` (6 preceding siblings ...)
2023-11-13 17:42 ` [PATCH 07/12] arm64: Treat HCR_EL2.E2H as RES1 when ID_AA64MMFR4_EL1.E2H0 is non-zero Marc Zyngier
@ 2023-11-13 17:42 ` Marc Zyngier
2023-11-13 17:42 ` [PATCH 09/12] arm64: Add MIDR-based override infrastructure Marc Zyngier
` (3 subsequent siblings)
11 siblings, 0 replies; 21+ messages in thread
From: Marc Zyngier @ 2023-11-13 17:42 UTC (permalink / raw)
To: linux-arm-kernel, kvmarm
Cc: Catalin Marinas, Will Deacon, Mark Rutland, 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.
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 a733c9a83f83..bc1880e6a2e6 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -692,6 +692,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;
@@ -760,7 +761,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] 21+ messages in thread* [PATCH 09/12] arm64: Add MIDR-based override infrastructure
2023-11-13 17:42 [PATCH 00/12] arm64: Add support for FEAT_E2H0, or lack thereof Marc Zyngier
` (7 preceding siblings ...)
2023-11-13 17:42 ` [PATCH 08/12] arm64: Add override for ID_AA64MMFR4_EL1.E2H0 Marc Zyngier
@ 2023-11-13 17:42 ` Marc Zyngier
2023-11-13 17:42 ` [PATCH 10/12] arm64: Add MIDR-based overrides for ID_AA64MMFR4_EL1.E2H0 Marc Zyngier
` (2 subsequent siblings)
11 siblings, 0 replies; 21+ messages in thread
From: Marc Zyngier @ 2023-11-13 17:42 UTC (permalink / raw)
To: linux-arm-kernel, kvmarm
Cc: Catalin Marinas, Will Deacon, Mark Rutland, 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 teh 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.
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] 21+ messages in thread* [PATCH 10/12] arm64: Add MIDR-based overrides for ID_AA64MMFR4_EL1.E2H0
2023-11-13 17:42 [PATCH 00/12] arm64: Add support for FEAT_E2H0, or lack thereof Marc Zyngier
` (8 preceding siblings ...)
2023-11-13 17:42 ` [PATCH 09/12] arm64: Add MIDR-based override infrastructure Marc Zyngier
@ 2023-11-13 17:42 ` Marc Zyngier
2023-11-13 17:42 ` [PATCH 11/12] KVM: arm64: Expose ID_AA64MMFR4_EL1 to guests Marc Zyngier
2023-11-13 17:42 ` [PATCH 12/12] KVM: arm64: Force guest's HCR_EL2.E2H RES1 when NV1 is not implemented Marc Zyngier
11 siblings, 0 replies; 21+ messages in thread
From: Marc Zyngier @ 2023-11-13 17:42 UTC (permalink / raw)
To: linux-arm-kernel, kvmarm
Cc: Catalin Marinas, Will Deacon, Mark Rutland, 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.
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] 21+ messages in thread* [PATCH 11/12] KVM: arm64: Expose ID_AA64MMFR4_EL1 to guests
2023-11-13 17:42 [PATCH 00/12] arm64: Add support for FEAT_E2H0, or lack thereof Marc Zyngier
` (9 preceding siblings ...)
2023-11-13 17:42 ` [PATCH 10/12] arm64: Add MIDR-based overrides for ID_AA64MMFR4_EL1.E2H0 Marc Zyngier
@ 2023-11-13 17:42 ` Marc Zyngier
2023-11-13 17:42 ` [PATCH 12/12] KVM: arm64: Force guest's HCR_EL2.E2H RES1 when NV1 is not implemented Marc Zyngier
11 siblings, 0 replies; 21+ messages in thread
From: Marc Zyngier @ 2023-11-13 17:42 UTC (permalink / raw)
To: linux-arm-kernel, kvmarm
Cc: Catalin Marinas, Will Deacon, Mark Rutland, 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.
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 4735e1b37fb3..4461eafca16c 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -2196,7 +2196,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] 21+ messages in thread* [PATCH 12/12] KVM: arm64: Force guest's HCR_EL2.E2H RES1 when NV1 is not implemented
2023-11-13 17:42 [PATCH 00/12] arm64: Add support for FEAT_E2H0, or lack thereof Marc Zyngier
` (10 preceding siblings ...)
2023-11-13 17:42 ` [PATCH 11/12] KVM: arm64: Expose ID_AA64MMFR4_EL1 to guests Marc Zyngier
@ 2023-11-13 17:42 ` Marc Zyngier
11 siblings, 0 replies; 21+ messages in thread
From: Marc Zyngier @ 2023-11-13 17:42 UTC (permalink / raw)
To: linux-arm-kernel, kvmarm
Cc: Catalin Marinas, Will Deacon, Mark Rutland, 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.
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 4461eafca16c..a2769e17411c 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -2021,6 +2021,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
@@ -2512,7 +2522,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] 21+ messages in thread