kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] KVM: arm64: FEAT_RASv1p1 support and RAS selection
@ 2025-07-21 10:19 Marc Zyngier
  2025-07-21 10:19 ` [PATCH 1/7] arm64: Add capability denoting FEAT_RASv1p1 Marc Zyngier
                   ` (7 more replies)
  0 siblings, 8 replies; 15+ messages in thread
From: Marc Zyngier @ 2025-07-21 10:19 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel, kvm
  Cc: Joey Gouly, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
	Will Deacon, Catalin Marinas

As I was debugging some RAS-related issues[1], I realised that:

- My test box is implementing RASv1p1

- We unconditionally advertise it to guests

- Issuing RASv1p1 accesses doesn't end very well

- [...]

- Profit?

The overall goal of this is to allow the RAS support to be downgraded
to not much, as we're not implementing anything interesting yet, while
still offering the appearance of architecture compliance up to RASv1p1
(everything is RAZ/WI). Along the way, we plug the most glaring holes
(HCR_EL2 bits propagated at the wrong spot, HCR_EL2.FIEN not being
filtered out).

Unusually, this is on top of the DoubleFault2 series, as this is where
the problems started.

[1] https://lore.kernel.org/r/87tt37ulvf.wl-maz@kernel.org

Marc Zyngier (7):
  arm64: Add capability denoting FEAT_RASv1p1
  KVM: arm64: Filter out HCR_EL2 bits when running in hypervisor context
  KVM: arm64: Make RAS registers UNDEF when RAS isn't advertised
  KVM: arm64: Handle RASv1p1 registers
  KVM: arm64: Ignore HCR_EL2.FIEN set by L1 guest's EL2
  KVM: arm64: Expose FEAT_RASv1p1 in a canonical manner
  KVM: arm64: Make ID_AA64PFR0_EL1.RAS writable

 arch/arm64/kernel/cpufeature.c  | 24 ++++++++++++++
 arch/arm64/kvm/hyp/vhe/switch.c | 19 +++++++++--
 arch/arm64/kvm/sys_regs.c       | 56 +++++++++++++++++++++++++++------
 arch/arm64/tools/cpucaps        |  1 +
 4 files changed, 88 insertions(+), 12 deletions(-)

-- 
2.39.2


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

* [PATCH 1/7] arm64: Add capability denoting FEAT_RASv1p1
  2025-07-21 10:19 [PATCH 0/7] KVM: arm64: FEAT_RASv1p1 support and RAS selection Marc Zyngier
@ 2025-07-21 10:19 ` Marc Zyngier
  2025-07-21 13:52   ` Catalin Marinas
  2025-07-21 10:19 ` [PATCH 2/7] KVM: arm64: Filter out HCR_EL2 bits when running in hypervisor context Marc Zyngier
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 15+ messages in thread
From: Marc Zyngier @ 2025-07-21 10:19 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel, kvm
  Cc: Joey Gouly, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
	Will Deacon, Catalin Marinas

Detecting FEAT_RASv1p1 is rather complicated, as there are two
ways for the architecture to advertise the same thing (always a
delight...).

Add a capability that will advertise this in a synthetic way to
the rest of the kernel.

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

diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index a40b94f8e14e1..2da246b593ff7 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2235,6 +2235,24 @@ static void cpu_clear_disr(const struct arm64_cpu_capabilities *__unused)
 	/* Firmware may have left a deferred SError in this register. */
 	write_sysreg_s(0, SYS_DISR_EL1);
 }
+static bool has_rasv1p1(const struct arm64_cpu_capabilities *__unused, int scope)
+{
+	const struct arm64_cpu_capabilities rasv1p1_caps[] = {
+		{
+			ARM64_CPUID_FIELDS(ID_AA64PFR0_EL1, RAS, V1P1)
+		},
+		{
+			ARM64_CPUID_FIELDS(ID_AA64PFR0_EL1, RAS, IMP)
+		},
+		{
+			ARM64_CPUID_FIELDS(ID_AA64PFR1_EL1, RAS_frac, RASv1p1)
+		},
+	};
+
+	return (has_cpuid_feature(&rasv1p1_caps[0], scope) ||
+		(has_cpuid_feature(&rasv1p1_caps[1], scope) &&
+		 has_cpuid_feature(&rasv1p1_caps[2], scope)));
+}
 #endif /* CONFIG_ARM64_RAS_EXTN */
 
 #ifdef CONFIG_ARM64_PTR_AUTH
@@ -2653,6 +2671,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.cpu_enable = cpu_clear_disr,
 		ARM64_CPUID_FIELDS(ID_AA64PFR0_EL1, RAS, IMP)
 	},
+	{
+		.desc = "RASv1p1 Extension Support",
+		.capability = ARM64_HAS_RASV1P1_EXTN,
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.matches = has_rasv1p1,
+	},
 #endif /* CONFIG_ARM64_RAS_EXTN */
 #ifdef CONFIG_ARM64_AMU_EXTN
 	{
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 115161dd9a24d..eb7f1f5622a8f 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -52,6 +52,7 @@ HAS_S1PIE
 HAS_S1POE
 HAS_SCTLR2
 HAS_RAS_EXTN
+HAS_RASV1P1_EXTN
 HAS_RNG
 HAS_SB
 HAS_STAGE2_FWB
-- 
2.39.2


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

* [PATCH 2/7] KVM: arm64: Filter out HCR_EL2 bits when running in hypervisor context
  2025-07-21 10:19 [PATCH 0/7] KVM: arm64: FEAT_RASv1p1 support and RAS selection Marc Zyngier
  2025-07-21 10:19 ` [PATCH 1/7] arm64: Add capability denoting FEAT_RASv1p1 Marc Zyngier
