fixed severe XRSTOR emulation issue, prevented boot of Win10

This commit is contained in:
Stanislav Shwartsman 2024-01-29 18:40:19 +02:00
parent 6554f9b7b6
commit 7aa8489b1a
2 changed files with 14 additions and 13 deletions

View File

@ -5,7 +5,7 @@ We welcome every new contributor !
Brief summary :
- Bugfixes for CPU emulation correctness (MONITOR/MWAIT, VMX/SVM, x87, AVX-VNNI, AVX-512, CET)
- Critical CPU emulation bugfixes for SHA and GFNI instructions, ADOX instruction (prevented boot of Win10)
- Critical CPU emulation bugfixes for SHA and GFNI instructions, ADOX and XRSTOR/XRSTORS instructions (prevented boot of Win10)
! SVM: Implemented SVM VM_CR_MSR and INIT redirect (required for booting SMP with SVM)
! Implemented VMX MBE (Mode Based Execution Control) emulation required for Windows 11 guest
! Implemented VMX 'Shadow Stack Prematurely Busy' control
@ -39,7 +39,7 @@ Detailed change log :
- CPU/CPUDB
- Bugfixes for CPU emulation correctness (MONITOR/MWAIT, VMX/SVM, x87, AVX-VNNI, AVX-512, CET)
- Critical CPU emulation bugfixes for SHA and GFNI instructions, ADOX instruction (prevented boot of Win10)
- Critical CPU emulation bugfixes for SHA and GFNI instructions, ADOX and XRSTOR/XRSTORS instructions (prevented boot of Win10)
- SVM: Implemented SVM VM_CR_MSR and INIT redirect (required for booting SMP with SVM)
- Implemented VMX MBE (Mode Based Execution Control) emulation required for Windows 11 guest
- Implemented advanced VM-exit information for EPT violations (tied to MBE Control)

View File

@ -189,14 +189,12 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::XSAVEC(bxInstruction_c *i)
Bit64u xstate_bv = requested_feature_bitmap & xinuse;
Bit64u xcomp_bv = requested_feature_bitmap | XSAVEC_COMPACTION_ENABLED;
if ((requested_feature_bitmap & BX_XCR0_FPU_MASK) != 0)
if ((xstate_bv & BX_XCR0_FPU_MASK) != 0)
{
if (xinuse & BX_XCR0_FPU_MASK) {
xsave_x87_state(i, eaddr);
}
xsave_x87_state(i, eaddr);
}
if ((requested_feature_bitmap & BX_XCR0_SSE_MASK) != 0)
if ((xstate_bv & BX_XCR0_SSE_MASK) != 0)
{
// write cannot cause any boundary cross because XSAVE image is 64-byte aligned
write_virtual_dword(i->seg(), eaddr + 24, BX_MXCSR_REGISTER);
@ -341,19 +339,21 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::XRSTOR(bxInstruction_c *i)
}
Bit32u requested_feature_bitmap = xcr0 & EAX;
Bit64u format = xcomp_bv & ~XSAVEC_COMPACTION_ENABLED;
Bit32u restore_mask = xstate_bv & format;
/////////////////////////////////////////////////////////////////////////////
if ((requested_feature_bitmap & BX_XCR0_FPU_MASK) != 0)
{
if (xstate_bv & BX_XCR0_FPU_MASK)
if (restore_mask & BX_XCR0_FPU_MASK)
xrstor_x87_state(i, eaddr);
else
xrstor_init_x87_state();
}
/////////////////////////////////////////////////////////////////////////////
if ((requested_feature_bitmap & BX_XCR0_SSE_MASK) != 0 ||
((requested_feature_bitmap & BX_XCR0_YMM_MASK) != 0 && ! compaction))
if ((requested_feature_bitmap & restore_mask & BX_XCR0_SSE_MASK) != 0 ||
((requested_feature_bitmap & restore_mask & BX_XCR0_YMM_MASK) != 0 && ! compaction))
{
// read cannot cause any boundary cross because XSAVE image is 64-byte aligned
Bit32u new_mxcsr = read_virtual_dword(i->seg(), eaddr + 24);
@ -365,7 +365,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::XRSTOR(bxInstruction_c *i)
/////////////////////////////////////////////////////////////////////////////
if ((requested_feature_bitmap & BX_XCR0_SSE_MASK) != 0)
{
if (xstate_bv & BX_XCR0_SSE_MASK)
if (restore_mask & BX_XCR0_SSE_MASK)
xrstor_sse_state(i, eaddr+XSAVE_SSE_STATE_OFFSET);
else
xrstor_init_sse_state();
@ -386,7 +386,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::XRSTOR(bxInstruction_c *i)
continue;
}
if (xstate_bv & feature_mask) {
if (restore_mask & feature_mask) {
BX_ASSERT(xsave_restore[feature].xrstor_method);
CALL_XSAVE_FN(xsave_restore[feature].xrstor_method)(i, eaddr+offset);
}
@ -395,7 +395,8 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::XRSTOR(bxInstruction_c *i)
CALL_XSAVE_FN(xsave_restore[feature].xrstor_init_method)();
}
offset += xsave_restore[feature].len;
if (format & feature_mask)
offset += xsave_restore[feature].len;
}
}
}