Changeset 45276 in vbox
- Timestamp:
- Apr 2, 2013 8:17:11 AM (11 years ago)
- Location:
- trunk
- Files:
-
- 39 edited
-
include/VBox/vmm/cpum.h (modified) (1 diff)
-
include/VBox/vmm/em.h (modified) (1 diff)
-
include/VBox/vmm/selm.h (modified) (1 diff)
-
include/VBox/vmm/vm.h (modified) (2 diffs)
-
include/VBox/vmm/vm.mac (modified) (2 diffs)
-
src/VBox/Main/Makefile.kmk (modified) (1 diff)
-
src/VBox/Main/src-all/Global.cpp (modified) (1 diff)
-
src/VBox/Main/src-client/ConsoleImpl2.cpp (modified) (1 diff)
-
src/VBox/VMM/Makefile.kmk (modified) (1 diff)
-
src/VBox/VMM/VMMAll/CPUMAllRegs.cpp (modified) (2 diffs)
-
src/VBox/VMM/VMMAll/EMAll.cpp (modified) (7 diffs)
-
src/VBox/VMM/VMMAll/PATMAll.cpp (modified) (1 diff)
-
src/VBox/VMM/VMMAll/PGMAllBth.h (modified) (1 diff)
-
src/VBox/VMM/VMMAll/PGMAllPool.cpp (modified) (1 diff)
-
src/VBox/VMM/VMMAll/SELMAll.cpp (modified) (3 diffs)
-
src/VBox/VMM/VMMAll/TRPMAll.cpp (modified) (6 diffs)
-
src/VBox/VMM/VMMR3/CPUM.cpp (modified) (6 diffs)
-
src/VBox/VMM/VMMR3/CSAM.cpp (modified) (4 diffs)
-
src/VBox/VMM/VMMR3/DBGFDisas.cpp (modified) (2 diffs)
-
src/VBox/VMM/VMMR3/EM.cpp (modified) (11 diffs)
-
src/VBox/VMM/VMMR3/EMHM.cpp (modified) (1 diff)
-
src/VBox/VMM/VMMR3/EMRaw.cpp (modified) (8 diffs)
-
src/VBox/VMM/VMMR3/PATM.cpp (modified) (7 diffs)
-
src/VBox/VMM/VMMR3/PATMA.asm (modified) (2 diffs)
-
src/VBox/VMM/VMMR3/PATMPatch.cpp (modified) (4 diffs)
-
src/VBox/VMM/VMMR3/PATMSSM.cpp (modified) (1 diff)
-
src/VBox/VMM/VMMR3/PGMHandler.cpp (modified) (1 diff)
-
src/VBox/VMM/VMMR3/SELM.cpp (modified) (24 diffs)
-
src/VBox/VMM/VMMR3/TRPM.cpp (modified) (1 diff)
-
src/VBox/VMM/VMMR3/VMM.cpp (modified) (1 diff)
-
src/VBox/VMM/VMMRC/CPUMRC.cpp (modified) (2 diffs)
-
src/VBox/VMM/VMMRC/PATMRC.cpp (modified) (4 diffs)
-
src/VBox/VMM/VMMRC/SELMRC.cpp (modified) (10 diffs)
-
src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp (modified) (6 diffs)
-
src/VBox/VMM/include/PATMA.h (modified) (1 diff)
-
src/VBox/VMM/include/SELMInternal.h (modified) (5 diffs)
-
src/recompiler/Makefile.kmk (modified) (1 diff)
-
src/recompiler/VBoxRecompiler.c (modified) (4 diffs)
-
src/recompiler/target-i386/op_helper.c (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/cpum.h
r44793 r45276 485 485 DECLASM(void) CPUMGCCallV86Code(PCPUMCTXCORE pRegFrame); 486 486 487 488 /** 489 * Get the current privilege level of the guest. 490 * 491 * @returns CPL 492 * @param pVCpu The current virtual CPU. 493 * @param pRegFrame Pointer to the register frame. 494 */ 495 VMMDECL(uint32_t) CPUMRCGetGuestCPL(PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); 496 497 #ifdef VBOX_WITH_RAW_RING1 498 /** 499 * Transforms the guest CPU state to raw-ring mode. 500 * 501 * This function will change the any of the cs and ss register with DPL=0 to DPL=1. 502 * 503 * @returns VBox status. (recompiler failure) 504 * @param pVCpu Pointer to the VMCPU. 505 * @param pCtxCore The context core (for trap usage). 506 * @see @ref pg_raw 507 */ 508 VMMDECL(void) CPUMRCRecheckRawState(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore); 509 #endif 510 487 511 /** @} */ 488 512 #endif /* IN_RC */ -
trunk/include/VBox/vmm/em.h
r44528 r45276 133 133 #define EMIsRawRing0Enabled(pVM) (!(pVM)->fRecompileSupervisor) 134 134 135 #ifdef VBOX_WITH_RAW_RING1 136 /** 137 * Checks if raw ring-1 execute mode is enabled. 138 * 139 * @returns true if enabled. 140 * @returns false if disabled. 141 * @param pVM The VM to operate on. 142 */ 143 #define EMIsRawRing1Enabled(pVM) ((pVM)->fRawRing1Enabled) 144 #else 145 #define EMIsRawRing1Enabled(pVM) false 146 #endif 147 135 148 /** 136 149 * Checks if execution with hardware assisted virtualization is enabled. -
trunk/include/VBox/vmm/selm.h
r42427 r45276 107 107 VMMR3DECL(bool) SELMR3CheckTSS(PVM pVM); 108 108 VMMR3DECL(int) SELMR3DebugCheck(PVM pVM); 109 #ifdef VBOX_WITH_SAFE_STR 110 VMMR3DECL(bool) SELMR3CheckShadowTR(PVM pVM); 111 #endif 112 109 113 /** @def SELMR3_DEBUG_CHECK 110 114 * Invokes SELMR3DebugCheck in stricts builds. */ -
trunk/include/VBox/vmm/vm.h
r45152 r45276 843 843 /** Whether to recompile supervisor mode code or run it raw/hm. */ 844 844 bool fRecompileSupervisor; 845 /** Whether raw mode supports ring-1 code or not. */ 846 bool fRawRing1Enabled; 845 847 /** PATM enabled flag. 846 848 * This is placed here for performance reasons. */ … … 862 864 863 865 /** Alignment padding.. */ 864 uint 32_t uPadding1;866 uint8_t uPadding1[3]; 865 867 866 868 /** @name Debugging -
trunk/include/VBox/vmm/vm.mac
r45152 r45276 59 59 .fRecompileUser resb 1 60 60 .fRecompileSupervisor resb 1 61 .fRawRing1Enabled resb 1 61 62 .fPATMEnabled resb 1 62 63 .fCSAMEnabled resb 1 … … 66 67 .fUseLargePages resb 1 67 68 68 .uPadding1 res d 169 .uPadding1 resb 3 69 70 70 71 .hTraceBufRC RTRCPTR_RES 1 -
trunk/src/VBox/Main/Makefile.kmk
r45138 r45276 56 56 VBOX_MAIN_DEFS += \ 57 57 $(if $(VBOX_WITH_RAW_MODE),VBOX_WITH_RAW_MODE,) \ 58 $(if $(VBOX_WITH_RAW_RING1),VBOX_WITH_RAW_RING1,) \ 58 59 $(if $(VBOX_WITH_NETFLT),VBOX_WITH_NETFLT,) \ 59 60 $(if $(VBOX_WITH_COPYTOGUEST),VBOX_WITH_COPYTOGUEST,) \ -
trunk/src/VBox/Main/src-all/Global.cpp
r44413 r45276 313 313 StorageControllerType_PIIX4, StorageBus_IDE, ChipsetType_PIIX3, AudioControllerType_AC97 }, 314 314 { "Other", "Other", "QNX", "QNX", 315 #ifdef VBOX_WITH_RAW_RING1 316 VBOXOSTYPE_QNX, VBOXOSHINT_NONE, 317 #else 315 318 VBOXOSTYPE_QNX, VBOXOSHINT_HWVIRTEX, 319 #endif 316 320 512, 4, 4 * _1G64, NetworkAdapterType_Am79C973, 0, StorageControllerType_PIIX4, StorageBus_IDE, 317 321 StorageControllerType_PIIX4, StorageBus_IDE, ChipsetType_PIIX3, AudioControllerType_AC97 }, -
trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp
r44829 r45276 810 810 InsertConfigInteger(pRoot, "CSAMEnabled", 1); /* boolean */ 811 811 #endif 812 813 #ifdef VBOX_WITH_RAW_RING1 814 if (osTypeId == "QNX") 815 { 816 /* QNX needs special treatment in raw mode due to its use of ring-1. */ 817 InsertConfigInteger(pRoot, "RawR1Enabled", 1); /* boolean */ 818 } 819 #endif 820 812 821 /* Not necessary, but to make sure these two settings end up in the release log. */ 813 822 BOOL fPageFusion = FALSE; -
trunk/src/VBox/VMM/Makefile.kmk
r45152 r45276 57 57 VMM_COMMON_DEFS += VBOX_WITH_OLD_VTX_CODE 58 58 endif 59 ifdef VBOX_WITH_SAFE_STR 60 VMM_COMMON_DEFS += VBOX_WITH_SAFE_STR 61 endif 62 ifdef VBOX_WITH_RAW_RING1 63 VMM_COMMON_DEFS += VBOX_WITH_RAW_RING1 64 endif 65 59 66 # VMM_COMMON_DEFS += VBOX_WITH_NS_ACCOUNTING_STATS 60 67 -
trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp
r45142 r45276 27 27 #include <VBox/vmm/pgm.h> 28 28 #include <VBox/vmm/mm.h> 29 #include <VBox/vmm/em.h> 29 30 #if defined(VBOX_WITH_RAW_MODE) && !defined(IN_RING0) 30 31 # include <VBox/vmm/selm.h> … … 2656 2657 uCpl = (pVCpu->cpum.s.Guest.ss.Sel & X86_SEL_RPL); 2657 2658 #ifdef VBOX_WITH_RAW_MODE_NOT_R0 2659 # ifdef VBOX_WITH_RAW_RING1 2660 if (pVCpu->cpum.s.fRawEntered) 2661 { 2662 if ( EMIsRawRing1Enabled(pVCpu->CTX_SUFF(pVM)) 2663 && uCpl == 2) 2664 uCpl = 1; 2665 else 2666 if (uCpl == 1) 2667 uCpl = 0; 2668 } 2669 Assert(uCpl != 2); /* ring 2 support not allowed anymore. */ 2670 # else 2658 2671 if (uCpl == 1) 2659 2672 uCpl = 0; 2673 # endif 2660 2674 #endif 2661 2675 } -
trunk/src/VBox/VMM/VMMAll/EMAll.cpp
r44528 r45276 54 54 //# define VBOX_SAME_AS_EM 55 55 //# define VBOX_COMPARE_IEM_LAST 56 #endif 57 58 #ifdef VBOX_WITH_RAW_RING1 59 #define EM_EMULATE_SMSW 56 60 #endif 57 61 … … 1029 1033 } 1030 1034 1031 #if defined(IN_RC) /*&& defined(VBOX_WITH_PATM)*/1035 #ifdef IN_RC 1032 1036 1033 1037 DECLINLINE(int) emRCStackRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, void *pvDst, RTGCPTR GCPtrSrc, uint32_t cb) … … 1095 1099 } 1096 1100 1097 #endif /* IN_RC && VBOX_WITH_PATM */ 1101 /** 1102 * IRET Emulation. 1103 */ 1104 static int emInterpretIret(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize) 1105 { 1106 #ifdef VBOX_WITH_RAW_RING1 1107 NOREF(pvFault); NOREF(pcbSize); 1108 if (EMIsRawRing1Enabled(pVM)) 1109 { 1110 RTGCUINTPTR pIretStack = (RTGCUINTPTR)pRegFrame->esp; 1111 RTGCUINTPTR eip, cs, esp, ss, eflags, uMask; 1112 int rc; 1113 uint32_t cpl, rpl; 1114 1115 /* We only execute 32-bits protected mode code in raw mode, so no need to bother to check for 16-bits code here. */ 1116 /* @todo: we don't verify all the edge cases that generate #GP faults */ 1117 1118 Assert(pRegFrame == CPUMGetGuestCtxCore(pVCpu)); 1119 Assert(!CPUMIsGuestIn64BitCode(pVCpu)); 1120 /** @todo Rainy day: Test what happens when VERR_EM_INTERPRETER is returned by 1121 * this function. Fear that it may guru on us, thus not converted to 1122 * IEM. */ 1123 1124 rc = emRCStackRead(pVM, pVCpu, pRegFrame, &eip, (RTGCPTR)pIretStack , 4); 1125 rc |= emRCStackRead(pVM, pVCpu, pRegFrame, &cs, (RTGCPTR)(pIretStack + 4), 4); 1126 rc |= emRCStackRead(pVM, pVCpu, pRegFrame, &eflags, (RTGCPTR)(pIretStack + 8), 4); 1127 AssertRCReturn(rc, VERR_EM_INTERPRETER); 1128 AssertReturn(eflags & X86_EFL_VM, VERR_EM_INTERPRETER); 1129 1130 /* Deal with V86 above. */ 1131 if (eflags & X86_EFL_VM) 1132 return EMInterpretIretV86ForPatm(pVM, pVCpu, pRegFrame); 1133 1134 cpl = CPUMRCGetGuestCPL(pVCpu, pRegFrame); 1135 rpl = cs & X86_SEL_RPL; 1136 1137 Log(("emInterpretIret: iret to CS:EIP=%04X:%08X eflags=%x\n", cs, eip, eflags)); 1138 if (rpl != cpl) 1139 { 1140 rc |= emRCStackRead(pVM, pVCpu, pRegFrame, &esp, (RTGCPTR)(pIretStack + 12), 4); 1141 rc |= emRCStackRead(pVM, pVCpu, pRegFrame, &ss, (RTGCPTR)(pIretStack + 16), 4); 1142 AssertRCReturn(rc, VERR_EM_INTERPRETER); 1143 Log(("emInterpretIret: return to different privilege level (rpl=%d cpl=%d)\n", rpl, cpl)); 1144 Log(("emInterpretIret: SS:ESP=%04X:08X\n", ss, esp)); 1145 pRegFrame->ss.Sel = ss; 1146 pRegFrame->esp = esp; 1147 } 1148 pRegFrame->cs.Sel = cs; 1149 pRegFrame->eip = eip; 1150 1151 /* Adjust CS & SS as required. */ 1152 CPUMRCRecheckRawState(pVCpu, pRegFrame); 1153 1154 /* Mask away all reserved bits */ 1155 uMask = X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_TF | X86_EFL_IF | X86_EFL_DF | X86_EFL_OF | X86_EFL_IOPL | X86_EFL_NT | X86_EFL_RF | X86_EFL_VM | X86_EFL_AC | X86_EFL_VIF | X86_EFL_VIP | X86_EFL_ID; 1156 eflags &= uMask; 1157 1158 CPUMRawSetEFlags(pVCpu, eflags); 1159 Assert((pRegFrame->eflags.u32 & (X86_EFL_IF|X86_EFL_IOPL)) == X86_EFL_IF); 1160 return VINF_SUCCESS; 1161 } 1162 #else 1163 NOREF(pVM); NOREF(pVCpu); NOREF(pDis); NOREF(pRegFrame); NOREF(pvFault); NOREF(pcbSize); 1164 #endif 1165 return VERR_EM_INTERPRETER; 1166 } 1167 1168 #endif /* IN_RC */ 1098 1169 1099 1170 … … 2508 2579 return VERR_EM_INTERPRETER; 2509 2580 2510 #ifdef IN_RC 2511 if (TRPMHasTrap(pVCpu)) 2512 { 2513 if (TRPMGetErrorCode(pVCpu) & X86_TRAP_PF_RW) 2581 if (param1.type == DISQPV_TYPE_ADDRESS) 2582 { 2583 RTGCPTR pDest; 2584 uint64_t val64; 2585 2586 switch(param1.type) 2514 2587 { 2515 #else 2516 /** @todo Make this the default and don't rely on TRPM information. */ 2517 if (param1.type == DISQPV_TYPE_ADDRESS) 2588 case DISQPV_TYPE_IMMEDIATE: 2589 if(!(param1.flags & (DISQPV_FLAG_32|DISQPV_FLAG_64))) 2590 return VERR_EM_INTERPRETER; 2591 /* fallthru */ 2592 2593 case DISQPV_TYPE_ADDRESS: 2594 pDest = (RTGCPTR)param1.val.val64; 2595 pDest = emConvertToFlatAddr(pVM, pRegFrame, pDis, &pDis->Param1, pDest); 2596 break; 2597 2598 default: 2599 AssertFailed(); 2600 return VERR_EM_INTERPRETER; 2601 } 2602 2603 switch(param2.type) 2518 2604 { 2519 #endif 2520 RTGCPTR pDest; 2521 uint64_t val64; 2522 2523 switch(param1.type) 2605 case DISQPV_TYPE_IMMEDIATE: /* register type is translated to this one too */ 2606 val64 = param2.val.val64; 2607 break; 2608 2609 default: 2610 Log(("emInterpretMov: unexpected type=%d rip=%RGv\n", param2.type, (RTGCPTR)pRegFrame->rip)); 2611 return VERR_EM_INTERPRETER; 2612 } 2613 #ifdef LOG_ENABLED 2614 if (pDis->uCpuMode == DISCPUMODE_64BIT) 2615 LogFlow(("EMInterpretInstruction at %RGv: OP_MOV %RGv <- %RX64 (%d) &val64=%RHv\n", (RTGCPTR)pRegFrame->rip, pDest, val64, param2.size, &val64)); 2616 else 2617 LogFlow(("EMInterpretInstruction at %08RX64: OP_MOV %RGv <- %08X (%d) &val64=%RHv\n", pRegFrame->rip, pDest, (uint32_t)val64, param2.size, &val64)); 2618 #endif 2619 2620 Assert(param2.size <= 8 && param2.size > 0); 2621 EM_ASSERT_FAULT_RETURN(pDest == pvFault, VERR_EM_INTERPRETER); 2622 rc = emRamWrite(pVM, pVCpu, pRegFrame, pDest, &val64, param2.size); 2623 if (RT_FAILURE(rc)) 2624 return VERR_EM_INTERPRETER; 2625 2626 *pcbSize = param2.size; 2627 } 2628 #if defined(IN_RC) && defined(VBOX_WITH_RAW_RING1) 2629 /* mov xx, cs instruction is dangerous in raw mode and replaced by an 'int3' by csam/patm. */ 2630 else if ( param1.type == DISQPV_TYPE_REGISTER 2631 && param2.type == DISQPV_TYPE_REGISTER) 2632 { 2633 AssertReturn((pDis->Param1.fUse & (DISUSE_REG_GEN8|DISUSE_REG_GEN16|DISUSE_REG_GEN32)), VERR_EM_INTERPRETER); 2634 AssertReturn(pDis->Param2.fUse == DISUSE_REG_SEG, VERR_EM_INTERPRETER); 2635 AssertReturn(pDis->Param2.Base.idxSegReg == DISSELREG_CS, VERR_EM_INTERPRETER); 2636 2637 uint32_t u32Cpl = CPUMRCGetGuestCPL(pVCpu, pRegFrame); 2638 uint32_t uValCS = (pRegFrame->cs.Sel & ~X86_SEL_RPL) | u32Cpl; 2639 2640 Log(("EMInterpretInstruction: OP_MOV cs=%x->%x\n", pRegFrame->cs.Sel, uValCS)); 2641 switch (param1.size) 2642 { 2643 case 1: rc = DISWriteReg8(pRegFrame, pDis->Param1.Base.idxGenReg, (uint8_t) uValCS); break; 2644 case 2: rc = DISWriteReg16(pRegFrame, pDis->Param1.Base.idxGenReg, (uint16_t)uValCS); break; 2645 case 4: rc = DISWriteReg32(pRegFrame, pDis->Param1.Base.idxGenReg, (uint32_t)uValCS); break; 2646 default: 2647 AssertFailed(); 2648 return VERR_EM_INTERPRETER; 2649 } 2650 AssertRCReturn(rc, rc); 2651 } 2652 #endif 2653 else 2654 { /* read fault */ 2655 RTGCPTR pSrc; 2656 uint64_t val64; 2657 2658 /* Source */ 2659 switch(param2.type) 2660 { 2661 case DISQPV_TYPE_IMMEDIATE: 2662 if(!(param2.flags & (DISQPV_FLAG_32|DISQPV_FLAG_64))) 2663 return VERR_EM_INTERPRETER; 2664 /* fallthru */ 2665 2666 case DISQPV_TYPE_ADDRESS: 2667 pSrc = (RTGCPTR)param2.val.val64; 2668 pSrc = emConvertToFlatAddr(pVM, pRegFrame, pDis, &pDis->Param2, pSrc); 2669 break; 2670 2671 default: 2672 return VERR_EM_INTERPRETER; 2673 } 2674 2675 Assert(param1.size <= 8 && param1.size > 0); 2676 EM_ASSERT_FAULT_RETURN(pSrc == pvFault, VERR_EM_INTERPRETER); 2677 rc = emRamRead(pVM, pVCpu, pRegFrame, &val64, pSrc, param1.size); 2678 if (RT_FAILURE(rc)) 2679 return VERR_EM_INTERPRETER; 2680 2681 /* Destination */ 2682 switch(param1.type) 2683 { 2684 case DISQPV_TYPE_REGISTER: 2685 switch(param1.size) 2524 2686 { 2525 case DISQPV_TYPE_IMMEDIATE: 2526 if(!(param1.flags & (DISQPV_FLAG_32|DISQPV_FLAG_64))) 2527 return VERR_EM_INTERPRETER; 2528 /* fallthru */ 2529 2530 case DISQPV_TYPE_ADDRESS: 2531 pDest = (RTGCPTR)param1.val.val64; 2532 pDest = emConvertToFlatAddr(pVM, pRegFrame, pDis, &pDis->Param1, pDest); 2533 break; 2534 2535 default: 2536 AssertFailed(); 2537 return VERR_EM_INTERPRETER; 2538 } 2539 2540 switch(param2.type) 2541 { 2542 case DISQPV_TYPE_IMMEDIATE: /* register type is translated to this one too */ 2543 val64 = param2.val.val64; 2544 break; 2545 2546 default: 2547 Log(("emInterpretMov: unexpected type=%d rip=%RGv\n", param2.type, (RTGCPTR)pRegFrame->rip)); 2548 return VERR_EM_INTERPRETER; 2549 } 2550 #ifdef LOG_ENABLED 2551 if (pDis->uCpuMode == DISCPUMODE_64BIT) 2552 LogFlow(("EMInterpretInstruction at %RGv: OP_MOV %RGv <- %RX64 (%d) &val64=%RHv\n", (RTGCPTR)pRegFrame->rip, pDest, val64, param2.size, &val64)); 2553 else 2554 LogFlow(("EMInterpretInstruction at %08RX64: OP_MOV %RGv <- %08X (%d) &val64=%RHv\n", pRegFrame->rip, pDest, (uint32_t)val64, param2.size, &val64)); 2555 #endif 2556 2557 Assert(param2.size <= 8 && param2.size > 0); 2558 EM_ASSERT_FAULT_RETURN(pDest == pvFault, VERR_EM_INTERPRETER); 2559 rc = emRamWrite(pVM, pVCpu, pRegFrame, pDest, &val64, param2.size); 2560 if (RT_FAILURE(rc)) 2561 return VERR_EM_INTERPRETER; 2562 2563 *pcbSize = param2.size; 2564 } 2565 else 2566 { /* read fault */ 2567 RTGCPTR pSrc; 2568 uint64_t val64; 2569 2570 /* Source */ 2571 switch(param2.type) 2572 { 2573 case DISQPV_TYPE_IMMEDIATE: 2574 if(!(param2.flags & (DISQPV_FLAG_32|DISQPV_FLAG_64))) 2575 return VERR_EM_INTERPRETER; 2576 /* fallthru */ 2577 2578 case DISQPV_TYPE_ADDRESS: 2579 pSrc = (RTGCPTR)param2.val.val64; 2580 pSrc = emConvertToFlatAddr(pVM, pRegFrame, pDis, &pDis->Param2, pSrc); 2581 break; 2582 2687 case 1: rc = DISWriteReg8(pRegFrame, pDis->Param1.Base.idxGenReg, (uint8_t) val64); break; 2688 case 2: rc = DISWriteReg16(pRegFrame, pDis->Param1.Base.idxGenReg, (uint16_t)val64); break; 2689 case 4: rc = DISWriteReg32(pRegFrame, pDis->Param1.Base.idxGenReg, (uint32_t)val64); break; 2690 case 8: rc = DISWriteReg64(pRegFrame, pDis->Param1.Base.idxGenReg, val64); break; 2583 2691 default: 2584 2692 return VERR_EM_INTERPRETER; 2585 2693 } 2586 2587 Assert(param1.size <= 8 && param1.size > 0);2588 EM_ASSERT_FAULT_RETURN(pSrc == pvFault, VERR_EM_INTERPRETER);2589 rc = emRamRead(pVM, pVCpu, pRegFrame, &val64, pSrc, param1.size);2590 2694 if (RT_FAILURE(rc)) 2591 return VERR_EM_INTERPRETER; 2592 2593 /* Destination */ 2594 switch(param1.type) 2595 { 2596 case DISQPV_TYPE_REGISTER: 2597 switch(param1.size) 2598 { 2599 case 1: rc = DISWriteReg8(pRegFrame, pDis->Param1.Base.idxGenReg, (uint8_t) val64); break; 2600 case 2: rc = DISWriteReg16(pRegFrame, pDis->Param1.Base.idxGenReg, (uint16_t)val64); break; 2601 case 4: rc = DISWriteReg32(pRegFrame, pDis->Param1.Base.idxGenReg, (uint32_t)val64); break; 2602 case 8: rc = DISWriteReg64(pRegFrame, pDis->Param1.Base.idxGenReg, val64); break; 2603 default: 2604 return VERR_EM_INTERPRETER; 2605 } 2606 if (RT_FAILURE(rc)) 2607 return rc; 2608 break; 2609 2610 default: 2611 return VERR_EM_INTERPRETER; 2612 } 2695 return rc; 2696 break; 2697 2698 default: 2699 return VERR_EM_INTERPRETER; 2700 } 2613 2701 #ifdef LOG_ENABLED 2614 if (pDis->uCpuMode == DISCPUMODE_64BIT) 2615 LogFlow(("EMInterpretInstruction: OP_MOV %RGv -> %RX64 (%d)\n", pSrc, val64, param1.size)); 2616 else 2617 LogFlow(("EMInterpretInstruction: OP_MOV %RGv -> %08X (%d)\n", pSrc, (uint32_t)val64, param1.size)); 2618 #endif 2619 } 2620 return VINF_SUCCESS; 2621 #ifdef IN_RC 2622 } 2623 return VERR_EM_INTERPRETER; 2624 #endif 2702 if (pDis->uCpuMode == DISCPUMODE_64BIT) 2703 LogFlow(("EMInterpretInstruction: OP_MOV %RGv -> %RX64 (%d)\n", pSrc, val64, param1.size)); 2704 else 2705 LogFlow(("EMInterpretInstruction: OP_MOV %RGv -> %08X (%d)\n", pSrc, (uint32_t)val64, param1.size)); 2706 #endif 2707 } 2708 return VINF_SUCCESS; 2625 2709 } 2626 2710 … … 3015 3099 #endif /* IN_RC */ 3016 3100 3017 3018 /**3019 * IRET Emulation.3020 */3021 static int emInterpretIret(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize)3022 {3023 /* only allow direct calls to EMInterpretIret for now */3024 NOREF(pVM); NOREF(pVCpu); NOREF(pDis); NOREF(pRegFrame); NOREF(pvFault); NOREF(pcbSize);3025 return VERR_EM_INTERPRETER;3026 }3027 3101 3028 3102 /** … … 3597 3671 /* Get the current privilege level. */ 3598 3672 uint32_t cpl = CPUMGetGuestCPL(pVCpu); 3599 if ( cpl != 0 3600 && pDis->pCurInstr->uOpcode != OP_RDTSC) /* rdtsc requires emulation in ring 3 as well */ 3673 #ifdef VBOX_WITH_RAW_RING1 3674 if ( !EMIsRawRing1Enabled(pVM) 3675 || cpl > 1 3676 || pRegFrame->eflags.Bits.u2IOPL > cpl 3677 ) 3601 3678 { 3602 Log(("WARNING: refusing instruction emulation for user-mode code!!\n")); 3603 STAM_COUNTER_INC(&pVCpu->em.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,FailedUserMode)); 3604 return VERR_EM_INTERPRETER; 3679 #endif 3680 if ( cpl != 0 3681 && pDis->pCurInstr->uOpcode != OP_RDTSC) /* rdtsc requires emulation in ring 3 as well */ 3682 { 3683 Log(("WARNING: refusing instruction emulation for user-mode code!!\n")); 3684 STAM_COUNTER_INC(&pVCpu->em.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,FailedUserMode)); 3685 return VERR_EM_INTERPRETER; 3686 } 3687 #ifdef VBOX_WITH_RAW_RING1 3605 3688 } 3689 #endif 3606 3690 } 3607 3691 else … … 3835 3919 INTERPRET_CASE(OP_STI,Sti); 3836 3920 INTERPRET_CASE(OP_XADD, XAdd); 3921 INTERPRET_CASE(OP_IRET,Iret); 3837 3922 #endif 3838 3923 INTERPRET_CASE(OP_CMPXCHG8B, CmpXchg8b); 3839 3924 INTERPRET_CASE(OP_HLT,Hlt); 3840 INTERPRET_CASE(OP_IRET,Iret);3841 3925 INTERPRET_CASE(OP_WBINVD,WbInvd); 3842 3926 #ifdef VBOX_WITH_STATISTICS -
trunk/src/VBox/VMM/VMMAll/PATMAll.cpp
r44362 r45276 627 627 case OP_MOV: 628 628 if (fPatchFlags & PATMFL_IDTHANDLER) 629 {630 629 pszInstr = "mov (Int/Trap Handler)"; 631 } 630 else 631 pszInstr = "mov (cs)"; 632 632 break; 633 633 case OP_SYSENTER: -
trunk/src/VBox/VMM/VMMAll/PGMAllBth.h
r45103 r45276 352 352 } 353 353 /* Unhandled part of a monitored page */ 354 Log(("Unhandled part of monitored page %RGv\n", pvFault)); 354 355 } 355 356 else -
trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp
r45103 r45276 756 756 757 757 /* Non-supervisor mode write means it's used for something else. */ 758 if (CPUMGetGuestCPL(pVCpu) != 0)758 if (CPUMGetGuestCPL(pVCpu) == 3) 759 759 return true; 760 760 -
trunk/src/VBox/VMM/VMMAll/SELMAll.cpp
r43387 r45276 838 838 } 839 839 840 #ifdef VBOX_WITH_RAW_RING1 841 /** 842 * Sets ss:esp for ring1 in main Hypervisor's TSS. 843 * 844 * @param pVM Pointer to the VM. 845 * @param ss Ring2 SS register value. Pass 0 if invalid. 846 * @param esp Ring2 ESP register value. 847 */ 848 void selmSetRing2Stack(PVM pVM, uint32_t ss, RTGCPTR32 esp) 849 { 850 Assert((ss & 3) == 2 || esp == 0); 851 pVM->selm.s.Tss.ss2 = ss; 852 pVM->selm.s.Tss.esp2 = (uint32_t)esp; 853 } 854 #endif 840 855 841 856 #ifdef VBOX_WITH_RAW_MODE_NOT_R0 … … 855 870 PVMCPU pVCpu = &pVM->aCpus[0]; 856 871 872 #ifdef SELM_TRACK_GUEST_TSS_CHANGES 857 873 if (pVM->selm.s.fSyncTSSRing0Stack) 858 874 { 875 #endif 859 876 RTGCPTR GCPtrTss = pVM->selm.s.GCPtrGuestTss; 860 877 int rc; … … 913 930 selmSetRing1Stack(pVM, tss.ss0 | 1, (RTGCPTR32)tss.esp0); 914 931 pVM->selm.s.fSyncTSSRing0Stack = false; 915 } 932 #ifdef SELM_TRACK_GUEST_TSS_CHANGES 933 } 934 #endif 916 935 917 936 *pSS = pVM->selm.s.Tss.ss1; -
trunk/src/VBox/VMM/VMMAll/TRPMAll.cpp
r44362 r45276 27 27 #include <VBox/vmm/selm.h> 28 28 #include <VBox/vmm/stam.h> 29 #include <VBox/vmm/dbgf.h> 29 30 #include "TRPMInternal.h" 30 31 #include <VBox/vmm/vm.h> … … 593 594 pTrapStack = (uint32_t *)(uintptr_t)pTrapStackGC; 594 595 #else 595 Assert(eflags.Bits.u1VM || (pRegFrame->ss.Sel & X86_SEL_RPL) == 0 || (pRegFrame->ss.Sel & X86_SEL_RPL) == 3 );596 Assert(eflags.Bits.u1VM || (pRegFrame->ss.Sel & X86_SEL_RPL) == 0 || (pRegFrame->ss.Sel & X86_SEL_RPL) == 3 || (EMIsRawRing1Enabled(pVM) && (pRegFrame->ss.Sel & X86_SEL_RPL) == 1)); 596 597 /* Check maximum amount we need (10 when executing in V86 mode) */ 597 598 if ((pTrapStackGC >> PAGE_SHIFT) != ((pTrapStackGC - 10*sizeof(uint32_t)) >> PAGE_SHIFT)) /* fail if we cross a page boundary */ … … 624 625 if (!fConforming && dpl < cpl) 625 626 { 626 if ((pRegFrame->ss.Sel & X86_SEL_RPL) == 1 && !eflags.Bits.u1VM) 627 pTrapStack[--idx] = pRegFrame->ss.Sel & ~1; /* Mask away traces of raw ring execution (ring 1). */ 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 629 && !eflags.Bits.u1VM) 630 pTrapStack[--idx] = pRegFrame->ss.Sel & ~1; /* Mask away traces of raw ring 0 execution (ring 1). */ 631 # ifdef VBOX_WITH_RAW_RING1 628 632 else 633 if ( EMIsRawRing1Enabled(pVM) 634 && (pRegFrame->ss.Sel & X86_SEL_RPL) == 2) 635 pTrapStack[--idx] = (pRegFrame->ss.Sel & ~2) | 1; /* Mask away traces of raw ring 1 execution (ring 2). */ 636 # endif 637 else 638 #endif /* IN_RC */ 629 639 pTrapStack[--idx] = pRegFrame->ss.Sel; 630 640 … … 635 645 /* Note: Not really necessary as we grab include those bits in the trap/irq handler trampoline */ 636 646 pTrapStack[--idx] = eflags.u32; 637 638 if ((pRegFrame->cs.Sel & X86_SEL_RPL) == 1 && !eflags.Bits.u1VM) 639 pTrapStack[--idx] = pRegFrame->cs.Sel & ~1; /* Mask away traces of raw ring execution (ring 1). */ 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 649 && !eflags.Bits.u1VM) 650 pTrapStack[--idx] = pRegFrame->cs.Sel & ~1; /* Mask away traces of raw ring execution (ring 1). */ 651 # ifdef VBOX_WITH_RAW_RING1 640 652 else 653 if ( EMIsRawRing1Enabled(pVM) 654 && (pRegFrame->cs.Sel & X86_SEL_RPL) == 2) 655 pTrapStack[--idx] = (pRegFrame->cs.Sel & ~2) | 1; /* Mask away traces of raw ring 1 execution (ring 2). */ 656 # endif 657 else 658 #endif /* IN_RC */ 641 659 pTrapStack[--idx] = pRegFrame->cs.Sel; 642 660 … … 660 678 /* Mask away dangerous flags for the trap/interrupt handler. */ 661 679 eflags.u32 &= ~(X86_EFL_TF | X86_EFL_VM | X86_EFL_RF | X86_EFL_NT); 680 #ifdef DEBUG 681 if (DBGFIsStepping(pVCpu)) 682 eflags.u32 |= X86_EFL_TF; 683 #endif 662 684 663 685 /* Turn off interrupts for interrupt gates. */ … … 669 691 #ifdef DEBUG 670 692 for (int j = idx; j < 0; j++) 671 Log 4(("Stack %RRv pos %02d: %08x\n", &pTrapStack[j], j, pTrapStack[j]));693 LogFlow(("Stack %RRv pos %02d: %08x\n", &pTrapStack[j], j, pTrapStack[j])); 672 694 673 695 Log4(("eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\n" -
trunk/src/VBox/VMM/VMMR3/CPUM.cpp
r44399 r45276 42 42 #include <VBox/vmm/pdmapi.h> 43 43 #include <VBox/vmm/mm.h> 44 #include <VBox/vmm/em.h> 44 45 #include <VBox/vmm/selm.h> 45 46 #include <VBox/vmm/dbgf.h> … … 4192 4193 * Are we in Ring-0? 4193 4194 */ 4194 if ( pCtxCore->ss.Sel && (pCtxCore->ss.Sel & X86_SEL_RPL) == 0 4195 if ( pCtxCore->ss.Sel 4196 && (pCtxCore->ss.Sel & X86_SEL_RPL) == 0 4195 4197 && !pCtxCore->eflags.Bits.u1VM) 4196 4198 { … … 4204 4206 */ 4205 4207 pCtxCore->ss.Sel |= 1; 4206 if (pCtxCore->cs.Sel && (pCtxCore->cs.Sel & X86_SEL_RPL) == 0) 4208 if ( pCtxCore->cs.Sel 4209 && (pCtxCore->cs.Sel & X86_SEL_RPL) == 0) 4207 4210 pCtxCore->cs.Sel |= 1; 4208 4211 } 4209 4212 else 4210 4213 { 4214 #ifdef VBOX_WITH_RAW_RING1 4215 if ( EMIsRawRing1Enabled(pVM) 4216 && !pCtxCore->eflags.Bits.u1VM 4217 && (pCtxCore->ss.Sel & X86_SEL_RPL) == 1) 4218 { 4219 /* Set CPL to Ring-2. */ 4220 pCtxCore->ss.Sel = (pCtxCore->ss.Sel & ~X86_SEL_RPL) | 2; 4221 if (pCtxCore->cs.Sel && (pCtxCore->cs.Sel & X86_SEL_RPL) == 1) 4222 pCtxCore->cs.Sel = (pCtxCore->cs.Sel & ~X86_SEL_RPL) | 2; 4223 } 4224 #else 4211 4225 AssertMsg((pCtxCore->ss.Sel & X86_SEL_RPL) >= 2 || pCtxCore->eflags.Bits.u1VM, 4212 4226 ("ring-1 code not supported\n")); 4227 #endif 4213 4228 /* 4214 4229 * PATM takes care of IOPL and IF flags for Ring-3 and Ring-2 code as well. … … 4221 4236 */ 4222 4237 AssertMsg((pCtxCore->eflags.u32 & X86_EFL_IF), ("X86_EFL_IF is clear\n")); 4223 AssertReleaseMsg( pCtxCore->eflags.Bits.u2IOPL < (unsigned)(pCtxCore->ss.Sel & X86_SEL_RPL) 4224 || pCtxCore->eflags.Bits.u1VM, 4238 AssertReleaseMsg(pCtxCore->eflags.Bits.u2IOPL == 0, 4225 4239 ("X86_EFL_IOPL=%d CPL=%d\n", pCtxCore->eflags.Bits.u2IOPL, pCtxCore->ss.Sel & X86_SEL_RPL)); 4226 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)); … … 4231 4245 return VINF_SUCCESS; 4232 4246 } 4247 4233 4248 4234 4249 … … 4300 4315 if (!pCtxCore->eflags.Bits.u1VM) 4301 4316 { 4302 /** @todo See what happens if we remove this. */ 4303 if ((pCtxCore->ds.Sel & X86_SEL_RPL) == 1) 4304 pCtxCore->ds.Sel &= ~X86_SEL_RPL; 4305 if ((pCtxCore->es.Sel & X86_SEL_RPL) == 1) 4306 pCtxCore->es.Sel &= ~X86_SEL_RPL; 4307 if ((pCtxCore->fs.Sel & X86_SEL_RPL) == 1) 4308 pCtxCore->fs.Sel &= ~X86_SEL_RPL; 4309 if ((pCtxCore->gs.Sel & X86_SEL_RPL) == 1) 4310 pCtxCore->gs.Sel &= ~X86_SEL_RPL; 4317 #ifdef VBOX_WITH_RAW_RING1 4318 if ( EMIsRawRing1Enabled(pVM) 4319 && (pCtxCore->ss.Sel & X86_SEL_RPL) == 2) 4320 { 4321 /* Not quite sure if this is really required, but shouldn't harm (too much anyways). */ 4322 /** @todo See what happens if we remove this. */ 4323 if ((pCtxCore->ds.Sel & X86_SEL_RPL) == 2) 4324 pCtxCore->ds.Sel = (pCtxCore->ds.Sel & ~X86_SEL_RPL) | 1; 4325 if ((pCtxCore->es.Sel & X86_SEL_RPL) == 2) 4326 pCtxCore->es.Sel = (pCtxCore->es.Sel & ~X86_SEL_RPL) | 1; 4327 if ((pCtxCore->fs.Sel & X86_SEL_RPL) == 2) 4328 pCtxCore->fs.Sel = (pCtxCore->fs.Sel & ~X86_SEL_RPL) | 1; 4329 if ((pCtxCore->gs.Sel & X86_SEL_RPL) == 2) 4330 pCtxCore->gs.Sel = (pCtxCore->gs.Sel & ~X86_SEL_RPL) | 1; 4331 4332 /* 4333 * Ring-2 selector => Ring-1. 4334 */ 4335 pCtxCore->ss.Sel = (pCtxCore->ss.Sel & ~X86_SEL_RPL) | 1; 4336 if ((pCtxCore->cs.Sel & X86_SEL_RPL) == 2) 4337 pCtxCore->cs.Sel = (pCtxCore->cs.Sel & ~X86_SEL_RPL) | 1; 4338 } 4339 else 4340 { 4341 #endif 4342 /** @todo See what happens if we remove this. */ 4343 if ((pCtxCore->ds.Sel & X86_SEL_RPL) == 1) 4344 pCtxCore->ds.Sel &= ~X86_SEL_RPL; 4345 if ((pCtxCore->es.Sel & X86_SEL_RPL) == 1) 4346 pCtxCore->es.Sel &= ~X86_SEL_RPL; 4347 if ((pCtxCore->fs.Sel & X86_SEL_RPL) == 1) 4348 pCtxCore->fs.Sel &= ~X86_SEL_RPL; 4349 if ((pCtxCore->gs.Sel & X86_SEL_RPL) == 1) 4350 pCtxCore->gs.Sel &= ~X86_SEL_RPL; 4351 #ifdef VBOX_WITH_RAW_RING1 4352 } 4353 #endif 4311 4354 } 4312 4355 } -
trunk/src/VBox/VMM/VMMR3/CSAM.cpp
r44399 r45276 847 847 break; 848 848 849 /* removing breaks win2k guests? */ 850 case OP_IRET: 851 #ifdef VBOX_WITH_RAW_RING1 852 if (EMIsRawRing1Enabled(pVM)) 853 break; 854 #endif 855 /* no break */ 856 849 857 case OP_ILLUD2: 850 858 /* This appears to be some kind of kernel panic in Linux 2.4; no point to continue. */ … … 852 860 case OP_INT3: 853 861 case OP_INVALID: 854 #if 1855 /* removing breaks win2k guests? */856 case OP_IRET:857 #endif858 862 return VINF_SUCCESS; 859 863 } … … 919 923 } 920 924 925 #ifdef VBOX_WITH_RAW_RING1 926 case OP_MOV: 927 /* mov xx, CS is a dangerous instruction as our raw ring usage leaks through. */ 928 if ( EMIsRawRing1Enabled(pVM) 929 && (pCpu->Param2.fUse & DISUSE_REG_SEG) 930 && (pCpu->Param2.Base.idxSegReg == DISSELREG_CS)) 931 { 932 Log(("CSAM: Patching dangerous 'mov xx, cs' instruction at %RGv with an int3\n", pCurInstrGC)); 933 if (PATMR3HasBeenPatched(pVM, pCurInstrGC) == false) 934 { 935 rc = PATMR3InstallPatch(pVM, pCurInstrGC, (pPage->fCode32) ? PATMFL_CODE32 : 0); 936 if (RT_FAILURE(rc)) 937 { 938 Log(("PATMR3InstallPatch failed with %d\n", rc)); 939 return VWRN_CONTINUE_ANALYSIS; 940 } 941 } 942 return VWRN_CONTINUE_ANALYSIS; 943 } 944 break; 945 #endif 946 921 947 case OP_PUSH: 948 /** @todo broken comparison!! should be if ((pCpu->Param1.fUse & DISUSE_REG_SEG) && (pCpu->Param1.Base.idxSegReg == DISSELREG_SS)) */ 922 949 if (pCpu->pCurInstr->fParam1 != OP_PARM_REG_CS) 923 950 break; 924 951 925 952 /* no break */ 953 #ifndef VBOX_WITH_SAFE_STR 926 954 case OP_STR: 955 #endif 927 956 case OP_LSL: 928 957 case OP_LAR: … … 2642 2671 2643 2672 rc = PATMR3InstallPatch(pVM, pHandler, fPatchFlags); 2644 if (RT_SUCCESS(rc) || rc == VERR_PATM_ALREADY_PATCHED) 2673 if ( RT_SUCCESS(rc) 2674 || rc == VERR_PATM_ALREADY_PATCHED) 2645 2675 { 2646 2676 Log(("Gate handler 0x%X is SAFE!\n", iGate)); -
trunk/src/VBox/VMM/VMMR3/DBGFDisas.cpp
r44528 r45276 661 661 RTStrPrintf(szBuf, sizeof(szBuf), "DBGFR3DisasInstrCurrentLog failed with rc=%Rrc\n", rc); 662 662 if (pszPrefix && *pszPrefix) 663 RTLogPrintf("%s-CPU%u: %s\n", pszPrefix, pVCpu->idCpu, szBuf); 663 { 664 if (pVCpu->CTX_SUFF(pVM)->cCpus > 1) 665 RTLogPrintf("%s-CPU%u: %s\n", pszPrefix, pVCpu->idCpu, szBuf); 666 else 667 RTLogPrintf("%s: %s\n", pszPrefix, szBuf); 668 } 664 669 else 665 670 RTLogPrintf("%s\n", szBuf); … … 692 697 RTStrPrintf(szBuf, sizeof(szBuf), "DBGFR3DisasInstrLog(, %RTsel, %RGv) failed with rc=%Rrc\n", Sel, GCPtr, rc); 693 698 if (pszPrefix && *pszPrefix) 694 RTLogPrintf("%s-CPU%u: %s\n", pszPrefix, pVCpu->idCpu, szBuf); 699 { 700 if (pVCpu->CTX_SUFF(pVM)->cCpus > 1) 701 RTLogPrintf("%s-CPU%u: %s\n", pszPrefix, pVCpu->idCpu, szBuf); 702 else 703 RTLogPrintf("%s: %s\n", pszPrefix, szBuf); 704 } 695 705 else 696 706 RTLogPrintf("%s\n", szBuf); -
trunk/src/VBox/VMM/VMMR3/EM.cpp
r45152 r45276 124 124 pVM->fRecompileSupervisor = RT_SUCCESS(rc) ? !fEnabled : false; 125 125 Log(("EMR3Init: fRecompileUser=%RTbool fRecompileSupervisor=%RTbool\n", pVM->fRecompileUser, pVM->fRecompileSupervisor)); 126 127 #ifdef VBOX_WITH_RAW_RING1 128 rc = CFGMR3QueryBool(CFGMR3GetRoot(pVM), "RawR1Enabled", &fEnabled); 129 pVM->fRawRing1Enabled = RT_SUCCESS(rc) ? fEnabled : false; 130 Log(("EMR3Init: fRawRing1Enabled=%RTbool\n", pVM->fRawRing1Enabled)); 131 #else 132 pVM->fRawRing1Enabled = false; /* disabled by default. */ 133 #endif 126 134 127 135 #ifdef VBOX_WITH_REM … … 268 276 EM_REG_COUNTER_USED(&pStats->StatRZLmsw, "/EM/CPU%d/RZ/Interpret/Success/Lmsw", "The number of times LMSW was successfully interpreted."); 269 277 EM_REG_COUNTER_USED(&pStats->StatR3Lmsw, "/EM/CPU%d/R3/Interpret/Success/Lmsw", "The number of times LMSW was successfully interpreted."); 278 EM_REG_COUNTER_USED(&pStats->StatRZSmsw, "/EM/CPU%d/RZ/Interpret/Success/Smsw", "The number of times SMSW was successfully interpreted."); 279 EM_REG_COUNTER_USED(&pStats->StatR3Smsw, "/EM/CPU%d/R3/Interpret/Success/Smsw", "The number of times SMSW was successfully interpreted."); 270 280 271 281 EM_REG_COUNTER(&pStats->StatRZInterpretFailed, "/EM/CPU%d/RZ/Interpret/Failed", "The number of times an instruction was not interpreted."); … … 322 332 EM_REG_COUNTER_USED(&pStats->StatRZFailedLmsw, "/EM/CPU%d/RZ/Interpret/Failed/Lmsw", "The number of times LMSW was not interpreted."); 323 333 EM_REG_COUNTER_USED(&pStats->StatR3FailedLmsw, "/EM/CPU%d/R3/Interpret/Failed/Lmsw", "The number of times LMSW was not interpreted."); 334 EM_REG_COUNTER_USED(&pStats->StatRZFailedSmsw, "/EM/CPU%d/RZ/Interpret/Failed/Smsw", "The number of times SMSW was not interpreted."); 335 EM_REG_COUNTER_USED(&pStats->StatR3FailedSmsw, "/EM/CPU%d/R3/Interpret/Failed/Smsw", "The number of times SMSW was not interpreted."); 324 336 325 337 EM_REG_COUNTER_USED(&pStats->StatRZFailedMisc, "/EM/CPU%d/RZ/Interpret/Failed/Misc", "The number of times some misc instruction was encountered."); … … 938 950 static int emR3RemStep(PVM pVM, PVMCPU pVCpu) 939 951 { 940 Log Flow(("emR3RemStep: cs:eip=%04x:%08x\n", CPUMGetGuestCS(pVCpu), CPUMGetGuestEIP(pVCpu)));952 Log3(("emR3RemStep: cs:eip=%04x:%08x\n", CPUMGetGuestCS(pVCpu), CPUMGetGuestEIP(pVCpu))); 941 953 942 954 #ifdef VBOX_WITH_REM … … 958 970 #endif 959 971 960 Log Flow(("emR3RemStep: returns %Rrc cs:eip=%04x:%08x\n", rc, CPUMGetGuestCS(pVCpu), CPUMGetGuestEIP(pVCpu)));972 Log3(("emR3RemStep: returns %Rrc cs:eip=%04x:%08x\n", rc, CPUMGetGuestCS(pVCpu), CPUMGetGuestEIP(pVCpu))); 961 973 return rc; 962 974 } … … 1182 1194 { 1183 1195 DBGFR3PrgStep(pVCpu); 1184 DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, "RSS :");1196 DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, "RSS"); 1185 1197 emR3RemStep(pVM, pVCpu); 1186 1198 if (emR3Reschedule(pVM, pVCpu, pVCpu->em.s.pCtx) != EMSTATE_REM) … … 1308 1320 return EMSTATE_REM; 1309 1321 1322 # ifdef VBOX_WITH_RAW_RING1 1323 /* Only ring 0 and 1 supervisor code. */ 1324 if (EMIsRawRing1Enabled(pVM)) 1325 { 1326 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 { 1328 Log2(("raw r0 mode refused: CPL %d\n", uSS & X86_SEL_RPL)); 1329 return EMSTATE_REM; 1330 } 1331 } 1332 else 1333 # endif 1310 1334 /* Only ring 0 supervisor code. */ 1311 1335 if ((uSS & X86_SEL_RPL) != 0) … … 1334 1358 { 1335 1359 Log2(("raw r0 mode forced: patch code\n")); 1360 # ifdef VBOX_WITH_SAFE_STR 1361 Assert(pCtx->tr.Sel); 1362 # endif 1336 1363 return EMSTATE_RAW; 1337 1364 } … … 1346 1373 # endif 1347 1374 1375 # ifndef VBOX_WITH_RAW_RING1 1348 1376 /** @todo still necessary??? */ 1349 1377 if (EFlags.Bits.u2IOPL != 0) … … 1352 1380 return EMSTATE_REM; 1353 1381 } 1382 # endif 1354 1383 } 1355 1384 … … 1387 1416 return EMSTATE_REM; 1388 1417 } 1418 1419 # ifdef VBOX_WITH_SAFE_STR 1420 if (pCtx->tr.Sel == 0) 1421 { 1422 Log(("Raw mode refused -> TR=0\n")); 1423 return EMSTATE_REM; 1424 } 1425 # endif 1389 1426 1390 1427 /*Assert(PGMPhysIsA20Enabled(pVCpu));*/ -
trunk/src/VBox/VMM/VMMR3/EMHM.cpp
r44528 r45276 137 137 { 138 138 DBGFR3PrgStep(pVCpu); 139 DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, "RSS :");139 DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, "RSS"); 140 140 rc = emR3HmStep(pVM, pVCpu); 141 141 if ( rc != VINF_SUCCESS -
trunk/src/VBox/VMM/VMMR3/EMRaw.cpp
r44399 r45276 159 159 PCPUMCTX pCtx = pVCpu->em.s.pCtx; 160 160 bool fGuest = pVCpu->em.s.enmState != EMSTATE_DEBUG_HYPER; 161 #ifndef DEBUG_sander vl161 #ifndef DEBUG_sander 162 162 Log(("emR3RawStep: cs:eip=%RTsel:%RGr efl=%RGr\n", fGuest ? CPUMGetGuestCS(pVCpu) : CPUMGetHyperCS(pVCpu), 163 163 fGuest ? CPUMGetGuestEIP(pVCpu) : CPUMGetHyperEIP(pVCpu), fGuest ? CPUMGetGuestEFlags(pVCpu) : CPUMGetHyperEFlags(pVCpu))); … … 196 196 else 197 197 rc = VMMR3RawRunGC(pVM, pVCpu); 198 #ifndef DEBUG_sander vl198 #ifndef DEBUG_sander 199 199 Log(("emR3RawStep: cs:eip=%RTsel:%RGr efl=%RGr - GC rc %Rrc\n", fGuest ? CPUMGetGuestCS(pVCpu) : CPUMGetHyperCS(pVCpu), 200 200 fGuest ? CPUMGetGuestEIP(pVCpu) : CPUMGetHyperEIP(pVCpu), fGuest ? CPUMGetGuestEFlags(pVCpu) : CPUMGetHyperEFlags(pVCpu), rc)); … … 237 237 { 238 238 DBGFR3PrgStep(pVCpu); 239 DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, "RSS :");239 DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, "RSS"); 240 240 rc = emR3RawStep(pVM, pVCpu); 241 if (rc != VINF_SUCCESS) 241 if ( rc != VINF_SUCCESS 242 && rc != VINF_EM_DBG_STEPPED) 242 243 break; 243 244 } … … 950 951 { 951 952 DBGFR3_INFO_LOG(pVM, "cpumguest", "PRIV"); 952 DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, "Privileged instr :");953 DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, "Privileged instr"); 953 954 } 954 955 #endif … … 1090 1091 { 1091 1092 DBGFR3_INFO_LOG(pVM, "cpumguest", "PRIV"); 1092 DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, "Privileged instr :");1093 DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, "Privileged instr"); 1093 1094 } 1094 1095 #endif … … 1361 1362 Assert(REMR3QueryPendingInterrupt(pVM, pVCpu) == REM_NO_PENDING_IRQ); 1362 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 1363 1367 Assert(pCtx->eflags.Bits.u1VM || (pCtx->ss.Sel & X86_SEL_RPL) == 3 || (pCtx->ss.Sel & X86_SEL_RPL) == 0); 1368 # endif 1364 1369 AssertMsg( (pCtx->eflags.u32 & X86_EFL_IF) 1365 1370 || PATMShouldUseRawMode(pVM, (RTGCPTR)pCtx->eip), … … 1429 1434 Log(("RV86: %04x:%08x IF=%d VMFlags=%x\n", pCtx->cs.Sel, pCtx->eip, pCtx->eflags.Bits.u1IF, pGCState->uVMFlags)); 1430 1435 else if ((pCtx->ss.Sel & X86_SEL_RPL) == 1) 1431 Log(("RR0: % 08x ESP=%08x EFL=%x IF=%d/%d VMFlags=%x PIF=%d CPL=%d (Scanned=%d)\n",1432 pCtx-> eip, pCtx->esp, CPUMRawGetEFlags(pVCpu), !!(pGCState->uVMFlags & X86_EFL_IF), pCtx->eflags.Bits.u1IF,1436 Log(("RR0: %x:%08x ESP=%x:%08x EFL=%x IF=%d/%d VMFlags=%x PIF=%d CPL=%d (Scanned=%d)\n", 1437 pCtx->cs.Sel, pCtx->eip, pCtx->ss.Sel, pCtx->esp, CPUMRawGetEFlags(pVCpu), !!(pGCState->uVMFlags & X86_EFL_IF), pCtx->eflags.Bits.u1IF, 1433 1438 pGCState->uVMFlags, pGCState->fPIF, (pCtx->ss.Sel & X86_SEL_RPL), CSAMIsPageScanned(pVM, (RTGCPTR)pCtx->eip))); 1439 # ifdef VBOX_WITH_RAW_RING1 1440 else if ((pCtx->ss.Sel & X86_SEL_RPL) == 2) 1441 Log(("RR1: %x:%08x ESP=%x:%08x IF=%d VMFlags=%x CPL=%x\n", pCtx->cs.Sel, pCtx->eip, pCtx->ss.Sel, pCtx->esp, pCtx->eflags.Bits.u1IF, pGCState->uVMFlags, (pCtx->ss.Sel & X86_SEL_RPL))); 1442 # endif 1434 1443 else if ((pCtx->ss.Sel & X86_SEL_RPL) == 3) 1435 Log(("RR3: % 08x ESP=%08x IF=%d VMFlags=%x\n", pCtx->eip, pCtx->esp, pCtx->eflags.Bits.u1IF, pGCState->uVMFlags));1444 Log(("RR3: %x:%08x ESP=%x:%08x IF=%d VMFlags=%x\n", pCtx->cs.Sel, pCtx->eip, pCtx->ss.Sel, pCtx->esp, pCtx->eflags.Bits.u1IF, pGCState->uVMFlags)); 1436 1445 #endif /* LOG_ENABLED */ 1437 1438 1446 1439 1447 … … 1543 1551 || VMCPU_FF_ISPENDING(pVCpu, ~VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK)) 1544 1552 { 1545 Assert(pCtx->eflags.Bits.u1VM || ( pCtx->ss.Sel & X86_SEL_RPL) != 1);1553 Assert(pCtx->eflags.Bits.u1VM || (EMIsRawRing1Enabled(pVM) ? ((pCtx->ss.Sel & X86_SEL_RPL) != 2) : ((pCtx->ss.Sel & X86_SEL_RPL) != 1))); 1546 1554 1547 1555 STAM_REL_PROFILE_ADV_SUSPEND(&pVCpu->em.s.StatRAWTotal, a); -
trunk/src/VBox/VMM/VMMR3/PATM.cpp
r44399 r45276 1535 1535 break; 1536 1536 1537 #ifdef VBOX_WITH_SAFE_STR /* @todo remove DISOPTYPE_PRIVILEGED_NOTRAP from disasm table */ 1538 case OP_STR: 1539 break; 1540 #endif 1541 1537 1542 default: 1538 1543 if (pCpu->pCurInstr->fOpType & (DISOPTYPE_PRIVILEGED_NOTRAP)) … … 1645 1650 case OP_RETN: 1646 1651 return VINF_SUCCESS; 1652 1653 #ifdef VBOX_WITH_SAFE_STR /* @todo remove DISOPTYPE_PRIVILEGED_NOTRAP from disasm table */ 1654 case OP_STR: 1655 break; 1656 #endif 1647 1657 1648 1658 case OP_POPF: … … 1806 1816 1807 1817 case OP_POP: 1818 /** @todo broken comparison!! should be if ((pCpu->Param1.fUse & DISUSE_REG_SEG) && (pCpu->Param1.Base.idxSegReg == DISSELREG_SS)) */ 1808 1819 if (pCpu->pCurInstr->fParam1 == OP_PARM_REG_SS) 1809 1820 { … … 1913 1924 1914 1925 case OP_PUSH: 1926 /** @todo broken comparison!! should be if ((pCpu->Param1.fUse & DISUSE_REG_SEG) && (pCpu->Param1.Base.idxSegReg == DISSELREG_SS)) */ 1915 1927 if (pCpu->pCurInstr->fParam1 == OP_PARM_REG_CS) 1916 1928 { … … 1947 1959 1948 1960 case OP_STR: 1961 #ifdef VBOX_WITH_SAFE_STR /* @todo remove DISOPTYPE_PRIVILEGED_NOTRAP from disasm table and move OP_STR into #ifndef */ 1962 /* Now safe because our shadow TR entry is identical to the guest's. */ 1963 goto duplicate_instr; 1964 #endif 1949 1965 case OP_SLDT: 1950 1966 rc = patmPatchGenSldtStr(pVM, pPatch, pCpu, pCurInstrGC); … … 4442 4458 break; 4443 4459 4460 #ifndef VBOX_WITH_SAFE_STR 4444 4461 case OP_STR: 4462 #endif 4445 4463 case OP_SGDT: 4446 4464 case OP_SLDT: … … 4453 4471 case OP_VERR: 4454 4472 case OP_IRET: 4473 #ifdef VBOX_WITH_RAW_RING1 4474 case OP_MOV: 4475 #endif 4455 4476 rc = patmR3PatchInstrInt3(pVM, pInstrGC, pInstrHC, &cpu, &pPatchRec->patch); 4456 4477 break; -
trunk/src/VBox/VMM/VMMR3/PATMA.asm
r44528 r45276 1262 1262 1263 1263 ; force ring 1 CS RPL 1264 or dword [esp+8], 1 1264 or dword [esp+8], 1 ;-> @todo we leave traces or raw mode if we jump back to the host context to handle pending interrupts! (below) 1265 1265 iret_notring0: 1266 1266 … … 1443 1443 DD PATM_FIXUP 1444 1444 DD PATMIretTable - PATMIretStart 1445 DD PATM_IRET_FUNCTION 1446 DD 0 1447 DD PATM_VMFLAGS 1448 DD 0 1449 DD PATM_VMFLAGS 1450 DD 0 1451 DD PATM_VMFLAGS 1452 DD 0 1453 DD PATM_TEMP_EAX 1454 DD 0 1455 DD PATM_TEMP_ECX 1456 DD 0 1457 DD PATM_TEMP_RESTORE_FLAGS 1458 DD 0 1459 DD PATM_PENDINGACTION 1460 DD 0 1461 DD 0ffffffffh 1462 SECTION .text 1463 1464 ;;**************************************************** 1465 ;; Abstract: 1466 ;; 1467 ;; if eflags.NT==0 && iretstack.eflags.VM==0 && iretstack.eflags.IOPL==0 1468 ;; then 1469 ;; if return to ring 0 (iretstack.new_cs & 3 == 0) 1470 ;; then 1471 ;; if iretstack.new_eflags.IF == 1 && iretstack.new_eflags.IOPL == 0 1472 ;; then 1473 ;; iretstack.new_cs |= 1 1474 ;; else 1475 ;; int 3 1476 ;; endif 1477 ;; uVMFlags &= ~X86_EFL_IF 1478 ;; iret 1479 ;; else 1480 ;; int 3 1481 ;;**************************************************** 1482 ;; 1483 ; Stack: 1484 ; 1485 ; esp + 32 - GS (V86 only) 1486 ; esp + 28 - FS (V86 only) 1487 ; esp + 24 - DS (V86 only) 1488 ; esp + 20 - ES (V86 only) 1489 ; esp + 16 - SS (if transfer to outer ring) 1490 ; esp + 12 - ESP (if transfer to outer ring) 1491 ; esp + 8 - EFLAGS 1492 ; esp + 4 - CS 1493 ; esp - EIP 1494 ;; 1495 BEGINPROC PATMIretRing1Replacement 1496 PATMIretRing1Start: 1497 mov dword [ss:PATM_INTERRUPTFLAG], 0 1498 pushfd 1499 1500 %ifdef PATM_LOG_PATCHIRET 1501 push eax 1502 push ecx 1503 push edx 1504 lea edx, dword [ss:esp+12+4] ;3 dwords + pushed flags -> iret eip 1505 mov eax, PATM_ACTION_LOG_IRET 1506 lock or dword [ss:PATM_PENDINGACTION], eax 1507 mov ecx, PATM_ACTION_MAGIC 1508 db 0fh, 0bh ; illegal instr (hardcoded assumption in PATMHandleIllegalInstrTrap) 1509 pop edx 1510 pop ecx 1511 pop eax 1512 %endif 1513 1514 test dword [esp], X86_EFL_NT 1515 jnz near iretring1_fault1 1516 1517 ; we can't do an iret to v86 code, as we run with CPL=1. The iret would attempt a protected mode iret and (most likely) fault. 1518 test dword [esp+12], X86_EFL_VM 1519 jnz near iretring1_return_to_v86 1520 1521 ;;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 1522 ;;@todo: not correct for iret back to ring 2!!!!! 1523 ;;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 1524 1525 test dword [esp+8], 2 1526 jnz iretring1_checkpendingirq 1527 1528 test dword [esp+12], X86_EFL_IF 1529 jz near iretring1_clearIF 1530 1531 iretring1_checkpendingirq: 1532 1533 ; if interrupts are pending, then we must go back to the host context to handle them! 1534 ; Note: This is very important as pending pic interrupts can be overridden by apic interrupts if we don't check early enough (Fedora 5 boot) 1535 ; @@todo fix this properly, so we can dispatch pending interrupts in GC 1536 test dword [ss:PATM_VM_FORCEDACTIONS], VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC 1537 jz iretring1_continue 1538 1539 ; Go to our hypervisor trap handler to dispatch the pending irq 1540 mov dword [ss:PATM_TEMP_EAX], eax 1541 mov dword [ss:PATM_TEMP_ECX], ecx 1542 mov dword [ss:PATM_TEMP_EDI], edi 1543 mov dword [ss:PATM_TEMP_RESTORE_FLAGS], PATM_RESTORE_EAX | PATM_RESTORE_ECX | PATM_RESTORE_EDI 1544 mov eax, PATM_ACTION_PENDING_IRQ_AFTER_IRET 1545 lock or dword [ss:PATM_PENDINGACTION], eax 1546 mov ecx, PATM_ACTION_MAGIC 1547 mov edi, PATM_CURINSTRADDR 1548 1549 popfd 1550 db 0fh, 0bh ; illegal instr (hardcoded assumption in PATMHandleIllegalInstrTrap) 1551 ; does not return 1552 1553 iretring1_continue: 1554 1555 test dword [esp+8], 2 1556 jnz iretring1_notring01 1557 1558 test dword [esp+8], 1 1559 jz iretring1_ring0 1560 1561 ; ring 1 return change CS & SS RPL to 2 from 1 1562 and dword [esp+8], ~1 ; CS 1563 or dword [esp+8], 2 1564 1565 and dword [esp+20], ~1 ; SS 1566 or dword [esp+20], 2 1567 1568 jmp short iretring1_notring01 1569 iretring1_ring0: 1570 ; force ring 1 CS RPL 1571 or dword [esp+8], 1 1572 1573 iretring1_notring01: 1574 ; This section must *always* be executed (!!) 1575 ; Extract the IOPL from the return flags, save them to our virtual flags and 1576 ; put them back to zero 1577 ; @note we assume iretd doesn't fault!!! 1578 push eax 1579 mov eax, dword [esp+16] 1580 and eax, X86_EFL_IOPL 1581 and dword [ss:PATM_VMFLAGS], ~X86_EFL_IOPL 1582 or dword [ss:PATM_VMFLAGS], eax 1583 pop eax 1584 and dword [esp+12], ~X86_EFL_IOPL 1585 1586 ; Set IF again; below we make sure this won't cause problems. 1587 or dword [ss:PATM_VMFLAGS], X86_EFL_IF 1588 1589 ; make sure iret is executed fully (including the iret below; cli ... iret can otherwise be interrupted) 1590 mov dword [ss:PATM_INHIBITIRQADDR], PATM_CURINSTRADDR 1591 1592 popfd 1593 mov dword [ss:PATM_INTERRUPTFLAG], 1 1594 iretd 1595 PATM_INT3 1596 1597 iretring1_fault: 1598 popfd 1599 mov dword [ss:PATM_INTERRUPTFLAG], 1 1600 PATM_INT3 1601 1602 iretring1_fault1: 1603 nop 1604 popfd 1605 mov dword [ss:PATM_INTERRUPTFLAG], 1 1606 PATM_INT3 1607 1608 iretring1_clearIF: 1609 push dword [esp+4] ; eip to return to 1610 pushfd 1611 push eax 1612 push PATM_FIXUP 1613 DB 0E8h ; call 1614 DD PATM_IRET_FUNCTION 1615 add esp, 4 ; pushed address of jump table 1616 1617 cmp eax, 0 1618 je near iretring1_fault3 1619 1620 mov dword [esp+12+4], eax ; stored eip in iret frame 1621 pop eax 1622 popfd 1623 add esp, 4 ; pushed eip 1624 1625 ; This section must *always* be executed (!!) 1626 ; Extract the IOPL from the return flags, save them to our virtual flags and 1627 ; put them back to zero 1628 push eax 1629 mov eax, dword [esp+16] 1630 and eax, X86_EFL_IOPL 1631 and dword [ss:PATM_VMFLAGS], ~X86_EFL_IOPL 1632 or dword [ss:PATM_VMFLAGS], eax 1633 pop eax 1634 and dword [esp+12], ~X86_EFL_IOPL 1635 1636 ; Clear IF 1637 and dword [ss:PATM_VMFLAGS], ~X86_EFL_IF 1638 popfd 1639 1640 test dword [esp+8], 1 1641 jz iretring1_clearIF_ring0 1642 1643 ; ring 1 return change CS & SS RPL to 2 from 1 1644 and dword [esp+8], ~1 ; CS 1645 or dword [esp+8], 2 1646 1647 and dword [esp+20], ~1 ; SS 1648 or dword [esp+20], 2 1649 ; the patched destination code will set PATM_INTERRUPTFLAG after the return! 1650 iretd 1651 1652 iretring1_clearIF_ring0: 1653 ; force ring 1 CS RPL 1654 or dword [esp+8], 1 1655 ; the patched destination code will set PATM_INTERRUPTFLAG after the return! 1656 iretd 1657 1658 iretring1_return_to_v86: 1659 test dword [esp+12], X86_EFL_IF 1660 jz iretring1_fault 1661 1662 ; Go to our hypervisor trap handler to perform the iret to v86 code 1663 mov dword [ss:PATM_TEMP_EAX], eax 1664 mov dword [ss:PATM_TEMP_ECX], ecx 1665 mov dword [ss:PATM_TEMP_RESTORE_FLAGS], PATM_RESTORE_EAX | PATM_RESTORE_ECX 1666 mov eax, PATM_ACTION_DO_V86_IRET 1667 lock or dword [ss:PATM_PENDINGACTION], eax 1668 mov ecx, PATM_ACTION_MAGIC 1669 1670 popfd 1671 1672 db 0fh, 0bh ; illegal instr (hardcoded assumption in PATMHandleIllegalInstrTrap) 1673 ; does not return 1674 1675 1676 iretring1_fault3: 1677 pop eax 1678 popfd 1679 add esp, 4 ; pushed eip 1680 jmp iretring1_fault 1681 1682 align 4 1683 PATMIretRing1Table: 1684 DW PATM_MAX_JUMPTABLE_ENTRIES ; nrSlots 1685 DW 0 ; ulInsertPos 1686 DD 0 ; cAddresses 1687 TIMES PATCHJUMPTABLE_SIZE DB 0 ; lookup slots 1688 1689 PATMIretRing1End: 1690 ENDPROC PATMIretRing1Replacement 1691 1692 SECTION .data 1693 ; Patch record for 'iretd' 1694 GLOBALNAME PATMIretRing1Record 1695 RTCCPTR_DEF PATMIretRing1Start 1696 DD 0 1697 DD 0 1698 DD 0 1699 DD PATMIretRing1End- PATMIretRing1Start 1700 %ifdef PATM_LOG_PATCHIRET 1701 DD 26 1702 %else 1703 DD 25 1704 %endif 1705 DD PATM_INTERRUPTFLAG 1706 DD 0 1707 %ifdef PATM_LOG_PATCHIRET 1708 DD PATM_PENDINGACTION 1709 DD 0 1710 %endif 1711 DD PATM_VM_FORCEDACTIONS 1712 DD 0 1713 DD PATM_TEMP_EAX 1714 DD 0 1715 DD PATM_TEMP_ECX 1716 DD 0 1717 DD PATM_TEMP_EDI 1718 DD 0 1719 DD PATM_TEMP_RESTORE_FLAGS 1720 DD 0 1721 DD PATM_PENDINGACTION 1722 DD 0 1723 DD PATM_CURINSTRADDR 1724 DD 0 1725 DD PATM_VMFLAGS 1726 DD 0 1727 DD PATM_VMFLAGS 1728 DD 0 1729 DD PATM_VMFLAGS 1730 DD 0 1731 DD PATM_INHIBITIRQADDR 1732 DD 0 1733 DD PATM_CURINSTRADDR 1734 DD 0 1735 DD PATM_INTERRUPTFLAG 1736 DD 0 1737 DD PATM_INTERRUPTFLAG 1738 DD 0 1739 DD PATM_INTERRUPTFLAG 1740 DD 0 1741 DD PATM_FIXUP 1742 DD PATMIretRing1Table - PATMIretRing1Start 1445 1743 DD PATM_IRET_FUNCTION 1446 1744 DD 0 -
trunk/src/VBox/VMM/VMMR3/PATMPatch.cpp
r44528 r45276 27 27 #include <VBox/vmm/cpum.h> 28 28 #include <VBox/vmm/mm.h> 29 #include <VBox/vmm/em.h> 29 30 #include <VBox/vmm/trpm.h> 30 31 #include <VBox/param.h> … … 436 437 437 438 AssertMsg(fSizeOverride == false, ("operand size override!!\n")); 438 439 439 callInfo.pCurInstrGC = pCurInstrGC; 440 440 441 size = patmPatchGenCode(pVM, pPatch, pPB, &PATMIretRecord, 0, false, &callInfo); 441 #ifdef VBOX_WITH_RAW_RING1 442 if (EMIsRawRing1Enabled(pVM)) 443 { 444 size = patmPatchGenCode(pVM, pPatch, pPB, &PATMIretRing1Record, 0, false, &callInfo); 445 } 446 else 447 #endif 448 size = patmPatchGenCode(pVM, pPatch, pPB, &PATMIretRecord, 0, false, &callInfo); 442 449 443 450 PATCHGEN_EPILOG(pPatch, size); … … 1074 1081 int patmPatchGenIntEntry(PVM pVM, PPATCHINFO pPatch, RTRCPTR pIntHandlerGC) 1075 1082 { 1076 uint32_t size;1077 1083 int rc = VINF_SUCCESS; 1078 1084 1079 PATCHGEN_PROLOG(pVM, pPatch); 1080 1081 /* Add lookup record for patch to guest address translation */ 1082 patmR3AddP2GLookupRecord(pVM, pPatch, pPB, pIntHandlerGC, PATM_LOOKUP_PATCH2GUEST); 1083 1084 /* Generate entrypoint for the interrupt handler (correcting CS in the interrupt stack frame) */ 1085 size = patmPatchGenCode(pVM, pPatch, pPB, 1086 (pPatch->flags & PATMFL_INTHANDLER_WITH_ERRORCODE) ? &PATMIntEntryRecordErrorCode : &PATMIntEntryRecord, 1087 0, false); 1088 1089 PATCHGEN_EPILOG(pPatch, size); 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 1089 uint32_t size; 1090 PATCHGEN_PROLOG(pVM, pPatch); 1091 1092 /* Add lookup record for patch to guest address translation */ 1093 patmR3AddP2GLookupRecord(pVM, pPatch, pPB, pIntHandlerGC, PATM_LOOKUP_PATCH2GUEST); 1094 1095 /* Generate entrypoint for the interrupt handler (correcting CS in the interrupt stack frame) */ 1096 size = patmPatchGenCode(pVM, pPatch, pPB, 1097 (pPatch->flags & PATMFL_INTHANDLER_WITH_ERRORCODE) ? &PATMIntEntryRecordErrorCode : &PATMIntEntryRecord, 1098 0, false); 1099 1100 PATCHGEN_EPILOG(pPatch, size); 1101 #ifdef VBOX_WITH_RAW_RING1 1102 } 1103 #endif 1090 1104 1091 1105 // Interrupt gates set IF to 0 … … 1107 1121 { 1108 1122 uint32_t size; 1123 1124 Assert(!EMIsRawRing1Enabled(pVM)); 1109 1125 1110 1126 PATCHGEN_PROLOG(pVM, pPatch); -
trunk/src/VBox/VMM/VMMR3/PATMSSM.cpp
r44528 r45276 810 810 patmR3PatchConvertSSM2Mem(pPatchRec, &patch); 811 811 812 Log(("Restoring patch %RRv -> %RRv \n", pPatchRec->patch.pPrivInstrGC, patmInfo.pPatchMemGC + pPatchRec->patch.pPatchBlockOffset));812 Log(("Restoring patch %RRv -> %RRv state %x\n", pPatchRec->patch.pPrivInstrGC, patmInfo.pPatchMemGC + pPatchRec->patch.pPatchBlockOffset, pPatchRec->patch.uState)); 813 813 bool ret = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTree, &pPatchRec->Core); 814 814 Assert(ret); -
trunk/src/VBox/VMM/VMMR3/PGMHandler.cpp
r44528 r45276 494 494 { 495 495 pgmUnlock(pVM); 496 #ifndef DEBUG_sander 496 497 AssertMsgFailed(("Range %#x not found!\n", GCPtr)); 498 #endif 497 499 return VERR_INVALID_PARAMETER; 498 500 } -
trunk/src/VBox/VMM/VMMR3/SELM.cpp
r44528 r45276 80 80 #include <iprt/string.h> 81 81 82 83 /**84 * Enable or disable tracking of Shadow GDT/LDT/TSS.85 * @{86 */87 #define SELM_TRACK_SHADOW_GDT_CHANGES88 #define SELM_TRACK_SHADOW_LDT_CHANGES89 #define SELM_TRACK_SHADOW_TSS_CHANGES90 /** @} */91 82 92 83 … … 565 556 * Uninstall guest GDT/LDT/TSS write access handlers. 566 557 */ 567 int rc ;558 int rc = VINF_SUCCESS; 568 559 if (pVM->selm.s.GuestGdtr.pGdt != RTRCPTR_MAX && pVM->selm.s.fGDTRangeRegistered) 569 560 { 561 #ifdef SELM_TRACK_GUEST_GDT_CHANGES 570 562 rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.GuestGdtr.pGdt); 571 563 AssertRC(rc); 564 #endif 572 565 pVM->selm.s.GuestGdtr.pGdt = RTRCPTR_MAX; 573 566 pVM->selm.s.GuestGdtr.cbGdt = 0; … … 576 569 if (pVM->selm.s.GCPtrGuestLdt != RTRCPTR_MAX) 577 570 { 571 #ifdef SELM_TRACK_GUEST_LDT_CHANGES 578 572 rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.GCPtrGuestLdt); 579 573 AssertRC(rc); 574 #endif 580 575 pVM->selm.s.GCPtrGuestLdt = RTRCPTR_MAX; 581 576 } 582 577 if (pVM->selm.s.GCPtrGuestTss != RTRCPTR_MAX) 583 578 { 579 #ifdef SELM_TRACK_GUEST_TSS_CHANGES 584 580 rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.GCPtrGuestTss); 585 581 AssertRC(rc); 582 #endif 586 583 pVM->selm.s.GCPtrGuestTss = RTRCPTR_MAX; 587 584 pVM->selm.s.GCSelTss = RTSEL_MAX; … … 619 616 if (pVM->selm.s.GuestGdtr.pGdt != RTRCPTR_MAX && pVM->selm.s.fGDTRangeRegistered) 620 617 { 618 #ifdef SELM_TRACK_GUEST_GDT_CHANGES 621 619 rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.GuestGdtr.pGdt); 622 620 AssertRC(rc); 621 #endif 623 622 pVM->selm.s.GuestGdtr.pGdt = RTRCPTR_MAX; 624 623 pVM->selm.s.GuestGdtr.cbGdt = 0; … … 627 626 if (pVM->selm.s.GCPtrGuestLdt != RTRCPTR_MAX) 628 627 { 628 #ifdef SELM_TRACK_GUEST_LDT_CHANGES 629 629 rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.GCPtrGuestLdt); 630 630 AssertRC(rc); 631 #endif 631 632 pVM->selm.s.GCPtrGuestLdt = RTRCPTR_MAX; 632 633 } 633 634 if (pVM->selm.s.GCPtrGuestTss != RTRCPTR_MAX) 634 635 { 636 #ifdef SELM_TRACK_GUEST_TSS_CHANGES 635 637 rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.GCPtrGuestTss); 636 638 AssertRC(rc); 639 #endif 637 640 pVM->selm.s.GCPtrGuestTss = RTRCPTR_MAX; 638 641 pVM->selm.s.GCSelTss = RTSEL_MAX; … … 953 956 } 954 957 958 #ifdef VBOX_WITH_SAFE_STR 959 /** Use the guest's TR selector to plug the str virtualization hole. */ 960 if (CPUMGetGuestTR(pVCpu, NULL) != 0) 961 { 962 Log(("SELM: Use guest TSS selector %x\n", CPUMGetGuestTR(pVCpu, NULL))); 963 aHyperSel[SELM_HYPER_SEL_TSS] = CPUMGetGuestTR(pVCpu, NULL); 964 } 965 #endif 966 955 967 /* 956 968 * Work thru the copied GDT entries adjusting them for correct virtualization. … … 960 972 { 961 973 if (pGDTE->Gen.u1Present) 962 selmGuestToShadowDesc(p GDTE);974 selmGuestToShadowDesc(pVM, pGDTE); 963 975 964 976 /* Next GDT entry. */ … … 990 1002 VMR3Relocate(pVM, 0); 991 1003 } 992 else if (cbEffLimit >= SELM_HYPER_DEFAULT_BASE) 1004 else 1005 #ifdef VBOX_WITH_SAFE_STR 1006 if ( cbEffLimit >= SELM_HYPER_DEFAULT_BASE 1007 || CPUMGetGuestTR(pVCpu, NULL) != 0) /* Our shadow TR entry was overwritten when we synced the guest's GDT. */ 1008 #else 1009 if (cbEffLimit >= SELM_HYPER_DEFAULT_BASE) 1010 #endif 993 1011 /* We overwrote all entries above, so we have to save them again. */ 994 1012 selmR3SetupHyperGDTSelectors(pVM); … … 1011 1029 { 1012 1030 Log(("SELMR3UpdateFromCPUM: Guest's GDT is changed to pGdt=%016RX64 cbGdt=%08X\n", GDTR.pGdt, GDTR.cbGdt)); 1013 1031 #ifdef SELM_TRACK_GUEST_GDT_CHANGES 1014 1032 /* 1015 1033 * [Re]Register write virtual handler for guest's GDT. … … 1025 1043 0, selmR3GuestGDTWriteHandler, "selmRCGuestGDTWriteHandler", 0, 1026 1044 "Guest GDT write access handler"); 1045 # 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 */ 1050 if (rc == VERR_PGM_HANDLER_VIRTUAL_CONFLICT) 1051 { 1052 LogRel(("selmR3UpdateShadowGdt: Virtual handler conflict %RGv -> kick out PATM handler for the higher priority GDT page monitor\n", GDTR.pGdt)); 1053 rc = PGMHandlerVirtualDeregister(pVM, GDTR.pGdt & PAGE_BASE_GC_MASK); 1054 AssertRC(rc); 1055 1056 rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_WRITE, 1057 GDTR.pGdt, GDTR.pGdt + GDTR.cbGdt /* already inclusive */, 1058 0, selmR3GuestGDTWriteHandler, "selmRCGuestGDTWriteHandler", 0, 1059 "Guest GDT write access handler"); 1060 } 1061 # endif 1027 1062 if (RT_FAILURE(rc)) 1028 1063 return rc; 1029 1064 #endif 1030 1065 /* Update saved Guest GDTR. */ 1031 1066 pVM->selm.s.GuestGdtr = GDTR; … … 1137 1172 pVM->selm.s.GCPtrGuestLdt, pVM->selm.s.cbLdtLimit, GCPtrLdt, cbLdt, pVM->selm.s.GuestGdtr.pGdt, pVM->selm.s.GuestGdtr.cbGdt)); 1138 1173 1174 #ifdef SELM_TRACK_GUEST_LDT_CHANGES 1139 1175 /* 1140 1176 * [Re]Register write virtual handler for guest's GDT. … … 1146 1182 AssertRC(rc); 1147 1183 } 1148 # ifdef DEBUG1184 # ifdef DEBUG 1149 1185 if (pDesc->Gen.u1Present) 1150 1186 Log(("LDT selector marked not present!!\n")); 1151 # endif1187 # endif 1152 1188 rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_WRITE, GCPtrLdt, GCPtrLdt + cbLdt /* already inclusive */, 1153 1189 0, selmR3GuestLDTWriteHandler, "selmRCGuestLDTWriteHandler", 0, "Guest LDT write access handler"); … … 1166 1202 return rc; 1167 1203 } 1168 1204 #else 1205 pVM->selm.s.GCPtrGuestLdt = GCPtrLdt; 1206 #endif 1169 1207 pVM->selm.s.cbLdtLimit = cbLdt; 1170 1208 } … … 1205 1243 /** @todo investigate how intel handle various operations on half present cross page entries. */ 1206 1244 off = GCPtrLdt & (sizeof(X86DESC) - 1); 1207 AssertMsg(!off, ("LDT is not aligned on entry size! GCPtrLdt=%08x\n", GCPtrLdt));1245 //// AssertMsg(!off, ("LDT is not aligned on entry size! GCPtrLdt=%08x\n", GCPtrLdt)); 1208 1246 1209 1247 /* Note: Do not skip the first selector; unlike the GDT, a zero LDT selector is perfectly valid. */ … … 1239 1277 { 1240 1278 if (pLDTE->Gen.u1Present) 1241 selmGuestToShadowDesc(p LDTE);1279 selmGuestToShadowDesc(pVM, pLDTE); 1242 1280 1243 1281 /* Next LDT entry. */ … … 1438 1476 } 1439 1477 1440 1478 #ifdef SELM_TRACK_GUEST_GDT_CHANGES 1441 1479 /** 1442 1480 * \#PF Handler callback for virtual access handler ranges. … … 1465 1503 return VINF_PGM_HANDLER_DO_DEFAULT; 1466 1504 } 1467 1468 1505 #endif 1506 1507 #ifdef SELM_TRACK_GUEST_LDT_CHANGES 1469 1508 /** 1470 1509 * \#PF Handler callback for virtual access handler ranges. … … 1493 1532 return VINF_PGM_HANDLER_DO_DEFAULT; 1494 1533 } 1495 1496 1534 #endif 1535 1536 1537 #ifdef SELM_TRACK_GUEST_TSS_CHANGES 1497 1538 /** 1498 1539 * \#PF Handler callback for virtual access handler ranges. … … 1526 1567 return VINF_PGM_HANDLER_DO_DEFAULT; 1527 1568 } 1528 1569 #endif 1529 1570 1530 1571 /** … … 1675 1716 selmSetRing1Stack(pVM, Tss.ss0 | 1, Tss.esp0); 1676 1717 pVM->selm.s.fSyncTSSRing0Stack = fNoRing1Stack = false; 1718 1719 #ifdef VBOX_WITH_RAW_RING1 1720 /* 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) 1725 { 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)); 1727 } 1728 #endif 1677 1729 } 1678 1730 } … … 1711 1763 if (cbMonitoredTss != 0) 1712 1764 { 1765 #ifdef SELM_TRACK_GUEST_TSS_CHANGES 1713 1766 rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_WRITE, GCPtrTss, GCPtrTss + cbMonitoredTss - 1, 1714 1767 0, selmR3GuestTSSWriteHandler, … … 1716 1769 if (RT_FAILURE(rc)) 1717 1770 { 1771 # 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 1775 */ 1776 if (rc == VERR_PGM_HANDLER_VIRTUAL_CONFLICT) 1777 { 1778 LogRel(("SELMR3SyncTSS: Virtual handler conflict %RGv -> kick out PATM handler for the higher priority TSS page monitor\n", GCPtrTss)); 1779 rc = PGMHandlerVirtualDeregister(pVM, GCPtrTss & PAGE_BASE_GC_MASK); 1780 AssertRC(rc); 1781 1782 rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_WRITE, GCPtrTss, GCPtrTss + cbMonitoredTss - 1, 1783 0, selmR3GuestTSSWriteHandler, 1784 "selmRCGuestTSSWriteHandler", 0, "Guest TSS write access handler"); 1785 if (RT_FAILURE(rc)) 1786 { 1787 STAM_PROFILE_STOP(&pVM->selm.s.StatUpdateFromCPUM, a); 1788 return rc; 1789 } 1790 } 1791 # else 1718 1792 STAM_PROFILE_STOP(&pVM->selm.s.StatUpdateFromCPUM, a); 1719 1793 return rc; 1720 } 1721 1794 # endif 1795 } 1796 #endif 1722 1797 /* Update saved Guest TSS info. */ 1723 1798 pVM->selm.s.GCPtrGuestTss = GCPtrTss; … … 1888 1963 VMMR3DECL(bool) SELMR3CheckTSS(PVM pVM) 1889 1964 { 1890 #if def VBOX_STRICT1965 #if defined(VBOX_STRICT) && defined(SELM_TRACK_GUEST_TSS_CHANGES) 1891 1966 PVMCPU pVCpu = VMMGetCpu(pVM); 1892 1967 … … 2019 2094 #endif /* !VBOX_STRICT */ 2020 2095 } 2096 2097 # ifdef VBOX_WITH_SAFE_STR 2098 /** 2099 * Validates the RawR0 TR shadow GDT entry 2100 * 2101 * @returns true if it matches. 2102 * @returns false and assertions on mismatch.. 2103 * @param pVM Pointer to the VM. 2104 */ 2105 VMMR3DECL(bool) SELMR3CheckShadowTR(PVM pVM) 2106 { 2107 # ifdef VBOX_STRICT 2108 PX86DESC paGdt = pVM->selm.s.paGdtR3; 2109 2110 /* 2111 * TSS descriptor 2112 */ 2113 PX86DESC pDesc = &paGdt[pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS] >> 3]; 2114 RTRCPTR RCPtrTSS = VM_RC_ADDR(pVM, &pVM->selm.s.Tss); 2115 2116 if ( pDesc->Gen.u16BaseLow != RT_LOWORD(RCPtrTSS) 2117 || pDesc->Gen.u8BaseHigh1 != RT_BYTE3(RCPtrTSS) 2118 || pDesc->Gen.u8BaseHigh2 != RT_BYTE4(RCPtrTSS) 2119 || pDesc->Gen.u16LimitLow != sizeof(VBOXTSS) - 1 2120 || pDesc->Gen.u4LimitHigh != 0 2121 || (pDesc->Gen.u4Type != X86_SEL_TYPE_SYS_386_TSS_AVAIL && pDesc->Gen.u4Type != X86_SEL_TYPE_SYS_386_TSS_BUSY) 2122 || pDesc->Gen.u1DescType != 0 /* system */ 2123 || pDesc->Gen.u2Dpl != 0 /* supervisor */ 2124 || pDesc->Gen.u1Present != 1 2125 || pDesc->Gen.u1Available != 0 2126 || pDesc->Gen.u1Long != 0 2127 || pDesc->Gen.u1DefBig != 0 2128 || pDesc->Gen.u1Granularity != 0 /* byte limit */ 2129 ) 2130 { 2131 AssertFailed(); 2132 return false; 2133 } 2134 # endif 2135 return true; 2136 } 2137 # endif 2021 2138 2022 2139 #endif /* VBOX_WITH_RAW_MODE */ -
trunk/src/VBox/VMM/VMMR3/TRPM.cpp
r44528 r45276 1330 1330 } 1331 1331 1332 if (EMIsRawRing0Enabled(pVM)) 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 1337 { 1334 1338 /* -
trunk/src/VBox/VMM/VMMR3/VMM.cpp
r45152 r45276 1257 1257 EMR3FatalError(pVCpu, VERR_VMM_HYPER_CR3_MISMATCH); 1258 1258 PGMMapCheck(pVM); 1259 # ifdef VBOX_WITH_SAFE_STR 1260 SELMR3CheckShadowTR(pVM); 1261 # endif 1259 1262 #endif 1260 1263 int rc; -
trunk/src/VBox/VMM/VMMRC/CPUMRC.cpp
r42774 r45276 25 25 #include <VBox/vmm/patm.h> 26 26 #include <VBox/vmm/trpm.h> 27 #include <VBox/vmm/em.h> 27 28 #include "CPUMInternal.h" 28 29 #include <VBox/vmm/vm.h> … … 106 107 //Log2(("cs:eip=%04x:%08x ss:esp=%04x:%08x cpl=%u raw/efl=%#x/%#x%s\n", pCtx->cs.Sel, pCtx->eip, pCtx->ss.Sel, pCtx->esp, uRawCpl, u32EFlags, pCtx->eflags.u, fPatch ? " patch" : "")); 107 108 } 109 110 111 /** 112 * Get the current privilege level of the guest. 113 * 114 * @returns CPL 115 * @param pVCpu The current virtual CPU. 116 * @param pRegFrame Pointer to the register frame. 117 */ 118 VMMDECL(uint32_t) CPUMRCGetGuestCPL(PVMCPU pVCpu, PCPUMCTXCORE pRegFrame) 119 { 120 /* 121 * CPL can reliably be found in SS.DPL (hidden regs valid) or SS if not. 122 * 123 * Note! We used to check CS.DPL here, assuming it was always equal to 124 * CPL even if a conforming segment was loaded. But this truned out to 125 * only apply to older AMD-V. With VT-x we had an ACP2 regression 126 * during install after a far call to ring 2 with VT-x. Then on newer 127 * AMD-V CPUs we have to move the VMCB.guest.u8CPL into cs.Attr.n.u2Dpl 128 * as well as ss.Attr.n.u2Dpl to make this (and other) code work right. 129 * 130 * So, forget CS.DPL, always use SS.DPL. 131 * 132 * Note! The SS RPL is always equal to the CPL, while the CS RPL 133 * isn't necessarily equal if the segment is conforming. 134 * See section 4.11.1 in the AMD manual. 135 */ 136 uint32_t uCpl; 137 if (!pRegFrame->eflags.Bits.u1VM) 138 { 139 uCpl = (pRegFrame->ss.Sel & X86_SEL_RPL); 140 #ifdef VBOX_WITH_RAW_MODE_NOT_R0 141 # ifdef VBOX_WITH_RAW_RING1 142 if (pVCpu->cpum.s.fRawEntered) 143 { 144 if ( EMIsRawRing1Enabled(pVCpu->CTX_SUFF(pVM)) 145 && uCpl == 2) 146 uCpl = 1; 147 else 148 if (uCpl == 1) 149 uCpl = 0; 150 } 151 Assert(uCpl != 2); /* ring 2 support not allowed anymore. */ 152 # else 153 if (uCpl == 1) 154 uCpl = 0; 155 # endif 156 #endif 157 } 158 else 159 uCpl = 3; /* V86 has CPL=3; REM doesn't set DPL=3 in V8086 mode. See @bugref{5130}. */ 160 161 return uCpl; 162 } 163 164 #ifdef VBOX_WITH_RAW_RING1 165 /** 166 * Transforms the guest CPU state to raw-ring mode. 167 * 168 * This function will change the any of the cs and ss register with DPL=0 to DPL=1. 169 * 170 * @returns VBox status. (recompiler failure) 171 * @param pVCpu Pointer to the VMCPU. 172 * @param pCtxCore The context core (for trap usage). 173 * @see @ref pg_raw 174 */ 175 VMMDECL(void) CPUMRCRecheckRawState(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore) 176 { 177 /* 178 * Are we in Ring-0? 179 */ 180 if ( pCtxCore->ss.Sel 181 && (pCtxCore->ss.Sel & X86_SEL_RPL) == 0 182 && !pCtxCore->eflags.Bits.u1VM) 183 { 184 /* 185 * Set CPL to Ring-1. 186 */ 187 pCtxCore->ss.Sel |= 1; 188 if ( pCtxCore->cs.Sel 189 && (pCtxCore->cs.Sel & X86_SEL_RPL) == 0) 190 pCtxCore->cs.Sel |= 1; 191 } 192 else 193 { 194 if ( EMIsRawRing1Enabled(pVCpu->CTX_SUFF(pVM)) 195 && !pCtxCore->eflags.Bits.u1VM 196 && (pCtxCore->ss.Sel & X86_SEL_RPL) == 1) 197 { 198 /* Set CPL to Ring-2. */ 199 pCtxCore->ss.Sel = (pCtxCore->ss.Sel & ~X86_SEL_RPL) | 2; 200 if (pCtxCore->cs.Sel && (pCtxCore->cs.Sel & X86_SEL_RPL) == 1) 201 pCtxCore->cs.Sel = (pCtxCore->cs.Sel & ~X86_SEL_RPL) | 2; 202 } 203 } 204 205 /* 206 * Assert sanity. 207 */ 208 AssertMsg((pCtxCore->eflags.u32 & X86_EFL_IF), ("X86_EFL_IF is clear\n")); 209 AssertReleaseMsg(pCtxCore->eflags.Bits.u2IOPL == 0, 210 ("X86_EFL_IOPL=%d CPL=%d\n", pCtxCore->eflags.Bits.u2IOPL, pCtxCore->ss.Sel & X86_SEL_RPL)); 211 212 pCtxCore->eflags.u32 |= X86_EFL_IF; /* paranoia */ 213 } 214 #endif /* VBOX_WITH_RAW_RING1 */ -
trunk/src/VBox/VMM/VMMRC/PATMRC.cpp
r44363 r45276 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 157 160 AssertReturn(!pRegFrame->eflags.Bits.u1VM && (pRegFrame->ss.Sel & X86_SEL_RPL) == 1, VERR_ACCESS_DENIED); 161 #endif 158 162 Assert(PATMIsPatchGCAddr(pVM, pRegFrame->eip)); 159 163 … … 455 459 int rc; 456 460 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 457 464 AssertReturn(!pRegFrame->eflags.Bits.u1VM && (pRegFrame->ss.Sel & X86_SEL_RPL) == 1, VERR_ACCESS_DENIED); 465 #endif 458 466 459 467 /* Int 3 in PATM generated code? (most common case) */ … … 490 498 case OP_CPUID: 491 499 case OP_IRET: 500 #ifdef VBOX_WITH_RAW_RING1 501 case OP_SMSW: 502 case OP_MOV: /* mov xx, CS */ 503 #endif 492 504 break; 493 505 … … 498 510 case OP_LSL: 499 511 case OP_LAR: 512 #ifndef VBOX_WITH_RAW_RING1 500 513 case OP_SMSW: 514 #endif 501 515 case OP_VERW: 502 516 case OP_VERR: -
trunk/src/VBox/VMM/VMMRC/SELMRC.cpp
r44528 r45276 44 44 #endif 45 45 46 46 #ifdef SELM_TRACK_GUEST_GDT_CHANGES 47 47 /** 48 48 * Synchronizes one GDT entry (guest -> shadow). … … 123 123 * Convert the guest selector to a shadow selector and update the shadow GDT. 124 124 */ 125 selmGuestToShadowDesc( &Desc);125 selmGuestToShadowDesc(pVM, &Desc); 126 126 PX86DESC pShwDescr = &pVM->selm.s.paGdtRC[iGDTEntry]; 127 127 //Log(("O: base=%08X limit=%08X attr=%04X\n", X86DESC_BASE(*pShwDescr)), X86DESC_LIMIT(*pShwDescr), (pShwDescr->au32[1] >> 8) & 0xFFFF )); … … 306 306 return rc; 307 307 } 308 309 308 #endif /* SELM_TRACK_GUEST_GDT_CHANGES */ 309 310 #ifdef SELM_TRACK_GUEST_LDT_CHANGES 310 311 /** 311 312 * \#PF Virtual Handler callback for Guest write access to the Guest's own LDT. … … 330 331 return VINF_EM_RAW_EMULATE_INSTR_LDT_FAULT; 331 332 } 332 333 333 #endif 334 335 #ifdef SELM_TRACK_GUEST_TSS_CHANGES 334 336 /** 335 337 * Read wrapper used by selmRCGuestTSSWriteHandler. … … 382 384 uint32_t cb; 383 385 int rc = EMInterpretInstructionEx(pVCpu, pRegFrame, (RTGCPTR)(RTRCUINTPTR)pvFault, &cb); 384 if (RT_SUCCESS(rc) && cb) 386 if ( RT_SUCCESS(rc) 387 && cb) 385 388 { 386 389 rc = VINF_SUCCESS; … … 403 406 STAM_COUNTER_INC(&pVM->selm.s.StatRCWriteGuestTSSHandledChanged); 404 407 } 408 #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 ) 416 { 417 Log(("selmRCGuestTSSWriteHandler: R1 stack: %RTsel:%RGv -> %RTsel:%RGv\n", 418 (RTSEL)((pVM->selm.s.Tss.ss2 & ~2) | 1), (RTGCPTR)pVM->selm.s.Tss.esp2, (RTSEL)pGuestTss->ss1, (RTGCPTR)pGuestTss->esp1)); 419 pVM->selm.s.Tss.esp2 = pGuestTss->esp1; 420 pVM->selm.s.Tss.ss2 = (pGuestTss->ss1 & ~1) | 2; 421 STAM_COUNTER_INC(&pVM->selm.s.StatRCWriteGuestTSSHandledChanged); 422 } 423 #endif 405 424 /* Handle misaligned TSS in a safe manner (just in case). */ 406 425 else if ( offRange >= RT_UOFFSETOF(VBOXTSS, esp0) … … 492 511 return rc; 493 512 } 494 495 513 #endif /* SELM_TRACK_GUEST_TSS_CHANGES */ 514 515 #ifdef SELM_TRACK_SHADOW_GDT_CHANGES 496 516 /** 497 517 * \#PF Virtual Handler callback for Guest write access to the VBox shadow GDT. … … 512 532 return VERR_SELM_SHADOW_GDT_WRITE; 513 533 } 514 515 534 #endif 535 536 #ifdef SELM_TRACK_SHADOW_LDT_CHANGES 516 537 /** 517 538 * \#PF Virtual Handler callback for Guest write access to the VBox shadow LDT. … … 533 554 return VERR_SELM_SHADOW_LDT_WRITE; 534 555 } 535 536 556 #endif 557 558 #ifdef SELM_TRACK_SHADOW_TSS_CHANGES 537 559 /** 538 560 * \#PF Virtual Handler callback for Guest write access to the VBox shadow TSS. … … 553 575 return VERR_SELM_SHADOW_TSS_WRITE; 554 576 } 555 577 #endif 578 -
trunk/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp
r44362 r45276 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 447 451 if ( (pRegFrame->ss.Sel & X86_SEL_RPL) == 1 452 #endif 448 453 && !pRegFrame->eflags.Bits.u1VM) 449 454 { … … 523 528 PGMRZDynMapStartAutoSet(pVCpu); 524 529 530 #ifdef VBOX_WITH_RAW_RING1 531 if (CPUMGetGuestCPL(pVCpu) <= (unsigned)(EMIsRawRing1Enabled(pVM) ? 1 : 0)) 532 #else 525 533 if (CPUMGetGuestCPL(pVCpu) == 0) 534 #endif 526 535 { 527 536 /* … … 949 958 { 950 959 uint32_t efl = CPUMRawGetEFlags(pVCpu); 951 if (X86_EFL_GET_IOPL(efl) >= (unsigned)(pRegFrame->ss.Sel & X86_SEL_RPL)) 960 uint32_t cpl = CPUMRCGetGuestCPL(pVCpu, pRegFrame); 961 if (X86_EFL_GET_IOPL(efl) >= cpl) 952 962 { 953 963 LogFlow(("trpmGCTrap0dHandlerRing3: CLI/STI -> REM\n")); … … 955 965 return trpmGCExitTrap(pVM, pVCpu, VINF_EM_RESCHEDULE_REM, pRegFrame); 956 966 } 957 LogFlow(("trpmGCTrap0dHandlerRing3: CLI/STI -> #GP(0) \n"));967 LogFlow(("trpmGCTrap0dHandlerRing3: CLI/STI -> #GP(0) iopl=%x, cpl=%x\n", X86_EFL_GET_IOPL(efl), cpl)); 958 968 break; 959 969 } … … 1096 1106 if (eflags.Bits.u2IOPL != 3) 1097 1107 { 1098 Assert( eflags.Bits.u2IOPL == 0);1108 Assert(EMIsRawRing1Enabled(pVM) || eflags.Bits.u2IOPL == 0); 1099 1109 1100 1110 rc = TRPMForwardTrap(pVCpu, pRegFrame, 0xD, 0, TRPM_TRAP_HAS_ERRORCODE, TRPM_TRAP, 0xd); -
trunk/src/VBox/VMM/include/PATMA.h
r44528 r45276 146 146 extern PATCHASMRECORD PATMPushf16Record; 147 147 extern PATCHASMRECORD PATMIretRecord; 148 extern PATCHASMRECORD PATMIretRing1Record; 148 149 extern PATCHASMRECORD PATMCpuidRecord; 149 150 extern PATCHASMRECORD PATMLoopRecord; -
trunk/src/VBox/VMM/include/SELMInternal.h
r44528 r45276 25 25 #include <VBox/log.h> 26 26 #include <iprt/x86.h> 27 #include <VBox/vmm/em.h> 27 28 28 29 … … 33 34 * @{ 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 35 55 36 56 /** The number of GDTS allocated for our GDT. (full size) */ … … 203 223 204 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 205 228 206 229 RT_C_DECLS_END … … 362 385 * Converts a guest GDT or LDT entry to a shadow table entry. 363 386 * 387 * @param pVM The VM handle. 364 388 * @param pDesc Guest entry on input, shadow entry on return. 365 389 */ 366 DECL_FORCE_INLINE(void) selmGuestToShadowDesc(P X86DESC pDesc)390 DECL_FORCE_INLINE(void) selmGuestToShadowDesc(PVM pVM, PX86DESC pDesc) 367 391 { 368 392 /* … … 391 415 pDesc->Gen.u1Available = 1; 392 416 } 417 # 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) ) 423 { 424 pDesc->Gen.u2Dpl = 2; 425 pDesc->Gen.u1Available = 1; 426 } 427 # endif 393 428 else 394 429 pDesc->Gen.u1Available = 0; -
trunk/src/recompiler/Makefile.kmk
r42604 r45276 70 70 ifdef IEM_VERIFICATION_MODE 71 71 VBoxRemPrimary_DEFS += IEM_VERIFICATION_MODE 72 endif 73 ifdef VBOX_WITH_RAW_RING1 74 VBoxRemPrimary_DEFS += VBOX_WITH_RAW_RING1 72 75 endif 73 76 VBoxRemPrimary_DEFS.linux = _GNU_SOURCE -
trunk/src/recompiler/VBoxRecompiler.c
r44528 r45276 1371 1371 */ 1372 1372 case EXCP_EXECUTE_RAW: 1373 Log2(("REMR3Run: cpu_exec -> EXCP_EXECUTE_RAW \n"));1373 Log2(("REMR3Run: cpu_exec -> EXCP_EXECUTE_RAW pc=%RGv\n", pVM->rem.s.Env.eip)); 1374 1374 rc = VINF_EM_RESCHEDULE_RAW; 1375 1375 break; … … 1633 1633 } 1634 1634 1635 # ifdef VBOX_WITH_RAW_RING1 1636 /* Only ring 0 and 1 supervisor code. */ 1637 if (EMIsRawRing1Enabled(env->pVM)) 1638 { 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. */ 1640 { 1641 Log2(("raw r0 mode refused: CPL %d\n", (fFlags >> HF_CPL_SHIFT) & 3)); 1642 return false; 1643 } 1644 } 1645 else 1646 # endif 1635 1647 // Only R0 1636 1648 if (((fFlags >> HF_CPL_SHIFT) & 3) != 0) … … 1665 1677 #endif 1666 1678 1679 #ifndef VBOX_WITH_RAW_RING1 1680 if (((env->eflags >> IOPL_SHIFT) & 3) != 0) 1681 { 1682 Log2(("raw r0 mode refused: IOPL %d\n", ((env->eflags >> IOPL_SHIFT) & 3))); 1683 return false; 1684 } 1685 #endif 1667 1686 env->state |= CPU_RAW_RING0; 1668 1687 } … … 1764 1783 if (pVM->rem.s.fIgnoreInvlPg || pVM->rem.s.cIgnoreAll) 1765 1784 return; 1766 Log (("remR3FlushPage: GCPtr=%RGv\n", GCPtr));1785 LogFlow(("remR3FlushPage: GCPtr=%RGv\n", GCPtr)); 1767 1786 Assert(pVM->rem.s.fInREM || pVM->rem.s.fInStateSync); 1768 1787 -
trunk/src/recompiler/target-i386/op_helper.c
r43387 r45276 232 232 #ifdef VBOX 233 233 /* Trying to load a selector with CPL=1? */ 234 if ((env->hflags & HF_CPL_MASK) == 0 && (selector & 3) == 1 && (env->state & CPU_RAW_RING0)) 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 if ((env->hflags & HF_CPL_MASK) == 0 && (selector & 3) == 1 && (env->state & CPU_RAW_RING0) && !EMIsRawRing1Enabled(env->pVM)) 235 237 { 236 238 Log(("RPL 1 -> sel %04X -> %04X\n", selector, selector & 0xfffc)); … … 238 240 } 239 241 #endif /* VBOX */ 240 242 241 243 if (selector & 0x4) 242 244 dt = &env->ldt; … … 345 347 if (cpl == 0 && (selector & 3) == 1 && (env->state & CPU_RAW_RING0)) 346 348 { 347 Log(("RPL 1 -> sel %04X -> %04X \n", selector, selector & 0xfffc));349 Log(("RPL 1 -> sel %04X -> %04X (tss_load_seg)\n", selector, selector & 0xfffc)); 348 350 selector = selector & 0xfffc; 349 351 } … … 2556 2558 2557 2559 #ifdef VBOX 2558 Log(("helper_ltr: old tr=%RTsel {.base=%RGv, .limit=%RGv, .flags=%RX32} new=%RTsel\n",2559 (RT SEL)env->tr.selector, (RTGCPTR)env->tr.base, (RTGCPTR)env->tr.limit,2560 Log(("helper_ltr: pc=%RGv old tr=%RTsel {.base=%RGv, .limit=%RGv, .flags=%RX32} new=%RTsel\n", 2561 (RTGCPTR)env->eip, (RTSEL)env->tr.selector, (RTGCPTR)env->tr.base, (RTGCPTR)env->tr.limit, 2560 2562 env->tr.flags, (RTSEL)(selector & 0xffff))); 2563 ASMAtomicOrS32((int32_t volatile *)&env->interrupt_request, 2564 CPU_INTERRUPT_EXTERNAL_EXIT); 2561 2565 #endif 2562 2566 selector &= 0xffff; … … 2637 2641 if (cpl == 0 && (selector & 3) == 1 && (env->state & CPU_RAW_RING0)) 2638 2642 { 2639 Log(("RPL 1 -> sel %04X -> %04X \n", selector, selector & 0xfffc));2643 Log(("RPL 1 -> sel %04X -> %04X (helper_load_seg)\n", selector, selector & 0xfffc)); 2640 2644 selector = selector & 0xfffc; 2641 2645 } … … 3169 3173 if (is_iret) { 3170 3174 POPL(ssp, sp, sp_mask, new_eflags); 3175 #define LOG_GROUP LOG_GROUP_REM 3171 3176 #if defined(VBOX) && defined(DEBUG) 3172 printf("iret: new CS %04X\n", new_cs);3173 printf("iret: new EIP %08X\n", (uint32_t)new_eip);3174 printf("iret: new EFLAGS %08X\n", new_eflags);3175 printf("iret: EAX=%08x\n", (uint32_t)EAX);3177 Log(("iret: new CS %04X (old=%x)\n", new_cs, env->segs[R_CS].selector)); 3178 Log(("iret: new EIP %08X\n", (uint32_t)new_eip)); 3179 Log(("iret: new EFLAGS %08X\n", new_eflags)); 3180 Log(("iret: EAX=%08x\n", (uint32_t)EAX)); 3176 3181 #endif 3177 3182 if (new_eflags & VM_MASK) … … 3181 3186 if ((new_cs & 0x3) == 1 && (env->state & CPU_RAW_RING0)) 3182 3187 { 3183 # ifdef DEBUG 3184 printf("RPL 1 -> new_cs %04X -> %04X\n", new_cs, new_cs & 0xfffc); 3188 # ifdef VBOX_WITH_RAW_RING1 3189 if ( !EMIsRawRing1Enabled(env->pVM) 3190 || env->segs[R_CS].selector == (new_cs & 0xfffc)) 3191 { 3192 Log(("RPL 1 -> new_cs %04X -> %04X\n", new_cs, new_cs & 0xfffc)); 3193 new_cs = new_cs & 0xfffc; 3194 } 3195 else 3196 { 3197 /* Ugly assumption: assume a genuine switch to ring-1. */ 3198 Log(("Genuine switch to ring-1 (iret)\n")); 3199 } 3200 # else 3201 Log(("RPL 1 -> new_cs %04X -> %04X\n", new_cs, new_cs & 0xfffc)); 3202 new_cs = new_cs & 0xfffc; 3185 3203 # endif 3186 new_cs = new_cs & 0xfffc; 3187 } 3204 } 3205 # ifdef VBOX_WITH_RAW_RING1 3206 else 3207 if ((new_cs & 0x3) == 2 && (env->state & CPU_RAW_RING0) && EMIsRawRing1Enabled(env->pVM)) 3208 { 3209 Log(("RPL 2 -> new_cs %04X -> %04X\n", new_cs, (new_cs & 0xfffc) | 1)); 3210 new_cs = (new_cs & 0xfffc) | 1; 3211 } 3212 # endif 3188 3213 #endif 3189 3214 } else { … … 3200 3225 { 3201 3226 #if defined(VBOX) && defined(DEBUG) 3202 printf("new_cs & 0xfffc) == 0\n");3227 Log(("new_cs & 0xfffc) == 0\n")); 3203 3228 #endif 3204 3229 raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); … … 3207 3232 { 3208 3233 #if defined(VBOX) && defined(DEBUG) 3209 printf("load_segment failed\n");3234 Log(("load_segment failed\n")); 3210 3235 #endif 3211 3236 raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); … … 3215 3240 { 3216 3241 #if defined(VBOX) && defined(DEBUG) 3217 printf("e2 mask %08x\n", e2);3242 Log(("e2 mask %08x\n", e2)); 3218 3243 #endif 3219 3244 raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); … … 3224 3249 { 3225 3250 #if defined(VBOX) && defined(DEBUG) 3226 printf("rpl < cpl (%d vs %d)\n", rpl, cpl);3251 Log(("rpl < cpl (%d vs %d)\n", rpl, cpl)); 3227 3252 #endif 3228 3253 raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); 3229 3254 } 3230 3255 dpl = (e2 >> DESC_DPL_SHIFT) & 3; 3256 3231 3257 if (e2 & DESC_C_MASK) { 3232 3258 if (dpl > rpl) 3233 3259 { 3234 3260 #if defined(VBOX) && defined(DEBUG) 3235 printf("dpl > rpl (%d vs %d)\n", dpl, rpl);3261 Log(("dpl > rpl (%d vs %d)\n", dpl, rpl)); 3236 3262 #endif 3237 3263 raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); … … 3241 3267 { 3242 3268 #if defined(VBOX) && defined(DEBUG) 3243 printf("dpl != rpl (%d vs %d) e1=%x e2=%x\n", dpl, rpl, e1, e2);3269 Log(("dpl != rpl (%d vs %d) e1=%x e2=%x\n", dpl, rpl, e1, e2)); 3244 3270 #endif 3245 3271 raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); … … 3249 3275 { 3250 3276 #if defined(VBOX) && defined(DEBUG) 3251 printf("DESC_P_MASK e2=%08x\n", e2);3277 Log(("DESC_P_MASK e2=%08x\n", e2)); 3252 3278 #endif 3253 3279 raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);
Note:
See TracChangeset
for help on using the changeset viewer.