@ 2025-07-21 10:19 ` Marc Zyngier
  2025-07-21 10:19 ` [PATCH 3/7] KVM: arm64: Make RAS registers UNDEF when RAS isn't advertised Marc Zyngier
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Marc Zyngier @ 2025-07-21 10:19 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel, kvm
  Cc: Joey Gouly, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
	Will Deacon, Catalin Marinas, stable

Most HCR_EL2 bits are not supposed to affect EL2 at all, but only
the guest. However, we gladly merge these bits with the host's
HCR_EL2 configuration, irrespective of entering L1 or L2.

This leads to some funky behaviour, such as L1 trying to inject
a virtual SError for L2, and getting a taste of its own medecine.
Not quite what the architecture anticipated.

In the end, the only bits that matter are those we have defined as
invariants, either because we've made them RESx (E2H, HCD...), or
that we actively refuse to merge because the mess with KVM's own
logic.

Use the sanitisation infrastructure to get the RES1 bits, and let
things rip in a safer way.

Fixes: 04ab519bb86df ("KVM: arm64: nv: Configure HCR_EL2 for FEAT_NV2")
Signed-off-by: Marc Zyngier <maz@kernel.org>
Cc: stable@vger.kernel.org
---
 arch/arm64/kvm/hyp/vhe/switch.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 477f1580ffeaa..e482181c66322 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -48,8 +48,7 @@ DEFINE_PER_CPU(unsigned long, kvm_hyp_vector);
 
 static u64 __compute_hcr(struct kvm_vcpu *vcpu)
 {
-	u64 guest_hcr = __vcpu_sys_reg(vcpu, HCR_EL2);
-	u64 hcr = vcpu->arch.hcr_el2;
+	u64 guest_hcr, hcr = vcpu->arch.hcr_el2;
 
 	if (!vcpu_has_nv(vcpu))
 		return hcr;
@@ -68,10 +67,21 @@ static u64 __compute_hcr(struct kvm_vcpu *vcpu)
 		if (!vcpu_el2_e2h_is_set(vcpu))
 			hcr |= HCR_NV1;
 
+		/*
+		 * Nothing in HCR_EL2 should impact running in hypervisor
+		 * context, apart from bits we have defined as RESx (E2H,
+		 * HCD and co), or that cannot be set directly (the EXCLUDE
+		 * bits). Given that we OR the guest's view with the host's,
+		 * we can use the 0 value as the starting point, and only
+		 * use the config-driven RES1 bits.
+		 */
+		guest_hcr = kvm_vcpu_apply_reg_masks(vcpu, HCR_EL2, 0);
+
 		write_sysreg_s(vcpu->arch.ctxt.vncr_array, SYS_VNCR_EL2);
 	} else {
 		host_data_clear_flag(VCPU_IN_HYP_CONTEXT);
 
+		guest_hcr = __vcpu_sys_reg(vcpu, HCR_EL2);
 		if (guest_hcr & HCR_NV) {
 			u64 va = __fix_to_virt(vncr_fixmap(smp_processor_id()));
 
-- 
2.39.2


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

* [PATCH 3/7] KVM: arm64: Make RAS registers UNDEF when RAS isn't advertised
  2025-07-21 10:19 [PATCH 0/7] KVM: arm64: FEAT_RASv1p1 support and RAS selection Marc Zyngier
  2025-07-21 10:19 ` [PATCH 1/7] arm64: Add capability denoting FEAT_RASv1p1 Marc Zyngier
  2025-07-21 10:19 ` [PATCH 2/7] KVM: arm64: Filter out HCR_EL2 bits when running in hypervisor context Marc Zyngier
@ 2025-07-21 10:19 ` Marc Zyngier
  2025-07-21 10:19 ` [PATCH 4/7] KVM: arm64: Handle RASv1p1 registers Marc Zyngier
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Marc Zyngier @ 2025-07-21 10:19 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel, kvm
  Cc: Joey Gouly, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
	Will Deacon, Catalin Marinas

We currently always expose FEAT_RAS when available on the host.

As we are about to make this feature selectable from userspace,
check for it being present before emulating register accesses
as RAZ/WI, and inject an UNDEF otherwise.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/kvm/sys_regs.c | 33 +++++++++++++++++++++++++--------
 1 file changed, 25 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 9d8c47e706b96..aea50870d9f11 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -2688,6 +2688,23 @@ static bool access_mdcr(struct kvm_vcpu *vcpu,
 	return true;
 }
 
+static bool access_ras(struct kvm_vcpu *vcpu,
+		       struct sys_reg_params *p,
+		       const struct sys_reg_desc *r)
+{
+	struct kvm *kvm = vcpu->kvm;
+
+	switch(reg_to_encoding(r)) {
+	default:
+		if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, IMP)) {
+			kvm_inject_undefined(vcpu);
+			return false;
+		}
+	}
+
+	return trap_raz_wi(vcpu, p, r);
+}
+
 /*
  * For historical (ahem ABI) reasons, KVM treated MIDR_EL1, REVIDR_EL1, and
  * AIDR_EL1 as "invariant" registers, meaning userspace cannot change them.
@@ -3035,14 +3052,14 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	{ SYS_DESC(SYS_AFSR1_EL1), access_vm_reg, reset_unknown, AFSR1_EL1 },
 	{ SYS_DESC(SYS_ESR_EL1), access_vm_reg, reset_unknown, ESR_EL1 },
 
-	{ SYS_DESC(SYS_ERRIDR_EL1), trap_raz_wi },
-	{ SYS_DESC(SYS_ERRSELR_EL1), trap_raz_wi },
-	{ SYS_DESC(SYS_ERXFR_EL1), trap_raz_wi },
-	{ SYS_DESC(SYS_ERXCTLR_EL1), trap_raz_wi },
-	{ SYS_DESC(SYS_ERXSTATUS_EL1), trap_raz_wi },
-	{ SYS_DESC(SYS_ERXADDR_EL1), trap_raz_wi },
-	{ SYS_DESC(SYS_ERXMISC0_EL1), trap_raz_wi },
-	{ SYS_DESC(SYS_ERXMISC1_EL1), trap_raz_wi },
+	{ SYS_DESC(SYS_ERRIDR_EL1), access_ras },
+	{ SYS_DESC(SYS_ERRSELR_EL1), access_ras },
+	{ SYS_DESC(SYS_ERXFR_EL1), access_ras },
+	{ SYS_DESC(SYS_ERXCTLR_EL1), access_ras },
+	{ SYS_DESC(SYS_ERXSTATUS_EL1), access_ras },
+	{ SYS_DESC(SYS_ERXADDR_EL1), access_ras },
+	{ SYS_DESC(SYS_ERXMISC0_EL1), access_ras },
+	{ SYS_DESC(SYS_ERXMISC1_EL1), access_ras },
 
 	MTE_REG(TFSR_EL1),
 	MTE_REG(TFSRE0_EL1),
-- 
2.39.2


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

* [PATCH 4/7] KVM: arm64: Handle RASv1p1 registers
  2025-07-21 10:19 [PATCH 0/7] KVM: arm64: FEAT_RASv1p1 support and RAS selection Marc Zyngier
                   ` (2 preceding siblings ...)
  2025-07-21 10:19 ` [PATCH 3/7] KVM: arm64: Make RAS registers UNDEF when RAS isn't advertised Marc Zyngier
@ 2025-07-21 10:19 ` Marc Zyngier
  2025-07-21 13:08   ` Marc Zyngier
  2025-07-21 10:19 ` [PATCH 5/7] KVM: arm64: Ignore HCR_EL2.FIEN set by L1 guest's EL2 Marc Zyngier
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 15+ messages in thread
From: Marc Zyngier @ 2025-07-21 10:19 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel, kvm
  Cc: Joey Gouly, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
	Will Deacon, Catalin Marinas

FEAT_RASv1p1 system registeres are not handled at all so far.
KVM will give an embarassed warning on the console and inject
an UNDEF, despite RASv1p1 being exposed to the guest on suitable HW.

Handle these registers similarly to FEAT_RAS, with the added fun
that there are *two* way to indicate the presence of FEAT_RASv1p1.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/kvm/sys_regs.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index aea50870d9f11..9fb2812106cb0 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -2695,6 +2695,16 @@ static bool access_ras(struct kvm_vcpu *vcpu,
 	struct kvm *kvm = vcpu->kvm;
 
 	switch(reg_to_encoding(r)) {
+	case SYS_ERXPFGCDN_EL1:
+	case SYS_ERXPFGCTL_EL1:
+	case SYS_ERXPFGF_EL1:
+		if (!(kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, V1P1) ||
+		      (kvm_has_feat_enum(kvm, ID_AA64PFR0_EL1, RAS, IMP) &&
+		       kvm_has_feat(kvm, ID_AA64PFR1_EL1, RAS_frac, RASv1p1)))) {
+			kvm_inject_undefined(vcpu);
+			return false;
+		}
+		break;
 	default:
 		if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, IMP)) {
 			kvm_inject_undefined(vcpu);
@@ -3058,6 +3068,9 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	{ SYS_DESC(SYS_ERXCTLR_EL1), access_ras },
 	{ SYS_DESC(SYS_ERXSTATUS_EL1), access_ras },
 	{ SYS_DESC(SYS_ERXADDR_EL1), access_ras },
+	{ SYS_DESC(SYS_ERXPFGF_EL1), access_ras },
+	{ SYS_DESC(SYS_ERXPFGCTL_EL1), access_ras },
+	{ SYS_DESC(SYS_ERXPFGCDN_EL1), access_ras },
 	{ SYS_DESC(SYS_ERXMISC0_EL1), access_ras },
 	{ SYS_DESC(SYS_ERXMISC1_EL1), access_ras },
 
-- 
2.39.2


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

* [PATCH 5/7] KVM: arm64: Ignore HCR_EL2.FIEN set by L1 guest's EL2
  2025-07-21 10:19 [PATCH 0/7] KVM: arm64: FEAT_RASv1p1 support and RAS selection Marc Zyngier
                   ` (3 preceding siblings ...)
  2025-07-21 10:19 ` [PATCH 4/7] KVM: arm64: Handle RASv1p1 registers Marc Zyngier
@ 2025-07-21 10:19 ` Marc Zyngier
  2025-07-21 10:19 ` [PATCH 6/7] KVM: arm64: Expose FEAT_RASv1p1 in a canonical manner Marc Zyngier
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Marc Zyngier @ 2025-07-21 10:19 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel, kvm
  Cc: Joey Gouly, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
	Will Deacon, Catalin Marinas

An EL2 guest can set HCR_EL2.FIEN, which gives access to the RASv1p1
fault injection mechanism. This would allow an EL1 guest to inject
error records into the system, which does sound like a terrible idea.

Prevent this situation by added FIEN to the list of bits we silently
exclude from being inserted into the host configuration.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/kvm/hyp/vhe/switch.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index e482181c66322..0998ad4a25524 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -43,8 +43,11 @@ DEFINE_PER_CPU(unsigned long, kvm_hyp_vector);
  *
  * - API/APK: they are already accounted for by vcpu_load(), and can
  *   only take effect across a load/put cycle (such as ERET)
+ *
+ * - FIEN: no way we let a guest have access to the RAS "Common Fault
+ *   Injection" thing, whatever that does
  */
