VirtualBox

Changeset 10687 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jul 16, 2008 9:22:28 AM (16 years ago)
Author:
vboxsync
Message:

Save the FPU control word and MXCSR on entry and restore them afterwards. (VT-x & AMD-V)
Security measure so the guest can't cause fpu/sse exceptions as we no longer restore the entire
host fpu state.

Location:
trunk/src/VBox/VMM
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/CPUM.cpp

    r10571 r10687  
    8383typedef CPUMDUMPTYPE *PCPUMDUMPTYPE;
    8484
    85 
    8685/*******************************************************************************
    8786*   Internal Functions                                                         *
     
    135134    }
    136135    ASMCpuId_ECX_EDX(1, &pVM->cpum.s.CPUFeatures.ecx, &pVM->cpum.s.CPUFeatures.edx);
     136    ASMCpuId_ECX_EDX(0x80000001, &pVM->cpum.s.CPUFeaturesExt.ecx, &pVM->cpum.s.CPUFeaturesExt.edx);
    137137
    138138    /* Setup the CR4 AND and OR masks used in the switcher */
  • trunk/src/VBox/VMM/CPUMInternal.h

    r10647 r10687  
    322322        X86CPUIDFEATECX     ecx;
    323323    }   CPUFeatures;
     324    /** Host extended CPU features. */
     325    struct
     326    {
     327        /** edx part */
     328        uint32_t     edx;
     329        /** ecx part */
     330        uint32_t     ecx;
     331    }   CPUFeaturesExt;
    324332
    325333    /* CPU manufacturer. */
     
    360368__BEGIN_DECLS
    361369
    362 DECLASM(int)  CPUMHandleLazyFPUAsm(PCPUM pCPUM);
    363 DECLASM(int)  CPUMRestoreHostFPUStateAsm(PCPUM pCPUM);
    364 DECLASM(void) CPUMLoadFPUAsm(PCPUMCTX pCtx);
    365 DECLASM(void) CPUMSaveFPUAsm(PCPUMCTX pCtx);
    366 DECLASM(void) CPUMLoadXMMAsm(PCPUMCTX pCtx);
    367 DECLASM(void) CPUMSaveXMMAsm(PCPUMCTX pCtx);
    368 
     370DECLASM(int)      CPUMHandleLazyFPUAsm(PCPUM pCPUM);
     371DECLASM(int)      CPUMRestoreHostFPUStateAsm(PCPUM pCPUM);
     372DECLASM(void)     CPUMLoadFPUAsm(PCPUMCTX pCtx);
     373DECLASM(void)     CPUMSaveFPUAsm(PCPUMCTX pCtx);
     374DECLASM(void)     CPUMLoadXMMAsm(PCPUMCTX pCtx);
     375DECLASM(void)     CPUMSaveXMMAsm(PCPUMCTX pCtx);
     376DECLASM(void)     CPUMSetFCW(uint16_t u16FCW);
     377DECLASM(uint16_t) CPUMGetFCW();
     378DECLASM(void)     CPUMSetMXCSR(uint32_t u32MXCSR);
     379DECLASM(uint32_t) CPUMGetMXCSR();
    369380
    370381__END_DECLS
  • trunk/src/VBox/VMM/CPUMInternal.mac

    r10569 r10687  
    406406    .CPUFeatures.ecx      resd    1
    407407
     408    ; CPUID eax=0x80000001
     409    .CPUFeaturesExt.edx   resd    1
     410    .CPUFeaturesExt.ecx   resd    1
     411
    408412    .enmCPUVendor         resd    1
    409413
  • trunk/src/VBox/VMM/VMMAll/CPUMAllA.asm

    r10648 r10687  
    291291; @param    pCtx  x86:[esp+4] GCC:rdi MSC:rcx     CPUMCTX pointer
    292292;
     293align 16
    293294BEGINPROC   CPUMLoadXMMAsm
    294295%ifdef RT_ARCH_AMD64
     
    334335; @param    pCtx  x86:[esp+4] GCC:rdi MSC:rcx     CPUMCTX pointer
    335336;
     337align 16
    336338BEGINPROC   CPUMSaveXMMAsm
    337339%ifdef RT_ARCH_AMD64
     
    371373ENDPROC     CPUMSaveXMMAsm
    372374
     375
     376;;
     377; Set the FPU control word; clearing exceptions first
     378;
     379; @param  u16FCW    x86:[esp+4] GCC:rdi MSC:rcx     New FPU control word
     380align 16
     381BEGINPROC CPUMSetFCW
     382%ifdef RT_ARCH_AMD64
     383 %ifdef RT_OS_WINDOWS
     384    mov     xAX, rcx
     385 %else
     386    mov     xAX, rdi
     387 %endif
     388%else
     389    mov     xAX, dword [esp + 4]
     390%endif
     391    fnclex
     392    push    xAX
     393    fldcw   [xSP]
     394    pop     xAX
     395    ret
     396ENDPROC   CPUMSetFCW
     397
     398;;
     399; Get the FPU control word
     400;
     401align 16
     402BEGINPROC CPUMGetFCW
     403    fnstcw  [xSP - 8]
     404    mov     ax, word [xSP - 8]
     405    ret
     406ENDPROC   CPUMGetFCW
     407
     408
     409;;
     410; Set the MXCSR;
     411;
     412; @param  u32MXCSR    x86:[esp+4] GCC:rdi MSC:rcx     New MXCSR
     413align 16
     414BEGINPROC CPUMSetMXCSR
     415%ifdef RT_ARCH_AMD64
     416 %ifdef RT_OS_WINDOWS
     417    mov     xAX, rcx
     418 %else
     419    mov     xAX, rdi
     420 %endif
     421%else
     422    mov     xAX, dword [esp + 4]
     423%endif
     424    push    xAX
     425    ldmxcsr [xSP]
     426    pop     xAX
     427    ret
     428ENDPROC   CPUMSetMXCSR
     429
     430;;
     431; Get the MXCSR
     432;
     433align 16
     434BEGINPROC CPUMGetMXCSR
     435    stmxcsr [xSP - 8]
     436    mov     eax, dword [xSP - 8]
     437    ret
     438ENDPROC   CPUMGetMXCSR
  • trunk/src/VBox/VMM/VMMR0/CPUMR0.cpp

    r10673 r10687  
    163163        break;
    164164    }
     165    /* Save the FPU control word and MXCSR, so we can restore the properly afterwards.
     166     * We don't want the guest to be able to trigger floating point/SSE exceptions on the host.
     167     */
     168    pVM->cpum.s.Host.fpu.FCW = CPUMGetFCW();
     169    if (pVM->cpum.s.CPUFeatures.edx.u1SSE)
     170        pVM->cpum.s.Host.fpu.MXCSR = CPUMGetMXCSR();
     171
    165172    CPUMLoadFPUAsm(pCtx);
    166173
     
    169176     * MSR_K6_EFER_FFXSR changes the behaviour of fxsave and fxrstore: the XMM state isn't saved/restored
    170177     */
    171     if (pVM->cpum.s.aGuestCpuIdExt[1].edx & X86_CPUID_AMD_FEATURE_EDX_FFXSR /* cpuid 0x80000001 */)
     178    if (pVM->cpum.s.CPUFeaturesExt.edx & X86_CPUID_AMD_FEATURE_EDX_FFXSR)
    172179    {
    173180        /* @todo Do we really need to read this every time?? The host could change this on the fly though. */
    174         /* Note: Solaris sets this bit on a per-process basis, so we do need to check each time. */
    175181        uint64_t msrEFERHost = ASMRdMsr(MSR_K6_EFER);
    176182
     
    207213        CPUMSaveXMMAsm(pCtx);
    208214    }
     215    /* Restore the original FPU control word and MXCSR.
     216     * We don't want the guest to be able to trigger floating point/SSE exceptions on the host.
     217     */
     218    CPUMSetFCW(pVM->cpum.s.Host.fpu.FCW);
     219    if (pVM->cpum.s.CPUFeatures.edx.u1SSE)
     220        CPUMSetMXCSR(pVM->cpum.s.Host.fpu.MXCSR);
     221
    209222    pVM->cpum.s.fUseFlags &= ~(CPUM_USED_FPU|CPUM_MANUAL_XMM_RESTORE);
    210223    return VINF_SUCCESS;
  • trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp

    r10683 r10687  
    770770    /*        We must restore the host FPU here to make absolutely sure we don't leave the guest FPU state active
    771771     *        or trash somebody else's FPU state.
    772      */
    773 
    774     /*
    775      * @note We are trashing our own FPU state. That could be a problem if some ring 3 code relies on the FPU control
    776      *       word having a specific value (exceptions, precision etc).
    777772     */
    778773    /* Save the guest FPU and XMM state if necessary. */
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