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.mo...@arm.com>
Signed-off-by: Andrew Scull <asc...@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(-)

diff --git a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h 
b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
index 7a986030145f..a549f8698bd4 100644
--- a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
+++ b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
@@ -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)
-- 
2.28.0.220.ged08abb693-goog

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

Reply via email to