Skip to contentSkip to conversation

KVM: arm64: Fix a vSError staying pending after delivery under pKVM

PATCH Superseded Fuad Tabba 1 participant 3 messages Sep 21

Subsystems (4)

v2 of 4 Superseded Latest is v4 →

lore
Share & tools
lore

Fuad Tabba

author reviewer
#0 lore raw

v2 cover KVM: arm64: Fix a vSError staying pending after delivery under pKVM

Hi folks,

Changes since v1 [1]:
- Added a cover letter. (Marc)
- Rebased on 7.3-rc4.

Under pKVM a vSError the guest has already taken stays pending in the host's copy of HCR_EL2, since the lazy state sync for non-protected guests stopped copying VSE back on exit. That's a 7.3-rc regression. Patch 1 reflects VSE back on every exit. Patch 2 makes the external_aborts selftest check that the SError is no longer pending once delivered: it fails on the unpatched base and passes with the fix, and also passes under nVHE and VHE.

The "Confine protected VM vCPU state to EL2" series [2] carries patch 1 as its own patch 1, since its later patches change the same exit path in hyp-main.c and don't apply on a tree without the fix. It isn't part of that series: the fix lands from here, and so does the selftest, which that series doesn't carry.

Based on Linux 7.3-rc4 (93f51579e7df2).

Cheers,
/fuad

[1] https://lore.kernel.org/all/[email protected]/
[2] https://lore.kernel.org/all/[email protected]/

Fuad Tabba (2):
KVM: arm64: Sync HCR_EL2.VSE back to the host vCPU under pKVM
KVM: arm64: selftests: Check SError is not pending after delivery

 arch/arm64/kvm/hyp/nvhe/hyp-main.c                  | 4 ++++
 tools/testing/selftests/kvm/arm64/external_aborts.c | 6 ++++++
 2 files changed, 10 insertions(+)

base-commit: 93f51579e7df248780214094418f205253383cc5

Signature · 1 line
2.39.5
author reviewer
#1 lore raw

PATCH v2 1/2 KVM: arm64: Sync HCR_EL2.VSE back to the host vCPU under pKVM

flush_hyp_vcpu() copies HCR_EL2.VSE from the host vCPU into the hyp vCPU on every entry, and nothing copies it back. Once the guest takes the vSError the hyp vCPU's copy clears with the hardware bit while the host's stays set, so the next entry pends the same SError again, KVM_GET_VCPU_EVENTS keeps reporting it, and kvm_arch_vcpu_runnable() never lets the vCPU block in WFI.

Reflect VSE back on every exit, which the flush-side comment already promises.

Fixes 734dc8c01c838 ("KVM: arm64: Implement lazy vCPU state sync for non-protected guests")
---
 arch/arm64/kvm/hyp/nvhe/hyp-main.c | 4 ++++
 1 file changed, 4 insertions(+)
arch/arm64/kvm/hyp/nvhe/hyp-main.c +4 -0
index 9a3b92e626adb..b6bfe502bcd04 100644
@@ -276,6 +276,10 @@ static void sync_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
 
 	host_vcpu->arch.iflags		= hyp_vcpu->vcpu.arch.iflags;
 
+	/* Cleared by hardware once the guest takes the vSError. */
+	host_vcpu->arch.hcr_el2 &= ~HCR_VSE;
+	host_vcpu->arch.hcr_el2 |= hyp_vcpu->vcpu.arch.hcr_el2 & HCR_VSE;
+
 	sync_hyp_vgic_state(hyp_vcpu);
 }
 
Signature · 1 line
2.39.5
author reviewer
#2 lore raw

PATCH v2 2/2 KVM: arm64: selftests: Check SError is not pending after delivery

In reply to Fuad Tabba

test_serror() never looks at the vCPU after the SError is delivered, so a stale pending SError goes unnoticed. Read the vCPU events back and check the SError is no longer pending.

---
 tools/testing/selftests/kvm/arm64/external_aborts.c | 6 ++++++
 1 file changed, 6 insertions(+)
tools/testing/selftests/kvm/arm64/external_aborts.c +6 -0
index d8fe17a6cc592..b276a4998a92c 100644
@@ -239,6 +239,7 @@ static void test_serror_guest(void)
 
 static void test_serror(void)
 {
+	struct kvm_vcpu_events events;
 	struct kvm_vcpu *vcpu;
 	struct kvm_vm *vm = vm_create_with_dabt_handler(&vcpu, test_serror_guest,
 							unexpected_dabt_handler);
@@ -247,6 +248,11 @@ static void test_serror(void)
 
 	vcpu_inject_serror(vcpu);
 	vcpu_run_expect_done(vcpu);
+
+	vcpu_events_get(vcpu, &events);
+	TEST_ASSERT(!events.exception.serror_pending,
+		    "SError still pending after the guest took it");
+
 	kvm_vm_free(vm);
 }
 
Signature · 1 line
2.39.5