Changeset 75822 in vbox
- Timestamp:
- Nov 29, 2018 5:37:35 PM (6 years ago)
- Location:
- trunk/src/VBox/VMM/VMMR0
- Files:
-
- 2 edited
-
HMSVMR0.cpp (modified) (8 diffs)
-
HMVMXR0.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp
r75759 r75822 401 401 static FNSVMEXITHANDLER hmR0SvmExitXcptAC; 402 402 static FNSVMEXITHANDLER hmR0SvmExitXcptBP; 403 static FNSVMEXITHANDLER hmR0SvmExitXcptGP; 403 404 #if defined(HMSVM_ALWAYS_TRAP_ALL_XCPTS) || defined(VBOX_WITH_NESTED_HWVIRT_SVM) 404 405 static FNSVMEXITHANDLER hmR0SvmExitXcptGeneric; … … 982 983 if (pVCpu->hm.s.fGIMTrapXcptUD) 983 984 pVmcbCtrl->u32InterceptXcpt |= RT_BIT(X86_XCPT_UD); 985 986 /* The mesa 3d driver hack needs #GP. */ 987 if (pVCpu->hm.s.fTrapXcptGpForLovelyMesaDrv) 988 pVmcbCtrl->u32InterceptXcpt |= RT_BIT(X86_XCPT_GP); 984 989 985 990 /* Set up unconditional intercepts and conditions. */ … … 1427 1432 Assert(uXcpt != X86_XCPT_DB); 1428 1433 Assert(uXcpt != X86_XCPT_AC); 1434 Assert(uXcpt != X86_XCPT_GP); 1429 1435 #ifndef HMSVM_ALWAYS_TRAP_ALL_XCPTS 1430 1436 if (pVmcb->ctrl.u32InterceptXcpt & RT_BIT(uXcpt)) … … 2232 2238 * Merge the guest's exception intercepts into the nested-guest VMCB. 2233 2239 * 2234 * - \#UD: Exclude these as the outer guest's GIM hypercalls are not applicable2240 * - #UD: Exclude these as the outer guest's GIM hypercalls are not applicable 2235 2241 * while executing the nested-guest. 2236 2242 * 2237 * - \#BP: Exclude breakpoints set by the VM debugger for the outer guest. This can2243 * - #BP: Exclude breakpoints set by the VM debugger for the outer guest. This can 2238 2244 * be tweaked later depending on how we wish to implement breakpoints. 2245 * 2246 * - #GP: Exclude these as it's the inner VMMs problem to get vmsvga 3d drivers 2247 * loaded into their guests, not ours. 2239 2248 * 2240 2249 * Warning!! This ASSUMES we only intercept \#UD for hypercall purposes and \#BP … … 2242 2251 */ 2243 2252 #ifndef HMSVM_ALWAYS_TRAP_ALL_XCPTS 2244 pVmcbNstGstCtrl->u32InterceptXcpt |= (pVmcb->ctrl.u32InterceptXcpt & ~( RT_BIT(X86_XCPT_UD) 2245 | RT_BIT(X86_XCPT_BP))); 2253 pVmcbNstGstCtrl->u32InterceptXcpt |= pVmcb->ctrl.u32InterceptXcpt 2254 & ~( RT_BIT(X86_XCPT_UD) 2255 | RT_BIT(X86_XCPT_BP) 2256 | (pVCpu->hm.s.fTrapXcptGpForLovelyMesaDrv ? RT_BIT(X86_XCPT_GP) : 0)); 2246 2257 #else 2247 2258 pVmcbNstGstCtrl->u32InterceptXcpt |= pVmcb->ctrl.u32InterceptXcpt; … … 5690 5701 case SVM_EXIT_XCPT_AC: VMEXIT_CALL_RET(0, hmR0SvmExitXcptAC(pVCpu, pSvmTransient)); 5691 5702 case SVM_EXIT_XCPT_BP: VMEXIT_CALL_RET(0, hmR0SvmExitXcptBP(pVCpu, pSvmTransient)); 5703 case SVM_EXIT_XCPT_GP: VMEXIT_CALL_RET(0, hmR0SvmExitXcptGP(pVCpu, pSvmTransient)); 5692 5704 case SVM_EXIT_XSETBV: VMEXIT_CALL_RET(0, hmR0SvmExitXsetbv(pVCpu, pSvmTransient)); 5693 5705 case SVM_EXIT_FERR_FREEZE: VMEXIT_CALL_RET(0, hmR0SvmExitFerrFreeze(pVCpu, pSvmTransient)); … … 5758 5770 case SVM_EXIT_XCPT_NP: 5759 5771 case SVM_EXIT_XCPT_SS: 5760 case SVM_EXIT_XCPT_GP:5772 /* SVM_EXIT_XCPT_GP: */ /* Handled above. */ 5761 5773 /* SVM_EXIT_XCPT_PF: */ 5762 5774 case SVM_EXIT_XCPT_15: /* Reserved. */ … … 7798 7810 7799 7811 7812 /** 7813 * Hacks its way around the lovely mesa driver's backdoor accesses. 7814 * 7815 * @sa hmR0VmxHandleMesaDrvGp 7816 */ 7817 static int hmR0SvmHandleMesaDrvGp(PVMCPU pVCpu, PSVMTRANSIENT pSvmTransient, PCPUMCTX pCtx, PCSVMVMCB pVmcb) 7818 { 7819 Log(("hmR0SvmHandleMesaDrvGp: at %04x:%08RX64 rcx=%RX64 rbx=%RX64\n", 7820 pVmcb->guest.CS.u16Sel, pVmcb->guest.u64RIP, pCtx->rcx, pCtx->rbx)); 7821 RT_NOREF(pCtx, pSvmTransient, pVmcb); 7822 7823 /* For now we'll just skip the instruction. */ 7824 hmR0SvmAdvanceRip(pVCpu, 1); 7825 return VINF_SUCCESS; 7826 } 7827 7828 7829 /** 7830 * Checks if the \#GP'ing instruction is the mesa driver doing it's lovely 7831 * backdoor logging w/o checking what it is running inside. 7832 * 7833 * This recognizes an "IN EAX,DX" instruction executed in flat ring-3, with the 7834 * backdoor port and magic numbers loaded in registers. 7835 * 7836 * @returns true if it is, false if it isn't. 7837 * @sa hmR0VmxIsMesaDrvGp 7838 */ 7839 DECLINLINE(bool) hmR0SvmIsMesaDrvGp(PVMCPU pVCpu, PSVMTRANSIENT pSvmTransient, PCPUMCTX pCtx, PCSVMVMCB pVmcb) 7840 { 7841 /* Check magic and port. */ 7842 Assert(!(pCtx->fExtrn & (CPUMCTX_EXTRN_RDX | CPUMCTX_EXTRN_RCX))); 7843 /*Log(("hmR0SvmIsMesaDrvGp: rax=%RX64 rdx=%RX64\n", pCtx->fExtrn & CPUMCTX_EXTRN_RAX ? pCtx->rax : pVmcb->guest.u64RAX, pCtx->rdx));*/ 7844 if (pCtx->dx != UINT32_C(0x5658)) 7845 return false; 7846 if ((pCtx->fExtrn & CPUMCTX_EXTRN_RAX ? pCtx->rax : pVmcb->guest.u64RAX) != UINT32_C(0x564d5868)) 7847 return false; 7848 7849 /* Check that it is #GP(0). */ 7850 if (pSvmTransient->u64ExitCode != 0) 7851 return false; 7852 7853 /* Flat ring-3 CS. */ 7854 /*Log(("hmR0SvmIsMesaDrvGp: u8CPL=%d base=%Rx64\n", pVmcb->guest.u8CPL, pCtx->fExtrn & CPUMCTX_EXTRN_CS ? pVmcb->guest.CS.u64Base : pCtx->cs.Sel));*/ 7855 if (pVmcb->guest.u8CPL != 3) 7856 return false; 7857 if ((pCtx->fExtrn & CPUMCTX_EXTRN_CS ? pVmcb->guest.CS.u64Base : pCtx->cs.Sel) != 0) 7858 return false; 7859 7860 /* 0xed: IN eAX,dx */ 7861 uint64_t const uRip = pCtx->fExtrn & CPUMCTX_EXTRN_RIP ? pCtx->rip : pVmcb->guest.u64RIP; 7862 uint8_t abInstr[1]; 7863 if ( hmR0SvmSupportsNextRipSave(pVCpu) 7864 && pVmcb->ctrl.u64NextRIP - uRip != sizeof(abInstr)) 7865 return false; 7866 if (pVmcb->ctrl.cbInstrFetched >= 1) 7867 { 7868 /*Log(("hmR0SvmIsMesaDrvGp: %#x\n", pVmcb->ctrl.abInstr));*/ 7869 if (pVmcb->ctrl.abInstr[0] != 0xed) 7870 return false; 7871 } 7872 else 7873 { 7874 int rc = PGMPhysSimpleReadGCPtr(pVCpu, abInstr, uRip, sizeof(abInstr)); 7875 /*Log(("hmR0SvmIsMesaDrvGp: PGMPhysSimpleReadGCPtr -> %Rrc %#x\n", rc, abInstr[0]));*/ 7876 if (RT_FAILURE(rc)) 7877 return false; 7878 if (abInstr[0] != 0xed) 7879 return false; 7880 } 7881 7882 return true; 7883 } 7884 7885 7886 /** 7887 * \#VMEXIT handler for general protection faults (SVM_EXIT_XCPT_BP). 7888 * Conditional \#VMEXIT. 7889 */ 7890 HMSVM_EXIT_DECL hmR0SvmExitXcptGP(PVMCPU pVCpu, PSVMTRANSIENT pSvmTransient) 7891 { 7892 HMSVM_VALIDATE_EXIT_HANDLER_PARAMS(pVCpu, pSvmTransient); 7893 HMSVM_CHECK_EXIT_DUE_TO_EVENT_DELIVERY(pVCpu, pSvmTransient); 7894 7895 PCSVMVMCB pVmcb = hmR0SvmGetCurrentVmcb(pVCpu); 7896 Assert(pSvmTransient->u64ExitCode == pVmcb->ctrl.u64ExitCode); 7897 7898 PCPUMCTX pCtx = &pVCpu->cpum.GstCtx; 7899 if ( !pVCpu->hm.s.fTrapXcptGpForLovelyMesaDrv 7900 || hmR0SvmIsMesaDrvGp(pVCpu, pSvmTransient, pCtx, pVmcb)) 7901 { 7902 SVMEVENT Event; 7903 Event.u = 0; 7904 Event.n.u1Valid = 1; 7905 Event.n.u3Type = SVM_EVENT_EXCEPTION; 7906 Event.n.u8Vector = X86_XCPT_GP; 7907 Event.n.u1ErrorCodeValid = 1; 7908 Event.n.u32ErrorCode = (uint32_t)pSvmTransient->u64ExitCode; 7909 hmR0SvmSetPendingEvent(pVCpu, &Event, 0 /* GCPtrFaultAddress */); 7910 return VINF_SUCCESS; 7911 } 7912 return hmR0SvmHandleMesaDrvGp(pVCpu, pSvmTransient, pCtx, pVmcb); 7913 } 7914 7915 7800 7916 #if defined(HMSVM_ALWAYS_TRAP_ALL_XCPTS) || defined(VBOX_WITH_NESTED_HWVIRT_SVM) 7801 7917 /** -
trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
r75821 r75822 13168 13168 /** 13169 13169 * Hacks its way around the lovely mesa driver's backdoor accesses. 13170 * 13171 * @sa hmR0SvmHandleMesaDrvGp 13170 13172 */ 13171 13173 static int hmR0VmxHandleMesaDrvGp(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient, PCPUMCTX pCtx) … … 13187 13189 * 13188 13190 * @returns true if it is, false if it isn't. 13191 * @sa hmR0SvmIsMesaDrvGp 13189 13192 */ 13190 13193 DECLINLINE(bool) hmR0VmxIsMesaDrvGp(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient, PCPUMCTX pCtx)
Note:
See TracChangeset
for help on using the changeset viewer.

