VirtualBox

Changeset 40022 in vbox for trunk


Ignore:
Timestamp:
Feb 7, 2012 8:29:04 PM (13 years ago)
Author:
vboxsync
Message:

IEM: fxsave & fxrstor.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/vm.h

    r39034 r40022  
    156156        struct IEMCPU       s;
    157157#endif
    158         uint8_t             padding[1024];      /* multiple of 64 */
     158        uint8_t             padding[3072];      /* multiple of 64 */
    159159    } iem;
    160160
     
    215215
    216216    /** Align the following members on page boundary. */
    217     uint8_t                 abAlignment2[3072];
     217    uint8_t                 abAlignment2[1024];
    218218
    219219    /** PGM part. */
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r40001 r40022  
    569569static VBOXSTRICTRC     iemRaiseSelectorInvalidAccess(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess);
    570570static VBOXSTRICTRC     iemRaisePageFault(PIEMCPU pIemCpu, RTGCPTR GCPtrWhere, uint32_t fAccess, int rc);
     571static VBOXSTRICTRC     iemRaiseAlignmentCheckException(PIEMCPU pIemCpu);
    571572static VBOXSTRICTRC     iemMemMap(PIEMCPU pIemCpu, void **ppvMem, size_t cbMem, uint8_t iSegReg, RTGCPTR GCPtrMem, uint32_t fAccess);
    572573static VBOXSTRICTRC     iemMemCommitAndUnmap(PIEMCPU pIemCpu, void *pvMem, uint32_t fAccess);
     
    23662367
    23672368
    2368 /** \#MF(n) - 10.  */
     2369/** \#MF(0) - 10.  */
    23692370DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseMathFault(PIEMCPU pIemCpu)
    23702371{
    23712372    return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_MF, IEM_XCPT_FLAGS_T_CPU_XCPT, 0, 0);
     2373}
     2374
     2375
     2376/** \#AC(0) - 11.  */
     2377DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseAlignmentCheckException(PIEMCPU pIemCpu)
     2378{
     2379    return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_AC, IEM_XCPT_FLAGS_T_CPU_XCPT, 0, 0);
    23722380}
    23732381
     
    38593867 *                              memory.
    38603868 * @param   cbMem               The number of bytes to map.  This is usually 1,
    3861  *                              2, 4, 6, 8, 12, 16 or 32.  When used by string
    3862  *                              operations it can be up to a page.
     3869 *                              2, 4, 6, 8, 12, 16, 32 or 512.  When used by
     3870 *                              string operations it can be up to a page.
    38633871 * @param   iSegReg             The index of the segment register to use for
    38643872 *                              this access.  The base and limits are checked.
     
    38773885     * Check the input and figure out which mapping entry to use.
    38783886     */
    3879     Assert(cbMem <= 32);
     3887    Assert(cbMem <= 32 || cbMem == 512);
    38803888    Assert(~(fAccess & ~(IEM_ACCESS_TYPE_MASK | IEM_ACCESS_WHAT_MASK)));
    38813889
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h

    r40017 r40022  
    33033303 * Implements 'FXSAVE'.
    33043304 *
     3305 * @param   iEffSeg         The effective segment.
    33053306 * @param   GCPtrEff        The address of the image.
    33063307 * @param   enmEffOpSize    The operand size (only REX.W really matters).
    33073308 */
    3308 IEM_CIMPL_DEF_2(iemCImpl_fxsave, RTGCPTR, GCPtrEff, IEMMODE, enmEffOpSize)
     3309IEM_CIMPL_DEF_3(iemCImpl_fxsave, uint8_t, iEffSeg, RTGCPTR, GCPtrEff, IEMMODE, enmEffOpSize)
    33093310{
    33103311    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
    33113312
     3313    /*
     3314     * Raise exceptions.
     3315     */
     3316    if (pCtx->cr0 & X86_CR0_EM)
     3317        return iemRaiseUndefinedOpcode(pIemCpu);
    33123318    if (pCtx->cr0 & (X86_CR0_TS | X86_CR0_EM))
    33133319        return iemRaiseDeviceNotAvailable(pIemCpu);
    3314     if (GCPtrEff & 15) /** @todo \#AC */
     3320    if (GCPtrEff & 15)
     3321    {
     3322        /** @todo CPU/VM detection possible! \#AC might not be signal for
     3323         * all/any misalignment sizes, intel says its an implementation detail. */
     3324        if (   (pCtx->cr0 & X86_CR0_AM)
     3325            && pCtx->eflags.Bits.u1AC
     3326            && pIemCpu->uCpl == 3)
     3327            return iemRaiseAlignmentCheckException(pIemCpu);
    33153328        return iemRaiseGeneralProtectionFault0(pIemCpu);
    3316 
    3317 
    3318     return VERR_IEM_INSTR_NOT_IMPLEMENTED;
     3329    }
     3330    AssertReturn(iemFRegIsFxSaveFormat(pIemCpu), VERR_IEM_IPE_2);
     3331
     3332    /*
     3333     * Access the memory.
     3334     */
     3335    void *pvMem512;
     3336    VBOXSTRICTRC rcStrict = iemMemMap(pIemCpu, &pvMem512, 512, iEffSeg, GCPtrEff, IEM_ACCESS_DATA_W);
     3337    if (rcStrict != VINF_SUCCESS)
     3338        return rcStrict;
     3339    PX86FXSTATE pDst = (PX86FXSTATE)pvMem512;
     3340
     3341    /*
     3342     * Store the registers.
     3343     */
     3344    /** @todo CPU/VM detection possible! If CR4.OSFXSR=0 MXCSR it's
     3345     * implementation specific whether MXCSR and XMM0-XMM7 are saved. */
     3346
     3347    /* common for all formats */
     3348    pDst->FCW           = pCtx->fpu.FCW;
     3349    pDst->FSW           = pCtx->fpu.FSW;
     3350    pDst->FTW           = pCtx->fpu.FTW & UINT16_C(0xff);
     3351    pDst->FOP           = pCtx->fpu.FOP;
     3352    pDst->MXCSR         = pCtx->fpu.MXCSR;
     3353    pDst->MXCSR_MASK    = pCtx->fpu.MXCSR_MASK;
     3354    for (uint32_t i = 0; i < RT_ELEMENTS(pDst->aRegs); i++)
     3355    {
     3356        /** @todo Testcase: What actually happens to the 6 reserved bytes? I'm clearing
     3357         *        them for now... */
     3358        pDst->aRegs[i].au32[0] = pCtx->fpu.aRegs[i].au32[0];
     3359        pDst->aRegs[i].au32[1] = pCtx->fpu.aRegs[i].au32[1];
     3360        pDst->aRegs[i].au32[2] = pCtx->fpu.aRegs[i].au32[2] & UINT32_C(0xffff);
     3361        pDst->aRegs[i].au32[3] = 0;
     3362    }
     3363
     3364    /* FPU IP, CS, DP and DS. */
     3365    /** @todo FPU IP, CS, DP and DS cannot be implemented correctly without extra
     3366     * state information. :-/
     3367     * Storing zeros now to prevent any potential leakage of host info. */
     3368    pDst->FPUIP  = 0;
     3369    pDst->CS     = 0;
     3370    pDst->Rsrvd1 = 0;
     3371    pDst->FPUDP  = 0;
     3372    pDst->DS     = 0;
     3373    pDst->Rsrvd2 = 0;
     3374
     3375    /* XMM registers. */
     3376    if (   !(pCtx->msrEFER & MSR_K6_EFER_FFXSR)
     3377        || pIemCpu->enmCpuMode != IEMMODE_64BIT
     3378        || pIemCpu->uCpl != 0)
     3379    {
     3380        uint32_t cXmmRegs = enmEffOpSize == IEMMODE_64BIT ? 16 : 8;
     3381        for (uint32_t i = 0; i < cXmmRegs; i++)
     3382            pDst->aXMM[i] = pCtx->fpu.aXMM[i];
     3383        /** @todo Testcase: What happens to the reserved XMM registers? Untouched,
     3384         *        right? */
     3385    }
     3386
     3387    /*
     3388     * Commit the memory.
     3389     */
     3390    rcStrict = iemMemCommitAndUnmap(pIemCpu, pvMem512, IEM_ACCESS_DATA_W);
     3391    if (rcStrict != VINF_SUCCESS)
     3392        return rcStrict;
     3393
     3394    iemRegAddToRip(pIemCpu, cbInstr);
     3395    return VINF_SUCCESS;
    33193396}
    33203397
     
    33263403 * @param   enmEffOpSize    The operand size (only REX.W really matters).
    33273404 */
    3328 IEM_CIMPL_DEF_2(iemCImpl_fxrstor, RTGCPTR, GCPtrEff, IEMMODE, enmEffOpSize)
     3405IEM_CIMPL_DEF_3(iemCImpl_fxrstor, uint8_t, iEffSeg, RTGCPTR, GCPtrEff, IEMMODE, enmEffOpSize)
    33293406{
    33303407    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
    33313408
     3409    /*
     3410     * Raise exceptions.
     3411     */
     3412    if (pCtx->cr0 & X86_CR0_EM)
     3413        return iemRaiseUndefinedOpcode(pIemCpu);
    33323414    if (pCtx->cr0 & (X86_CR0_TS | X86_CR0_EM))
    33333415        return iemRaiseDeviceNotAvailable(pIemCpu);
    3334     if (GCPtrEff & 15) /** @todo \#AC */
     3416    if (GCPtrEff & 15)
     3417    {
     3418        /** @todo CPU/VM detection possible! \#AC might not be signal for
     3419         * all/any misalignment sizes, intel says its an implementation detail. */
     3420        if (   (pCtx->cr0 & X86_CR0_AM)
     3421            && pCtx->eflags.Bits.u1AC
     3422            && pIemCpu->uCpl == 3)
     3423            return iemRaiseAlignmentCheckException(pIemCpu);
    33353424        return iemRaiseGeneralProtectionFault0(pIemCpu);
    3336 
    3337 
    3338     return VERR_IEM_INSTR_NOT_IMPLEMENTED;
     3425    }
     3426    AssertReturn(iemFRegIsFxSaveFormat(pIemCpu), VERR_IEM_IPE_2);
     3427
     3428    /*
     3429     * Access the memory.
     3430     */
     3431    void *pvMem512;
     3432    VBOXSTRICTRC rcStrict = iemMemMap(pIemCpu, &pvMem512, 512, iEffSeg, GCPtrEff, IEM_ACCESS_DATA_R);
     3433    if (rcStrict != VINF_SUCCESS)
     3434        return rcStrict;
     3435    PCX86FXSTATE pSrc = (PCX86FXSTATE)pvMem512;
     3436
     3437    /*
     3438     * Check the state for stuff which will GP(0).
     3439     */
     3440    uint32_t const fMXCSR      = pSrc->MXCSR;
     3441    uint32_t const fMXCSR_MASK = pCtx->fpu.MXCSR_MASK ? pCtx->fpu.MXCSR_MASK : UINT32_C(0xffbf);
     3442    if (fMXCSR & ~fMXCSR_MASK)
     3443    {
     3444        Log(("fxrstor: MXCSR=%#x (MXCSR_MASK=%#x) -> #GP(0)\n", fMXCSR, fMXCSR_MASK));
     3445        return iemRaiseGeneralProtectionFault0(pIemCpu);
     3446    }
     3447
     3448    /*
     3449     * Load the registers.
     3450     */
     3451    /** @todo CPU/VM detection possible! If CR4.OSFXSR=0 MXCSR it's
     3452     * implementation specific whether MXCSR and XMM0-XMM7 are restored. */
     3453
     3454    /* common for all formats */
     3455    pCtx->fpu.FCW       = pSrc->FCW;
     3456    pCtx->fpu.FSW       = pSrc->FSW;
     3457    pCtx->fpu.FTW       = pSrc->FTW & UINT16_C(0xff);
     3458    pCtx->fpu.FOP       = pSrc->FOP;
     3459    pCtx->fpu.MXCSR     = fMXCSR;
     3460    /* (MXCSR_MASK is read-only) */
     3461    for (uint32_t i = 0; i < RT_ELEMENTS(pSrc->aRegs); i++)
     3462    {
     3463        pCtx->fpu.aRegs[i].au32[0] = pSrc->aRegs[i].au32[0];
     3464        pCtx->fpu.aRegs[i].au32[1] = pSrc->aRegs[i].au32[1];
     3465        pCtx->fpu.aRegs[i].au32[2] = pSrc->aRegs[i].au32[2] & UINT32_C(0xffff);
     3466        pCtx->fpu.aRegs[i].au32[3] = 0;
     3467    }
     3468
     3469    /* FPU IP, CS, DP and DS. */
     3470    if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
     3471    {
     3472        pCtx->fpu.FPUIP  = pSrc->FPUIP;
     3473        pCtx->fpu.CS     = pSrc->CS;
     3474        pCtx->fpu.Rsrvd1 = pSrc->Rsrvd1;
     3475        pCtx->fpu.FPUDP  = pSrc->FPUDP;
     3476        pCtx->fpu.DS     = pSrc->DS;
     3477        pCtx->fpu.Rsrvd2 = pSrc->Rsrvd2;
     3478    }
     3479    else
     3480    {
     3481        pCtx->fpu.FPUIP  = pSrc->FPUIP;
     3482        pCtx->fpu.CS     = pSrc->CS;
     3483        pCtx->fpu.Rsrvd1 = 0;
     3484        pCtx->fpu.FPUDP  = pSrc->FPUDP;
     3485        pCtx->fpu.DS     = pSrc->DS;
     3486        pCtx->fpu.Rsrvd2 = 0;
     3487    }
     3488
     3489    /* XMM registers. */
     3490    if (   !(pCtx->msrEFER & MSR_K6_EFER_FFXSR)
     3491        || pIemCpu->enmCpuMode != IEMMODE_64BIT
     3492        || pIemCpu->uCpl != 0)
     3493    {
     3494        uint32_t cXmmRegs = enmEffOpSize == IEMMODE_64BIT ? 16 : 8;
     3495        for (uint32_t i = 0; i < cXmmRegs; i++)
     3496            pCtx->fpu.aXMM[i] = pSrc->aXMM[i];
     3497    }
     3498
     3499    /*
     3500     * Commit the memory.
     3501     */
     3502    rcStrict = iemMemCommitAndUnmap(pIemCpu, pvMem512, IEM_ACCESS_DATA_R);
     3503    if (rcStrict != VINF_SUCCESS)
     3504        return rcStrict;
     3505
     3506    iemRegAddToRip(pIemCpu, cbInstr);
     3507    return VINF_SUCCESS;
    33393508}
    33403509
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h

    r40017 r40022  
    33693369        return IEMOP_RAISE_INVALID_LOCK_PREFIX();
    33703370
    3371     IEM_MC_BEGIN(2, 1);
    3372     IEM_MC_ARG(RTGCPTR,         GCPtrEff,                                0);
    3373     IEM_MC_ARG_CONST(IEMMODE,   enmEffOpSize,/*=*/pIemCpu->enmEffOpSize, 1);
     3371    IEM_MC_BEGIN(3, 1);
     3372    IEM_MC_ARG_CONST(uint8_t,   iEffSeg,/*=*/pIemCpu->iEffSeg,           0);
     3373    IEM_MC_ARG(RTGCPTR,         GCPtrEff,                                1);
     3374    IEM_MC_ARG_CONST(IEMMODE,   enmEffOpSize,/*=*/pIemCpu->enmEffOpSize, 2);
    33743375    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEff, bRm);
    3375     IEM_MC_CALL_CIMPL_2(iemCImpl_fxsave, GCPtrEff, enmEffOpSize);
     3376    IEM_MC_CALL_CIMPL_3(iemCImpl_fxsave, iEffSeg, GCPtrEff, enmEffOpSize);
    33763377    IEM_MC_END();
    33773378    return VINF_SUCCESS;
     
    33873388        return IEMOP_RAISE_INVALID_LOCK_PREFIX();
    33883389
    3389     IEM_MC_BEGIN(2, 1);
    3390     IEM_MC_ARG(RTGCPTR,         GCPtrEff,                                0);
    3391     IEM_MC_ARG_CONST(IEMMODE,   enmEffOpSize,/*=*/pIemCpu->enmEffOpSize, 1);
     3390    IEM_MC_BEGIN(3, 1);
     3391    IEM_MC_ARG_CONST(uint8_t,   iEffSeg,/*=*/pIemCpu->iEffSeg,           0);
     3392    IEM_MC_ARG(RTGCPTR,         GCPtrEff,                                1);
     3393    IEM_MC_ARG_CONST(IEMMODE,   enmEffOpSize,/*=*/pIemCpu->enmEffOpSize, 2);
    33923394    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEff, bRm);
    3393     IEM_MC_CALL_CIMPL_2(iemCImpl_fxrstor, GCPtrEff, enmEffOpSize);
     3395    IEM_MC_CALL_CIMPL_3(iemCImpl_fxrstor, iEffSeg, GCPtrEff, enmEffOpSize);
    33943396    IEM_MC_END();
    33953397    return VINF_SUCCESS;
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r39989 r40022  
    266266    struct
    267267    {
    268         uint8_t             ab[64];
     268        uint8_t             ab[512];
    269269    } aBounceBuffers[3];
    270270
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