Changeset 75493 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- Nov 15, 2018 5:06:55 PM (6 years ago)
- Location:
- trunk/src/VBox/VMM/VMMAll
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/CPUMAllMsrs.cpp
r75387 r75493 1278 1278 && CPUMIsGuestVmxProcCtls2Set(pVCpu, &pVCpu->cpum.s.Guest, VMX_PROC_CTLS2_VIRT_X2APIC_MODE)) 1279 1279 { 1280 /** @todo NSTVMX: perhaps IEMExecVmxVirtApicAccessMsr should be moved to1281 * HMVMXAll.cpp? */1282 1280 VBOXSTRICTRC rcStrict = IEMExecVmxVirtApicAccessMsr(pVCpu, idMsr, puValue, false /* fWrite */); 1283 Assert(rcStrict == VINF_SUCCESS || rcStrict == VERR_OUT_OF_RANGE || rcStrict == VINF_VMX_INTERCEPT_NOT_ACTIVE); 1284 if (rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE) 1285 { 1286 if (rcStrict == VERR_OUT_OF_RANGE) 1287 return VERR_CPUM_RAISE_GP_0; 1288 Assert(rcStrict == VINF_SUCCESS); 1281 if (rcStrict == VINF_VMX_MODIFIES_BEHAVIOR) 1289 1282 return VINF_SUCCESS; 1290 } 1283 if (rcStrict == VERR_OUT_OF_RANGE) 1284 return VERR_CPUM_RAISE_GP_0; 1285 Assert(rcStrict == VINF_VMX_INTERCEPT_NOT_ACTIVE); 1291 1286 } 1292 1287 #endif … … 1303 1298 && CPUMIsGuestVmxProcCtls2Set(pVCpu, &pVCpu->cpum.s.Guest, VMX_PROC_CTLS2_VIRT_X2APIC_MODE)) 1304 1299 { 1305 /** @todo NSTVMX: perhaps IEMExecVmxVirtApicAccessMsr should be moved to1306 * HMVMXAll.cpp? */1307 1300 VBOXSTRICTRC rcStrict = IEMExecVmxVirtApicAccessMsr(pVCpu, idMsr, &uValue, true /* fWrite */); 1308 Assert(rcStrict == VINF_SUCCESS || rcStrict == VERR_OUT_OF_RANGE || rcStrict == VINF_VMX_INTERCEPT_NOT_ACTIVE); 1309 if (rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE) 1310 { 1311 if (rcStrict == VERR_OUT_OF_RANGE) 1312 return VERR_CPUM_RAISE_GP_0; 1313 Assert(rcStrict == VINF_SUCCESS); 1301 if (rcStrict == VINF_VMX_MODIFIES_BEHAVIOR) 1314 1302 return VINF_SUCCESS; 1315 } 1303 if (rcStrict == VERR_OUT_OF_RANGE) 1304 return VERR_CPUM_RAISE_GP_0; 1305 Assert(rcStrict == VINF_VMX_INTERCEPT_NOT_ACTIVE); 1316 1306 } 1317 1307 #endif -
trunk/src/VBox/VMM/VMMAll/CPUMAllVmx.cpp
r75440 r75493 21 21 *********************************************************************************************************************************/ 22 22 #define LOG_GROUP LOG_GROUP_CPUM 23 #include <VBox/log.h> 23 24 #include <VBox/vmm/cpum.h> 24 #include <VBox/log.h> 25 #include "CPUMInternal.h" 26 #include <VBox/vmm/iem.h> 27 #include <VBox/vmm/pgm.h> 28 #include <VBox/vmm/vm.h> 25 29 26 30 … … 134 138 } 135 139 140 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX 141 /** 142 * @callback_method_impl{FNPGMPHYSHANDLER, VMX APIC-access page accesses} 143 * 144 * @remarks The @a pvUser argument is currently unused. 145 */ 146 PGM_ALL_CB2_DECL(VBOXSTRICTRC) cpumVmxApicAccessPageHandler(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhysFault, void *pvPhys, 147 void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, 148 PGMACCESSORIGIN enmOrigin, void *pvUser) 149 { 150 RT_NOREF4(pVM, pvPhys, enmOrigin, pvUser); 151 152 uint16_t const offAccess = (GCPhysFault & PAGE_OFFSET_MASK); 153 bool const fWrite = RT_BOOL(enmAccessType == PGMACCESSTYPE_WRITE); 154 VBOXSTRICTRC rcStrict = IEMExecVmxVirtApicAccessMem(pVCpu, offAccess, cbBuf, pvBuf, fWrite); 155 if (rcStrict == VINF_VMX_MODIFIES_BEHAVIOR) 156 rcStrict = VINF_SUCCESS; 157 return rcStrict; 158 } 159 #endif 160 161 162 /** 163 * Registers the PGM physical page handelr for teh VMX APIC-access page. 164 * 165 * @returns VBox status code. 166 * @param pVCpu The cross context virtual CPU structure. 167 * @param GCPhysApicAccess The guest-physical address of the APIC-access page. 168 */ 169 VMM_INT_DECL(VBOXSTRICTRC) CPUMVmxApicAccessPageRegister(PVMCPU pVCpu, RTGCPHYS GCPhysApicAccess) 170 { 171 PVM pVM = pVCpu->CTX_SUFF(pVM); 172 int rc = PGMHandlerPhysicalRegister(pVM, GCPhysApicAccess, GCPhysApicAccess, pVM->cpum.s.hVmxApicAccessPage, 173 NIL_RTR3PTR /* pvUserR3 */, NIL_RTR0PTR /* pvUserR0 */, NIL_RTRCPTR /* pvUserRC */, 174 NULL /* pszDesc */); 175 return rc; 176 } 177 178 179 /** 180 * Registers the PGM physical page handelr for teh VMX APIC-access page. 181 * 182 * @returns VBox status code. 183 * @param pVCpu The cross context virtual CPU structure. 184 * @param GCPhysApicAccess The guest-physical address of the APIC-access page. 185 */ 186 VMM_INT_DECL(VBOXSTRICTRC) CPUMVmxApicAccessPageDeregister(PVMCPU pVCpu, RTGCPHYS GCPhysApicAccess) 187 { 188 /** @todo NSTVMX: If there's anything else to do while APIC-access page is 189 * de-registered, do it here. */ 190 PVM pVM = pVCpu->CTX_SUFF(pVM); 191 if (PGMHandlerPhysicalIsRegistered(pVM, GCPhysApicAccess)) 192 return PGMHandlerPhysicalDeregister(pVM, GCPhysApicAccess); 193 return VINF_SUCCESS; 194 } 195 -
trunk/src/VBox/VMM/VMMAll/HMVMXAll.cpp
r75440 r75493 132 132 VMXV_DIAG_DESC(kVmxVDiag_Vmentry_AddrApicAccess , "AddrApicAccess" ), 133 133 VMXV_DIAG_DESC(kVmxVDiag_Vmentry_AddrApicAccessEqVirtApic , "AddrApicAccessEqVirtApic" ), 134 VMXV_DIAG_DESC(kVmxVDiag_Vmentry_AddrApicAccessHandlerReg , "AddrApicAccessHandlerReg" ), 134 135 VMXV_DIAG_DESC(kVmxVDiag_Vmentry_AddrEntryMsrLoad , "AddrEntryMsrLoad" ), 135 136 VMXV_DIAG_DESC(kVmxVDiag_Vmentry_AddrExitMsrLoad , "AddrExitMsrLoad" ), -
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r75387 r75493 8910 8910 iemMemUpdateWrittenCounter(pVCpu, fAccess, cbMem); 8911 8911 *ppvMem = pvMem; 8912 8913 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX8914 /*8915 * Check if this is an APIC-access and whether it needs to be virtualized.8916 */8917 if ( CPUMIsGuestInVmxNonRootMode(IEM_GET_CTX(pVCpu))8918 && IEM_VMX_IS_PROCCTLS2_SET(pVCpu, VMX_PROC_CTLS2_VIRT_APIC_ACCESS))8919 {8920 RTGCPHYS const GCPhysMemAccessBase = GCPhysFirst & ~(RTGCPHYS)PAGE_OFFSET_MASK;8921 RTGCPHYS const GCPhysApicAccessBase = CPUMGetGuestVmxApicAccessPageAddr(pVCpu, IEM_GET_CTX(pVCpu))8922 & ~(RTGCPHYS)PAGE_OFFSET_MASK;8923 if (GCPhysMemAccessBase == GCPhysApicAccessBase)8924 {8925 Assert(pvMem);8926 uint16_t const offAccess = GCPhysFirst & (RTGCPHYS)PAGE_OFFSET_MASK;8927 return iemVmxVirtApicAccessMem(pVCpu, offAccess, cbMem, pvMem, fAccess);8928 }8929 }8930 #endif8931 8912 8932 8913 return VINF_SUCCESS; … … 13951 13932 int32_t const rcPassUp = pVCpu->iem.s.rcPassUp; 13952 13933 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX 13953 if ( ( rcStrict == VINF_VMX_VMEXIT 13954 || rcStrict == VINF_VMX_MODIFIES_BEHAVIOR) 13934 if ( rcStrict == VINF_VMX_VMEXIT 13955 13935 && rcPassUp == VINF_SUCCESS) 13956 13936 rcStrict = VINF_SUCCESS; … … 15701 15681 * 15702 15682 * @returns Strict VBox status code. 15703 * @retval VINF_ SUCCESSif the MSR access was virtualized.15683 * @retval VINF_VMX_MODIFIES_BEHAVIOR if the MSR access was virtualized. 15704 15684 * @retval VINF_VMX_INTERCEPT_NOT_ACTIVE if the MSR access must be handled by 15705 15685 * the x2APIC device. 15706 15686 * @retval VERR_OUT_RANGE if the caller must raise \#GP(0). 15687 * 15707 15688 * @param pVCpu The cross context virtual CPU structure of the calling EMT. 15708 15689 * @param idMsr The MSR being read. … … 15714 15695 VMM_INT_DECL(VBOXSTRICTRC) IEMExecVmxVirtApicAccessMsr(PVMCPU pVCpu, uint32_t idMsr, uint64_t *pu64Value, bool fWrite) 15715 15696 { 15716 IEM_CTX_ASSERT(pVCpu, IEM_CPUMCTX_EXTRN_ VMX_VMEXIT_MASK);15697 IEM_CTX_ASSERT(pVCpu, IEM_CPUMCTX_EXTRN_EXEC_DECODED_NO_MEM_MASK); 15717 15698 Assert(pu64Value); 15718 15699 … … 15726 15707 return iemExecStatusCodeFiddling(pVCpu, rcStrict); 15727 15708 15709 } 15710 15711 15712 /** 15713 * Interface for HM and EM to virtualize memory-mapped APIC accesses. 15714 * 15715 * @returns Strict VBox status code. 15716 * @retval VINF_VMX_MODIFIES_BEHAVIOR if the memory access was virtualized. 15717 * 15718 * @param pVCpu The cross context virtual CPU structure of the calling EMT. 15719 * @param offAccess The offset of the register being accessed (within the 15720 * APIC-access page). 15721 * @param cbAccess The size of the access in bytes. 15722 * @param pvData Pointer to the data being written or where to store the data 15723 * being read. 15724 * @param fWrite Whether this is a write or read access. 15725 * @thread EMT(pVCpu) 15726 */ 15727 VMM_INT_DECL(VBOXSTRICTRC) IEMExecVmxVirtApicAccessMem(PVMCPU pVCpu, uint16_t offAccess, size_t cbAccess, void *pvData, 15728 bool fWrite) 15729 { 15730 IEM_CTX_ASSERT(pVCpu, IEM_CPUMCTX_EXTRN_VMX_VMEXIT_MASK); 15731 Assert(pvData); 15732 15733 /** @todo NSTVMX: Unfortunately, the caller has no idea about instruction fetch 15734 * accesses, so we only use read/write here. Maybe in the future the PGM 15735 * physical handler will be extended to include this information? */ 15736 uint32_t const fAccess = fWrite ? IEM_ACCESS_TYPE_WRITE : IEM_ACCESS_TYPE_READ; 15737 VBOXSTRICTRC rcStrict = iemVmxVirtApicAccessMem(pVCpu, offAccess, cbAccess, pvData, fAccess); 15738 if (pVCpu->iem.s.cActiveMappings) 15739 iemMemRollback(pVCpu); 15740 return iemExecStatusCodeFiddling(pVCpu, rcStrict); 15728 15741 } 15729 15742 -
trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h
r75440 r75493 2681 2681 PCVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs); 2682 2682 bool const fHostInLongMode = RT_BOOL(pVmcs->u32ExitCtls & VMX_EXIT_CTLS_HOST_ADDR_SPACE_SIZE); 2683 bool const fVirtApicAccess = RT_BOOL(pVmcs->u32ProcCtls2 & VMX_PROC_CTLS2_VIRT_APIC_ACCESS); 2683 2684 2684 2685 /* We cannot return from a long-mode guest to a host that is not in long mode. */ … … 2706 2707 /* Clear address range monitoring. */ 2707 2708 EMMonitorWaitClear(pVCpu); 2709 2710 /* De-register the handler for the APIC-access page. */ 2711 if (fVirtApicAccess) 2712 { 2713 RTGCPHYS const GCPhysApicAccess = pVmcs->u64AddrApicAccess.u; 2714 int rc = CPUMVmxApicAccessPageDeregister(pVCpu, GCPhysApicAccess); 2715 if (RT_FAILURE(rc)) 2716 return rc; 2717 } 2708 2718 2709 2719 /* Perform the VMX transition (PGM updates). */ … … 4236 4246 * 4237 4247 * @returns VBox strict status code. 4248 * @retval VINF_VMX_MODIFIES_BEHAVIOR if the access was virtualized. 4249 * @retval VINF_VMX_VMEXIT if the access causes a VM-exit. 4250 * 4238 4251 * @param pVCpu The cross context virtual CPU structure. 4239 4252 * @param offAccess The offset of the register being accessed (within the 4240 4253 * APIC-access page). 4241 4254 * @param cbAccess The size of the access in bytes. 4242 * @param pvData Pointer to the data being read or written. 4255 * @param pvData Pointer to the data being written or where to store the data 4256 * being read. 4243 4257 * @param fAccess The type of access (must contain IEM_ACCESS_TYPE_READ or 4244 4258 * IEM_ACCESS_TYPE_WRITE or IEM_ACCESS_INSTRUCTION). … … 6006 6020 IEM_VMX_VMENTRY_FAILED_RET(pVCpu, pszInstr, pszFailure, kVmxVDiag_Vmentry_AddrApicAccessEqVirtApic); 6007 6021 } 6022 6023 /* Register the handler for the APIC-access page. */ 6024 int rc = CPUMVmxApicAccessPageRegister(pVCpu, GCPhysApicAccess); 6025 if (RT_FAILURE(rc)) 6026 IEM_VMX_VMENTRY_FAILED_RET(pVCpu, pszInstr, pszFailure, kVmxVDiag_Vmentry_AddrApicAccessHandlerReg); 6008 6027 } 6009 6028
Note:
See TracChangeset
for help on using the changeset viewer.