Changeset 74421 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Sep 22, 2018 2:38:39 PM (6 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/HMVMXAll.cpp
r74399 r74421 337 337 VMXV_DIAG_DESC(kVmxVDiag_Vmentry_VmxRoot , "VmxRoot" ), 338 338 VMXV_DIAG_DESC(kVmxVDiag_Vmentry_Vpid , "Vpid" ), 339 VMXV_DIAG_DESC(kVmxVDiag_Vmexit_HostPdpteCr3ReadPhys , "HostPdpteCr3ReadPhys" ), 340 VMXV_DIAG_DESC(kVmxVDiag_Vmexit_HostPdpte0Rsvd , "HostPdpte0Rsvd" ), 341 VMXV_DIAG_DESC(kVmxVDiag_Vmexit_HostPdpte1Rsvd , "HostPdpte1Rsvd" ), 342 VMXV_DIAG_DESC(kVmxVDiag_Vmexit_HostPdpte2Rsvd , "HostPdpte2Rsvd" ), 343 VMXV_DIAG_DESC(kVmxVDiag_Vmexit_HostPdpte3Rsvd , "HostPdpte3Rsvd" ), 339 344 VMXV_DIAG_DESC(kVmxVDiag_Vmexit_MsrStore , "MsrStore" ), 340 345 VMXV_DIAG_DESC(kVmxVDiag_Vmexit_MsrStoreCount , "MsrStoreCount" ), -
trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h
r74420 r74421 2346 2346 2347 2347 /** 2348 * Gets the instruction diagnostic for CR3 referenced PDPTE reserved bits failure2349 * during VM-entry of a nested-guest.2348 * Gets the instruction diagnostic for guest CR3 referenced PDPTE reserved bits 2349 * failure during VM-entry of a nested-guest. 2350 2350 * 2351 2351 * @param iSegReg The PDPTE entry index. … … 2361 2361 case 3: return kVmxVDiag_Vmentry_GuestPdpte3Rsvd; 2362 2362 IEM_NOT_REACHED_DEFAULT_CASE_RET2(kVmxVDiag_Ipe_11); 2363 } 2364 } 2365 2366 2367 /** 2368 * Gets the instruction diagnostic for host CR3 referenced PDPTE reserved bits 2369 * failure during VM-exit of a nested-guest. 2370 * 2371 * @param iSegReg The PDPTE entry index. 2372 */ 2373 IEM_STATIC VMXVDIAG iemVmxGetDiagVmexitPdpteRsvd(unsigned iPdpte) 2374 { 2375 Assert(iPdpte < X86_PG_PAE_PDPE_ENTRIES); 2376 switch (iPdpte) 2377 { 2378 case 0: return kVmxVDiag_Vmexit_HostPdpte0Rsvd; 2379 case 1: return kVmxVDiag_Vmexit_HostPdpte1Rsvd; 2380 case 2: return kVmxVDiag_Vmexit_HostPdpte2Rsvd; 2381 case 3: return kVmxVDiag_Vmexit_HostPdpte3Rsvd; 2382 IEM_NOT_REACHED_DEFAULT_CASE_RET2(kVmxVDiag_Ipe_12); 2363 2383 } 2364 2384 } … … 4244 4264 * nested-guest (or the guest). 4245 4265 * 4246 * - VMCPU_FF_INHIBIT_INTERRUPTS and RIP needs be preserved as there is no 4247 * implicit Global Interrupt Flag (GIF) handling as with AMD-V's VMRUN 4248 * instruction and the interrupt inhibition is in effect until the 4249 * completion of this VMLAUNCH/VMRESUME instruction. 4266 * - VMCPU_FF_INHIBIT_INTERRUPTS need not be preserved as VM-exit explicitly 4267 * clears interrupt-inhibition and on VM-entry the guest-interruptibility 4268 * state provides the inhibition if any. 4250 4269 * 4251 * - VMCPU_FF_BLOCK_NMIS needs to be preserved as it blocks NMI until the 4252 * execution of a subsequent IRET instruction in the guest. 4270 * - VMCPU_FF_BLOCK_NMIS needs not be preserved as VM-entry does not discard 4271 * any NMI blocking. VM-exits caused directly by NMIs (intercepted by the 4272 * exception bitmap) do block subsequent NMIs. 4253 4273 * 4254 * - MTF needs to be preserved as it's for a single instruction boundary 4255 * whichfollows the return from VMLAUNCH/VMRESUME instruction.4274 * - MTF needs to be preserved as it's for a single instruction boundary which 4275 * follows the return from VMLAUNCH/VMRESUME instruction. 4256 4276 * 4257 4277 * The remaining FFs (e.g. timers) can stay in place so that we will be able to 4258 4278 * generate interrupts that should cause #VMEXITs for the nested-guest. 4259 4279 */ 4260 if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)) 4261 pVCpu->cpum.GstCtx.hwvirt.uInhibitRip = EMGetInhibitInterruptsPC(pVCpu); 4262 4263 uint32_t const fGuestFFMask = VMCPU_FF_INHIBIT_INTERRUPTS | VMCPU_FF_BLOCK_NMIS | VMCPU_FF_MTF; 4264 pVCpu->cpum.GstCtx.hwvirt.fLocalForcedActions = pVCpu->fLocalForcedActions & fGuestFFMask; 4265 VMCPU_FF_CLEAR(pVCpu, fGuestFFMask); 4266 } 4267 4268 4269 #if 0 4280 uint32_t const fNstGstDiscardMask = VMCPU_FF_MTF; 4281 pVCpu->cpum.GstCtx.hwvirt.fLocalForcedActions = pVCpu->fLocalForcedActions & fNstGstDiscardMask; 4282 VMCPU_FF_CLEAR(pVCpu, fNstGstDiscardMask); 4283 } 4284 4285 4270 4286 /** 4271 4287 * Restores the guest force-flags in prepartion of exiting the nested-guest. … … 4281 4297 } 4282 4298 } 4283 #endif4284 4299 4285 4300 … … 4963 4978 uint64_t const uHostCr0 = pVmcs->u64HostCr0.u; 4964 4979 uint64_t const uGuestCr0 = pVCpu->cpum.GstCtx.cr0; 4965 pVCpu->cpum.GstCtx.cr0 = (uHostCr0 & ~fCr0IgnMask) | (uGuestCr0 & fCr0IgnMask); 4980 uint64_t const uValidCr0 = (uHostCr0 & ~fCr0IgnMask) | (uGuestCr0 & fCr0IgnMask); 4981 CPUMSetGuestCR0(pVCpu, uValidCr0); 4966 4982 } 4967 4983 … … 4972 4988 uint64_t const uHostCr4 = pVmcs->u64HostCr4.u; 4973 4989 uint64_t const uGuestCr4 = pVCpu->cpum.GstCtx.cr4; 4974 pVCpu->cpum.GstCtx.cr4 = (uHostCr4 & ~fCr4IgnMask) | (uGuestCr4 & fCr4IgnMask); 4975 4990 uint64_t uValidCr4 = (uHostCr4 & ~fCr4IgnMask) | (uGuestCr4 & fCr4IgnMask); 4976 4991 if (fHostInLongMode) 4977 pVCpu->cpum.GstCtx.cr4 |= X86_CR4_PAE;4992 uValidCr4 |= X86_CR4_PAE; 4978 4993 else 4979 pVCpu->cpum.GstCtx.cr4 &= ~X86_CR4_PCIDE; 4994 uValidCr4 &= ~X86_CR4_PCIDE; 4995 CPUMSetGuestCR4(pVCpu, uValidCr4); 4980 4996 } 4981 4997 … … 5146 5162 5147 5163 /** 5164 * Checks host PDPTes as part of VM-exit. 5165 * 5166 * @param pVCpu The cross context virtual CPU structure. 5167 * @param uExitReason The VM-exit reason (for logging purposes). 5168 */ 5169 IEM_STATIC int iemVmxVmexitCheckHostPdptes(PVMCPU pVCpu, uint32_t uExitReason) 5170 { 5171 /* 5172 * Check host PDPTEs. 5173 * See Intel spec. 27.5.4 "Checking and Loading Host Page-Directory-Pointer-Table Entries". 5174 */ 5175 PCVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs); 5176 const char *const pszFailure = "VMX-abort"; 5177 bool const fHostInLongMode = RT_BOOL(pVmcs->u32ExitCtls & VMX_EXIT_CTLS_HOST_ADDR_SPACE_SIZE); 5178 5179 if ( (pVCpu->cpum.GstCtx.cr4 & X86_CR4_PAE) 5180 && !fHostInLongMode) 5181 { 5182 uint64_t const uHostCr3 = pVCpu->cpum.GstCtx.cr3 & X86_CR3_PAE_PAGE_MASK; 5183 X86PDPE aPdptes[X86_PG_PAE_PDPE_ENTRIES]; 5184 int rc = PGMPhysSimpleReadGCPhys(pVCpu->CTX_SUFF(pVM), (void *)&aPdptes[0], uHostCr3, sizeof(aPdptes)); 5185 if (RT_SUCCESS(rc)) 5186 { 5187 for (unsigned iPdpte = 0; iPdpte < RT_ELEMENTS(aPdptes); iPdpte++) 5188 { 5189 if ( !(aPdptes[iPdpte].u & X86_PDPE_P) 5190 || !(aPdptes[iPdpte].u & X86_PDPE_PAE_MBZ_MASK)) 5191 { /* likely */ } 5192 else 5193 { 5194 VMXVDIAG const enmDiag = iemVmxGetDiagVmexitPdpteRsvd(iPdpte); 5195 IEM_VMX_VMEXIT_FAILED_RET(pVCpu, uExitReason, pszFailure, enmDiag); 5196 } 5197 } 5198 } 5199 else 5200 IEM_VMX_VMEXIT_FAILED_RET(pVCpu, uExitReason, pszFailure, kVmxVDiag_Vmexit_HostPdpteCr3ReadPhys); 5201 } 5202 5203 NOREF(pszFailure); 5204 NOREF(uExitReason); 5205 return VINF_SUCCESS; 5206 } 5207 5208 5209 /** 5148 5210 * Loads the host state as part of VM-exit. 5149 5211 * 5150 * @param pVCpu The cross context virtual CPU structure. 5151 */ 5152 IEM_STATIC int iemVmxVmexitLoadHostState(PVMCPU pVCpu) 5212 * @param pVCpu The cross context virtual CPU structure. 5213 * @param uExitReason The VM-exit reason (for logging purposes). 5214 */ 5215 IEM_STATIC int iemVmxVmexitLoadHostState(PVMCPU pVCpu, uint32_t uExitReason) 5153 5216 { 5154 5217 /* … … 5181 5244 pVCpu->cpum.GstCtx.rflags.u = X86_EFL_1; 5182 5245 5183 /** @todo NSTVMX: rest of host state loading. */ 5246 /* Update non-register state. */ 5247 iemVmxVmexitRestoreForceFlags(pVCpu); 5248 5249 /* Clear address range monitoring. */ 5250 EMMonitorWaitClear(pVCpu); 5251 5252 /* Perform the VMX transition (PGM updates). */ 5253 VBOXSTRICTRC rcStrict = iemVmxWorldSwitch(pVCpu); 5254 if (rcStrict == VINF_SUCCESS) 5255 { 5256 /* Check host PDPTEs. */ 5257 /** @todo r=ramshankar: I don't know if PGM does this for us already or not... */ 5258 int rc = iemVmxVmexitCheckHostPdptes(pVCpu, uExitReason); 5259 if (RT_FAILURE(rc)) 5260 { 5261 Log(("VM-exit failed while restoring host PDPTEs -> VMX-Abort\n")); 5262 return iemVmxAbort(pVCpu, VMXBOART_HOST_PDPTE); 5263 } 5264 } 5265 else if (RT_SUCCESS(rcStrict)) 5266 { 5267 Log3(("VM-exit: iemVmxWorldSwitch returns %Rrc (uExitReason=%u) -> Setting passup status\n", VBOXSTRICTRC_VAL(rcStrict), 5268 uExitReason)); 5269 rcStrict = iemSetPassUpStatus(pVCpu, rcStrict); 5270 } 5271 else 5272 { 5273 Log3(("VM-exit: iemVmxWorldSwitch failed! rc=%Rrc (uExitReason=%u)\n", VBOXSTRICTRC_VAL(rcStrict), uExitReason)); 5274 return rcStrict; 5275 } 5276 5277 /** @todo NSTVMX: rest of host state loading (loading MSRs). */ 5184 5278 5185 5279 return VINF_SUCCESS; … … 5222 5316 } 5223 5317 5224 int rc = iemVmxVmexitLoadHostState(pVCpu );5318 int rc = iemVmxVmexitLoadHostState(pVCpu, uExitReason); 5225 5319 if (RT_FAILURE(rc)) 5226 5320 return rc; -
trunk/src/VBox/VMM/include/CPUMInternal.mac
r74303 r74421 253 253 alignb 8 254 254 .Guest.hwvirt.svm.HCPhysVmcb RTHCPHYS_RES 1 255 .Guest.hwvirt.uInhibitRip resq 1256 255 .Guest.hwvirt.fLocalForcedActions resd 1 257 256 .Guest.hwvirt.fGif resb 1 … … 541 540 alignb 8 542 541 .Hyper.hwvirt.svm.HCPhysVmcb RTHCPHYS_RES 1 543 .Hyper.hwvirt.uInhibitRip resq 1544 542 .Hyper.hwvirt.fLocalForcedActions resd 1 545 543 .Hyper.hwvirt.fGif resb 1 -
trunk/src/VBox/VMM/testcase/tstVMStruct.h
r74303 r74421 149 149 GEN_CHECK_OFF(CPUMCTX, hwvirt.vmx.GCPhysVmcs); 150 150 GEN_CHECK_OFF(CPUMCTX, hwvirt.vmx.enmDiag); 151 GEN_CHECK_OFF(CPUMCTX, hwvirt.vmx.enmAbort); 152 GEN_CHECK_OFF(CPUMCTX, hwvirt.vmx.uAbortAux); 151 153 GEN_CHECK_OFF(CPUMCTX, hwvirt.vmx.fInVmxRootMode); 152 154 GEN_CHECK_OFF(CPUMCTX, hwvirt.vmx.fInVmxNonRootMode); … … 164 166 GEN_CHECK_OFF(CPUMCTX, hwvirt.vmx.pAutoMsrAreaR0); 165 167 GEN_CHECK_OFF(CPUMCTX, hwvirt.vmx.pAutoMsrAreaR3); 166 GEN_CHECK_OFF(CPUMCTX, hwvirt.uInhibitRip);167 168 GEN_CHECK_OFF(CPUMCTX, hwvirt.fLocalForcedActions); 168 169 GEN_CHECK_OFF(CPUMCTX, hwvirt.fGif);
Note:
See TracChangeset
for help on using the changeset viewer.