Changeset 47548 in vbox
- Timestamp:
- Aug 6, 2013 3:58:21 AM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 87746
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r47494 r47548 694 694 *******************************************************************************/ 695 695 static VBOXSTRICTRC iemRaiseTaskSwitchFaultCurrentTSS(PIEMCPU pIemCpu); 696 static VBOXSTRICTRC iemRaiseTaskSwitchFault0(PIEMCPU pIemCpu); 697 static VBOXSTRICTRC iemRaiseTaskSwitchFaultBySelector(PIEMCPU pIemCpu, uint16_t uSel); 696 698 /*static VBOXSTRICTRC iemRaiseSelectorNotPresent(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess);*/ 697 699 static VBOXSTRICTRC iemRaiseSelectorNotPresentBySelector(PIEMCPU pIemCpu, uint16_t uSel); … … 714 716 static VBOXSTRICTRC iemMemFetchSysU32(PIEMCPU pIemCpu, uint32_t *pu32Dst, uint8_t iSegReg, RTGCPTR GCPtrMem); 715 717 static VBOXSTRICTRC iemMemFetchSysU64(PIEMCPU pIemCpu, uint64_t *pu64Dst, uint8_t iSegReg, RTGCPTR GCPtrMem); 716 static VBOXSTRICTRC iemMemFetchSelDesc(PIEMCPU pIemCpu, PIEMSELDESC pDesc, uint16_t uSel );718 static VBOXSTRICTRC iemMemFetchSelDesc(PIEMCPU pIemCpu, PIEMSELDESC pDesc, uint16_t uSel, uint8_t uXcpt); 717 719 static VBOXSTRICTRC iemMemStackPushCommitSpecial(PIEMCPU pIemCpu, void *pvMem, uint64_t uNewRsp); 718 720 static VBOXSTRICTRC iemMemStackPushBeginSpecial(PIEMCPU pIemCpu, size_t cbMem, void **ppvMem, uint64_t *puNewRsp); … … 725 727 static VBOXSTRICTRC iemVerifyFakeIOPortRead(PIEMCPU pIemCpu, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue); 726 728 static VBOXSTRICTRC iemVerifyFakeIOPortWrite(PIEMCPU pIemCpu, RTIOPORT Port, uint32_t u32Value, size_t cbValue); 729 730 static void iemHlpLoadNullDataSelectorProt(PCPUMSELREG pSReg, RTSEL uRpl); 727 731 728 732 … … 1889 1893 if (!(NewSS & X86_SEL_MASK_OFF_RPL)) 1890 1894 { 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); 1893 1904 } 1894 1905 … … 1896 1907 * Read the descriptor. 1897 1908 */ 1898 VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, pDesc, NewSS );1909 VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, pDesc, NewSS, X86_XCPT_TS); 1899 1910 if (rcStrict != VINF_SUCCESS) 1900 1911 return rcStrict; … … 1905 1916 if (!pDesc->Legacy.Gen.u1DescType) 1906 1917 { 1907 Log(("iemMiscValidateNewSSandRsp: %#x - system selector -> # GP\n", NewSS, pDesc->Legacy.Gen.u4Type));1908 return iemRaise GeneralProtectionFaultBySelector(pIemCpu, NewSS);1918 Log(("iemMiscValidateNewSSandRsp: %#x - system selector -> #TS\n", NewSS, pDesc->Legacy.Gen.u4Type)); 1919 return iemRaiseTaskSwitchFaultBySelector(pIemCpu, NewSS); 1909 1920 } 1910 1921 … … 1912 1923 || !(pDesc->Legacy.Gen.u4Type & X86_SEL_TYPE_WRITE) ) 1913 1924 { 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); 1922 1927 } 1923 1928 if (pDesc->Legacy.Gen.u2Dpl != uCpl) 1924 1929 { 1925 Log(("iemMiscValidateNewSSandRsp: %#x - DPL (%d) and CPL (%d) differs -> # GP\n", NewSS, pDesc->Legacy.Gen.u2Dpl, uCpl));1926 return iemRaise GeneralProtectionFaultBySelector(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); 1927 1932 } 1928 1933 … … 2257 2262 return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT)); 2258 2263 } 2264 uint8_t f32BitGate = true; 2259 2265 uint32_t fEflToClear = X86_EFL_TF | X86_EFL_NT | X86_EFL_RF | X86_EFL_VM; 2260 2266 switch (Idte.Gate.u4Type) … … 2279 2285 2280 2286 case X86_SEL_TYPE_SYS_286_INT_GATE: 2287 f32BitGate = false; 2281 2288 case X86_SEL_TYPE_SYS_386_INT_GATE: 2282 2289 fEflToClear |= X86_EFL_IF; … … 2288 2295 2289 2296 case X86_SEL_TYPE_SYS_286_TRAP_GATE: 2297 f32BitGate = false; 2290 2298 case X86_SEL_TYPE_SYS_386_TRAP_GATE: 2291 2299 break; … … 2321 2329 /* Fetch the descriptor for the new CS. */ 2322 2330 IEMSELDESC DescCS; 2323 rcStrict = iemMemFetchSelDesc(pIemCpu, &DescCS, NewCS );2331 rcStrict = iemMemFetchSelDesc(pIemCpu, &DescCS, NewCS, X86_XCPT_GP); /** @todo correct exception? */ 2324 2332 if (rcStrict != VINF_SUCCESS) 2325 2333 { … … 2372 2380 } 2373 2381 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 2374 2393 /* 2375 2394 * If the privilege level changes, we need to get a new stack from the TSS. 2376 2395 * This in turns means validating the new SS and ESP... 2377 2396 */ 2378 uint32_t fEfl = IEMMISC_GET_EFL(pIemCpu, pCtx);2379 uint8_t const uNewCpl = DescCS.Legacy.Gen.u4Type & X86_SEL_TYPE_CONF2380 ? pIemCpu->uCpl : DescCS.Legacy.Gen.u2Dpl;2381 2397 if (uNewCpl != pIemCpu->uCpl) 2382 2398 { … … 2399 2415 } 2400 2416 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; 2402 2420 if ( uNewEsp - 1 > cbLimitSS 2403 2421 || uNewEsp < cbStackFrame) … … 2419 2437 return rcStrict; 2420 2438 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 } 2429 2475 rcStrict = iemMemCommitAndUnmap(pIemCpu, pvStackFrame, IEM_ACCESS_STACK_W | IEM_ACCESS_WHAT_SYS); 2430 2476 if (rcStrict != VINF_SUCCESS) … … 2462 2508 pCtx->rsp = uNewEsp - cbStackFrame; /** @todo Is the high word cleared for 16-bit stacks and/or interrupt handlers? */ 2463 2509 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 } 2464 2518 } 2465 2519 /* … … 2470 2524 uint64_t uNewRsp; 2471 2525 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; 2473 2527 rcStrict = iemMemStackPushBeginSpecial(pIemCpu, cbStackFrame, &uStackFrame.pv, &uNewRsp); 2474 2528 if (rcStrict != VINF_SUCCESS) … … 2476 2530 void * const pvStackFrame = uStackFrame.pv; 2477 2531 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 } 2483 2548 rcStrict = iemMemCommitAndUnmap(pIemCpu, pvStackFrame, IEM_ACCESS_STACK_W); /* don't use the commit here */ 2484 2549 if (rcStrict != VINF_SUCCESS) … … 2523 2588 2524 2589 /** 2525 * Implements exceptions and interrupts for V8086mode.2590 * Implements exceptions and interrupts for long mode. 2526 2591 * 2527 2592 * @returns VBox strict status code. … … 2536 2601 */ 2537 2602 static 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 return2559 * 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 VBOXSTRICTRC2566 2603 iemRaiseXcptOrIntInLongMode(PIEMCPU pIemCpu, 2567 2604 PCPUMCTX pCtx, … … 2643 2680 /* Fetch the descriptor for the new CS. */ 2644 2681 IEMSELDESC DescCS; 2645 rcStrict = iemMemFetchSelDesc(pIemCpu, &DescCS, NewCS );2682 rcStrict = iemMemFetchSelDesc(pIemCpu, &DescCS, NewCS, X86_XCPT_GP); 2646 2683 if (rcStrict != VINF_SUCCESS) 2647 2684 { … … 2811 2848 { 2812 2849 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 } 2813 2864 2814 2865 /* … … 2896 2947 else if (pCtx->msrEFER & MSR_K6_EFER_LMA) 2897 2948 rcStrict = iemRaiseXcptOrIntInLongMode( pIemCpu, pCtx, cbInstr, u8Vector, fFlags, uErr, uCr2); 2898 else if (!pCtx->eflags.Bits.u1VM)2949 else 2899 2950 rcStrict = iemRaiseXcptOrIntInProtMode( pIemCpu, pCtx, cbInstr, u8Vector, fFlags, uErr, uCr2); 2900 else2901 rcStrict = iemRaiseXcptOrIntInV8086Mode(pIemCpu, pCtx, cbInstr, u8Vector, fFlags, uErr, uCr2);2902 2951 2903 2952 /* … … 2956 3005 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_TS, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, 2957 3006 pIemCpu->CTX_SUFF(pCtx)->tr.Sel, 0); 3007 } 3008 3009 3010 /** \#TS(0) - 0a. */ 3011 DECL_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. */ 3019 DECL_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); 2958 3023 } 2959 3024 … … 5501 5566 pIemCpu->aMemMappings[iMemMap].pv = pbBuf; 5502 5567 pIemCpu->aMemMappings[iMemMap].fAccess = fAccess | IEM_ACCESS_BOUNCE_BUFFERED; 5568 pIemCpu->iNextMapping = iMemMap + 1; 5503 5569 pIemCpu->cActiveMappings++; 5504 5570 … … 5590 5656 pIemCpu->aMemMappings[iMemMap].pv = pbBuf; 5591 5657 pIemCpu->aMemMappings[iMemMap].fAccess = fAccess | IEM_ACCESS_BOUNCE_BUFFERED; 5658 pIemCpu->iNextMapping = iMemMap + 1; 5592 5659 pIemCpu->cActiveMappings++; 5593 5660 … … 5637 5704 5638 5705 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) 5640 5708 { 5641 5709 iMemMap = iemMemMapFindFree(pIemCpu); … … 5706 5774 pIemCpu->cActiveMappings--; 5707 5775 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 */ 5787 static 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 } 5708 5804 } 5709 5805 … … 6810 6906 * @param pDesc Where to return the descriptor table entry. 6811 6907 * @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 */ 6910 static VBOXSTRICTRC iemMemFetchSelDesc(PIEMCPU pIemCpu, PIEMSELDESC pDesc, uint16_t uSel, uint8_t uXcpt) 6814 6911 { 6815 6912 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx); … … 6827 6924 Log(("iemMemFetchSelDesc: LDT selector %#x is out of bounds (%3x) or ldtr is NP (%#x)\n", 6828 6925 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); 6831 6928 } 6832 6929 … … 6839 6936 { 6840 6937 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); 6843 6940 } 6844 6941 GCPtrBase = pCtx->gdtr.pGdt; … … 6861 6958 Log(("iemMemFetchSelDesc: system selector %#x is out of bounds\n", uSel)); 6862 6959 /** @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); 6864 6962 } 6865 6963 } … … 8340 8438 || (pOrgCtx->rip == 0x000000000215e240) 8341 8439 #endif 8440 #if 1 /* DOS's size-overridden iret to v8086. */ 8441 || (pOrgCtx->rip == 0x427 && pOrgCtx->cs.Sel == 0xb8) 8442 #endif 8342 8443 ) 8343 8444 ) … … 8734 8835 && pEvtRec->u.RamWrite.cb != 4) ) 8735 8836 { 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) 8739 8839 && pEvtRec->u.RamWrite.GCPhys - UINT32_C(0xfffc0000) > UINT32_C(0x40000) ) 8740 8840 { … … 9160 9260 if (rcStrict == VINF_SUCCESS) 9161 9261 pIemCpu->cInstructions++; 9262 if (pIemCpu->cActiveMappings > 0) 9263 iemMemRollback(pIemCpu); 9162 9264 //#ifdef DEBUG 9163 9265 // AssertMsg(pIemCpu->offOpcode == cbInstr || rcStrict != VINF_SUCCESS, ("%u %u\n", pIemCpu->offOpcode, cbInstr)); … … 9178 9280 if (rcStrict == VINF_SUCCESS) 9179 9281 pIemCpu->cInstructions++; 9282 if (pIemCpu->cActiveMappings > 0) 9283 iemMemRollback(pIemCpu); 9180 9284 } 9181 9285 EMSetInhibitInterruptsPC(pVCpu, UINT64_C(0x7777555533331111)); -
trunk/src/VBox/VMM/VMMAll/IEMAllAImpl.asm
r47411 r47548 410 410 IEMIMPL_BIN_OP sub, 1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0 411 411 IEMIMPL_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 ,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 415 415 IEMIMPL_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 ,416 IEMIMPL_BIN_OP test, 0, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), X86_EFL_AF 417 417 418 418 -
trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h
r47429 r47548 1031 1031 /* Fetch the descriptor. */ 1032 1032 IEMSELDESC Desc; 1033 VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, &Desc, uSel );1033 VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, &Desc, uSel, X86_XCPT_GP); 1034 1034 if (rcStrict != VINF_SUCCESS) 1035 1035 return rcStrict; … … 1208 1208 /* Fetch the descriptor. */ 1209 1209 IEMSELDESC Desc; 1210 rcStrict = iemMemFetchSelDesc(pIemCpu, &Desc, uSel );1210 rcStrict = iemMemFetchSelDesc(pIemCpu, &Desc, uSel, X86_XCPT_GP); 1211 1211 if (rcStrict != VINF_SUCCESS) 1212 1212 return rcStrict; … … 1434 1434 /* Fetch the descriptor. */ 1435 1435 IEMSELDESC DescCs; 1436 rcStrict = iemMemFetchSelDesc(pIemCpu, &DescCs, uNewCs );1436 rcStrict = iemMemFetchSelDesc(pIemCpu, &DescCs, uNewCs, X86_XCPT_GP); 1437 1437 if (rcStrict != VINF_SUCCESS) 1438 1438 return rcStrict; … … 1535 1535 { 1536 1536 /* Fetch the descriptor for the new stack segment. */ 1537 rcStrict = iemMemFetchSelDesc(pIemCpu, &DescSs, uNewOuterSs );1537 rcStrict = iemMemFetchSelDesc(pIemCpu, &DescSs, uNewOuterSs, X86_XCPT_GP); 1538 1538 if (rcStrict != VINF_SUCCESS) 1539 1539 return rcStrict; … … 2012 2012 * iret throws an exception if VME isn't enabled. 2013 2013 */ 2014 if ( pCtx->eflags.Bits.u1VM 2014 if ( Efl.Bits.u1VM 2015 && Efl.Bits.u2IOPL != 3 2015 2016 && !(pCtx->cr4 & X86_CR4_VME)) 2016 2017 return iemRaiseGeneralProtectionFault0(pIemCpu); … … 2033 2034 return rcStrict; 2034 2035 uNewEip = uFrame.pu32[0]; 2036 if (uNewEip > UINT16_MAX) 2037 return iemRaiseGeneralProtectionFault0(pIemCpu); 2038 2035 2039 uNewCs = (uint16_t)uFrame.pu32[1]; 2036 2040 uNewFlags = uFrame.pu32[2]; … … 2137 2141 * @param uNewFlags The new EFLAGS. 2138 2142 * @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. 2139 2145 */ 2140 2146 IEM_CIMPL_DEF_5(iemCImpl_iret_prot_v8086, PCPUMCTX, pCtx, uint32_t, uNewEip, uint16_t, uNewCs, … … 2179 2185 pCtx->rip = uNewEip; 2180 2186 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); 2182 2190 pIemCpu->uCpl = 3; 2183 2191 … … 2269 2277 2270 2278 IEMSELDESC DescCS; 2271 rcStrict = iemMemFetchSelDesc(pIemCpu, &DescCS, uNewCs );2279 rcStrict = iemMemFetchSelDesc(pIemCpu, &DescCS, uNewCs, X86_XCPT_GP); 2272 2280 if (rcStrict != VINF_SUCCESS) 2273 2281 { … … 2345 2353 2346 2354 IEMSELDESC DescSS; 2347 rcStrict = iemMemFetchSelDesc(pIemCpu, &DescSS, uNewSS );2355 rcStrict = iemMemFetchSelDesc(pIemCpu, &DescSS, uNewSS, X86_XCPT_GP); /** @todo Correct exception? */ 2348 2356 if (rcStrict != VINF_SUCCESS) 2349 2357 { … … 2431 2439 pCtx->ss.u64Base = X86DESC_BASE(&DescSS.Legacy); 2432 2440 2433 uint32_t fEFlagsMask = X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF 2441 uint32_t fEFlagsMask = X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF 2434 2442 | X86_EFL_TF | X86_EFL_DF | X86_EFL_OF | X86_EFL_NT; 2435 2443 if (enmEffOpSize != IEMMODE_16BIT) … … 2487 2495 X86EFLAGS NewEfl; 2488 2496 NewEfl.u = IEMMISC_GET_EFL(pIemCpu, pCtx); 2489 uint32_t fEFlagsMask = X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF 2497 uint32_t fEFlagsMask = X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF 2490 2498 | X86_EFL_TF | X86_EFL_DF | X86_EFL_OF | X86_EFL_NT; 2491 2499 if (enmEffOpSize != IEMMODE_16BIT) … … 2587 2595 2588 2596 IEMSELDESC DescCS; 2589 rcStrict = iemMemFetchSelDesc(pIemCpu, &DescCS, uNewCs );2597 rcStrict = iemMemFetchSelDesc(pIemCpu, &DescCS, uNewCs, X86_XCPT_GP); 2590 2598 if (rcStrict != VINF_SUCCESS) 2591 2599 { … … 2643 2651 else 2644 2652 { 2645 rcStrict = iemMemFetchSelDesc(pIemCpu, &DescSS, uNewSs );2653 rcStrict = iemMemFetchSelDesc(pIemCpu, &DescSS, uNewSs, X86_XCPT_GP); /** @todo Correct exception? */ 2646 2654 if (rcStrict != VINF_SUCCESS) 2647 2655 { … … 2761 2769 } 2762 2770 2763 uint32_t fEFlagsMask = X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF 2771 uint32_t fEFlagsMask = X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF 2764 2772 | X86_EFL_TF | X86_EFL_DF | X86_EFL_OF | X86_EFL_NT; 2765 2773 if (enmEffOpSize != IEMMODE_16BIT) … … 2797 2805 * Call a mode specific worker. 2798 2806 */ 2799 if ( pIemCpu->enmCpuMode == IEMMODE_16BIT 2800 && IEM_IS_REAL_OR_V86_MODE(pIemCpu)) 2807 if (IEM_IS_REAL_OR_V86_MODE(pIemCpu)) 2801 2808 return IEM_CIMPL_CALL_1(iemCImpl_iret_real_v8086, enmEffOpSize); 2802 2809 if (IEM_IS_LONG_MODE(pIemCpu)) … … 3088 3095 /* Fetch the descriptor. */ 3089 3096 IEMSELDESC Desc; 3090 VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, &Desc, uSel );3097 VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, &Desc, uSel, X86_XCPT_GP); /** @todo Correct exception? */ 3091 3098 if (rcStrict != VINF_SUCCESS) 3092 3099 return rcStrict; … … 3489 3496 */ 3490 3497 IEMSELDESC Desc; 3491 VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, &Desc, uNewLdt );3498 VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, &Desc, uNewLdt, X86_XCPT_GP); /** @todo Correct exception? */ 3492 3499 if (rcStrict != VINF_SUCCESS) 3493 3500 return rcStrict; … … 3586 3593 */ 3587 3594 IEMSELDESC Desc; 3588 VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, &Desc, uNewTr );3595 VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, &Desc, uNewTr, X86_XCPT_GP); /** @todo Correct exception? */ 3589 3596 if (rcStrict != VINF_SUCCESS) 3590 3597 return rcStrict; -
trunk/src/VBox/VMM/VMMR3/EMHM.cpp
r47421 r47548 366 366 pCtx->rip += Cpu.cbInstr; 367 367 STAM_PROFILE_STOP(&pVCpu->em.s.StatIOEmu, a); 368 LogFlow(("emR3ExecuteIOInstruction: %Rrc 1\n", VBOXSTRICTRC_VAL(rcStrict))); 368 369 return VBOXSTRICTRC_TODO(rcStrict); 369 370 } … … 374 375 Assert(TRPMHasTrap(pVCpu)); 375 376 STAM_PROFILE_STOP(&pVCpu->em.s.StatIOEmu, a); 377 LogFlow(("emR3ExecuteIOInstruction: VINF_SUCCESS 2\n")); 376 378 return VINF_SUCCESS; 377 379 } … … 381 383 { 382 384 STAM_PROFILE_STOP(&pVCpu->em.s.StatIOEmu, a); 385 LogFlow(("emR3ExecuteIOInstruction: %Rrc 3\n", VBOXSTRICTRC_VAL(rcStrict))); 383 386 return VBOXSTRICTRC_TODO(rcStrict); 384 387 } … … 387 390 388 391 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; 390 395 #endif 391 396 } -
trunk/src/VBox/VMM/VMMR3/IEMR3.cpp
r47307 r47548 88 88 pVCpu->iem.s.enmHostCpuVendor = pVM->aCpus[0].iem.s.enmHostCpuVendor; 89 89 } 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; 90 97 } 91 98 return VINF_SUCCESS;
Note:
See TracChangeset
for help on using the changeset viewer.