VirtualBox

Changeset 47548 in vbox


Ignore:
Timestamp:
Aug 6, 2013 3:58:21 AM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
87746
Message:

IEM: Bunch of fixes, mostly DOS related.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r47494 r47548  
    694694*******************************************************************************/
    695695static VBOXSTRICTRC     iemRaiseTaskSwitchFaultCurrentTSS(PIEMCPU pIemCpu);
     696static VBOXSTRICTRC     iemRaiseTaskSwitchFault0(PIEMCPU pIemCpu);
     697static VBOXSTRICTRC     iemRaiseTaskSwitchFaultBySelector(PIEMCPU pIemCpu, uint16_t uSel);
    696698/*static VBOXSTRICTRC     iemRaiseSelectorNotPresent(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess);*/
    697699static VBOXSTRICTRC     iemRaiseSelectorNotPresentBySelector(PIEMCPU pIemCpu, uint16_t uSel);
     
    714716static VBOXSTRICTRC     iemMemFetchSysU32(PIEMCPU pIemCpu, uint32_t *pu32Dst, uint8_t iSegReg, RTGCPTR GCPtrMem);
    715717static VBOXSTRICTRC     iemMemFetchSysU64(PIEMCPU pIemCpu, uint64_t *pu64Dst, uint8_t iSegReg, RTGCPTR GCPtrMem);
    716 static VBOXSTRICTRC     iemMemFetchSelDesc(PIEMCPU pIemCpu, PIEMSELDESC pDesc, uint16_t uSel);
     718static VBOXSTRICTRC     iemMemFetchSelDesc(PIEMCPU pIemCpu, PIEMSELDESC pDesc, uint16_t uSel, uint8_t uXcpt);
    717719static VBOXSTRICTRC     iemMemStackPushCommitSpecial(PIEMCPU pIemCpu, void *pvMem, uint64_t uNewRsp);
    718720static VBOXSTRICTRC     iemMemStackPushBeginSpecial(PIEMCPU pIemCpu, size_t cbMem, void **ppvMem, uint64_t *puNewRsp);
     
    725727static VBOXSTRICTRC     iemVerifyFakeIOPortRead(PIEMCPU pIemCpu, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue);
    726728static VBOXSTRICTRC     iemVerifyFakeIOPortWrite(PIEMCPU pIemCpu, RTIOPORT Port, uint32_t u32Value, size_t cbValue);
     729
     730static void             iemHlpLoadNullDataSelectorProt(PCPUMSELREG pSReg, RTSEL uRpl);
    727731
    728732
     
    18891893    if (!(NewSS & X86_SEL_MASK_OFF_RPL))
    18901894    {
    1891         Log(("iemMiscValidateNewSSandRsp: #x - null selector -> #GP(0)\n", NewSS));
    1892         return iemRaiseGeneralProtectionFault0(pIemCpu);
     1895        Log(("iemMiscValidateNewSSandRsp: #x - null selector -> #TS(0)\n", NewSS));
     1896        return iemRaiseTaskSwitchFault0(pIemCpu);
     1897    }
     1898
     1899    /** @todo testcase: check that the TSS.ssX RPL is checked.  Also check when. */
     1900    if ((NewSS & X86_SEL_RPL) != uCpl)
     1901    {
     1902        Log(("iemMiscValidateNewSSandRsp: %#x - RPL and CPL (%d) differs -> #TS\n", NewSS, uCpl));
     1903        return iemRaiseTaskSwitchFaultBySelector(pIemCpu, NewSS);
    18931904    }
    18941905
     
    18961907     * Read the descriptor.
    18971908     */
    1898     VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, pDesc, NewSS);
     1909    VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, pDesc, NewSS, X86_XCPT_TS);
    18991910    if (rcStrict != VINF_SUCCESS)
    19001911        return rcStrict;
     
    19051916    if (!pDesc->Legacy.Gen.u1DescType)
    19061917    {
    1907         Log(("iemMiscValidateNewSSandRsp: %#x - system selector -> #GP\n", NewSS, pDesc->Legacy.Gen.u4Type));
    1908         return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, NewSS);
     1918        Log(("iemMiscValidateNewSSandRsp: %#x - system selector -> #TS\n", NewSS, pDesc->Legacy.Gen.u4Type));
     1919        return iemRaiseTaskSwitchFaultBySelector(pIemCpu, NewSS);
    19091920    }
    19101921
     
    19121923        || !(pDesc->Legacy.Gen.u4Type & X86_SEL_TYPE_WRITE) )
    19131924    {
    1914         Log(("iemMiscValidateNewSSandRsp: %#x - code or read only (%#x) -> #GP\n", NewSS, pDesc->Legacy.Gen.u4Type));
    1915         return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, NewSS);
    1916     }
    1917     /** @todo testcase: check if the TSS.ssX RPL is checked. */
    1918     if ((NewSS & X86_SEL_RPL) != uCpl)
    1919     {
    1920         Log(("iemMiscValidateNewSSandRsp: %#x - RPL and CPL (%d) differs -> #GP\n", NewSS, uCpl));
    1921         return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, NewSS);
     1925        Log(("iemMiscValidateNewSSandRsp: %#x - code or read only (%#x) -> #TS\n", NewSS, pDesc->Legacy.Gen.u4Type));
     1926        return iemRaiseTaskSwitchFaultBySelector(pIemCpu, NewSS);
    19221927    }
    19231928    if (pDesc->Legacy.Gen.u2Dpl != uCpl)
    19241929    {
    1925         Log(("iemMiscValidateNewSSandRsp: %#x - DPL (%d) and CPL (%d) differs -> #GP\n", NewSS, pDesc->Legacy.Gen.u2Dpl, uCpl));
    1926         return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, NewSS);
     1930        Log(("iemMiscValidateNewSSandRsp: %#x - DPL (%d) and CPL (%d) differs -> #TS\n", NewSS, pDesc->Legacy.Gen.u2Dpl, uCpl));
     1931        return iemRaiseTaskSwitchFaultBySelector(pIemCpu, NewSS);
    19271932    }
    19281933
     
    22572262        return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
    22582263    }
     2264    uint8_t  f32BitGate  = true;
    22592265    uint32_t fEflToClear = X86_EFL_TF | X86_EFL_NT | X86_EFL_RF | X86_EFL_VM;
    22602266    switch (Idte.Gate.u4Type)
     
    22792285
    22802286        case X86_SEL_TYPE_SYS_286_INT_GATE:
     2287            f32BitGate = false;
    22812288        case X86_SEL_TYPE_SYS_386_INT_GATE:
    22822289            fEflToClear |= X86_EFL_IF;
     
    22882295
    22892296        case X86_SEL_TYPE_SYS_286_TRAP_GATE:
     2297            f32BitGate = false;
    22902298        case X86_SEL_TYPE_SYS_386_TRAP_GATE:
    22912299            break;
     
    23212329    /* Fetch the descriptor for the new CS. */
    23222330    IEMSELDESC DescCS;
    2323     rcStrict = iemMemFetchSelDesc(pIemCpu, &DescCS, NewCS);
     2331    rcStrict = iemMemFetchSelDesc(pIemCpu, &DescCS, NewCS, X86_XCPT_GP); /** @todo correct exception? */
    23242332    if (rcStrict != VINF_SUCCESS)
    23252333    {
     
    23722380    }
    23732381
     2382    uint32_t        fEfl    = IEMMISC_GET_EFL(pIemCpu, pCtx);
     2383    uint8_t const   uNewCpl = DescCS.Legacy.Gen.u4Type & X86_SEL_TYPE_CONF
     2384                            ? pIemCpu->uCpl : DescCS.Legacy.Gen.u2Dpl;
     2385
     2386    /* From V8086 mode only go to CPL 0. */
     2387    if ((fEfl & X86_EFL_VM) && uNewCpl != 0) /** @todo When exactly is this raised? */
     2388    {
     2389        Log(("RaiseXcptOrIntInProtMode %#x - CS=%#x - New CPL (%d) != 0 w/ VM=1 -> #GP\n", u8Vector, NewCS, uNewCpl));
     2390        return iemRaiseGeneralProtectionFault(pIemCpu, 0);
     2391    }
     2392
    23742393    /*
    23752394     * If the privilege level changes, we need to get a new stack from the TSS.
    23762395     * This in turns means validating the new SS and ESP...
    23772396     */
    2378     uint32_t        fEfl    = IEMMISC_GET_EFL(pIemCpu, pCtx);
    2379     uint8_t const   uNewCpl = DescCS.Legacy.Gen.u4Type & X86_SEL_TYPE_CONF
    2380                             ? pIemCpu->uCpl : DescCS.Legacy.Gen.u2Dpl;
    23812397    if (uNewCpl != pIemCpu->uCpl)
    23822398    {
     
    23992415        }
    24002416
    2401         uint8_t const cbStackFrame = fFlags & IEM_XCPT_FLAGS_ERR ? 24 : 20;
     2417        uint8_t const cbStackFrame = !(fEfl & X86_EFL_VM)
     2418                                   ? (fFlags & IEM_XCPT_FLAGS_ERR ? 12 : 10) << f32BitGate
     2419                                   : (fFlags & IEM_XCPT_FLAGS_ERR ? 20 : 18) << f32BitGate;
    24022420        if (   uNewEsp - 1 > cbLimitSS
    24032421            || uNewEsp < cbStackFrame)
     
    24192437            return rcStrict;
    24202438        void * const pvStackFrame = uStackFrame.pv;
    2421 
    2422         if (fFlags & IEM_XCPT_FLAGS_ERR)
    2423             *uStackFrame.pu32++ = uErr;
    2424         uStackFrame.pu32[0] = (fFlags & IEM_XCPT_FLAGS_T_SOFT_INT) ? pCtx->eip + cbInstr : pCtx->eip;
    2425         uStackFrame.pu32[1] = (pCtx->cs.Sel & ~X86_SEL_RPL) | pIemCpu->uCpl;
    2426         uStackFrame.pu32[2] = fEfl;
    2427         uStackFrame.pu32[3] = pCtx->esp;
    2428         uStackFrame.pu32[4] = pCtx->ss.Sel;
     2439        if (f32BitGate)
     2440        {
     2441            if (fFlags & IEM_XCPT_FLAGS_ERR)
     2442                *uStackFrame.pu32++ = uErr;
     2443            uStackFrame.pu32[0] = (fFlags & IEM_XCPT_FLAGS_T_SOFT_INT) ? pCtx->eip + cbInstr : pCtx->eip;
     2444            uStackFrame.pu32[1] = (pCtx->cs.Sel & ~X86_SEL_RPL) | pIemCpu->uCpl;
     2445            uStackFrame.pu32[2] = fEfl;
     2446            uStackFrame.pu32[3] = pCtx->esp;
     2447            uStackFrame.pu32[4] = pCtx->ss.Sel;
     2448            if (fEfl & X86_EFL_VM)
     2449            {
     2450                uStackFrame.pu32[1] = pCtx->cs.Sel;
     2451                uStackFrame.pu32[5] = pCtx->es.Sel;
     2452                uStackFrame.pu32[6] = pCtx->ds.Sel;
     2453                uStackFrame.pu32[7] = pCtx->fs.Sel;
     2454                uStackFrame.pu32[8] = pCtx->gs.Sel;
     2455            }
     2456        }
     2457        else
     2458        {
     2459            if (fFlags & IEM_XCPT_FLAGS_ERR)
     2460                *uStackFrame.pu16++ = uErr;
     2461            uStackFrame.pu16[0] = (fFlags & IEM_XCPT_FLAGS_T_SOFT_INT) ? pCtx->ip + cbInstr : pCtx->ip;
     2462            uStackFrame.pu16[1] = (pCtx->cs.Sel & ~X86_SEL_RPL) | pIemCpu->uCpl;
     2463            uStackFrame.pu16[2] = fEfl;
     2464            uStackFrame.pu16[3] = pCtx->sp;
     2465            uStackFrame.pu16[4] = pCtx->ss.Sel;
     2466            if (fEfl & X86_EFL_VM)
     2467            {
     2468                uStackFrame.pu16[1] = pCtx->cs.Sel;
     2469                uStackFrame.pu16[5] = pCtx->es.Sel;
     2470                uStackFrame.pu16[6] = pCtx->ds.Sel;
     2471                uStackFrame.pu16[7] = pCtx->fs.Sel;
     2472                uStackFrame.pu16[8] = pCtx->gs.Sel;
     2473            }
     2474        }
    24292475        rcStrict = iemMemCommitAndUnmap(pIemCpu, pvStackFrame, IEM_ACCESS_STACK_W | IEM_ACCESS_WHAT_SYS);
    24302476        if (rcStrict != VINF_SUCCESS)
     
    24622508        pCtx->rsp               = uNewEsp - cbStackFrame; /** @todo Is the high word cleared for 16-bit stacks and/or interrupt handlers? */
    24632509        pIemCpu->uCpl           = uNewCpl;
     2510
     2511        if (fEfl & X86_EFL_VM)
     2512        {
     2513            iemHlpLoadNullDataSelectorProt(&pCtx->gs, 0);
     2514            iemHlpLoadNullDataSelectorProt(&pCtx->fs, 0);
     2515            iemHlpLoadNullDataSelectorProt(&pCtx->es, 0);
     2516            iemHlpLoadNullDataSelectorProt(&pCtx->ds, 0);
     2517        }
    24642518    }
    24652519    /*
     
    24702524        uint64_t        uNewRsp;
    24712525        RTPTRUNION      uStackFrame;
    2472         uint8_t const   cbStackFrame = fFlags & IEM_XCPT_FLAGS_ERR ? 16 : 12;
     2526        uint8_t const   cbStackFrame = (fFlags & IEM_XCPT_FLAGS_ERR ? 8 : 6) << f32BitGate;
    24732527        rcStrict = iemMemStackPushBeginSpecial(pIemCpu, cbStackFrame, &uStackFrame.pv, &uNewRsp);
    24742528        if (rcStrict != VINF_SUCCESS)
     
    24762530        void * const pvStackFrame = uStackFrame.pv;
    24772531
    2478         if (fFlags & IEM_XCPT_FLAGS_ERR)
    2479             *uStackFrame.pu32++ = uErr;
    2480         uStackFrame.pu32[0] = fFlags & IEM_XCPT_FLAGS_T_SOFT_INT ? pCtx->eip + cbInstr : pCtx->eip;
    2481         uStackFrame.pu32[1] = (pCtx->cs.Sel & ~X86_SEL_RPL) | pIemCpu->uCpl;
    2482         uStackFrame.pu32[2] = fEfl;
     2532        if (f32BitGate)
     2533        {
     2534            if (fFlags & IEM_XCPT_FLAGS_ERR)
     2535                *uStackFrame.pu32++ = uErr;
     2536            uStackFrame.pu32[0] = fFlags & IEM_XCPT_FLAGS_T_SOFT_INT ? pCtx->eip + cbInstr : pCtx->eip;
     2537            uStackFrame.pu32[1] = (pCtx->cs.Sel & ~X86_SEL_RPL) | pIemCpu->uCpl;
     2538            uStackFrame.pu32[2] = fEfl;
     2539        }
     2540        else
     2541        {
     2542            if (fFlags & IEM_XCPT_FLAGS_ERR)
     2543                *uStackFrame.pu16++ = uErr;
     2544            uStackFrame.pu16[0] = fFlags & IEM_XCPT_FLAGS_T_SOFT_INT ? pCtx->eip + cbInstr : pCtx->eip;
     2545            uStackFrame.pu16[1] = (pCtx->cs.Sel & ~X86_SEL_RPL) | pIemCpu->uCpl;
     2546            uStackFrame.pu16[2] = fEfl;
     2547        }
    24832548        rcStrict = iemMemCommitAndUnmap(pIemCpu, pvStackFrame, IEM_ACCESS_STACK_W); /* don't use the commit here */
    24842549        if (rcStrict != VINF_SUCCESS)
     
    25232588
    25242589/**
    2525  * Implements exceptions and interrupts for V8086 mode.
     2590 * Implements exceptions and interrupts for long mode.
    25262591 *
    25272592 * @returns VBox strict status code.
     
    25362601 */
    25372602static VBOXSTRICTRC
    2538 iemRaiseXcptOrIntInV8086Mode(PIEMCPU     pIemCpu,
    2539                              PCPUMCTX    pCtx,
    2540                              uint8_t     cbInstr,
    2541                              uint8_t     u8Vector,
    2542                              uint32_t    fFlags,
    2543                              uint16_t    uErr,
    2544                              uint64_t    uCr2)
    2545 {
    2546     NOREF(pIemCpu); NOREF(pCtx); NOREF(cbInstr); NOREF(u8Vector); NOREF(fFlags); NOREF(uErr); NOREF(uCr2);
    2547     /** @todo implement me. */
    2548     IEM_RETURN_ASPECT_NOT_IMPLEMENTED_LOG(("V8086 exception / interrupt dispatching\n"));
    2549 }
    2550 
    2551 
    2552 /**
    2553  * Implements exceptions and interrupts for long mode.
    2554  *
    2555  * @returns VBox strict status code.
    2556  * @param   pIemCpu         The IEM per CPU instance data.
    2557  * @param   pCtx            The CPU context.
    2558  * @param   cbInstr         The number of bytes to offset rIP by in the return
    2559  *                          address.
    2560  * @param   u8Vector        The interrupt / exception vector number.
    2561  * @param   fFlags          The flags.
    2562  * @param   uErr            The error value if IEM_XCPT_FLAGS_ERR is set.
    2563  * @param   uCr2            The CR2 value if IEM_XCPT_FLAGS_CR2 is set.
    2564  */
    2565 static VBOXSTRICTRC
    25662603iemRaiseXcptOrIntInLongMode(PIEMCPU     pIemCpu,
    25672604                            PCPUMCTX    pCtx,
     
    26432680    /* Fetch the descriptor for the new CS. */
    26442681    IEMSELDESC DescCS;
    2645     rcStrict = iemMemFetchSelDesc(pIemCpu, &DescCS, NewCS);
     2682    rcStrict = iemMemFetchSelDesc(pIemCpu, &DescCS, NewCS, X86_XCPT_GP);
    26462683    if (rcStrict != VINF_SUCCESS)
    26472684    {
     
    28112848{
    28122849    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
     2850
     2851    /*
     2852     * Perform the V8086 IOPL check and upgrade the fault without nesting.
     2853     */
     2854    if (   pCtx->eflags.Bits.u1VM
     2855        && pCtx->eflags.Bits.u2IOPL != 3
     2856        && (fFlags & (IEM_XCPT_FLAGS_T_SOFT_INT | IEM_XCPT_FLAGS_BP_INSTR)) == IEM_XCPT_FLAGS_T_SOFT_INT
     2857        && (pCtx->cr0 & X86_CR0_PE) )
     2858    {
     2859        Log(("iemRaiseXcptOrInt: V8086 IOPL check failed for int %#x -> #GP(0)\n", u8Vector));
     2860        fFlags   = IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR;
     2861        u8Vector = X86_XCPT_GP;
     2862        uErr     = 0;
     2863    }
    28132864
    28142865    /*
     
    28962947    else if (pCtx->msrEFER & MSR_K6_EFER_LMA)
    28972948        rcStrict = iemRaiseXcptOrIntInLongMode( pIemCpu, pCtx, cbInstr, u8Vector, fFlags, uErr, uCr2);
    2898     else if (!pCtx->eflags.Bits.u1VM)
     2949    else
    28992950        rcStrict = iemRaiseXcptOrIntInProtMode( pIemCpu, pCtx, cbInstr, u8Vector, fFlags, uErr, uCr2);
    2900     else
    2901         rcStrict = iemRaiseXcptOrIntInV8086Mode(pIemCpu, pCtx, cbInstr, u8Vector, fFlags, uErr, uCr2);
    29022951
    29032952    /*
     
    29563005    return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_TS, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR,
    29573006                             pIemCpu->CTX_SUFF(pCtx)->tr.Sel, 0);
     3007}
     3008
     3009
     3010/** \#TS(0) - 0a.  */
     3011DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseTaskSwitchFault0(PIEMCPU pIemCpu)
     3012{
     3013    return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_TS, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR,
     3014                             0, 0);
     3015}
     3016
     3017
     3018/** \#TS(err) - 0a.  */
     3019DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseTaskSwitchFaultBySelector(PIEMCPU pIemCpu, uint16_t uSel)
     3020{
     3021    return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_TS, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR,
     3022                             uSel & X86_SEL_MASK_OFF_RPL, 0);
    29583023}
    29593024
     
    55015566    pIemCpu->aMemMappings[iMemMap].pv               = pbBuf;
    55025567    pIemCpu->aMemMappings[iMemMap].fAccess          = fAccess | IEM_ACCESS_BOUNCE_BUFFERED;
     5568    pIemCpu->iNextMapping = iMemMap + 1;
    55035569    pIemCpu->cActiveMappings++;
    55045570
     
    55905656    pIemCpu->aMemMappings[iMemMap].pv               = pbBuf;
    55915657    pIemCpu->aMemMappings[iMemMap].fAccess          = fAccess | IEM_ACCESS_BOUNCE_BUFFERED;
     5658    pIemCpu->iNextMapping = iMemMap + 1;
    55925659    pIemCpu->cActiveMappings++;
    55935660
     
    56375704
    56385705    unsigned iMemMap = pIemCpu->iNextMapping;
    5639     if (iMemMap >= RT_ELEMENTS(pIemCpu->aMemMappings))
     5706    if (   iMemMap >= RT_ELEMENTS(pIemCpu->aMemMappings)
     5707        || pIemCpu->aMemMappings[iMemMap].fAccess != IEM_ACCESS_INVALID)
    56405708    {
    56415709        iMemMap = iemMemMapFindFree(pIemCpu);
     
    57065774    pIemCpu->cActiveMappings--;
    57075775    return VINF_SUCCESS;
     5776}
     5777
     5778
     5779/**
     5780 * Rollbacks mappings, releasing page locks and such.
     5781 *
     5782 * The caller shall only call this after checking cActiveMappings.
     5783 *
     5784 * @returns Strict VBox status code to pass up.
     5785 * @param   pIemCpu     The IEM per CPU data.
     5786 */
     5787static void iemMemRollback(PIEMCPU pIemCpu)
     5788{
     5789    Assert(pIemCpu->cActiveMappings > 0);
     5790
     5791    uint32_t iMemMap = RT_ELEMENTS(pIemCpu->aMemMappings);
     5792    while (iMemMap-- > 0)
     5793    {
     5794        uint32_t fAccess = pIemCpu->aMemMappings[iMemMap].fAccess;
     5795        if (fAccess != IEM_ACCESS_INVALID)
     5796        {
     5797            pIemCpu->aMemMappings[iMemMap].fAccess = IEM_ACCESS_INVALID;
     5798            if (!(fAccess & IEM_ACCESS_BOUNCE_BUFFERED))
     5799                PGMPhysReleasePageMappingLock(IEMCPU_TO_VM(pIemCpu), &pIemCpu->aMemMappingLocks[iMemMap].Lock);
     5800            Assert(pIemCpu->cActiveMappings > 0);
     5801            pIemCpu->cActiveMappings--;
     5802        }
     5803    }
    57085804}
    57095805
     
    68106906 * @param   pDesc               Where to return the descriptor table entry.
    68116907 * @param   uSel                The selector which table entry to fetch.
    6812  */
    6813 static VBOXSTRICTRC iemMemFetchSelDesc(PIEMCPU pIemCpu, PIEMSELDESC pDesc, uint16_t uSel)
     6908 * @param   uXcpt               The exception to raise on table lookup error.
     6909 */
     6910static VBOXSTRICTRC iemMemFetchSelDesc(PIEMCPU pIemCpu, PIEMSELDESC pDesc, uint16_t uSel, uint8_t uXcpt)
    68146911{
    68156912    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
     
    68276924            Log(("iemMemFetchSelDesc: LDT selector %#x is out of bounds (%3x) or ldtr is NP (%#x)\n",
    68286925                 uSel, pCtx->ldtr.u32Limit, pCtx->ldtr.Sel));
    6829             /** @todo is this the right exception? */
    6830             return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
     6926            return iemRaiseXcptOrInt(pIemCpu, 0, uXcpt, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR,
     6927                                     uSel & ~X86_SEL_RPL, 0);
    68316928        }
    68326929
     
    68396936        {
    68406937            Log(("iemMemFetchSelDesc: GDT selector %#x is out of bounds (%3x)\n", uSel, pCtx->gdtr.cbGdt));
    6841             /** @todo is this the right exception? */
    6842             return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
     6938            return iemRaiseXcptOrInt(pIemCpu, 0, uXcpt, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR,
     6939                                     uSel & ~X86_SEL_RPL, 0);
    68436940        }
    68446941        GCPtrBase = pCtx->gdtr.pGdt;
     
    68616958            Log(("iemMemFetchSelDesc: system selector %#x is out of bounds\n", uSel));
    68626959            /** @todo is this the right exception? */
    6863             return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
     6960            return iemRaiseXcptOrInt(pIemCpu, 0, uXcpt, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR,
     6961                                     uSel & ~X86_SEL_RPL, 0);
    68646962        }
    68656963    }
     
    83408438            || (pOrgCtx->rip == 0x000000000215e240)
    83418439#endif
     8440#if 1 /* DOS's size-overridden iret to v8086. */
     8441            || (pOrgCtx->rip == 0x427 && pOrgCtx->cs.Sel == 0xb8)
     8442#endif
    83428443           )
    83438444       )
     
    87348835                && pEvtRec->u.RamWrite.cb != 4) )
    87358836        {
    8736             /* fend off ROMs */
    8737             if (   pEvtRec->u.RamWrite.GCPhys - UINT32_C(0x000c0000) > UINT32_C(0x8000)
    8738                 && pEvtRec->u.RamWrite.GCPhys - UINT32_C(0x000e0000) > UINT32_C(0x20000)
     8837            /* fend off ROMs and MMIO */
     8838            if (   pEvtRec->u.RamWrite.GCPhys - UINT32_C(0x000a0000) > UINT32_C(0x60000)
    87398839                && pEvtRec->u.RamWrite.GCPhys - UINT32_C(0xfffc0000) > UINT32_C(0x40000) )
    87408840            {
     
    91609260    if (rcStrict == VINF_SUCCESS)
    91619261        pIemCpu->cInstructions++;
     9262    if (pIemCpu->cActiveMappings > 0)
     9263        iemMemRollback(pIemCpu);
    91629264//#ifdef DEBUG
    91639265//    AssertMsg(pIemCpu->offOpcode == cbInstr || rcStrict != VINF_SUCCESS, ("%u %u\n", pIemCpu->offOpcode, cbInstr));
     
    91789280            if (rcStrict == VINF_SUCCESS)
    91799281                pIemCpu->cInstructions++;
     9282            if (pIemCpu->cActiveMappings > 0)
     9283                iemMemRollback(pIemCpu);
    91809284        }
    91819285        EMSetInhibitInterruptsPC(pVCpu, UINT64_C(0x7777555533331111));
  • trunk/src/VBox/VMM/VMMAll/IEMAllAImpl.asm

    r47411 r47548  
    410410IEMIMPL_BIN_OP sub,  1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
    411411IEMIMPL_BIN_OP sbb,  1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
    412 IEMIMPL_BIN_OP or,   1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), X86_EFL_AF,
    413 IEMIMPL_BIN_OP xor,  1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), X86_EFL_AF,
    414 IEMIMPL_BIN_OP and,  1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), X86_EFL_AF,
     412IEMIMPL_BIN_OP or,   1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), X86_EFL_AF
     413IEMIMPL_BIN_OP xor,  1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), X86_EFL_AF
     414IEMIMPL_BIN_OP and,  1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), X86_EFL_AF
    415415IEMIMPL_BIN_OP cmp,  0, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
    416 IEMIMPL_BIN_OP test, 0, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), X86_EFL_AF,
     416IEMIMPL_BIN_OP test, 0, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), X86_EFL_AF
    417417
    418418
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h

    r47429 r47548  
    10311031    /* Fetch the descriptor. */
    10321032    IEMSELDESC Desc;
    1033     VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, &Desc, uSel);
     1033    VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, &Desc, uSel, X86_XCPT_GP);
    10341034    if (rcStrict != VINF_SUCCESS)
    10351035        return rcStrict;
     
    12081208    /* Fetch the descriptor. */
    12091209    IEMSELDESC Desc;
    1210     rcStrict = iemMemFetchSelDesc(pIemCpu, &Desc, uSel);
     1210    rcStrict = iemMemFetchSelDesc(pIemCpu, &Desc, uSel, X86_XCPT_GP);
    12111211    if (rcStrict != VINF_SUCCESS)
    12121212        return rcStrict;
     
    14341434    /* Fetch the descriptor. */
    14351435    IEMSELDESC DescCs;
    1436     rcStrict = iemMemFetchSelDesc(pIemCpu, &DescCs, uNewCs);
     1436    rcStrict = iemMemFetchSelDesc(pIemCpu, &DescCs, uNewCs, X86_XCPT_GP);
    14371437    if (rcStrict != VINF_SUCCESS)
    14381438        return rcStrict;
     
    15351535        {
    15361536            /* Fetch the descriptor for the new stack segment. */
    1537             rcStrict = iemMemFetchSelDesc(pIemCpu, &DescSs, uNewOuterSs);
     1537            rcStrict = iemMemFetchSelDesc(pIemCpu, &DescSs, uNewOuterSs, X86_XCPT_GP);
    15381538            if (rcStrict != VINF_SUCCESS)
    15391539                return rcStrict;
     
    20122012     * iret throws an exception if VME isn't enabled.
    20132013     */
    2014     if (   pCtx->eflags.Bits.u1VM
     2014    if (   Efl.Bits.u1VM
     2015        && Efl.Bits.u2IOPL != 3
    20152016        && !(pCtx->cr4 & X86_CR4_VME))
    20162017        return iemRaiseGeneralProtectionFault0(pIemCpu);
     
    20332034            return rcStrict;
    20342035        uNewEip    = uFrame.pu32[0];
     2036        if (uNewEip > UINT16_MAX)
     2037            return iemRaiseGeneralProtectionFault0(pIemCpu);
     2038
    20352039        uNewCs     = (uint16_t)uFrame.pu32[1];
    20362040        uNewFlags  = uFrame.pu32[2];
     
    21372141 * @param   uNewFlags       The new EFLAGS.
    21382142 * @param   uNewRsp         The RSP after the initial IRET frame.
     2143 *
     2144 * @note    This can only be a 32-bit iret du to the X86_EFL_VM position.
    21392145 */
    21402146IEM_CIMPL_DEF_5(iemCImpl_iret_prot_v8086, PCPUMCTX, pCtx, uint32_t, uNewEip, uint16_t, uNewCs,
     
    21792185    pCtx->rip      = uNewEip;
    21802186    pCtx->rsp      = uNewEsp;
    2181     pCtx->rflags.u = uNewFlags;
     2187    uNewFlags &= X86_EFL_LIVE_MASK;
     2188    uNewFlags |= X86_EFL_RA1_MASK;
     2189    IEMMISC_SET_EFL(pIemCpu, pCtx, uNewFlags);
    21822190    pIemCpu->uCpl  = 3;
    21832191
     
    22692277
    22702278    IEMSELDESC DescCS;
    2271     rcStrict = iemMemFetchSelDesc(pIemCpu, &DescCS, uNewCs);
     2279    rcStrict = iemMemFetchSelDesc(pIemCpu, &DescCS, uNewCs, X86_XCPT_GP);
    22722280    if (rcStrict != VINF_SUCCESS)
    22732281    {
     
    23452353
    23462354        IEMSELDESC DescSS;
    2347         rcStrict = iemMemFetchSelDesc(pIemCpu, &DescSS, uNewSS);
     2355        rcStrict = iemMemFetchSelDesc(pIemCpu, &DescSS, uNewSS, X86_XCPT_GP); /** @todo Correct exception? */
    23482356        if (rcStrict != VINF_SUCCESS)
    23492357        {
     
    24312439        pCtx->ss.u64Base    = X86DESC_BASE(&DescSS.Legacy);
    24322440
    2433         uint32_t fEFlagsMask = X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF  | X86_EFL_SF
     2441        uint32_t fEFlagsMask = X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF
    24342442                             | X86_EFL_TF | X86_EFL_DF | X86_EFL_OF | X86_EFL_NT;
    24352443        if (enmEffOpSize != IEMMODE_16BIT)
     
    24872495        X86EFLAGS NewEfl;
    24882496        NewEfl.u = IEMMISC_GET_EFL(pIemCpu, pCtx);
    2489         uint32_t fEFlagsMask = X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF  | X86_EFL_SF
     2497        uint32_t fEFlagsMask = X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF
    24902498                             | X86_EFL_TF | X86_EFL_DF | X86_EFL_OF | X86_EFL_NT;
    24912499        if (enmEffOpSize != IEMMODE_16BIT)
     
    25872595
    25882596    IEMSELDESC DescCS;
    2589     rcStrict = iemMemFetchSelDesc(pIemCpu, &DescCS, uNewCs);
     2597    rcStrict = iemMemFetchSelDesc(pIemCpu, &DescCS, uNewCs, X86_XCPT_GP);
    25902598    if (rcStrict != VINF_SUCCESS)
    25912599    {
     
    26432651    else
    26442652    {
    2645         rcStrict = iemMemFetchSelDesc(pIemCpu, &DescSS, uNewSs);
     2653        rcStrict = iemMemFetchSelDesc(pIemCpu, &DescSS, uNewSs, X86_XCPT_GP); /** @todo Correct exception? */
    26462654        if (rcStrict != VINF_SUCCESS)
    26472655        {
     
    27612769    }
    27622770
    2763     uint32_t fEFlagsMask = X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF  | X86_EFL_SF
     2771    uint32_t fEFlagsMask = X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF
    27642772                         | X86_EFL_TF | X86_EFL_DF | X86_EFL_OF | X86_EFL_NT;
    27652773    if (enmEffOpSize != IEMMODE_16BIT)
     
    27972805     * Call a mode specific worker.
    27982806     */
    2799     if (   pIemCpu->enmCpuMode == IEMMODE_16BIT
    2800         && IEM_IS_REAL_OR_V86_MODE(pIemCpu))
     2807    if (IEM_IS_REAL_OR_V86_MODE(pIemCpu))
    28012808        return IEM_CIMPL_CALL_1(iemCImpl_iret_real_v8086, enmEffOpSize);
    28022809    if (IEM_IS_LONG_MODE(pIemCpu))
     
    30883095    /* Fetch the descriptor. */
    30893096    IEMSELDESC Desc;
    3090     VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, &Desc, uSel);
     3097    VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, &Desc, uSel, X86_XCPT_GP); /** @todo Correct exception? */
    30913098    if (rcStrict != VINF_SUCCESS)
    30923099        return rcStrict;
     
    34893496     */
    34903497    IEMSELDESC Desc;
    3491     VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, &Desc, uNewLdt);
     3498    VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, &Desc, uNewLdt, X86_XCPT_GP); /** @todo Correct exception? */
    34923499    if (rcStrict != VINF_SUCCESS)
    34933500        return rcStrict;
     
    35863593     */
    35873594    IEMSELDESC Desc;
    3588     VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, &Desc, uNewTr);
     3595    VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, &Desc, uNewTr, X86_XCPT_GP); /** @todo Correct exception? */
    35893596    if (rcStrict != VINF_SUCCESS)
    35903597        return rcStrict;
  • trunk/src/VBox/VMM/VMMR3/EMHM.cpp

    r47421 r47548  
    366366            pCtx->rip += Cpu.cbInstr;
    367367            STAM_PROFILE_STOP(&pVCpu->em.s.StatIOEmu, a);
     368            LogFlow(("emR3ExecuteIOInstruction: %Rrc 1\n", VBOXSTRICTRC_VAL(rcStrict)));
    368369            return VBOXSTRICTRC_TODO(rcStrict);
    369370        }
     
    374375            Assert(TRPMHasTrap(pVCpu));
    375376            STAM_PROFILE_STOP(&pVCpu->em.s.StatIOEmu, a);
     377            LogFlow(("emR3ExecuteIOInstruction: VINF_SUCCESS 2\n"));
    376378            return VINF_SUCCESS;
    377379        }
     
    381383        {
    382384            STAM_PROFILE_STOP(&pVCpu->em.s.StatIOEmu, a);
     385            LogFlow(("emR3ExecuteIOInstruction: %Rrc 3\n", VBOXSTRICTRC_VAL(rcStrict)));
    383386            return VBOXSTRICTRC_TODO(rcStrict);
    384387        }
     
    387390
    388391    STAM_PROFILE_STOP(&pVCpu->em.s.StatIOEmu, a);
    389     return emR3ExecuteInstruction(pVM, pVCpu, "IO: ");
     392    int rc3 = emR3ExecuteInstruction(pVM, pVCpu, "IO: ");
     393    LogFlow(("emR3ExecuteIOInstruction: %Rrc 4 (rc2=%Rrc, rc3=%Rrc)\n", VBOXSTRICTRC_VAL(rcStrict), rc2, rc3));
     394    return rc3;
    390395#endif
    391396}
  • trunk/src/VBox/VMM/VMMR3/IEMR3.cpp

    r47307 r47548  
    8888            pVCpu->iem.s.enmHostCpuVendor         = pVM->aCpus[0].iem.s.enmHostCpuVendor;
    8989        }
     90
     91        /*
     92         * Mark all buffers free.
     93         */
     94        uint32_t iMemMap = RT_ELEMENTS(pVCpu->iem.s.aMemMappings);
     95        while (iMemMap-- > 0)
     96            pVCpu->iem.s.aMemMappings[iMemMap].fAccess = IEM_ACCESS_INVALID;
    9097    }
    9198    return VINF_SUCCESS;
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