-#define NV_HCR_GUEST_EXCLUDE	(HCR_TGE | HCR_API | HCR_APK)
+#define NV_HCR_GUEST_EXCLUDE	(HCR_TGE | HCR_API | HCR_APK | HCR_FIEN)
 
 static u64 __compute_hcr(struct kvm_vcpu *vcpu)
 {
-- 
2.39.2


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

* [PATCH 6/7] KVM: arm64: Expose FEAT_RASv1p1 in a canonical manner
  2025-07-21 10:19 [PATCH 0/7] KVM: arm64: FEAT_RASv1p1 support and RAS selection Marc Zyngier
                   ` (4 preceding siblings ...)
  2025-07-21 10:19 ` [PATCH 5/7] KVM: arm64: Ignore HCR_EL2.FIEN set by L1 guest's EL2 Marc Zyngier
@ 2025-07-21 10:19 ` Marc Zyngier
  2025-07-21 12:32   ` Cornelia Huck
  2025-07-21 10:19 ` [PATCH 7/7] KVM: arm64: Make ID_AA64PFR0_EL1.RAS writable Marc Zyngier
  2025-07-21 22:24 ` (subset) [PATCH 0/7] KVM: arm64: FEAT_RASv1p1 support and RAS selection Oliver Upton
  7 siblings, 1 reply; 15+ messages in thread
From: Marc Zyngier @ 2025-07-21 10:19 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel, kvm
  Cc: Joey Gouly, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
	Will Deacon, Catalin Marinas

If we have RASv1p1 on the host, advertise it to the guest in the
"canonical way", by setting ID_AA64PFR0_EL1 to V1P1, rather than
the convoluted RAS+RAS_frac method.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/kvm/sys_regs.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 9fb2812106cb0..549766d7abca8 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1800,6 +1800,15 @@ static u64 sanitise_id_aa64pfr0_el1(const struct kvm_vcpu *vcpu, u64 val)
 	if (!vcpu_has_sve(vcpu))
 		val &= ~ID_AA64PFR0_EL1_SVE_MASK;
 
+	/*
+	 * Describe RASv1p1 in a canonical way -- ID_AA64PFR1_EL1.RAS_frac
+	 * is cleared separately.
+	 */
+	if (cpus_have_final_cap(ARM64_HAS_RASV1P1_EXTN)) {
+		val &= ~ID_AA64PFR0_EL1_RAS;
+		val |= SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, RAS, V1P1);
+	}
+
 	/*
 	 * The default is to expose CSV2 == 1 if the HW isn't affected.
 	 * Although this is a per-CPU feature, we make it global because
-- 
2.39.2


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

* [PATCH 7/7] KVM: arm64: Make ID_AA64PFR0_EL1.RAS writable
  2025-07-21 10:19 [PATCH 0/7] KVM: arm64: FEAT_RASv1p1 support and RAS selection Marc Zyngier
                   ` (5 preceding siblings ...)
  2025-07-21 10:19 ` [PATCH 6/7] KVM: arm64: Expose FEAT_RASv1p1 in a canonical manner Marc Zyngier
@ 2025-07-21 10:19 ` Marc Zyngier
  2025-07-21 22:24 ` (subset) [PATCH 0/7] KVM: arm64: FEAT_RASv1p1 support and RAS selection Oliver Upton
  7 siblings, 0 replies; 15+ messages in thread
From: Marc Zyngier @ 2025-07-21 10:19 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel, kvm
  Cc: Joey Gouly, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
	Will Deacon, Catalin Marinas

Make ID_AA64PFR0_EL1.RAS writable so that we can restore a VM from
a system without RAS to a RAS-equipped machine (or disable RAS
in the guest).

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/kvm/sys_regs.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 549766d7abca8..64707c62f1cf9 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -2946,7 +2946,6 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 		    ~(ID_AA64PFR0_EL1_AMU |
 		      ID_AA64PFR0_EL1_MPAM |
 		      ID_AA64PFR0_EL1_SVE |
-		      ID_AA64PFR0_EL1_RAS |
 		      ID_AA64PFR0_EL1_AdvSIMD |
 		      ID_AA64PFR0_EL1_FP)),
 	ID_FILTERED(ID_AA64PFR1_EL1, id_aa64pfr1_el1,
-- 
2.39.2


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

* Re: [PATCH 6/7] KVM: arm64: Expose FEAT_RASv1p1 in a canonical manner
  2025-07-21 10:19 ` [PATCH 6/7] KVM: arm64: Expose FEAT_RASv1p1 in a canonical manner Marc Zyngier
@ 2025-07-21 12:32   ` Cornelia Huck
  2025-07-21 12:55     ` Marc Zyngier
  0 siblings, 1 reply; 15+ messages in thread
From: Cornelia Huck @ 2025-07-21 12:32 UTC (permalink / raw)
  To: Marc Zyngier, kvmarm, linux-arm-kernel, kvm
  Cc: Joey Gouly, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
	Will Deacon, Catalin Marinas

On Mon, Jul 21 2025, Marc Zyngier <maz@kernel.org> wrote:

> If we have RASv1p1 on the host, advertise it to the guest in the
> "canonical way", by setting ID_AA64PFR0_EL1 to V1P1, rather than
> the convoluted RAS+RAS_frac method.

Don't the two methods have slightly different semantics with RAS == V1P1
possibly implying FEAT_DoubleFault, and RAS+RAS_frac not?

>
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
>  arch/arm64/kvm/sys_regs.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
>
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 9fb2812106cb0..549766d7abca8 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -1800,6 +1800,15 @@ static u64 sanitise_id_aa64pfr0_el1(const struct kvm_vcpu *vcpu, u64 val)
>  	if (!vcpu_has_sve(vcpu))
>  		val &= ~ID_AA64PFR0_EL1_SVE_MASK;
>  
> +	/*
> +	 * Describe RASv1p1 in a canonical way -- ID_AA64PFR1_EL1.RAS_frac
> +	 * is cleared separately.
> +	 */
> +	if (cpus_have_final_cap(ARM64_HAS_RASV1P1_EXTN)) {
> +		val &= ~ID_AA64PFR0_EL1_RAS;
> +		val |= SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, RAS, V1P1);
> +	}
> +
>  	/*
>  	 * The default is to expose CSV2 == 1 if the HW isn't affected.
>  	 * Although this is a per-CPU feature, we make it global because
> -- 
> 2.39.2


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

* Re: [PATCH 6/7] KVM: arm64: Expose FEAT_RASv1p1 in a canonical manner
  2025-07-21 12:32   ` Cornelia Huck
@ 2025-07-21 12:55     ` Marc Zyngier
  2025-07-21 13:12       ` Cornelia Huck
  0 siblings, 1 reply; 15+ messages in thread
From: Marc Zyngier @ 2025-07-21 12:55 UTC (permalink / raw)
  To: Cornelia Huck
  Cc: kvmarm, linux-arm-kernel, kvm, Joey Gouly, Suzuki K Poulose,
	Oliver Upton, Zenghui Yu, Will Deacon, Catalin Marinas

On Mon, 21 Jul 2025 13:32:08 +0100,
Cornelia Huck <cohuck@redhat.com> wrote:
> 
> On Mon, Jul 21 2025, Marc Zyngier <maz@kernel.org> wrote:
> 
> > If we have RASv1p1 on the host, advertise it to the guest in the
> > "canonical way", by setting ID_AA64PFR0_EL1 to V1P1, rather than
> > the convoluted RAS+RAS_frac method.
> 
> Don't the two methods have slightly different semantics with RAS == V1P1
> possibly implying FEAT_DoubleFault, and RAS+RAS_frac not?

Ah, that's an interesting point -- I definitely had glanced over that.

But I'm not sure a guest can actually distinguish between these two
configurations, given that FEAT_DoubleFault is essentially an EL3
feature (as indicated in the RAS == V1P1 section, and further
confirmed in R_GRJVN), making it invisible to the guest.

FEAT_DoubleFault2 is, on the contrary, totally visible from the guest,
and independent of EL3.

Does this make sense to you?

Thanks,

	M.

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

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

* Re: [PATCH 4/7] KVM: arm64: Handle RASv1p1 registers
  2025-07-21 10:19 ` [PATCH 4/7] KVM: arm64: Handle RASv1p1 registers Marc Zyngier
@ 2025-07-21 13:08   ` Marc Zyngier
  0 siblings, 0 replies; 15+ messages in thread
From: Marc Zyngier @ 2025-07-21 13:08 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel, kvm
  Cc: Joey Gouly, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
	Will Deacon, Catalin Marinas

On Mon, 21 Jul 2025 11:19:52 +0100,
Marc Zyngier <maz@kernel.org> wrote:
> 
> FEAT_RASv1p1 system registeres are not handled at all so far.
> KVM will give an embarassed warning on the console and inject
> an UNDEF, despite RASv1p1 being exposed to the guest on suitable HW.
> 
> Handle these registers similarly to FEAT_RAS, with the added fun
> that there are *two* way to indicate the presence of FEAT_RASv1p1.
> 
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
>  arch/arm64/kvm/sys_regs.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index aea50870d9f11..9fb2812106cb0 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -2695,6 +2695,16 @@ static bool access_ras(struct kvm_vcpu *vcpu,
>  	struct kvm *kvm = vcpu->kvm;
>  
>  	switch(reg_to_encoding(r)) {
> +	case SYS_ERXPFGCDN_EL1:
> +	case SYS_ERXPFGCTL_EL1:
> +	case SYS_ERXPFGF_EL1:
> +		if (!(kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, V1P1) ||
> +		      (kvm_has_feat_enum(kvm, ID_AA64PFR0_EL1, RAS, IMP) &&
> +		       kvm_has_feat(kvm, ID_AA64PFR1_EL1, RAS_frac, RASv1p1)))) {
> +			kvm_inject_undefined(vcpu);
> +			return false;
> +		}
> +		break;
>  	default:
>  		if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, IMP)) {
>  			kvm_inject_undefined(vcpu);
> @@ -3058,6 +3068,9 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>  	{ SYS_DESC(SYS_ERXCTLR_EL1), access_ras },
>  	{ SYS_DESC(SYS_ERXSTATUS_EL1), access_ras },
>  	{ SYS_DESC(SYS_ERXADDR_EL1), access_ras },
> +	{ SYS_DESC(SYS_ERXPFGF_EL1), access_ras },
> +	{ SYS_DESC(SYS_ERXPFGCTL_EL1), access_ras },
> +	{ SYS_DESC(SYS_ERXPFGCDN_EL1), access_ras },
>  	{ SYS_DESC(SYS_ERXMISC0_EL1), access_ras },
>  	{ SYS_DESC(SYS_ERXMISC1_EL1), access_ras },
>  

This is obviously missing the ERXMISC{2,3}_EL1 registers, which I have
now added as a fixup on top of the current series. I'll squash that
before reposting.

Thanks,

	M.

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

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

* Re: [PATCH 6/7] KVM: arm64: Expose FEAT_RASv1p1 in a canonical manner
  2025-07-21 12:55     ` Marc Zyngier
@ 2025-07-21 13:12       ` Cornelia Huck
  2025-07-21 13:33         ` Marc Zyngier
  0 siblings, 1 reply; 15+ messages in thread
From: Cornelia Huck @ 2025-07-21 13:12 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: kvmarm, linux-arm-kernel, kvm, Joey Gouly, Suzuki K Poulose,
	Oliver Upton, Zenghui Yu, Will Deacon, Catalin Marinas

On Mon, Jul 21 2025, Marc Zyngier <maz@kernel.org> wrote:

> On Mon, 21 Jul 2025 13:32:08 +0100,
> Cornelia Huck <cohuck@redhat.com> wrote:
>> 
>> On Mon, Jul 21 2025, Marc Zyngier <maz@kernel.org> wrote:
>> 
>> > If we have RASv1p1 on the host, advertise it to the guest in the
>> > "canonical way", by setting ID_AA64PFR0_EL1 to V1P1, rather than
>> > the convoluted RAS+RAS_frac method.
>> 
>> Don't the two methods have slightly different semantics with RAS == V1P1
>> possibly implying FEAT_DoubleFault, and RAS+RAS_frac not?
>
> Ah, that's an interesting point -- I definitely had glanced over that.
>
> But I'm not sure a guest can actually distinguish between these two
> configurations, given that FEAT_DoubleFault is essentially an EL3
> feature (as indicated in the RAS == V1P1 section, and further
> confirmed in R_GRJVN), making it invisible to the guest.
>
> FEAT_DoubleFault2 is, on the contrary, totally visible from the guest,
> and independent of EL3.
>
> Does this make sense to you?

It does; but it might make sense to add a comment explaining that.

Userspace should hopefully be able to just map everything to RAS == V1P1
and be done with it.


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

* Re: [PATCH 6/7] KVM: arm64: Expose FEAT_RASv1p1 in a canonical manner
  2025-07-21 13:12       ` Cornelia Huck
@ 2025-07-21 13:33         ` Marc Zyngier
  0 siblings, 0 replies; 15+ messages in thread
From: Marc Zyngier @ 2025-07-21 13:33 UTC (permalink / raw)
  To: Cornelia Huck
  Cc: kvmarm, linux-arm-kernel, kvm, Joey Gouly, Suzuki K Poulose,
	Oliver Upton, Zenghui Yu, Will Deacon, Catalin Marinas

On Mon, 21 Jul 2025 14:12:19 +0100,
Cornelia Huck <cohuck@redhat.com> wrote:
> 
> On Mon, Jul 21 2025, Marc Zyngier <maz@kernel.org> wrote:
> 
> > On Mon, 21 Jul 2025 13:32:08 +0100,
> > Cornelia Huck <cohuck@redhat.com> wrote:
> >> 
> >> On Mon, Jul 21 2025, Marc Zyngier <maz@kernel.org> wrote:
> >> 
> >> > If we have RASv1p1 on the host, advertise it to the guest in the
> >> > "canonical way", by setting ID_AA64PFR0_EL1 to V1P1, rather than
> >> > the convoluted RAS+RAS_frac method.
> >> 
> >> Don't the two methods have slightly different semantics with RAS == V1P1
> >> possibly implying FEAT_DoubleFault, and RAS+RAS_frac not?
> >
> > Ah, that's an interesting point -- I definitely had glanced over that.
> >
> > But I'm not sure a guest can actually distinguish between these two
> > configurations, given that FEAT_DoubleFault is essentially an EL3
> > feature (as indicated in the RAS == V1P1 section, and further
> > confirmed in R_GRJVN), making it invisible to the guest.
> >
> > FEAT_DoubleFault2 is, on the contrary, totally visible from the guest,
> > and independent of EL3.
> >
> > Does this make sense to you?
> 
> It does; but it might make sense to add a comment explaining that.

Sure thing. I'll add a sentence or three on the subject.

> Userspace should hopefully be able to just map everything to RAS == V1P1
> and be done with it.

Indeed, that's the intention. RAS_frac is zeroed and made
non-writable.  This is also consistent with RASv2, for which RAS_frac
is not relevant (not that there is a plan to support RASv2 in the
foreseeable future!).

Thanks,

	M.

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

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

* Re: [PATCH 1/7] arm64: Add capability denoting FEAT_RASv1p1
  2025-07-21 10:19 ` [PATCH 1/7] arm64: Add capability denoting FEAT_RASv1p1 Marc Zyngier
@ 2025-07-21 13:52   ` Catalin Marinas
  0 siblings, 0 replies; 15+ messages in thread
From: Catalin Marinas @ 2025-07-21 13:52 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: kvmarm, linux-arm-kernel, kvm, Joey Gouly, Suzuki K Poulose,
	Oliver Upton, Zenghui Yu, Will Deacon

On Mon, Jul 21, 2025 at 11:19:49AM +0100, Marc Zyngier wrote:
> Detecting FEAT_RASv1p1 is rather complicated, as there are two
> ways for the architecture to advertise the same thing (always a
> delight...).
> 
> Add a capability that will advertise this in a synthetic way to
> the rest of the kernel.
> 
> Signed-off-by: Marc Zyngier <maz@kernel.org>

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

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

* Re: (subset) [PATCH 0/7] KVM: arm64: FEAT_RASv1p1 support and RAS selection
  2025-07-21 10:19 [PATCH 0/7] KVM: arm64: FEAT_RASv1p1 support and RAS selection Marc Zyngier
                   ` (6 preceding siblings ...)
  2025-07-21 10:19 ` [PATCH 7/7] KVM: arm64: Make ID_AA64PFR0_EL1.RAS writable Marc Zyngier
@ 2025-07-21 22:24 ` Oliver Upton
  7 siblings, 0 replies; 15+ messages in thread
From: Oliver Upton @ 2025-07-21 22:24 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel, kvm, Marc Zyngier
  Cc: Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
	Will Deacon, Catalin Marinas

On Mon, 21 Jul 2025 11:19:48 +0100, Marc Zyngier wrote:
> As I was debugging some RAS-related issues[1], I realised that:
> 
> - My test box is implementing RASv1p1
> 
> - We unconditionally advertise it to guests
> 
> - Issuing RASv1p1 accesses doesn't end very well
> 
> [...]

I haven't reviewed this series in full yet but wanted to pick up the
HCR fix that we need urgently and the obvious FEAT_RAS change.

Applied to next, thanks!

[2/7] KVM: arm64: Filter out HCR_EL2 bits when running in hypervisor context
      https://git.kernel.org/kvmarm/kvmarm/c/303084ad1276
[3/7] KVM: arm64: Make RAS registers UNDEF when RAS isn't advertised
      https://git.kernel.org/kvmarm/kvmarm/c/d9c5c2320156

--
Best,
Oliver

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

end of thread, other threads:[~2025-07-21 22:25 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-21 10:19 [PATCH 0/7] KVM: arm64: FEAT_RASv1p1 support and RAS selection Marc Zyngier
2025-07-21 10:19 ` [PATCH 1/7] arm64: Add capability denoting FEAT_RASv1p1 Marc Zyngier
2025-07-21 13:52   ` Catalin Marinas
2025-07-21 10:19 ` [PATCH 2/7] KVM: arm64: Filter out HCR_EL2 bits when running in hypervisor context Marc Zyngier
2025-07-21 10:19 ` [PATCH 3/7] KVM: arm64: Make RAS registers UNDEF when RAS isn't advertised Marc Zyngier
2025-07-21 10:19 ` [PATCH 4/7] KVM: arm64: Handle RASv1p1 registers Marc Zyngier
2025-07-21 13:08   ` Marc Zyngier
2025-07-21 10:19 ` [PATCH 5/7] KVM: arm64: Ignore HCR_EL2.FIEN set by L1 guest's EL2 Marc Zyngier
2025-07-21 10:19 ` [PATCH 6/7] KVM: arm64: Expose FEAT_RASv1p1 in a canonical manner Marc Zyngier
2025-07-21 12:32   ` Cornelia Huck
2025-07-21 12:55     ` Marc Zyngier
2025-07-21 13:12       ` Cornelia Huck
2025-07-21 13:33         ` Marc Zyngier
2025-07-21 10:19 ` [PATCH 7/7] KVM: arm64: Make ID_AA64PFR0_EL1.RAS writable Marc Zyngier
2025-07-21 22:24 ` (subset) [PATCH 0/7] KVM: arm64: FEAT_RASv1p1 support and RAS selection Oliver Upton

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