lib: sbi_trap: Set hypervisor CSRs for HS-mode
authorVivian Wang <dramforever@live.com>
Thu, 4 Aug 2022 14:32:30 +0000 (22:32 +0800)
committerAnup Patel <anup@brainfault.org>
Mon, 22 Aug 2022 03:20:04 +0000 (08:50 +0530)
The hypervisor CSRs hstatus, htval, htinst should always be set if the
trap is to be taken in HS-mode, regardless of which mode it came from.

Signed-off-by: Vivian Wang <dramforever@live.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
lib/sbi/sbi_trap.c

index db70c26..1cf2e6f 100644 (file)
@@ -118,12 +118,14 @@ int sbi_trap_redirect(struct sbi_trap_regs *regs,
        regs->mstatus |= (next_virt) ? MSTATUS_MPV : 0UL;
 #endif
 
-       /* Update HSTATUS for VS/VU-mode to HS-mode transition */
-       if (misa_extension('H') && prev_virt && !next_virt) {
-               /* Update HSTATUS SPVP and SPV bits */
+       /* Update hypervisor CSRs if going to HS-mode */
+       if (misa_extension('H') && !next_virt) {
                hstatus = csr_read(CSR_HSTATUS);
-               hstatus &= ~HSTATUS_SPVP;
-               hstatus |= (prev_mode == PRV_S) ? HSTATUS_SPVP : 0;
+               if (prev_virt) {
+                       /* hstatus.SPVP is only updated if coming from VS/VU-mode */
+                       hstatus &= ~HSTATUS_SPVP;
+                       hstatus |= (prev_mode == PRV_S) ? HSTATUS_SPVP : 0;
+               }
                hstatus &= ~HSTATUS_SPV;
                hstatus |= (prev_virt) ? HSTATUS_SPV : 0;
                csr_write(CSR_HSTATUS, hstatus);