- Timestamp:
- Aug 17, 2018 6:12:20 PM (6 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/CPUMAllMsrs.cpp
r73628 r73745 1566 1566 | (pGuestFeatures->fVmxUnrestrictedGuest << VMX_BF_PROC_CTLS2_UNRESTRICTED_GUEST_SHIFT) 1567 1567 | (pGuestFeatures->fVmxPauseLoopExit << VMX_BF_PROC_CTLS2_PAUSE_LOOP_EXIT_SHIFT ) 1568 | (pGuestFeatures->fVmxInvpcid << VMX_BF_PROC_CTLS2_INVPCID_SHIFT ); 1568 | (pGuestFeatures->fVmxInvpcid << VMX_BF_PROC_CTLS2_INVPCID_SHIFT ) 1569 | (pGuestFeatures->fVmxVmcsShadowing << VMX_BF_PROC_CTLS2_VMCS_SHADOWING_SHIFT ); 1569 1570 uint32_t const fVal = 0; 1570 1571 uint32_t const fZap = fFeatures; -
trunk/src/VBox/VMM/VMMAll/HMVMXAll.cpp
r73617 r73745 51 51 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmxon_LongModeCS , "LongModeCS" ), 52 52 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmxon_MsrFeatCtl , "MsrFeatCtl" ), 53 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmxon_PtrAbnormal , "PtrAbnormal" ), 53 54 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmxon_PtrAlign , "PtrAlign" ), 54 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmxon_PtrAbnormal , "PtrAbnormal" ),55 55 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmxon_PtrMap , "PtrMap" ), 56 56 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmxon_PtrPhysRead , "PtrPhysRead" ), … … 70 70 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmxoff_Success , "Success" ), 71 71 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmxoff_Vmxe , "Vmxe" ), 72 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmxoff_VmxRoot , "VmxRoot" ) 72 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmxoff_VmxRoot , "VmxRoot" ), 73 /* VMPTRLD. */ 74 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrld_Cpl , "Cpl" ), 75 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrld_PtrAbnormal , "PtrAbnormal" ), 76 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrld_PtrAlign , "PtrAlign" ), 77 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrld_PtrMap , "PtrMap" ), 78 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrld_PtrReadPhys , "PtrReadPhys" ), 79 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrld_PtrVmxon , "PtrVmxon" ), 80 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrld_PtrWidth , "PtrWidth" ), 81 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrld_ShadowVmcs , "ShadowVmcs" ), 82 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrld_Success , "Success" ), 83 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrld_VmcsRevId , "VmcsRevId" ) 73 84 /* kVmxVInstrDiag_Last */ 74 85 }; -
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r73608 r73745 12586 12586 return IEMOP_RAISE_INVALID_OPCODE(); \ 12587 12587 } while (0) 12588 #endif 12588 12589 /** The instruction can only be executed in VMX operation (VMX root mode and 12590 * non-root mode). 12591 */ 12592 # define IEMOP_HLP_IN_VMX_OPERATION() \ 12593 do \ 12594 { \ 12595 if (IEM_IS_VMX_ROOT_MODE(pVCpu)) { /* likely */ } \ 12596 else return IEMOP_RAISE_INVALID_OPCODE(); \ 12597 } while (0) 12598 #endif /* VBOX_WITH_NESTED_HWVIRT_VMX */ 12589 12599 12590 12600 /** The instruction is not available in 64-bit mode, throw \#UD if we're in -
trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h
r73739 r73745 481 481 482 482 /** 483 * VMPTRLD instruction execution worker. 484 * 485 * @param pVCpu The cross context virtual CPU structure. 486 * @param cbInstr The instruction length. 487 * @param GCPtrVmcs The linear address of the current VMCS pointer. 488 * @param pExitInstrInfo Pointer to the VM-exit instruction information field. 489 * @param GCPtrDisp The displacement field for @a GCPtrVmcs if any. 490 * 491 * @remarks Common VMX instruction checks are already expected to by the caller, 492 * i.e. VMX operation, CR4.VMXE, Real/V86 mode, EFER/CS.L checks. 493 */ 494 IEM_STATIC VBOXSTRICTRC iemVmxVmptrld(PVMCPU pVCpu, uint8_t cbInstr, RTGCPHYS GCPtrVmcs, PCVMXEXITINSTRINFO pExitInstrInfo, 495 RTGCPTR GCPtrDisp) 496 { 497 if (IEM_IS_VMX_NON_ROOT_MODE(pVCpu)) 498 { 499 RT_NOREF(GCPtrDisp); 500 /** @todo NSTVMX: intercept. */ 501 } 502 Assert(IEM_IS_VMX_ROOT_MODE(pVCpu)); 503 504 /* CPL. */ 505 if (CPUMGetGuestCPL(pVCpu) > 0) 506 { 507 Log(("vmptrld: CPL %u -> #GP(0)\n", pVCpu->iem.s.uCpl)); 508 pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmptrld_Cpl; 509 return iemRaiseGeneralProtectionFault0(pVCpu); 510 } 511 512 /* Get the VMCS pointer from the location specified by the source memory operand. */ 513 RTGCPHYS GCPhysVmcs; 514 VBOXSTRICTRC rcStrict = iemMemFetchDataU64(pVCpu, &GCPhysVmcs, pExitInstrInfo->VmxXsave.iSegReg, GCPtrVmcs); 515 if (RT_UNLIKELY(rcStrict != VINF_SUCCESS)) 516 { 517 Log(("vmptrld: Failed to read VMCS physaddr from %#RGv, rc=%Rrc\n", GCPtrVmcs, VBOXSTRICTRC_VAL(rcStrict))); 518 pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmptrld_PtrMap; 519 return rcStrict; 520 } 521 522 /* VMCS pointer alignment. */ 523 if (GCPhysVmcs & X86_PAGE_4K_OFFSET_MASK) 524 { 525 Log(("vmptrld: VMCS pointer not page-aligned -> VMFail()\n")); 526 pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmptrld_PtrAlign; 527 iemVmxVmFail(pVCpu, VMXINSTRERR_VMPTRLD_INVALID_PHYSADDR); 528 iemRegAddToRipAndClearRF(pVCpu, cbInstr); 529 return VINF_SUCCESS; 530 } 531 532 /* VMCS physical-address width limits. */ 533 Assert(!VMX_V_VMCS_PHYSADDR_4G_LIMIT); 534 if (GCPhysVmcs >> IEM_GET_GUEST_CPU_FEATURES(pVCpu)->cMaxPhysAddrWidth) 535 { 536 Log(("vmptrld: VMCS pointer extends beyond physical-address width -> VMFail()\n")); 537 pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmptrld_PtrWidth; 538 iemVmxVmFail(pVCpu, VMXINSTRERR_VMPTRLD_INVALID_PHYSADDR); 539 iemRegAddToRipAndClearRF(pVCpu, cbInstr); 540 return VINF_SUCCESS; 541 } 542 543 /* VMCS is not the VMXON region. */ 544 if (GCPhysVmcs == pVCpu->cpum.GstCtx.hwvirt.vmx.GCPhysVmxon) 545 { 546 Log(("vmptrld: VMCS pointer cannot be identical to VMXON region pointer -> VMFail()\n")); 547 pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmptrld_PtrVmxon; 548 iemVmxVmFail(pVCpu, VMXINSTRERR_VMPTRLD_VMXON_PTR); 549 iemRegAddToRipAndClearRF(pVCpu, cbInstr); 550 return VINF_SUCCESS; 551 } 552 553 /* Ensure VMCS is not MMIO, ROM etc. This is not an Intel requirement but a 554 restriction imposed by our implementation. */ 555 if (!PGMPhysIsGCPhysNormal(pVCpu->CTX_SUFF(pVM), GCPhysVmcs)) 556 { 557 Log(("vmptrld: VMCS not normal memory -> VMFail()\n")); 558 pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmptrld_PtrAbnormal; 559 iemVmxVmFail(pVCpu, VMXINSTRERR_VMPTRLD_INVALID_PHYSADDR); 560 iemRegAddToRipAndClearRF(pVCpu, cbInstr); 561 return VINF_SUCCESS; 562 } 563 564 /* Read the VMCS revision ID from the VMCS. */ 565 VMXVMCSREVID VmcsRevId; 566 int rc = PGMPhysSimpleReadGCPhys(pVCpu->CTX_SUFF(pVM), &VmcsRevId, GCPhysVmcs, sizeof(VmcsRevId)); 567 if (RT_FAILURE(rc)) 568 { 569 Log(("vmptrld: Failed to read VMCS at %#RGp, rc=%Rrc\n", GCPhysVmcs, rc)); 570 pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmptrld_PtrReadPhys; 571 return rc; 572 } 573 574 /* Verify the VMCS revision specified by the guest matches what we reported to the guest, 575 also check VMCS shadowing feature. */ 576 if ( VmcsRevId.n.u31RevisionId != VMX_V_VMCS_REVISION_ID 577 || ( VmcsRevId.n.fIsShadowVmcs 578 && !IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fVmxVmcsShadowing)) 579 { 580 if (VmcsRevId.n.u31RevisionId != VMX_V_VMCS_REVISION_ID) 581 { 582 Log(("vmptrld: VMCS revision mismatch, expected %#RX32 got %#RX32 -> VMFail()\n", VMX_V_VMCS_REVISION_ID, 583 VmcsRevId.n.u31RevisionId)); 584 pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmptrld_VmcsRevId; 585 iemVmxVmFail(pVCpu, VMXINSTRERR_VMPTRLD_INCORRECT_VMCS_REV); 586 iemRegAddToRipAndClearRF(pVCpu, cbInstr); 587 return VINF_SUCCESS; 588 } 589 590 Log(("vmptrld: Shadow VMCS -> VMFail()\n")); 591 pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmptrld_ShadowVmcs; 592 iemVmxVmFail(pVCpu, VMXINSTRERR_VMPTRLD_INCORRECT_VMCS_REV); 593 iemRegAddToRipAndClearRF(pVCpu, cbInstr); 594 return VINF_SUCCESS; 595 } 596 597 pVCpu->cpum.GstCtx.hwvirt.vmx.GCPhysVmcs = GCPhysVmcs; 598 pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmptrld_Success; 599 iemVmxVmSucceed(pVCpu); 600 iemRegAddToRipAndClearRF(pVCpu, cbInstr); 601 return VINF_SUCCESS; 602 } 603 604 605 /** 483 606 * VMXON instruction execution worker. 484 607 * … … 733 856 } 734 857 858 859 /** 860 * Implements 'VMPTRLD'. 861 */ 862 IEM_CIMPL_DEF_1(iemCImpl_vmptrld, RTGCPTR, GCPtrVmcs) 863 { 864 RTGCPTR GCPtrDisp; 865 VMXEXITINSTRINFO ExitInstrInfo; 866 ExitInstrInfo.u = iemVmxGetExitInstrInfo(pVCpu, VMX_EXIT_VMPTRLD, VMX_INSTR_ID_NONE, &GCPtrDisp); 867 return iemVmxVmptrld(pVCpu, cbInstr, GCPtrVmcs, &ExitInstrInfo, GCPtrDisp); 868 } 869 870 735 871 #endif 736 872 -
trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsTwoByte0f.cpp.h
r73606 r73745 8421 8421 8422 8422 /** Opcode 0x0f 0xc7 !11/6. */ 8423 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX 8424 FNIEMOP_DEF_1(iemOp_Grp9_vmptrld_Mq, uint8_t, bRm) 8425 { 8426 IEMOP_MNEMONIC(vmptrld, "vmptrld"); 8427 IEMOP_HLP_IN_VMX_OPERATION(); 8428 IEMOP_HLP_VMX_INSTR(); 8429 IEM_MC_BEGIN(1, 0); 8430 IEM_MC_ARG(RTGCPTR, GCPtrEffSrc, 0); 8431 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0); 8432 IEMOP_HLP_DONE_DECODING_NO_LOCK_REPZ_OR_REPNZ_PREFIXES(); 8433 IEM_MC_CALL_CIMPL_1(iemCImpl_vmptrld, GCPtrEffSrc); 8434 IEM_MC_END(); 8435 return VINF_SUCCESS; 8436 } 8437 #else 8423 8438 FNIEMOP_UD_STUB_1(iemOp_Grp9_vmptrld_Mq, uint8_t, bRm); 8439 #endif 8424 8440 8425 8441 /** Opcode 0x66 0x0f 0xc7 !11/6. */ -
trunk/src/VBox/VMM/VMMR3/CPUM.cpp
r73742 r73745 1021 1021 VMXFEATDUMP("PauseLoopExit - PAUSE-loop exiting ", fVmxPauseLoopExit); 1022 1022 VMXFEATDUMP("Invpcid - Enable INVPCID ", fVmxInvpcid); 1023 VMXFEATDUMP("VmcsShadowing - VMCS shadowing ", fVmxVmcsShadowing); 1023 1024 /* VM-entry controls. */ 1024 1025 VMXFEATDUMP("EntryLoadDebugCtls - Load debug controls on VM-entry ", fVmxEntryLoadDebugCtls); … … 1108 1109 pHostFeat->fVmxPauseLoopExit = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_PAUSE_LOOP_EXIT); 1109 1110 pHostFeat->fVmxInvpcid = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_INVPCID); 1111 pHostFeat->fVmxVmcsShadowing = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_VMCS_SHADOWING); 1110 1112 } 1111 1113 … … 1176 1178 EmuFeat.fVmxPauseLoopExit = 0; 1177 1179 EmuFeat.fVmxInvpcid = 1; 1180 EmuFeat.fVmxVmcsShadowing = 0; 1178 1181 EmuFeat.fVmxEntryLoadDebugCtls = 1; 1179 1182 EmuFeat.fVmxIa32eModeGuest = 1; … … 1236 1239 pGuestFeat->fVmxPauseLoopExit = (pBaseFeat->fVmxPauseLoopExit & EmuFeat.fVmxPauseLoopExit ); 1237 1240 pGuestFeat->fVmxInvpcid = (pBaseFeat->fVmxInvpcid & EmuFeat.fVmxInvpcid ); 1241 pGuestFeat->fVmxVmcsShadowing = (pBaseFeat->fVmxVmcsShadowing & EmuFeat.fVmxVmcsShadowing ); 1238 1242 pGuestFeat->fVmxEntryLoadDebugCtls = (pBaseFeat->fVmxEntryLoadDebugCtls & EmuFeat.fVmxEntryLoadDebugCtls ); 1239 1243 pGuestFeat->fVmxIa32eModeGuest = (pBaseFeat->fVmxIa32eModeGuest & EmuFeat.fVmxIa32eModeGuest ); -
trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp
r73606 r73745 129 129 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX 130 130 # define IEMOP_HLP_VMX_INSTR() do { } while (0) 131 # define IEMOP_HLP_IN_VMX_OPERATION() do { } while (0) 131 132 #endif 132 133
Note:
See TracChangeset
for help on using the changeset viewer.