@@ -56,8 +56,12 @@ static inline void __sysreg_save_el2_return_state(struct kvm_cpu_context *ctxt)
ctxt->regs.pc = read_sysreg_el2(SYS_ELR);
ctxt->regs.pstate = read_sysreg_el2(SYS_SPSR);
- if (cpus_have_final_cap(ARM64_HAS_RAS_EXTN))
- ctxt_sys_reg(ctxt, DISR_EL1) = read_sysreg_s(SYS_VDISR_EL2);
+ if (cpus_have_final_cap(ARM64_HAS_RAS_EXTN)) {
+ if (ctxt->__hyp_running_vcpu)
+ ctxt_sys_reg(ctxt, DISR_EL1) = read_sysreg_s(SYS_DISR_EL1);
+ else
+ ctxt_sys_reg(ctxt, DISR_EL1) = read_sysreg_s(SYS_VDISR_EL2);
+ }
}
static inline void __sysreg_restore_common_state(struct kvm_cpu_context *ctxt)
@@ -152,8 +156,12 @@ static inline void __sysreg_restore_el2_return_state(struct kvm_cpu_context *ctx
write_sysreg_el2(ctxt->regs.pc, SYS_ELR);
write_sysreg_el2(pstate, SYS_SPSR);
- if (cpus_have_final_cap(ARM64_HAS_RAS_EXTN))
- write_sysreg_s(ctxt_sys_reg(ctxt, DISR_EL1), SYS_VDISR_EL2);
+ if (cpus_have_final_cap(ARM64_HAS_RAS_EXTN)) {
+ if (ctxt->__hyp_running_vcpu)
+ write_sysreg_s(ctxt_sys_reg(ctxt, DISR_EL1), SYS_DISR_EL1);
+ else
+ write_sysreg_s(ctxt_sys_reg(ctxt, DISR_EL1), SYS_VDISR_EL2);
+ }
}
static inline void __sysreg32_save_state(struct kvm_vcpu *vcpu)
With the RAS extension available, guest exits can overwrite DISR_EL1 after checking for any guest SErrors. If the host was using DISR_EL1 to track a deferred SError, it would be lost so save and restore DISR_EL1 for the host. Cc: James Morse <james.morse@arm.com> Signed-off-by: Andrew Scull <ascull@google.com> --- This may not be necessary if it is a safe assumption that the host doesn't mind that DISR_EL1 is clobbered across the kvm_vcpu_run call. --- arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)