VirtualBox

Changeset 10647 in vbox for trunk/src/VBox/VMM/VMMR0


Ignore:
Timestamp:
Jul 15, 2008 12:07:24 PM (17 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
33357
Message:

Manual saving of XMM registers.
Use new FPU/MMX/XMM state saving for VT-x and AMD-V.

Location:
trunk/src/VBox/VMM/VMMR0
Files:
4 edited

Legend:

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

    r10630 r10647  
    119119{
    120120    Assert(pVM->cpum.s.CPUFeatures.edx.u1FXSR);
     121    Assert(ASMGetCR4() & X86_CR4_OSFSXR);
    121122
    122123    /* If the FPU state has already been loaded, then it's a guest trap. */
     
    163164    }
    164165    CPUMLoadFPUAsm(pCtx);
     166
     167    /* The MSR_K6_EFER_FFXSR feature is AMD only so far, but check the cpuid just in case Intel adds it in the future.
     168     *
     169     * MSR_K6_EFER_FFXSR changes the behaviour of fxsave and fxrstore: the XMM state isn't saved/restored
     170     *
     171     * If the guest uses the MSR_K6_EFER_FFXSR as well, then it has to manually restore the XMM state.
     172     * In that case we don't care.
     173     *
     174     * We would end up saving/restoring too much if the guest has it enabled, but the host hasn't.
     175     */
     176    if (    (pVM->cpum.s.aGuestCpuIdExt[1].edx & X86_CPUID_AMD_FEATURE_EDX_FFXSR) /* 0x80000001 */
     177        &&  !(pCtx->msrEFER & MSR_K6_EFER_FFXSR))
     178    {
     179        /* @todo Do we really need to read this every time?? The host could change this on the fly though. */
     180        uint64_t msrEFERHost = ASMRdMsr(MSR_K6_EFER);
     181
     182        if (msrEFERHost & MSR_K6_EFER_FFXSR)
     183        {
     184            /* fxrstor doesn't restore the XMM state! */
     185            CPUMLoadXMMAsm(pCtx);
     186            pVM->cpum.s.fUseFlags |= CPUM_MANUAL_XMM_RESTORE;
     187        }
     188    }
     189
    165190    pVM->cpum.s.fUseFlags |= CPUM_USED_FPU;
    166191    return VINF_SUCCESS;
     
    178203{
    179204    Assert(pVM->cpum.s.CPUFeatures.edx.u1FXSR);
     205    Assert(ASMGetCR4() & X86_CR4_OSFSXR);
    180206    AssertReturn((pVM->cpum.s.fUseFlags & CPUM_USED_FPU), VINF_SUCCESS);
    181207
    182208    CPUMSaveFPUAsm(pCtx);
    183     pVM->cpum.s.fUseFlags &= ~CPUM_USED_FPU;
     209    if (pVM->cpum.s.fUseFlags & CPUM_MANUAL_XMM_RESTORE)
     210    {
     211        /* fxsave doesn't save the XMM state! */
     212        CPUMSaveXMMAsm(pCtx);
     213    }
     214    pVM->cpum.s.fUseFlags &= ~(CPUM_USED_FPU|CPUM_MANUAL_XMM_RESTORE);
    184215    return VINF_SUCCESS;
    185216}
  • trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp

    r10572 r10647  
    774774    if (CPUMIsGuestFPUStateActive(pVM))
    775775    {
    776         Log2(("CPUMRestoreHostFPUState\n"));
    777         /** @note CPUMRestoreHostFPUState keeps the current CR0 intact. */
    778         CPUMRestoreHostFPUState(pVM);
     776        Log2(("CPUMR0SaveGuestFPU\n"));
     777        CPUMR0SaveGuestFPU(pVM, pCtx);
    779778
    780779        pVM->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_CR0;
  • trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp

    r10609 r10647  
    12261226        case X86_XCPT_NM:
    12271227        {
    1228             uint32_t oldCR0;
    1229 
    12301228            Log(("#NM fault at %VGv\n", pCtx->rip));
    12311229
    12321230            /** @todo don't intercept #NM exceptions anymore when we've activated the guest FPU state. */
    1233             oldCR0 = ASMGetCR0();
    12341231            /* If we sync the FPU/XMM state on-demand, then we can continue execution as if nothing has happened. */
    1235             rc = CPUMHandleLazyFPU(pVM);
     1232            rc = CPUMR0LoadGuestFPU(pVM, pCtx);
    12361233            if (rc == VINF_SUCCESS)
    12371234            {
    12381235                Assert(CPUMIsGuestFPUStateActive(pVM));
    1239 
    1240                 /* CPUMHandleLazyFPU could have changed CR0; restore it. */
    1241                 ASMSetCR0(oldCR0);
    1242 
    12431236                STAM_COUNTER_INC(&pVM->hwaccm.s.StatExitShadowNM);
    12441237
  • trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp

    r10609 r10647  
    15561556            case X86_XCPT_NM:
    15571557            {
    1558                 uint32_t oldCR0;
    1559 
    15601558                Log(("#NM fault at %VGv error code %x\n", pCtx->rip, errCode));
    15611559
    15621560                /** @todo don't intercept #NM exceptions anymore when we've activated the guest FPU state. */
    1563                 oldCR0 = ASMGetCR0();
    15641561                /* If we sync the FPU/XMM state on-demand, then we can continue execution as if nothing has happened. */
    1565                 rc = CPUMHandleLazyFPU(pVM);
     1562                rc = CPUMR0LoadGuestFPU(pVM, pCtx);
    15661563                if (rc == VINF_SUCCESS)
    15671564                {
    15681565                    Assert(CPUMIsGuestFPUStateActive(pVM));
    1569 
    1570                     /* CPUMHandleLazyFPU could have changed CR0; restore it. */
    1571                     ASMSetCR0(oldCR0);
    15721566
    15731567                    STAM_COUNTER_INC(&pVM->hwaccm.s.StatExitShadowNM);
Note: See TracChangeset for help on using the changeset viewer.

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