- Timestamp:
- Apr 11, 2013 2:46:04 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 21 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/cpum.h
r45291 r45485 491 491 492 492 493 /**494 * Get the current privilege level of the guest.495 *496 * @returns CPL497 * @param pVCpu The current virtual CPU.498 * @param pRegFrame Pointer to the register frame.499 */500 493 VMMDECL(uint32_t) CPUMRCGetGuestCPL(PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); 501 502 494 #ifdef VBOX_WITH_RAW_RING1 503 /** 504 * Transforms the guest CPU state to raw-ring mode. 505 * 506 * This function will change the any of the cs and ss register with DPL=0 to DPL=1. 507 * 508 * @returns VBox status. (recompiler failure) 509 * @param pVCpu Pointer to the VMCPU. 510 * @param pCtxCore The context core (for trap usage). 511 * @see @ref pg_raw 512 */ 513 VMMDECL(void) CPUMRCRecheckRawState(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore); 495 VMMDECL(void) CPUMRCRecheckRawState(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore); 514 496 #endif 515 497 -
trunk/include/VBox/vmm/em.h
r45276 r45485 122 122 * @param pVM The VM to operate on. 123 123 */ 124 #define EMIsRawRing3Enabled(pVM) (!(pVM)->fRecompileUser)124 #define EMIsRawRing3Enabled(pVM) (!(pVM)->fRecompileUser) 125 125 126 126 /** … … 131 131 * @param pVM The VM to operate on. 132 132 */ 133 #define EMIsRawRing0Enabled(pVM) (!(pVM)->fRecompileSupervisor)133 #define EMIsRawRing0Enabled(pVM) (!(pVM)->fRecompileSupervisor) 134 134 135 135 #ifdef VBOX_WITH_RAW_RING1 … … 141 141 * @param pVM The VM to operate on. 142 142 */ 143 # define EMIsRawRing1Enabled(pVM)((pVM)->fRawRing1Enabled)143 # define EMIsRawRing1Enabled(pVM) ((pVM)->fRawRing1Enabled) 144 144 #else 145 # define EMIsRawRing1Enabled(pVM)false145 # define EMIsRawRing1Enabled(pVM) false 146 146 #endif 147 147 … … 153 153 * @param pVM The VM to operate on. 154 154 */ 155 #define EMIsHwVirtExecutionEnabled(pVM) (!(pVM)->fRecompileSupervisor && !(pVM)->fRecompileUser)155 #define EMIsHwVirtExecutionEnabled(pVM) (!(pVM)->fRecompileSupervisor && !(pVM)->fRecompileUser) 156 156 157 157 /** -
trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp
r45291 r45485 2666 2666 if (pVCpu->cpum.s.fRawEntered) 2667 2667 { 2668 if ( EMIsRawRing1Enabled(pVCpu->CTX_SUFF(pVM))2669 && uCpl == 2)2668 if ( uCpl == 2 2669 && EMIsRawRing1Enabled(pVCpu->CTX_SUFF(pVM))) 2670 2670 uCpl = 1; 2671 else 2672 if (uCpl == 1) 2671 else if (uCpl == 1) 2673 2672 uCpl = 0; 2674 2673 } -
trunk/src/VBox/VMM/VMMAll/EMAll.cpp
r45479 r45485 57 57 58 58 #ifdef VBOX_WITH_RAW_RING1 59 #define EM_EMULATE_SMSW 60 #endif 59 # define EM_EMULATE_SMSW 60 #endif 61 61 62 62 63 /******************************************************************************* … … 3674 3675 || pRegFrame->eflags.Bits.u2IOPL > cpl 3675 3676 ) 3677 #endif 3676 3678 { 3677 #endif3678 3679 if ( cpl != 0 3679 3680 || pDis->pCurInstr->uOpcode != OP_RDTSC) /* rdtsc requires emulation in ring 3 as well */ … … 3683 3684 return VERR_EM_INTERPRETER; 3684 3685 } 3685 #ifdef VBOX_WITH_RAW_RING13686 3686 } 3687 #endif3688 3687 } 3689 3688 else -
trunk/src/VBox/VMM/VMMAll/SELMAll.cpp
r45276 r45485 23 23 #include <VBox/vmm/selm.h> 24 24 #include <VBox/vmm/stam.h> 25 #include <VBox/vmm/em.h> 25 26 #include <VBox/vmm/mm.h> 26 27 #include <VBox/vmm/pgm.h> … … 33 34 #include <VBox/vmm/vmm.h> 34 35 #include <iprt/x86.h> 36 37 #include "SELMInline.h" 35 38 36 39 … … 838 841 } 839 842 843 840 844 #ifdef VBOX_WITH_RAW_RING1 841 845 /** … … 853 857 } 854 858 #endif 859 855 860 856 861 #ifdef VBOX_WITH_RAW_MODE_NOT_R0 -
trunk/src/VBox/VMM/VMMAll/TRPMAll.cpp
r45276 r45485 625 625 if (!fConforming && dpl < cpl) 626 626 { 627 #ifdef IN_RC /* Only in GC mode we still see tracing of our ring modifications*/628 if ( (pRegFrame->ss.Sel & X86_SEL_RPL) == 1 627 #ifdef IN_RC /* Only in RC we still see tracing of our ring modifications. */ 628 if ( (pRegFrame->ss.Sel & X86_SEL_RPL) == 1 629 629 && !eflags.Bits.u1VM) 630 630 pTrapStack[--idx] = pRegFrame->ss.Sel & ~1; /* Mask away traces of raw ring 0 execution (ring 1). */ 631 # ifdef VBOX_WITH_RAW_RING1 632 else 633 if ( EMIsRawRing1Enabled(pVM) 634 && (pRegFrame->ss.Sel & X86_SEL_RPL) == 2) 631 else if ( EMIsRawRing1Enabled(pVM) 632 && (pRegFrame->ss.Sel & X86_SEL_RPL) == 2) 635 633 pTrapStack[--idx] = (pRegFrame->ss.Sel & ~2) | 1; /* Mask away traces of raw ring 1 execution (ring 2). */ 636 # endif637 634 else 638 635 #endif /* IN_RC */ … … 645 642 /* Note: Not really necessary as we grab include those bits in the trap/irq handler trampoline */ 646 643 pTrapStack[--idx] = eflags.u32; 647 #ifdef IN_RC /* Only in GC mode we still see tracing of our ring modifications */ 648 if ( (pRegFrame->cs.Sel & X86_SEL_RPL) == 1 644 645 #ifdef IN_RC /* Only in RC mode we still see tracing of our ring modifications */ 646 if ( (pRegFrame->cs.Sel & X86_SEL_RPL) == 1 649 647 && !eflags.Bits.u1VM) 650 648 pTrapStack[--idx] = pRegFrame->cs.Sel & ~1; /* Mask away traces of raw ring execution (ring 1). */ 651 # ifdef VBOX_WITH_RAW_RING1 652 else 653 if ( EMIsRawRing1Enabled(pVM) 654 && (pRegFrame->cs.Sel & X86_SEL_RPL) == 2) 649 else if ( EMIsRawRing1Enabled(pVM) 650 && (pRegFrame->cs.Sel & X86_SEL_RPL) == 2) 655 651 pTrapStack[--idx] = (pRegFrame->cs.Sel & ~2) | 1; /* Mask away traces of raw ring 1 execution (ring 2). */ 656 # endif657 652 else 658 653 #endif /* IN_RC */ -
trunk/src/VBox/VMM/VMMR3/CPUM.cpp
r45276 r45485 4193 4193 * Are we in Ring-0? 4194 4194 */ 4195 if ( pCtxCore->ss.Sel 4195 if ( pCtxCore->ss.Sel 4196 4196 && (pCtxCore->ss.Sel & X86_SEL_RPL) == 0 4197 4197 && !pCtxCore->eflags.Bits.u1VM) … … 4206 4206 */ 4207 4207 pCtxCore->ss.Sel |= 1; 4208 if ( pCtxCore->cs.Sel 4208 if ( pCtxCore->cs.Sel 4209 4209 && (pCtxCore->cs.Sel & X86_SEL_RPL) == 0) 4210 4210 pCtxCore->cs.Sel |= 1; … … 4236 4236 */ 4237 4237 AssertMsg((pCtxCore->eflags.u32 & X86_EFL_IF), ("X86_EFL_IF is clear\n")); 4238 AssertReleaseMsg(pCtxCore->eflags.Bits.u2IOPL == 0, 4238 AssertReleaseMsg(pCtxCore->eflags.Bits.u2IOPL == 0, 4239 4239 ("X86_EFL_IOPL=%d CPL=%d\n", pCtxCore->eflags.Bits.u2IOPL, pCtxCore->ss.Sel & X86_SEL_RPL)); 4240 4240 Assert((pVCpu->cpum.s.Guest.cr0 & (X86_CR0_PG | X86_CR0_WP | X86_CR0_PE)) == (X86_CR0_PG | X86_CR0_PE | X86_CR0_WP)); … … 4245 4245 return VINF_SUCCESS; 4246 4246 } 4247 4248 4247 4249 4248 -
trunk/src/VBox/VMM/VMMR3/CSAM.cpp
r45276 r45485 849 849 /* removing breaks win2k guests? */ 850 850 case OP_IRET: 851 #ifdef VBOX_WITH_RAW_RING1852 851 if (EMIsRawRing1Enabled(pVM)) 853 852 break; 854 #endif855 853 /* no break */ 856 854 -
trunk/src/VBox/VMM/VMMR3/EM.cpp
r45301 r45485 1320 1320 return EMSTATE_REM; 1321 1321 1322 # ifdef VBOX_WITH_RAW_RING11323 /* Only ring 0 and 1 supervisor code. */1324 1322 if (EMIsRawRing1Enabled(pVM)) 1325 1323 { 1324 /* Only ring 0 and 1 supervisor code. */ 1326 1325 if ((uSS & X86_SEL_RPL) == 2) /* ring 1 code is moved into ring 2, so we can't support ring-2 in that case. */ 1327 1326 { … … 1330 1329 } 1331 1330 } 1332 else1333 # endif1334 1331 /* Only ring 0 supervisor code. */ 1335 if ((uSS & X86_SEL_RPL) != 0)1332 else if ((uSS & X86_SEL_RPL) != 0) 1336 1333 { 1337 1334 Log2(("raw r0 mode refused: CPL %d\n", uSS & X86_SEL_RPL)); -
trunk/src/VBox/VMM/VMMR3/EMRaw.cpp
r45305 r45485 1362 1362 Assert(REMR3QueryPendingInterrupt(pVM, pVCpu) == REM_NO_PENDING_IRQ); 1363 1363 # endif 1364 # ifdef VBOX_WITH_RAW_RING1 1365 Assert(pCtx->eflags.Bits.u1VM || (pCtx->ss.Sel & X86_SEL_RPL) == 3 || (pCtx->ss.Sel & X86_SEL_RPL) == 0 || (EMIsRawRing1Enabled(pVM) && (pCtx->ss.Sel & X86_SEL_RPL) == 1)); 1366 # else 1367 Assert(pCtx->eflags.Bits.u1VM || (pCtx->ss.Sel & X86_SEL_RPL) == 3 || (pCtx->ss.Sel & X86_SEL_RPL) == 0); 1368 # endif 1364 Assert(pCtx->eflags.Bits.u1VM || (pCtx->ss.Sel & X86_SEL_RPL) == 3 || (pCtx->ss.Sel & X86_SEL_RPL) == 0 1365 || (EMIsRawRing1Enabled(pVM) && (pCtx->ss.Sel & X86_SEL_RPL) == 1)); 1369 1366 AssertMsg( (pCtx->eflags.u32 & X86_EFL_IF) 1370 1367 || PATMShouldUseRawMode(pVM, (RTGCPTR)pCtx->eip), … … 1446 1443 1447 1444 1445 1448 1446 /* 1449 1447 * Execute the code. … … 1551 1549 || VMCPU_FF_ISPENDING(pVCpu, ~VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK)) 1552 1550 { 1553 Assert(pCtx->eflags.Bits.u1VM || ( EMIsRawRing1Enabled(pVM) ? ((pCtx->ss.Sel & X86_SEL_RPL) != 2) : ((pCtx->ss.Sel & X86_SEL_RPL) != 1)));1551 Assert(pCtx->eflags.Bits.u1VM || (pCtx->ss.Sel & X86_SEL_RPL) != (EMIsRawRing1Enabled(pVM) ? 2 : 1)); 1554 1552 1555 1553 STAM_REL_PROFILE_ADV_SUSPEND(&pVCpu->em.s.StatRAWTotal, a); -
trunk/src/VBox/VMM/VMMR3/PATM.cpp
r45276 r45485 1535 1535 break; 1536 1536 1537 #ifdef VBOX_WITH_SAFE_STR /* @todo remove DISOPTYPE_PRIVILEGED_NOTRAP from disasm table */1537 #ifdef VBOX_WITH_SAFE_STR /** @todo remove DISOPTYPE_PRIVILEGED_NOTRAP from disasm table */ 1538 1538 case OP_STR: 1539 1539 break; … … 1651 1651 return VINF_SUCCESS; 1652 1652 1653 #ifdef VBOX_WITH_SAFE_STR /* @todo remove DISOPTYPE_PRIVILEGED_NOTRAP from disasm table */1653 #ifdef VBOX_WITH_SAFE_STR /** @todo remove DISOPTYPE_PRIVILEGED_NOTRAP from disasm table */ 1654 1654 case OP_STR: 1655 1655 break; -
trunk/src/VBox/VMM/VMMR3/PATMPatch.cpp
r45276 r45485 439 439 callInfo.pCurInstrGC = pCurInstrGC; 440 440 441 #ifdef VBOX_WITH_RAW_RING1442 441 if (EMIsRawRing1Enabled(pVM)) 443 {444 442 size = patmPatchGenCode(pVM, pPatch, pPB, &PATMIretRing1Record, 0, false, &callInfo); 445 }446 443 else 447 #endif448 444 size = patmPatchGenCode(pVM, pPatch, pPB, &PATMIretRecord, 0, false, &callInfo); 449 445 … … 1083 1079 int rc = VINF_SUCCESS; 1084 1080 1085 #ifdef VBOX_WITH_RAW_RING1 1086 if (!EMIsRawRing1Enabled(pVM)) /* direct passthru of interrupts is not allowed in the ring-1 support case as we can't deal with the ring-1/2 ambiguity in the patm asm code and we don't need it either as TRPMForwardTrap takes care of the details. */1087 {1088 #endif 1081 if (!EMIsRawRing1Enabled(pVM)) /* direct passthru of interrupts is not allowed in the ring-1 support case as we can't 1082 deal with the ring-1/2 ambiguity in the patm asm code and we don't need it either as 1083 TRPMForwardTrap takes care of the details. */ 1084 { 1089 1085 uint32_t size; 1090 1086 PATCHGEN_PROLOG(pVM, pPatch); … … 1099 1095 1100 1096 PATCHGEN_EPILOG(pPatch, size); 1101 #ifdef VBOX_WITH_RAW_RING1 1102 } 1103 #endif 1097 } 1104 1098 1105 1099 // Interrupt gates set IF to 0 -
trunk/src/VBox/VMM/VMMR3/SELM.cpp
r45276 r45485 63 63 #include <VBox/vmm/cpum.h> 64 64 #include <VBox/vmm/stam.h> 65 #include <VBox/vmm/em.h> 65 66 #include <VBox/vmm/mm.h> 66 67 #include <VBox/vmm/ssm.h> … … 80 81 #include <iprt/string.h> 81 82 83 #include "SELMInline.h" 82 84 83 85 … … 957 959 958 960 #ifdef VBOX_WITH_SAFE_STR 959 /* *Use the guest's TR selector to plug the str virtualization hole. */961 /* Use the guest's TR selector to plug the str virtualization hole. */ 960 962 if (CPUMGetGuestTR(pVCpu, NULL) != 0) 961 963 { … … 1029 1031 { 1030 1032 Log(("SELMR3UpdateFromCPUM: Guest's GDT is changed to pGdt=%016RX64 cbGdt=%08X\n", GDTR.pGdt, GDTR.cbGdt)); 1033 1031 1034 #ifdef SELM_TRACK_GUEST_GDT_CHANGES 1032 1035 /* … … 1044 1047 "Guest GDT write access handler"); 1045 1048 # ifdef VBOX_WITH_RAW_RING1 1046 /* Some guest OSes (QNX) share code and the GDT on the same page; PGMR3HandlerVirtualRegister doesn't support more than one handler, so we kick out the 1047 * PATM handler as this one is more important. 1048 * @todo fix this properly in PGMR3HandlerVirtualRegister 1049 /** @todo !HACK ALERT! 1050 * Some guest OSes (QNX) share code and the GDT on the same page; 1051 * PGMR3HandlerVirtualRegister doesn't support more than one handler, 1052 * so we kick out the PATM handler as this one is more important. 1053 * Fix this properly in PGMR3HandlerVirtualRegister? 1049 1054 */ 1050 1055 if (rc == VERR_PGM_HANDLER_VIRTUAL_CONFLICT) … … 1062 1067 if (RT_FAILURE(rc)) 1063 1068 return rc; 1064 #endif 1069 #endif /* SELM_TRACK_GUEST_GDT_CHANGES */ 1070 1065 1071 /* Update saved Guest GDTR. */ 1066 1072 pVM->selm.s.GuestGdtr = GDTR; … … 1243 1249 /** @todo investigate how intel handle various operations on half present cross page entries. */ 1244 1250 off = GCPtrLdt & (sizeof(X86DESC) - 1); 1245 ////AssertMsg(!off, ("LDT is not aligned on entry size! GCPtrLdt=%08x\n", GCPtrLdt));1251 AssertMsg(!off, ("LDT is not aligned on entry size! GCPtrLdt=%08x\n", GCPtrLdt)); 1246 1252 1247 1253 /* Note: Do not skip the first selector; unlike the GDT, a zero LDT selector is perfectly valid. */ … … 1473 1479 STAM_PROFILE_STOP(&pVM->selm.s.StatUpdateFromCPUM, a); 1474 1480 return rcStrict; 1475 #endif 1476 } 1481 #endif /* VBOX_WITH_RAW_MODE */ 1482 } 1483 1477 1484 1478 1485 #ifdef SELM_TRACK_GUEST_GDT_CHANGES … … 1568 1575 } 1569 1576 #endif 1577 1570 1578 1571 1579 /** … … 1719 1727 #ifdef VBOX_WITH_RAW_RING1 1720 1728 /* Update our TSS structure for the guest's ring 2 stack */ 1721 selmSetRing2Stack(pVM, (Tss.ss1 & ~1) | 2, Tss.esp1); 1722 1723 if ( (pVM->selm.s.Tss.ss2 != ((Tss.ss1 & ~2) | 1)) 1724 || pVM->selm.s.Tss.esp2 != Tss.esp1) 1729 if (EMIsRawRing1Enabled(pVM)) 1725 1730 { 1726 Log(("SELMR3SyncTSS: Updating TSS ring 1 stack to %04X:%08X from %04X:%08X\n", Tss.ss1, Tss.esp1, (pVM->selm.s.Tss.ss2 & ~2) | 1, pVM->selm.s.Tss.esp2)); 1731 if ( (pVM->selm.s.Tss.ss2 != ((Tss.ss1 & ~2) | 1)) 1732 || pVM->selm.s.Tss.esp2 != Tss.esp1) 1733 Log(("SELMR3SyncTSS: Updating TSS ring 1 stack to %04X:%08X from %04X:%08X\n", Tss.ss1, Tss.esp1, (pVM->selm.s.Tss.ss2 & ~2) | 1, pVM->selm.s.Tss.esp2)); 1734 selmSetRing2Stack(pVM, (Tss.ss1 & ~1) | 2, Tss.esp1); 1727 1735 } 1728 1736 #endif … … 1770 1778 { 1771 1779 # ifdef VBOX_WITH_RAW_RING1 1772 /* Some guest OSes (QNX) share code and the TSS on the same page; PGMR3HandlerVirtualRegister doesn't support more than one handler, so we kick out the 1773 * PATM handler as this one is more important. 1774 * @todo fix this properly in PGMR3HandlerVirtualRegister 1780 /** @todo !HACK ALERT! 1781 * Some guest OSes (QNX) share code and the TSS on the same page; 1782 * PGMR3HandlerVirtualRegister doesn't support more than one 1783 * handler, so we kick out the PATM handler as this one is more 1784 * important. Fix this properly in PGMR3HandlerVirtualRegister? 1775 1785 */ 1776 1786 if (rc == VERR_PGM_HANDLER_VIRTUAL_CONFLICT) … … 1794 1804 # endif 1795 1805 } 1796 #endif 1806 #endif /* SELM_TRACK_GUEST_TSS_CHANGES */ 1807 1797 1808 /* Update saved Guest TSS info. */ 1798 1809 pVM->selm.s.GCPtrGuestTss = GCPtrTss; … … 2095 2106 } 2096 2107 2108 2097 2109 # ifdef VBOX_WITH_SAFE_STR 2098 2110 /** 2099 * Validates the RawR0 TR shadow GDT entry 2111 * Validates the RawR0 TR shadow GDT entry. 2100 2112 * 2101 2113 * @returns true if it matches. … … 2135 2147 return true; 2136 2148 } 2137 # endif 2149 # endif /* VBOX_WITH_SAFE_STR */ 2138 2150 2139 2151 #endif /* VBOX_WITH_RAW_MODE */ -
trunk/src/VBox/VMM/VMMR3/TRPM.cpp
r45276 r45485 1331 1331 1332 1332 if ( EMIsRawRing0Enabled(pVM) 1333 #ifdef VBOX_WITH_RAW_RING1 1334 && !EMIsRawRing1Enabled(pVM) /* can't deal with the ambiguity of ring 1 & 2 in the patch code. */ 1335 #endif 1336 ) 1333 && !EMIsRawRing1Enabled(pVM)) /* can't deal with the ambiguity of ring 1 & 2 in the patch code. */ 1337 1334 { 1338 1335 /* -
trunk/src/VBox/VMM/VMMRC/CPUMRC.cpp
r45276 r45485 115 115 * @param pVCpu The current virtual CPU. 116 116 * @param pRegFrame Pointer to the register frame. 117 * 118 * @todo r=bird: This is very similar to CPUMGetGuestCPL and I cannot quite 119 * see why this variant of the code is necessary. 117 120 */ 118 121 VMMDECL(uint32_t) CPUMRCGetGuestCPL(PVMCPU pVCpu, PCPUMCTXCORE pRegFrame) … … 142 145 if (pVCpu->cpum.s.fRawEntered) 143 146 { 144 if ( EMIsRawRing1Enabled(pVCpu->CTX_SUFF(pVM))145 && uCpl == 2)147 if ( uCpl == 2 148 && EMIsRawRing1Enabled(pVCpu->CTX_SUFF(pVM)) ) 146 149 uCpl = 1; 147 else 148 if (uCpl == 1) 150 else if (uCpl == 1) 149 151 uCpl = 0; 150 152 } … … 162 164 } 163 165 166 164 167 #ifdef VBOX_WITH_RAW_RING1 165 168 /** … … 168 171 * This function will change the any of the cs and ss register with DPL=0 to DPL=1. 169 172 * 170 * @returns VBox status. (recompiler failure) 173 * Used by emInterpretIret() after the new state has been loaded. 174 * 171 175 * @param pVCpu Pointer to the VMCPU. 172 176 * @param pCtxCore The context core (for trap usage). 173 177 * @see @ref pg_raw 178 * @remarks Will be probably obsoleted by #5653 (it will leave and reenter raw 179 * mode instead, I think). 174 180 */ 175 181 VMMDECL(void) CPUMRCRecheckRawState(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore) … … 213 219 } 214 220 #endif /* VBOX_WITH_RAW_RING1 */ 221 -
trunk/src/VBox/VMM/VMMRC/PATMRC.cpp
r45276 r45485 155 155 156 156 /* Very important check -> otherwise we have a security leak. */ 157 #ifdef VBOX_WITH_RAW_RING1 158 AssertReturn(!pRegFrame->eflags.Bits.u1VM && (pRegFrame->ss.Sel & X86_SEL_RPL) <= (unsigned) (EMIsRawRing1Enabled(pVM) ? 2 : 1), VERR_ACCESS_DENIED); 159 #else 160 AssertReturn(!pRegFrame->eflags.Bits.u1VM && (pRegFrame->ss.Sel & X86_SEL_RPL) == 1, VERR_ACCESS_DENIED); 161 #endif 157 AssertReturn(!pRegFrame->eflags.Bits.u1VM && (pRegFrame->ss.Sel & X86_SEL_RPL) <= (EMIsRawRing1Enabled(pVM) ? 2U : 1U), 158 VERR_ACCESS_DENIED); 162 159 Assert(PATMIsPatchGCAddr(pVM, pRegFrame->eip)); 163 160 … … 459 456 int rc; 460 457 461 #ifdef VBOX_WITH_RAW_RING1 462 AssertReturn(!pRegFrame->eflags.Bits.u1VM && ((pRegFrame->ss.Sel & X86_SEL_RPL) == 1 || (EMIsRawRing1Enabled(pVM) && (pRegFrame->ss.Sel & X86_SEL_RPL) == 2)), VERR_ACCESS_DENIED); 463 #else 464 AssertReturn(!pRegFrame->eflags.Bits.u1VM && (pRegFrame->ss.Sel & X86_SEL_RPL) == 1, VERR_ACCESS_DENIED); 465 #endif 458 AssertReturn(!pRegFrame->eflags.Bits.u1VM 459 && ( (pRegFrame->ss.Sel & X86_SEL_RPL) == 1 460 || (EMIsRawRing1Enabled(pVM) && (pRegFrame->ss.Sel & X86_SEL_RPL) == 2)), VERR_ACCESS_DENIED); 466 461 467 462 /* Int 3 in PATM generated code? (most common case) */ -
trunk/src/VBox/VMM/VMMRC/SELMRC.cpp
r45276 r45485 35 35 #include <iprt/asm.h> 36 36 37 #include "SELMInline.h" 38 37 39 38 40 /******************************************************************************* … … 43 45 static char const g_aszSRegNms[X86_SREG_COUNT][4] = { "ES", "CS", "SS", "DS", "FS", "GS" }; 44 46 #endif 47 45 48 46 49 #ifdef SELM_TRACK_GUEST_GDT_CHANGES … … 308 311 #endif /* SELM_TRACK_GUEST_GDT_CHANGES */ 309 312 313 310 314 #ifdef SELM_TRACK_GUEST_LDT_CHANGES 311 315 /** … … 332 336 } 333 337 #endif 338 334 339 335 340 #ifdef SELM_TRACK_GUEST_TSS_CHANGES … … 407 412 } 408 413 #ifdef VBOX_WITH_RAW_RING1 409 else 410 if ( EMIsRawRing1Enabled(pVM) 411 && PAGE_ADDRESS(&pGuestTss->esp1) == PAGE_ADDRESS(&pGuestTss->padding_ss1) 412 && PAGE_ADDRESS(&pGuestTss->esp1) == PAGE_ADDRESS((uint8_t *)pGuestTss + offRange) 413 && ( pGuestTss->esp1 != pVM->selm.s.Tss.esp2 414 || pGuestTss->ss1 != ((pVM->selm.s.Tss.ss2 & ~2) | 1)) /* undo raw-r1 */ 415 ) 414 else if ( EMIsRawRing1Enabled(pVM) 415 && PAGE_ADDRESS(&pGuestTss->esp1) == PAGE_ADDRESS(&pGuestTss->padding_ss1) 416 && PAGE_ADDRESS(&pGuestTss->esp1) == PAGE_ADDRESS((uint8_t *)pGuestTss + offRange) 417 && ( pGuestTss->esp1 != pVM->selm.s.Tss.esp2 418 || pGuestTss->ss1 != ((pVM->selm.s.Tss.ss2 & ~2) | 1)) /* undo raw-r1 */ 419 ) 416 420 { 417 421 Log(("selmRCGuestTSSWriteHandler: R1 stack: %RTsel:%RGv -> %RTsel:%RGv\n", … … 513 517 #endif /* SELM_TRACK_GUEST_TSS_CHANGES */ 514 518 519 515 520 #ifdef SELM_TRACK_SHADOW_GDT_CHANGES 516 521 /** … … 534 539 #endif 535 540 541 536 542 #ifdef SELM_TRACK_SHADOW_LDT_CHANGES 537 543 /** … … 556 562 #endif 557 563 564 558 565 #ifdef SELM_TRACK_SHADOW_TSS_CHANGES 559 566 /** -
trunk/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp
r45305 r45485 304 304 PVM pVM = TRPMCPU_2_VM(pTrpmCpu); 305 305 PVMCPU pVCpu = TRPMCPU_2_VMCPU(pTrpmCpu); 306 //LogFlow(("TRPMGC01: cs:eip=%04x:%08x uDr6=%RTreg EFL=%x\n", pRegFrame->cs.Sel, pRegFrame->eip, uDr6, CPUMRawGetEFlags(pVCpu)));306 LogFlow(("TRPMGC01: cs:eip=%04x:%08x uDr6=%RTreg EFL=%x\n", pRegFrame->cs.Sel, pRegFrame->eip, uDr6, CPUMRawGetEFlags(pVCpu))); 307 307 TRPM_ENTER_DBG_HOOK(1); 308 308 … … 445 445 * PATM is using INT3s, let them have a go first. 446 446 */ 447 #ifdef VBOX_WITH_RAW_RING1 448 if ( ( (pRegFrame->ss.Sel & X86_SEL_RPL) == 1 449 || (EMIsRawRing1Enabled(pVM) && (pRegFrame->ss.Sel & X86_SEL_RPL) == 2)) 450 #else 451 if ( (pRegFrame->ss.Sel & X86_SEL_RPL) == 1 452 #endif 453 && !pRegFrame->eflags.Bits.u1VM) 447 if ( ( (pRegFrame->ss.Sel & X86_SEL_RPL) == 1 448 || (EMIsRawRing1Enabled(pVM) && (pRegFrame->ss.Sel & X86_SEL_RPL) == 2) ) 449 && !pRegFrame->eflags.Bits.u1VM) 454 450 { 455 451 rc = PATMRCHandleInt3PatchTrap(pVM, pRegFrame); … … 528 524 PGMRZDynMapStartAutoSet(pVCpu); 529 525 530 #ifdef VBOX_WITH_RAW_RING1 531 if (CPUMGetGuestCPL(pVCpu) <= (unsigned)(EMIsRawRing1Enabled(pVM) ? 1 : 0)) 532 #else 533 if (CPUMGetGuestCPL(pVCpu) == 0) 534 #endif 526 if (CPUMGetGuestCPL(pVCpu) <= (EMIsRawRing1Enabled(pVM) ? 1U : 0U)) 535 527 { 536 528 /* -
trunk/src/VBox/VMM/include/SELMInline.h
r45473 r45485 16 16 */ 17 17 18 #ifndef ___SELMInternal_h 19 #define ___SELMInternal_h 20 21 #include <VBox/cdefs.h> 22 #include <VBox/types.h> 23 #include <VBox/vmm/stam.h> 24 #include <VBox/vmm/cpum.h> 25 #include <VBox/log.h> 26 #include <iprt/x86.h> 27 #include <VBox/vmm/em.h> 28 29 30 31 /** @defgroup grp_selm_int Internals 32 * @ingroup grp_selm 33 * @internal 34 * @{ 35 */ 36 37 /** 38 * Enable or disable tracking of Shadow GDT/LDT/TSS. 39 * @{ 40 */ 41 #define SELM_TRACK_SHADOW_GDT_CHANGES 42 #define SELM_TRACK_SHADOW_LDT_CHANGES 43 #define SELM_TRACK_SHADOW_TSS_CHANGES 44 /** @} */ 45 46 /** 47 * Enable or disable tracking of Guest GDT/LDT/TSS. 48 * @{ 49 */ 50 #define SELM_TRACK_GUEST_GDT_CHANGES 51 #define SELM_TRACK_GUEST_LDT_CHANGES 52 #define SELM_TRACK_GUEST_TSS_CHANGES 53 /** @} */ 54 55 56 /** The number of GDTS allocated for our GDT. (full size) */ 57 #define SELM_GDT_ELEMENTS 8192 58 59 /** aHyperSel index to retrieve hypervisor selectors */ 60 /** The Flat CS selector used by the VMM inside the GC. */ 61 #define SELM_HYPER_SEL_CS 0 62 /** The Flat DS selector used by the VMM inside the GC. */ 63 #define SELM_HYPER_SEL_DS 1 64 /** The 64-bit mode CS selector used by the VMM inside the GC. */ 65 #define SELM_HYPER_SEL_CS64 2 66 /** The TSS selector used by the VMM inside the GC. */ 67 #define SELM_HYPER_SEL_TSS 3 68 /** The TSS selector for taking trap 08 (\#DF). */ 69 #define SELM_HYPER_SEL_TSS_TRAP08 4 70 /** Number of GDTs we need for internal use */ 71 #define SELM_HYPER_SEL_MAX (SELM_HYPER_SEL_TSS_TRAP08 + 1) 72 73 74 /** Default GDT selectors we use for the hypervisor. */ 75 #define SELM_HYPER_DEFAULT_SEL_CS ((SELM_GDT_ELEMENTS - 0x1) << 3) 76 #define SELM_HYPER_DEFAULT_SEL_DS ((SELM_GDT_ELEMENTS - 0x2) << 3) 77 #define SELM_HYPER_DEFAULT_SEL_CS64 ((SELM_GDT_ELEMENTS - 0x3) << 3) 78 #define SELM_HYPER_DEFAULT_SEL_TSS ((SELM_GDT_ELEMENTS - 0x4) << 3) 79 #define SELM_HYPER_DEFAULT_SEL_TSS_TRAP08 ((SELM_GDT_ELEMENTS - 0x5) << 3) 80 /** The lowest value default we use. */ 81 #define SELM_HYPER_DEFAULT_BASE SELM_HYPER_DEFAULT_SEL_TSS_TRAP08 82 83 /** 84 * Converts a SELM pointer into a VM pointer. 85 * @returns Pointer to the VM structure the SELM is part of. 86 * @param pSELM Pointer to SELM instance data. 87 */ 88 #define SELM2VM(pSELM) ( (PVM)((char *)pSELM - pSELM->offVM) ) 89 90 91 92 /** 93 * SELM Data (part of VM) 94 */ 95 typedef struct SELM 96 { 97 /** Offset to the VM structure. 98 * See SELM2VM(). */ 99 RTINT offVM; 100 101 /** Flat CS, DS, 64 bit mode CS, TSS & trap 8 TSS. */ 102 RTSEL aHyperSel[SELM_HYPER_SEL_MAX]; 103 104 /** Pointer to the GCs - R3 Ptr. 105 * This size is governed by SELM_GDT_ELEMENTS. */ 106 R3PTRTYPE(PX86DESC) paGdtR3; 107 /** Pointer to the GCs - RC Ptr. 108 * This is not initialized until the first relocation because it's used to 109 * check if the shadow GDT virtual handler requires deregistration. */ 110 RCPTRTYPE(PX86DESC) paGdtRC; 111 /** Current (last) Guest's GDTR. 112 * The pGdt member is set to RTRCPTR_MAX if we're not monitoring the guest GDT. */ 113 VBOXGDTR GuestGdtr; 114 /** The current (last) effective Guest GDT size. */ 115 RTUINT cbEffGuestGdtLimit; 116 117 uint32_t padding0; 118 119 /** R3 pointer to the LDT shadow area in HMA. */ 120 R3PTRTYPE(void *) pvLdtR3; 121 /** RC pointer to the LDT shadow area in HMA. */ 122 RCPTRTYPE(void *) pvLdtRC; 123 #if GC_ARCH_BITS == 64 124 RTRCPTR padding1; 125 #endif 126 /** The address of the guest LDT. 127 * RTRCPTR_MAX if not monitored. */ 128 RTGCPTR GCPtrGuestLdt; 129 /** Current LDT limit, both Guest and Shadow. */ 130 RTUINT cbLdtLimit; 131 /** Current LDT offset relative to pvLdtR3/pvLdtRC. */ 132 RTUINT offLdtHyper; 133 #if HC_ARCH_BITS == 32 && GC_ARCH_BITS == 64 134 uint32_t padding2[2]; 135 #endif 136 /** TSS. (This is 16 byte aligned!) 137 * @todo I/O bitmap & interrupt redirection table? */ 138 VBOXTSS Tss; 139 140 /** TSS for trap 08 (\#DF). */ 141 VBOXTSS TssTrap08; 142 143 /** Monitored shadow TSS address. */ 144 RCPTRTYPE(void *) pvMonShwTssRC; 145 #if GC_ARCH_BITS == 64 146 RTRCPTR padding3; 147 #endif 148 /** GC Pointer to the current Guest's TSS. 149 * RTRCPTR_MAX if not monitored. */ 150 RTGCPTR GCPtrGuestTss; 151 /** The size of the guest TSS. */ 152 RTUINT cbGuestTss; 153 /** Set if it's a 32-bit TSS. */ 154 bool fGuestTss32Bit; 155 /** The size of the Guest's TSS part we're monitoring. */ 156 RTUINT cbMonitoredGuestTss; 157 /** The guest TSS selector at last sync (part of monitoring). 158 * Contains RTSEL_MAX if not set. */ 159 RTSEL GCSelTss; 160 /** The last known offset of the I/O bitmap. 161 * This is only used if we monitor the bitmap. */ 162 uint16_t offGuestIoBitmap; 163 164 /** Indicates that the Guest GDT access handler have been registered. */ 165 bool fGDTRangeRegistered; 166 167 /** Indicates whether LDT/GDT/TSS monitoring and syncing is disabled. */ 168 bool fDisableMonitoring; 169 170 /** Indicates whether the TSS stack selector & base address need to be refreshed. */ 171 bool fSyncTSSRing0Stack; 172 bool fPadding2[1+2]; 173 174 /** SELMR3UpdateFromCPUM() profiling. */ 175 STAMPROFILE StatUpdateFromCPUM; 176 /** SELMR3SyncTSS() profiling. */ 177 STAMPROFILE StatTSSSync; 178 179 /** GC: The number of handled writes to the Guest's GDT. */ 180 STAMCOUNTER StatRCWriteGuestGDTHandled; 181 /** GC: The number of unhandled write to the Guest's GDT. */ 182 STAMCOUNTER StatRCWriteGuestGDTUnhandled; 183 /** GC: The number of times writes to Guest's LDT was detected. */ 184 STAMCOUNTER StatRCWriteGuestLDT; 185 /** GC: The number of handled writes to the Guest's TSS. */ 186 STAMCOUNTER StatRCWriteGuestTSSHandled; 187 /** GC: The number of handled writes to the Guest's TSS where we detected a change. */ 188 STAMCOUNTER StatRCWriteGuestTSSHandledChanged; 189 /** GC: The number of handled redir writes to the Guest's TSS where we detected a change. */ 190 STAMCOUNTER StatRCWriteGuestTSSRedir; 191 /** GC: The number of unhandled writes to the Guest's TSS. */ 192 STAMCOUNTER StatRCWriteGuestTSSUnhandled; 193 /** The number of times we had to relocate our hypervisor selectors. */ 194 STAMCOUNTER StatHyperSelsChanged; 195 /** The number of times we had find free hypervisor selectors. */ 196 STAMCOUNTER StatScanForHyperSels; 197 /** Counts the times we detected state selectors in SELMR3UpdateFromCPUM. */ 198 STAMCOUNTER aStatDetectedStaleSReg[X86_SREG_COUNT]; 199 /** Counts the times we were called with already state selectors in 200 * SELMR3UpdateFromCPUM. */ 201 STAMCOUNTER aStatAlreadyStaleSReg[X86_SREG_COUNT]; 202 /** Counts the times we found a stale selector becomming valid again. */ 203 STAMCOUNTER StatStaleToUnstaleSReg; 204 #ifdef VBOX_WITH_STATISTICS 205 /** Times we updated hidden selector registers in CPUMR3UpdateFromCPUM. */ 206 STAMCOUNTER aStatUpdatedSReg[X86_SREG_COUNT]; 207 STAMCOUNTER StatLoadHidSelGst; 208 STAMCOUNTER StatLoadHidSelShw; 209 #endif 210 STAMCOUNTER StatLoadHidSelReadErrors; 211 STAMCOUNTER StatLoadHidSelGstNoGood; 212 } SELM, *PSELM; 213 214 RT_C_DECLS_BEGIN 215 216 VMMRCDECL(int) selmRCGuestGDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange); 217 VMMRCDECL(int) selmRCGuestLDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange); 218 VMMRCDECL(int) selmRCGuestTSSWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange); 219 220 VMMRCDECL(int) selmRCShadowGDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange); 221 VMMRCDECL(int) selmRCShadowLDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange); 222 VMMRCDECL(int) selmRCShadowTSSWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange); 223 224 void selmSetRing1Stack(PVM pVM, uint32_t ss, RTGCPTR32 esp); 225 #ifdef VBOX_WITH_RAW_RING1 226 void selmSetRing2Stack(PVM pVM, uint32_t ss, RTGCPTR32 esp); 227 #endif 228 229 RT_C_DECLS_END 230 18 #ifndef ___SELMInline_h 19 #define ___SELMInline_h 231 20 232 21 #ifdef VBOX_WITH_RAW_MODE_NOT_R0 … … 416 205 } 417 206 # ifdef VBOX_WITH_RAW_RING1 418 else 419 if ( pDesc->Gen.u2Dpl == 1 420 // && EMIsRawRing1Enabled(pVM) 421 && (pDesc->Gen.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF)) 422 != (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF) ) 207 else if ( pDesc->Gen.u2Dpl == 1 208 && EMIsRawRing1Enabled(pVM) 209 && (pDesc->Gen.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF)) 210 != (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF) ) 423 211 { 424 212 pDesc->Gen.u2Dpl = 2; -
trunk/src/VBox/VMM/include/SELMInternal.h
r45276 r45485 25 25 #include <VBox/log.h> 26 26 #include <iprt/x86.h> 27 #include <VBox/vmm/em.h>28 27 29 28 … … 229 228 RT_C_DECLS_END 230 229 231 232 #ifdef VBOX_WITH_RAW_MODE_NOT_R0233 234 /**235 * Checks if a shadow descriptor table entry is good for the given segment236 * register.237 *238 * @returns @c true if good, @c false if not.239 * @param pSReg The segment register.240 * @param pShwDesc The shadow descriptor table entry.241 * @param iSReg The segment register index (X86_SREG_XXX).242 * @param uCpl The CPL.243 */244 DECLINLINE(bool) selmIsShwDescGoodForSReg(PCCPUMSELREG pSReg, PCX86DESC pShwDesc, uint32_t iSReg, uint32_t uCpl)245 {246 /*247 * See iemMiscValidateNewSS, iemCImpl_LoadSReg and intel+amd manuals.248 */249 250 if (!pShwDesc->Gen.u1Present)251 {252 Log(("selmIsShwDescGoodForSReg: Not present\n"));253 return false;254 }255 256 if (!pShwDesc->Gen.u1DescType)257 {258 Log(("selmIsShwDescGoodForSReg: System descriptor\n"));259 return false;260 }261 262 if (iSReg == X86_SREG_SS)263 {264 if ((pShwDesc->Gen.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_WRITE)) != X86_SEL_TYPE_WRITE)265 {266 Log(("selmIsShwDescGoodForSReg: Stack must be writable\n"));267 return false;268 }269 if (uCpl > (unsigned)pShwDesc->Gen.u2Dpl - pShwDesc->Gen.u1Available)270 {271 Log(("selmIsShwDescGoodForSReg: CPL(%d) > DPL(%d)\n", uCpl, pShwDesc->Gen.u2Dpl - pShwDesc->Gen.u1Available));272 return false;273 }274 }275 else276 {277 if (iSReg == X86_SREG_CS)278 {279 if (!(pShwDesc->Gen.u4Type & X86_SEL_TYPE_CODE))280 {281 Log(("selmIsShwDescGoodForSReg: CS needs code segment\n"));282 return false;283 }284 }285 else if ((pShwDesc->Gen.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_READ)) == X86_SEL_TYPE_CODE)286 {287 Log(("selmIsShwDescGoodForSReg: iSReg=%u execute only\n", iSReg));288 return false;289 }290 291 if ( (pShwDesc->Gen.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF))292 != (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF)293 && ( ( (pSReg->Sel & X86_SEL_RPL) > (unsigned)pShwDesc->Gen.u2Dpl - pShwDesc->Gen.u1Available294 && (pSReg->Sel & X86_SEL_RPL) != pShwDesc->Gen.u1Available )295 || uCpl > (unsigned)pShwDesc->Gen.u2Dpl - pShwDesc->Gen.u1Available ) )296 {297 Log(("selmIsShwDescGoodForSReg: iSReg=%u DPL=%u CPL=%u RPL=%u\n", iSReg,298 pShwDesc->Gen.u2Dpl - pShwDesc->Gen.u1Available, uCpl, pSReg->Sel & X86_SEL_RPL));299 return false;300 }301 }302 303 return true;304 }305 306 307 /**308 * Checks if a guest descriptor table entry is good for the given segment309 * register.310 *311 * @returns @c true if good, @c false if not.312 * @param pVCpu The current virtual CPU.313 * @param pSReg The segment register.314 * @param pGstDesc The guest descriptor table entry.315 * @param iSReg The segment register index (X86_SREG_XXX).316 * @param uCpl The CPL.317 */318 DECLINLINE(bool) selmIsGstDescGoodForSReg(PVMCPU pVCpu, PCCPUMSELREG pSReg, PCX86DESC pGstDesc, uint32_t iSReg, uint32_t uCpl)319 {320 /*321 * See iemMiscValidateNewSS, iemCImpl_LoadSReg and intel+amd manuals.322 */323 324 if (!pGstDesc->Gen.u1Present)325 {326 Log(("selmIsGstDescGoodForSReg: Not present\n"));327 return false;328 }329 330 if (!pGstDesc->Gen.u1DescType)331 {332 Log(("selmIsGstDescGoodForSReg: System descriptor\n"));333 return false;334 }335 336 if (iSReg == X86_SREG_SS)337 {338 if ((pGstDesc->Gen.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_WRITE)) != X86_SEL_TYPE_WRITE)339 {340 Log(("selmIsGstDescGoodForSReg: Stack must be writable\n"));341 return false;342 }343 if (uCpl > pGstDesc->Gen.u2Dpl)344 {345 Log(("selmIsGstDescGoodForSReg: CPL(%d) > DPL(%d)\n", uCpl, pGstDesc->Gen.u2Dpl));346 return false;347 }348 }349 else350 {351 if (iSReg == X86_SREG_CS)352 {353 if (!(pGstDesc->Gen.u4Type & X86_SEL_TYPE_CODE))354 {355 Log(("selmIsGstDescGoodForSReg: CS needs code segment\n"));356 return false;357 }358 }359 else if ((pGstDesc->Gen.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_READ)) == X86_SEL_TYPE_CODE)360 {361 Log(("selmIsGstDescGoodForSReg: iSReg=%u execute only\n", iSReg));362 return false;363 }364 365 if ( (pGstDesc->Gen.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF))366 != (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF)367 && ( ( (pSReg->Sel & X86_SEL_RPL) > pGstDesc->Gen.u2Dpl368 && ( (pSReg->Sel & X86_SEL_RPL) != 1369 || !CPUMIsGuestInRawMode(pVCpu) ) )370 || uCpl > (unsigned)pGstDesc->Gen.u2Dpl371 )372 )373 {374 Log(("selmIsGstDescGoodForSReg: iSReg=%u DPL=%u CPL=%u RPL=%u InRawMode=%u\n", iSReg,375 pGstDesc->Gen.u2Dpl, uCpl, pSReg->Sel & X86_SEL_RPL, CPUMIsGuestInRawMode(pVCpu)));376 return false;377 }378 }379 380 return true;381 }382 383 384 /**385 * Converts a guest GDT or LDT entry to a shadow table entry.386 *387 * @param pVM The VM handle.388 * @param pDesc Guest entry on input, shadow entry on return.389 */390 DECL_FORCE_INLINE(void) selmGuestToShadowDesc(PVM pVM, PX86DESC pDesc)391 {392 /*393 * Code and data selectors are generally 1:1, with the394 * 'little' adjustment we do for DPL 0 selectors.395 */396 if (pDesc->Gen.u1DescType)397 {398 /*399 * Hack for A-bit against Trap E on read-only GDT.400 */401 /** @todo Fix this by loading ds and cs before turning off WP. */402 pDesc->Gen.u4Type |= X86_SEL_TYPE_ACCESSED;403 404 /*405 * All DPL 0 code and data segments are squeezed into DPL 1.406 *407 * We're skipping conforming segments here because those408 * cannot give us any trouble.409 */410 if ( pDesc->Gen.u2Dpl == 0411 && (pDesc->Gen.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF))412 != (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF) )413 {414 pDesc->Gen.u2Dpl = 1;415 pDesc->Gen.u1Available = 1;416 }417 # ifdef VBOX_WITH_RAW_RING1418 else419 if ( pDesc->Gen.u2Dpl == 1420 // && EMIsRawRing1Enabled(pVM)421 && (pDesc->Gen.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF))422 != (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF) )423 {424 pDesc->Gen.u2Dpl = 2;425 pDesc->Gen.u1Available = 1;426 }427 # endif428 else429 pDesc->Gen.u1Available = 0;430 }431 else432 {433 /*434 * System type selectors are marked not present.435 * Recompiler or special handling is required for these.436 */437 /** @todo what about interrupt gates and rawr0? */438 pDesc->Gen.u1Present = 0;439 }440 }441 442 443 /**444 * Checks if a segment register is stale given the shadow descriptor table445 * entry.446 *447 * @returns @c true if stale, @c false if not.448 * @param pSReg The segment register.449 * @param pShwDesc The shadow descriptor entry.450 * @param iSReg The segment register number (X86_SREG_XXX).451 */452 DECLINLINE(bool) selmIsSRegStale32(PCCPUMSELREG pSReg, PCX86DESC pShwDesc, uint32_t iSReg)453 {454 if ( pSReg->Attr.n.u1Present != pShwDesc->Gen.u1Present455 || pSReg->Attr.n.u4Type != pShwDesc->Gen.u4Type456 || pSReg->Attr.n.u1DescType != pShwDesc->Gen.u1DescType457 || pSReg->Attr.n.u1DefBig != pShwDesc->Gen.u1DefBig458 || pSReg->Attr.n.u1Granularity != pShwDesc->Gen.u1Granularity459 || pSReg->Attr.n.u2Dpl != pShwDesc->Gen.u2Dpl - pShwDesc->Gen.u1Available)460 {461 Log(("selmIsSRegStale32: Attributes changed (%#x -> %#x)\n", pSReg->Attr.u, X86DESC_GET_HID_ATTR(pShwDesc)));462 return true;463 }464 465 if (pSReg->u64Base != X86DESC_BASE(pShwDesc))466 {467 Log(("selmIsSRegStale32: base changed (%#llx -> %#llx)\n", pSReg->u64Base, X86DESC_BASE(pShwDesc)));468 return true;469 }470 471 if (pSReg->u32Limit != X86DESC_LIMIT_G(pShwDesc))472 {473 Log(("selmIsSRegStale32: limit changed (%#x -> %#x)\n", pSReg->u32Limit, X86DESC_LIMIT_G(pShwDesc)));474 return true;475 }476 477 return false;478 }479 480 481 /**482 * Loads the hidden bits of a selector register from a shadow descriptor table483 * entry.484 *485 * @param pSReg The segment register in question.486 * @param pShwDesc The shadow descriptor table entry.487 */488 DECLINLINE(void) selmLoadHiddenSRegFromShadowDesc(PCPUMSELREG pSReg, PCX86DESC pShwDesc)489 {490 pSReg->Attr.u = X86DESC_GET_HID_ATTR(pShwDesc);491 pSReg->Attr.n.u2Dpl -= pSReg->Attr.n.u1Available;492 Assert(pSReg->Attr.n.u4Type & X86_SEL_TYPE_ACCESSED);493 pSReg->u32Limit = X86DESC_LIMIT_G(pShwDesc);494 pSReg->u64Base = X86DESC_BASE(pShwDesc);495 pSReg->ValidSel = pSReg->Sel;496 if (pSReg->Attr.n.u1Available)497 pSReg->ValidSel &= ~(RTSEL)1;498 pSReg->fFlags = CPUMSELREG_FLAGS_VALID;499 }500 501 502 /**503 * Loads the hidden bits of a selector register from a guest descriptor table504 * entry.505 *506 * @param pVCpu The current virtual CPU.507 * @param pSReg The segment register in question.508 * @param pGstDesc The guest descriptor table entry.509 */510 DECLINLINE(void) selmLoadHiddenSRegFromGuestDesc(PVMCPU pVCpu, PCPUMSELREG pSReg, PCX86DESC pGstDesc)511 {512 pSReg->Attr.u = X86DESC_GET_HID_ATTR(pGstDesc);513 pSReg->Attr.n.u4Type |= X86_SEL_TYPE_ACCESSED;514 pSReg->u32Limit = X86DESC_LIMIT_G(pGstDesc);515 pSReg->u64Base = X86DESC_BASE(pGstDesc);516 pSReg->ValidSel = pSReg->Sel;517 if ((pSReg->ValidSel & 1) && CPUMIsGuestInRawMode(pVCpu))518 pSReg->ValidSel &= ~(RTSEL)1;519 pSReg->fFlags = CPUMSELREG_FLAGS_VALID;520 }521 522 #endif /* VBOX_WITH_RAW_MODE_NOT_R0 */523 524 230 /** @} */ 525 231 -
trunk/src/recompiler/VBoxRecompiler.c
r45305 r45485 1633 1633 } 1634 1634 1635 # ifdef VBOX_WITH_RAW_RING11636 /* Only ring 0 and 1 supervisor code. */1637 1635 if (EMIsRawRing1Enabled(env->pVM)) 1638 1636 { 1639 if (((fFlags >> HF_CPL_SHIFT) & 3) == 2) /* ring 1 code is moved into ring 2, so we can't support ring-2 in that case. */ 1637 /* Only ring 0 and 1 supervisor code. */ 1638 if (((fFlags >> HF_CPL_SHIFT) & 3) == 2) /* ring 1 code is moved into ring 2, so we can't support ring-2 in that case. */ 1640 1639 { 1641 1640 Log2(("raw r0 mode refused: CPL %d\n", (fFlags >> HF_CPL_SHIFT) & 3)); … … 1643 1642 } 1644 1643 } 1645 else 1646 # endif 1647 // Only R0 1648 if (((fFlags >> HF_CPL_SHIFT) & 3) != 0) 1644 /* Only R0. */ 1645 else if (((fFlags >> HF_CPL_SHIFT) & 3) != 0) 1649 1646 { 1650 1647 STAM_COUNTER_INC(&gStatRefuseRing1or2); -
trunk/src/recompiler/target-i386/op_helper.c
r45276 r45485 232 232 #ifdef VBOX 233 233 /* Trying to load a selector with CPL=1? */ 234 /* @todo this is a hack to correct the incorrect checking order for pending interrupts in the patm iret replacement code (corrected in the ring-1 version) */235 /* @todo in theory the iret could fault and we'd still need this. */234 /** @todo this is a hack to correct the incorrect checking order for pending interrupts in the patm iret replacement code (corrected in the ring-1 version) */ 235 /** @todo in theory the iret could fault and we'd still need this. */ 236 236 if ((env->hflags & HF_CPL_MASK) == 0 && (selector & 3) == 1 && (env->state & CPU_RAW_RING0) && !EMIsRawRing1Enabled(env->pVM)) 237 237 { … … 2561 2561 (RTGCPTR)env->eip, (RTSEL)env->tr.selector, (RTGCPTR)env->tr.base, (RTGCPTR)env->tr.limit, 2562 2562 env->tr.flags, (RTSEL)(selector & 0xffff))); 2563 # if 0 /** @todo r=bird: This looks very fishy, need good reason to re-enable it. */ 2563 2564 ASMAtomicOrS32((int32_t volatile *)&env->interrupt_request, 2564 2565 CPU_INTERRUPT_EXTERNAL_EXIT); 2566 # endif 2565 2567 #endif 2566 2568 selector &= 0xffff; … … 3186 3188 if ((new_cs & 0x3) == 1 && (env->state & CPU_RAW_RING0)) 3187 3189 { 3188 # ifdef VBOX_WITH_RAW_RING13189 3190 if ( !EMIsRawRing1Enabled(env->pVM) 3190 3191 || env->segs[R_CS].selector == (new_cs & 0xfffc)) … … 3198 3199 Log(("Genuine switch to ring-1 (iret)\n")); 3199 3200 } 3200 # else 3201 Log(("RPL 1 -> new_cs %04X -> %04X\n", new_cs, new_cs & 0xfffc)); 3202 new_cs = new_cs & 0xfffc; 3203 # endif 3204 } 3205 # ifdef VBOX_WITH_RAW_RING1 3206 else 3207 if ((new_cs & 0x3) == 2 && (env->state & CPU_RAW_RING0) && EMIsRawRing1Enabled(env->pVM)) 3201 } 3202 else if ((new_cs & 0x3) == 2 && (env->state & CPU_RAW_RING0) && EMIsRawRing1Enabled(env->pVM)) 3208 3203 { 3209 3204 Log(("RPL 2 -> new_cs %04X -> %04X\n", new_cs, (new_cs & 0xfffc) | 1)); 3210 3205 new_cs = (new_cs & 0xfffc) | 1; 3211 3206 } 3212 # endif3213 3207 #endif 3214 3208 } else {
Note:
See TracChangeset
for help on using the changeset viewer.