diff options
| author | Oliver Upton <[email protected]> | 2025-07-08 17:25:11 +0000 |
|---|---|---|
| committer | Oliver Upton <[email protected]> | 2025-07-08 18:36:31 +0000 |
| commit | 77ee70a073575977b403e9add25f185d614217d8 (patch) | |
| tree | 8a727a6e591ab61cc26230a9d8cd309ececbd642 /arch/arm64/kvm/emulate-nested.c | |
| parent | KVM: arm64: nv: Respect exception routing rules for SEAs (diff) | |
| download | kernel-77ee70a073575977b403e9add25f185d614217d8.tar.gz kernel-77ee70a073575977b403e9add25f185d614217d8.zip | |
KVM: arm64: nv: Honor SError exception routing / masking
To date KVM has used HCR_EL2.VSE to track the state of a pending SError
for the guest. With this bit set, hardware respects the EL1 exception
routing / masking rules and injects the vSError when appropriate.
This isn't correct for NV guests as hardware is oblivious to vEL2's
intentions for SErrors. Better yet, with FEAT_NV2 the guest can change
the routing behind our back as HCR_EL2 is redirected to memory. Cope
with this mess by:
- Using a flag (instead of HCR_EL2.VSE) to track the pending SError
state when SErrors are unconditionally masked for the current context
- Resampling the routing / masking of a pending SError on every guest
entry/exit
- Emulating exception entry when SError routing implies a translation
regime change
Reviewed-by: Marc Zyngier <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Oliver Upton <[email protected]>
Diffstat (limited to 'arch/arm64/kvm/emulate-nested.c')
| -rw-r--r-- | arch/arm64/kvm/emulate-nested.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c index 65a2471c5638..b01a482b41be 100644 --- a/arch/arm64/kvm/emulate-nested.c +++ b/arch/arm64/kvm/emulate-nested.c @@ -2714,6 +2714,9 @@ static void kvm_inject_el2_exception(struct kvm_vcpu *vcpu, u64 esr_el2, case except_type_irq: kvm_pend_exception(vcpu, EXCEPT_AA64_EL2_IRQ); break; + case except_type_serror: + kvm_pend_exception(vcpu, EXCEPT_AA64_EL2_SERR); + break; default: WARN_ONCE(1, "Unsupported EL2 exception injection %d\n", type); } @@ -2821,3 +2824,14 @@ int kvm_inject_nested_sea(struct kvm_vcpu *vcpu, bool iabt, u64 addr) vcpu_write_sys_reg(vcpu, FAR_EL2, addr); return kvm_inject_nested_sync(vcpu, esr); } + +int kvm_inject_nested_serror(struct kvm_vcpu *vcpu, u64 esr) +{ + /* + * Hardware sets up the EC field when propagating ESR as a result of + * vSError injection. Manually populate EC for an emulated SError + * exception. + */ + esr |= FIELD_PREP(ESR_ELx_EC_MASK, ESR_ELx_EC_SERROR); + return kvm_inject_nested(vcpu, esr, except_type_serror); +} |
