Browse Source

Fix Guest/VM and Host extension status sync-up

When transitioning from virt-on (VS/VU) to virt-off (HS/M) we should
mark Host extension status (i.e. FS, VS, and XS bits) as dirty when
Guest/VM extension status is dirty and Host extension status is
initial, clean, or dirty.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
pull/647/head
Anup Patel 6 years ago
committed by Anup Patel
parent
commit
142a3bbaee
  1. 25
      riscv/processor.cc

25
riscv/processor.cc

@ -647,17 +647,24 @@ void processor_t::set_virt(bool virt)
if (state.v and !virt) { if (state.v and !virt) {
/* /*
* When transitioning from virt-on (VS/VU) to virt-off (HS/M) * When transitioning from virt-on (VS/VU) to virt-off (HS/M)
* we should sync Guest/VM FS, VS, and XS state with Host FS, * we should mark Host extension status (i.e. FS, VS, and XS
* VS, and XS state. * bits) as dirty when Guest/VM extension status is dirty and
* Host extension status is initial, clean, or dirty.
*/ */
state.vsstatus &= ~SSTATUS_FS; if ((state.vsstatus & SSTATUS_FS) &&
state.vsstatus |= (state.mstatus & SSTATUS_FS); ((state.mstatus & SSTATUS_FS) == SSTATUS_FS)) {
if (supports_extension('V')) { state.vsstatus |= SSTATUS_FS;
state.vsstatus &= ~SSTATUS_VS;
state.vsstatus |= (state.mstatus & SSTATUS_VS);
} }
state.vsstatus &= ~SSTATUS_XS; if (supports_extension('V') &&
state.vsstatus |= (state.mstatus & SSTATUS_XS); (state.vsstatus & SSTATUS_VS) &&
((state.mstatus & SSTATUS_VS) == SSTATUS_VS)) {
state.vsstatus |= SSTATUS_VS;
}
if ((state.vsstatus & SSTATUS_XS) &&
((state.mstatus & SSTATUS_XS) == SSTATUS_XS)) {
state.vsstatus |= SSTATUS_XS;
}
/* Update SD bit of Host */
state.vsstatus &= (xlen == 64 ? ~SSTATUS64_SD : ~SSTATUS32_SD); state.vsstatus &= (xlen == 64 ? ~SSTATUS64_SD : ~SSTATUS32_SD);
if (((state.mstatus & SSTATUS_FS) == SSTATUS_FS) || if (((state.mstatus & SSTATUS_FS) == SSTATUS_FS) ||
((state.vsstatus & SSTATUS_VS) == SSTATUS_VS) || ((state.vsstatus & SSTATUS_VS) == SSTATUS_VS) ||

Loading…
Cancel
Save