VirtualBox

Changeset 10858 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Jul 24, 2008 4:21:42 PM (17 years ago)
Author:
vboxsync
Message:

We can't rely on #NM handling in kernel mode, so do what we did before (change cr0, save host, restore guest)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/CPUMR0.cpp

    r10687 r10858  
    163163        break;
    164164    }
     165
     166#ifndef CPUM_CAN_HANDLE_NM_TRAPS_IN_KERNEL_MODE
     167    uint64_t oldMsrEFERHost;
     168        uint32_t oldCR0 = ASMGetCR0();
     169
     170    /* Clear MSR_K6_EFER_FFXSR or else we'll be unable to save/restore the XMM state with fxsave/fxrstor. */
     171    if (pVM->cpum.s.CPUFeaturesExt.edx & X86_CPUID_AMD_FEATURE_EDX_FFXSR)
     172    {
     173        /* @todo Do we really need to read this every time?? The host could change this on the fly though. */
     174        oldMsrEFERHost = ASMRdMsr(MSR_K6_EFER);
     175
     176        if (oldMsrEFERHost & MSR_K6_EFER_FFXSR)
     177        {
     178            ASMWrMsr(MSR_K6_EFER, oldMsrEFERHost & ~MSR_K6_EFER_FFXSR);
     179            pVM->cpum.s.fUseFlags |= CPUM_MANUAL_XMM_RESTORE;
     180        }
     181    }
     182
     183    /* If we sync the FPU/XMM state on-demand, then we can continue execution as if nothing has happened. */
     184    int rc = CPUMHandleLazyFPU(pVM);
     185    AssertRC(rc);
     186    Assert(CPUMIsGuestFPUStateActive(pVM));
     187
     188    /* Restore EFER MSR */
     189    if (pVM->cpum.s.fUseFlags & CPUM_MANUAL_XMM_RESTORE)
     190        ASMWrMsr(MSR_K6_EFER, oldMsrEFERHost);
     191
     192        /* CPUMHandleLazyFPU could have changed CR0; restore it. */
     193    ASMSetCR0(oldCR0);
     194#else
    165195    /* Save the FPU control word and MXCSR, so we can restore the properly afterwards.
    166196     * We don't want the guest to be able to trigger floating point/SSE exceptions on the host.
     
    188218        }
    189219    }
     220#endif
    190221
    191222    pVM->cpum.s.fUseFlags |= CPUM_USED_FPU;
     
    207238    AssertReturn((pVM->cpum.s.fUseFlags & CPUM_USED_FPU), VINF_SUCCESS);
    208239
     240#ifndef CPUM_CAN_HANDLE_NM_TRAPS_IN_KERNEL_MODE
     241    uint64_t oldMsrEFERHost;
     242
     243    /* Clear MSR_K6_EFER_FFXSR or else we'll be unable to save/restore the XMM state with fxsave/fxrstor. */
     244    if (pVM->cpum.s.fUseFlags & CPUM_MANUAL_XMM_RESTORE)
     245    {
     246        oldMsrEFERHost = ASMRdMsr(MSR_K6_EFER);
     247        ASMWrMsr(MSR_K6_EFER, oldMsrEFERHost & ~MSR_K6_EFER_FFXSR);
     248    }
     249    CPUMRestoreHostFPUState(pVM);
     250
     251    /* Restore EFER MSR */
     252    if (pVM->cpum.s.fUseFlags & CPUM_MANUAL_XMM_RESTORE)
     253        ASMWrMsr(MSR_K6_EFER, oldMsrEFERHost | MSR_K6_EFER_FFXSR);
     254
     255#else
    209256    CPUMSaveFPUAsm(pCtx);
    210257    if (pVM->cpum.s.fUseFlags & CPUM_MANUAL_XMM_RESTORE)
     
    219266    if (pVM->cpum.s.CPUFeatures.edx.u1SSE)
    220267        CPUMSetMXCSR(pVM->cpum.s.Host.fpu.MXCSR);
     268#endif
    221269
    222270    pVM->cpum.s.fUseFlags &= ~(CPUM_USED_FPU|CPUM_MANUAL_XMM_RESTORE);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette