Changeset 96761 in vbox
- Timestamp:
- Sep 16, 2022 5:40:42 AM (2 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp
r96407 r96761 1201 1201 * instruction. Interrupt inhibition for any nested-guest instruction 1202 1202 * is supplied by the guest-interruptibility state VMCS field and will 1203 * be set up as part of loading the guest state. 1203 * be set up as part of loading the guest state. Technically 1204 * blocking-by-STI is possible with VMLAUNCH/VMRESUME but we currently 1205 * disallow it since we can't distinguish it from blocking-by-MovSS 1206 * and no nested-hypervisor we care about uses STI immediately 1207 * followed by VMLAUNCH/VMRESUME. 1204 1208 * 1205 1209 * - VMCPU_FF_BLOCK_NMIS needs to be cached as VM-exits caused before … … 1247 1251 int rc = PGMChangeMode(pVCpu, pVCpu->cpum.GstCtx.cr0 | X86_CR0_PE, pVCpu->cpum.GstCtx.cr4, pVCpu->cpum.GstCtx.msrEFER, 1248 1252 true /* fForce */); 1249 AssertRCReturn(rc, rc); 1253 if (RT_SUCCESS(rc)) 1254 { /* likely */ } 1255 else 1256 return rc; 1250 1257 1251 1258 /* Invalidate IEM TLBs now that we've forced a PGM mode change. */ … … 1467 1474 * currently. */ 1468 1475 pVmcs->u32GuestIntrState |= VMX_VMCS_GUEST_INT_STATE_BLOCK_STI; 1476 1477 /* Clear inhibition unconditionally since we've ensured it isn't set prior to executing VMLAUNCH/VMRESUME. */ 1478 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS); 1469 1479 } 1470 1480 /* Nothing to do for SMI/enclave. We don't support enclaves or SMM yet. */ … … 2452 2462 pVmcs->u64RoExitQual.u = u64ExitQual; 2453 2463 2454 LogFlow(("vmexit: reason=%u qual=%#RX64 cs:rip=%04x:%#RX64 cr0=%#RX64 cr3=%#RX64 cr4=%#RX64 \n", uExitReason,2464 LogFlow(("vmexit: reason=%u qual=%#RX64 cs:rip=%04x:%#RX64 cr0=%#RX64 cr3=%#RX64 cr4=%#RX64 eflags=%#RX32\n", uExitReason, 2455 2465 pVmcs->u64RoExitQual.u, pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, pVCpu->cpum.GstCtx.cr0, 2456 pVCpu->cpum.GstCtx.cr3, pVCpu->cpum.GstCtx.cr4 ));2466 pVCpu->cpum.GstCtx.cr3, pVCpu->cpum.GstCtx.cr4, pVCpu->cpum.GstCtx.eflags.u32)); 2457 2467 2458 2468 /* … … 4622 4632 */ 4623 4633 iemVmxVirtApicSetPendingWrite(pVCpu, offAccess); 4634 4635 LogFlowFunc(("Write access at offset %#x not intercepted -> Wrote %#RX32\n", offAccess, u32Data)); 4624 4636 } 4625 4637 else … … 4640 4652 u32Data &= s_auAccessSizeMasks[cbAccess]; 4641 4653 *(uint32_t *)pvData = u32Data; 4654 4655 LogFlowFunc(("Read access at offset %#x not intercepted -> Read %#RX32\n", offAccess, u32Data)); 4642 4656 } 4643 4657 … … 7030 7044 && (pVmcs->u32GuestIntrState & (VMX_VMCS_GUEST_INT_STATE_BLOCK_STI | VMX_VMCS_GUEST_INT_STATE_BLOCK_MOVSS))) 7031 7045 EMSetInhibitInterruptsPC(pVCpu, pVmcs->u64GuestRip.u); 7032 else if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))7033 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS);7046 else 7047 Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)); 7034 7048 7035 7049 /* NMI blocking. */ … … 7146 7160 pVM->iem.s.hVmxApicAccessPage, 0 /*uUser*/, NULL /*pszDesc*/); 7147 7161 if (RT_SUCCESS(rc)) 7148 { 7149 /* 7150 * This to make double sure we trigger EPT violations (rather than EPT misconfigs) 7151 * in case we somehow managed to sync the page when CPUMIsGuestVmxApicAccessPageAddr 7152 * returned false while sycing its PTE in (SyncHandlerPte). 7153 */ 7154 PGMShwMakePageNotPresent(pVCpu, GCPhysApicAccess, 0 /* fOpFlags */); 7155 } 7162 { /* likely */ } 7156 7163 else 7157 7164 IEM_VMX_VMENTRY_FAILED_RET(pVCpu, pszInstr, pszFailure, kVmxVDiag_Vmentry_AddrApicAccessHandlerReg); … … 9886 9893 uint32_t const fAccess = enmAccessType == PGMACCESSTYPE_WRITE ? IEM_ACCESS_DATA_W : IEM_ACCESS_DATA_R; 9887 9894 uint16_t const offAccess = GCPhysFault & GUEST_PAGE_OFFSET_MASK; 9895 9896 LogFlowFunc(("Fault at %#RGp (cbBuf=%u fAccess=%#x)\n", GCPhysFault, cbBuf, fAccess)); 9888 9897 VBOXSTRICTRC rcStrict = iemVmxVirtApicAccessMem(pVCpu, offAccess, cbBuf, pvBuf, fAccess); 9889 9898 if (RT_FAILURE(rcStrict)) … … 9918 9927 * Handle the VMX APIC-access page only when the guest is in VMX non-root mode. 9919 9928 * Otherwise we must deregister the page and allow regular RAM access. 9920 * Failing to do so lands us with endless EPT misconfigurationVM-exits.9929 * Failing to do so lands us with endless EPT VM-exits. 9921 9930 */ 9922 9931 RTGCPHYS const GCPhysPage = GCPhysFault & ~(RTGCPHYS)GUEST_PAGE_OFFSET_MASK; … … 9940 9949 uint16_t const offAccess = GCPhysNestedFault & GUEST_PAGE_OFFSET_MASK; 9941 9950 bool const fIntercept = iemVmxVirtApicIsMemAccessIntercepted(pVCpu, offAccess, 1 /* cbAccess */, fAccess); 9951 LogFlowFunc(("#PF at %#RGp (GCPhysNestedFault=%#RGp offAccess=%#x)\n", GCPhysFault, GCPhysNestedFault, offAccess)); 9942 9952 if (fIntercept) 9943 9953 { … … 9946 9956 * within the APIC-access page. Currently only HM is supported. 9947 9957 */ 9948 AssertMsg(VM_IS_HM_ENABLED(pVM), ("VM-exit auxiliary info. fetching not supported for execution engine %d\n", 9949 pVM->bMainExecutionEngine)); 9958 AssertMsg(VM_IS_HM_ENABLED(pVM), 9959 ("VM-exit auxiliary info. fetching not supported for execution engine %d\n", pVM->bMainExecutionEngine)); 9960 9950 9961 HMEXITAUX HmExitAux; 9951 9962 RT_ZERO(HmExitAux); … … 9961 9972 * Refer to @bugref{10092#c33s} for a more detailed explanation. 9962 9973 */ 9963 AssertMsg (HmExitAux.Vmx.uReason == VMX_EXIT_EPT_VIOLATION,9964 ("Unexpected call to APIC-access page #PF handler for %#RGp off=%u uErr=%#RGx uReason=%u\n",9965 GCPhysPage, offAccess, uErr, HmExitAux.Vmx.uReason));9974 AssertMsgReturn(HmExitAux.Vmx.uReason == VMX_EXIT_EPT_VIOLATION, 9975 ("Unexpected call to APIC-access page #PF handler for %#RGp offAcesss=%u uErr=%#RGx uReason=%u\n", 9976 GCPhysPage, offAccess, uErr, HmExitAux.Vmx.uReason), VERR_IEM_IPE_7); 9966 9977 9967 9978 /* … … 9979 9990 else 9980 9991 enmAccess = VMXAPICACCESS_LINEAR_READ; 9992 9993 /* For linear-address accesss the instruction length must be valid. */ 9994 AssertMsg(HmExitAux.Vmx.cbInstr > 0, 9995 ("Invalid APIC-access VM-exit instruction length. cbInstr=%u\n", HmExitAux.Vmx.cbInstr)); 9981 9996 } 9982 9997 else … … 9990 10005 enmAccess = VMXAPICACCESS_PHYSICAL_INSTR; 9991 10006 } 10007 10008 /* For physical accesses the instruction length is undefined, we zero it for safety and consistency. */ 10009 HmExitAux.Vmx.cbInstr = 0; 9992 10010 } 9993 10011 … … 10007 10025 * Raise the APIC-access VM-exit. 10008 10026 */ 10027 LogFlowFunc(("Raising APIC-access VM-exit from #PF handler at offset %#x\n", offAccess)); 10009 10028 VBOXSTRICTRC rcStrict = iemVmxVmexitApicAccessWithInfo(pVCpu, &ExitInfo, &ExitEventInfo); 10010 10029 return iemExecStatusCodeFiddling(pVCpu, rcStrict); … … 10018 10037 * the APIC-access page (which we derive from the faulting address). 10019 10038 */ 10039 LogFlowFunc(("Access at offset %#x not intercepted -> VINF_EM_RAW_EMULATE_INSTR\n", offAccess)); 10020 10040 return VINF_EM_RAW_EMULATE_INSTR; 10021 10041 }
Note:
See TracChangeset
for help on using the changeset viewer.