Changeset 93922 in vbox for trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h
- Timestamp:
- Feb 24, 2022 3:14:31 PM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h
r93650 r93922 3711 3711 * This need not be page aligned (e.g. nested-guest in real 3712 3712 * mode). 3713 * @param pExitEventInfo Pointer to the VM-exit event information. Optional, can 3714 * be NULL. 3715 */ 3716 IEM_STATIC VBOXSTRICTRC iemVmxVmexitEptMisconfig(PVMCPUCC pVCpu, RTGCPHYS GCPhysAddr, PCVMXVEXITEVENTINFO pExitEventInfo) 3717 { 3718 if (pExitEventInfo) 3719 { 3720 iemVmxVmcsSetExitIntInfo(pVCpu, pExitEventInfo->uExitIntInfo); 3721 iemVmxVmcsSetExitIntErrCode(pVCpu, pExitEventInfo->uExitIntErrCode); 3722 iemVmxVmcsSetIdtVectoringInfo(pVCpu, pExitEventInfo->uIdtVectoringInfo); 3723 iemVmxVmcsSetIdtVectoringErrCode(pVCpu, pExitEventInfo->uIdtVectoringErrCode); 3724 } 3725 3713 */ 3714 IEM_STATIC VBOXSTRICTRC iemVmxVmexitEptMisconfig(PVMCPUCC pVCpu, RTGCPHYS GCPhysAddr) 3715 { 3716 iemVmxVmcsSetExitGuestPhysAddr(pVCpu, GCPhysAddr); 3717 return iemVmxVmexit(pVCpu, VMX_EXIT_EPT_MISCONFIG, 0 /* u64ExitQual */); 3718 } 3719 3720 3721 /** 3722 * VMX VM-exit handler for EPT misconfiguration. 3723 * 3724 * This is intended for EPT misconfigurations where the caller provides all the 3725 * relevant VM-exit information. 3726 * 3727 * @param pVCpu The cross context virtual CPU structure. 3728 * @param GCPhysAddr The physical address causing the EPT misconfiguration. 3729 * This need not be page aligned (e.g. nested-guest in real 3730 * mode). 3731 * @param pExitEventInfo Pointer to the VM-exit event information. 3732 */ 3733 IEM_STATIC VBOXSTRICTRC iemVmxVmexitEptMisconfigWithInfo(PVMCPUCC pVCpu, RTGCPHYS GCPhysAddr, PCVMXVEXITEVENTINFO pExitEventInfo) 3734 { 3735 Assert(pExitEventInfo); 3736 Assert(!VMX_EXIT_INT_INFO_IS_VALID(pExitEventInfo->uExitIntInfo)); 3737 iemVmxVmcsSetIdtVectoringInfo(pVCpu, pExitEventInfo->uIdtVectoringInfo); 3738 iemVmxVmcsSetIdtVectoringErrCode(pVCpu, pExitEventInfo->uIdtVectoringErrCode); 3726 3739 iemVmxVmcsSetExitGuestPhysAddr(pVCpu, GCPhysAddr); 3727 3740 return iemVmxVmexit(pVCpu, VMX_EXIT_EPT_MISCONFIG, 0 /* u64ExitQual */); … … 3745 3758 */ 3746 3759 IEM_STATIC VBOXSTRICTRC iemVmxVmexitEptViolation(PVMCPUCC pVCpu, uint32_t fAccess, uint32_t fSlatFail, uint64_t fEptAccess, 3747 RTGCPHYS GCPhysAddr, bool fLinearAddrValid, uint64_t GCPtrAddr, uint8_t cbInstr) 3760 RTGCPHYS GCPhysAddr, bool fIsLinearAddrValid, uint64_t GCPtrAddr, 3761 uint8_t cbInstr) 3748 3762 { 3749 3763 /* … … 3752 3766 * While we can leave it this way, it's preferrable to zero it for consistency. 3753 3767 */ 3754 Assert(f LinearAddrValid || GCPtrAddr == 0);3768 Assert(fIsLinearAddrValid || GCPtrAddr == 0); 3755 3769 3756 3770 uint64_t const fCaps = pVCpu->cpum.GstCtx.hwvirt.vmx.Msrs.u64EptVpidCaps; 3757 uint8_t const fSupportsAccessDirty = fCaps & MSR_IA32_VMX_EPT_VPID_CAP_ACCESS_DIRTY; 3758 3759 uint8_t const fDataRead = ((fAccess & IEM_ACCESS_DATA_R) == IEM_ACCESS_DATA_R) | fSupportsAccessDirty; 3760 uint8_t const fDataWrite = ((fAccess & IEM_ACCESS_DATA_RW) == IEM_ACCESS_DATA_RW) | fSupportsAccessDirty; 3761 uint8_t const fInstrFetch = (fAccess & IEM_ACCESS_INSTRUCTION) == IEM_ACCESS_INSTRUCTION; 3762 bool const fEptRead = RT_BOOL(fEptAccess & EPT_E_READ); 3763 bool const fEptWrite = RT_BOOL(fEptAccess & EPT_E_WRITE); 3764 bool const fEptExec = RT_BOOL(fEptAccess & EPT_E_EXECUTE); 3765 bool const fNmiUnblocking = pVCpu->cpum.GstCtx.hwvirt.vmx.fNmiUnblockingIret; 3766 bool const fLinearToPhysAddr = fLinearAddrValid & RT_BOOL(fSlatFail & IEM_SLAT_FAIL_LINEAR_TO_PHYS_ADDR); 3771 bool const fSupportsAccessDirty = RT_BOOL(fCaps & MSR_IA32_VMX_EPT_VPID_CAP_ACCESS_DIRTY); 3772 3773 uint32_t const fDataRdMask = IEM_ACCESS_WHAT_MASK | IEM_ACCESS_TYPE_READ; 3774 uint32_t const fDataWrMask = IEM_ACCESS_WHAT_MASK | IEM_ACCESS_TYPE_WRITE; 3775 uint32_t const fInstrMask = IEM_ACCESS_WHAT_MASK | IEM_ACCESS_TYPE_EXEC; 3776 bool const fDataRead = ((fAccess & fDataRdMask) == IEM_ACCESS_DATA_R) | fSupportsAccessDirty; 3777 bool const fDataWrite = ((fAccess & fDataWrMask) == IEM_ACCESS_DATA_W) | fSupportsAccessDirty; 3778 bool const fInstrFetch = ((fAccess & fInstrMask) == IEM_ACCESS_INSTRUCTION); 3779 bool const fEptRead = RT_BOOL(fEptAccess & EPT_E_READ); 3780 bool const fEptWrite = RT_BOOL(fEptAccess & EPT_E_WRITE); 3781 bool const fEptExec = RT_BOOL(fEptAccess & EPT_E_EXECUTE); 3782 bool const fNmiUnblocking = pVCpu->cpum.GstCtx.hwvirt.vmx.fNmiUnblockingIret; 3783 bool const fIsLinearToPhysAddr = fIsLinearAddrValid & RT_BOOL(fSlatFail & IEM_SLAT_FAIL_LINEAR_TO_PHYS_ADDR); 3767 3784 3768 3785 uint64_t const u64ExitQual = RT_BF_MAKE(VMX_BF_EXIT_QUAL_EPT_ACCESS_READ, fDataRead) … … 3772 3789 | RT_BF_MAKE(VMX_BF_EXIT_QUAL_EPT_ENTRY_WRITE, fEptWrite) 3773 3790 | RT_BF_MAKE(VMX_BF_EXIT_QUAL_EPT_ENTRY_EXECUTE, fEptExec) 3774 | RT_BF_MAKE(VMX_BF_EXIT_QUAL_EPT_LINEAR_ADDR_VALID, f LinearAddrValid)3775 | RT_BF_MAKE(VMX_BF_EXIT_QUAL_EPT_LINEAR_TO_PHYS_ADDR, f LinearToPhysAddr)3791 | RT_BF_MAKE(VMX_BF_EXIT_QUAL_EPT_LINEAR_ADDR_VALID, fIsLinearAddrValid) 3792 | RT_BF_MAKE(VMX_BF_EXIT_QUAL_EPT_LINEAR_TO_PHYS_ADDR, fIsLinearToPhysAddr) 3776 3793 | RT_BF_MAKE(VMX_BF_EXIT_QUAL_EPT_NMI_UNBLOCK_IRET, fNmiUnblocking); 3777 3794 … … 3807 3824 PCVMXVEXITEVENTINFO pExitEventInfo) 3808 3825 { 3826 Assert(pExitInfo); 3827 Assert(pExitEventInfo); 3809 3828 Assert(pExitInfo->uReason == VMX_EXIT_EPT_VIOLATION); 3810 3811 iemVmxVmcsSetExitIntInfo(pVCpu, pExitEventInfo->uExitIntInfo); 3812 iemVmxVmcsSetExitIntErrCode(pVCpu, pExitEventInfo->uExitIntErrCode); 3829 Assert(!VMX_EXIT_INT_INFO_IS_VALID(pExitEventInfo->uExitIntInfo)); 3830 3813 3831 iemVmxVmcsSetIdtVectoringInfo(pVCpu, pExitEventInfo->uIdtVectoringInfo); 3814 3832 iemVmxVmcsSetIdtVectoringErrCode(pVCpu, pExitEventInfo->uIdtVectoringErrCode); … … 3818 3836 iemVmxVmcsSetExitGuestLinearAddr(pVCpu, pExitInfo->u64GuestLinearAddr); 3819 3837 else 3820 iemVmxVmcsSetExitGuestLinearAddr(pVCpu, 3838 iemVmxVmcsSetExitGuestLinearAddr(pVCpu, 0); 3821 3839 iemVmxVmcsSetExitInstrLen(pVCpu, pExitInfo->cbInstr); 3822 3840 return iemVmxVmexit(pVCpu, VMX_EXIT_EPT_VIOLATION, pExitInfo->u64Qual); … … 3834 3852 * applicable. 3835 3853 */ 3836 IEM_STATIC VBOXSTRICTRC iemVmxVmexitEpt(PVMCPUCC pVCpu, PPGMPTWALK pWalk, uint32_t fAccess, uint32_t fSlatFail, 3837 uint8_t cbInstr) 3854 IEM_STATIC VBOXSTRICTRC iemVmxVmexitEpt(PVMCPUCC pVCpu, PPGMPTWALK pWalk, uint32_t fAccess, uint32_t fSlatFail, uint8_t cbInstr) 3838 3855 { 3839 3856 Assert(pWalk->fIsSlat); … … 3852 3869 Log(("EptMisconfig: cs:rip=%x:%#RX64 fAccess=%#RX32\n", pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, fAccess)); 3853 3870 Assert(pWalk->fFailed & PGM_WALKFAIL_EPT_MISCONFIG); 3854 return iemVmxVmexitEptMisconfig(pVCpu, pWalk->GCPhysNested , NULL /* pExitEventInfo */);3871 return iemVmxVmexitEptMisconfig(pVCpu, pWalk->GCPhysNested); 3855 3872 } 3856 3873 … … 3861 3878 * @param pVCpu The cross context virtual CPU structure. 3862 3879 * @param offAccess The offset of the register being accessed. 3863 * @param fAccess The type of access (must contain IEM_ACCESS_TYPE_READ or 3864 * IEM_ACCESS_TYPE_WRITE or IEM_ACCESS_INSTRUCTION). 3880 * @param fAccess The type of access, see IEM_ACCESS_XXX. 3865 3881 */ 3866 3882 IEM_STATIC VBOXSTRICTRC iemVmxVmexitApicAccess(PVMCPUCC pVCpu, uint16_t offAccess, uint32_t fAccess) 3867 3883 { 3868 Assert((fAccess & IEM_ACCESS_TYPE_READ) || (fAccess & IEM_ACCESS_TYPE_WRITE) || (fAccess & IEM_ACCESS_INSTRUCTION));3869 3870 3884 VMXAPICACCESS enmAccess; 3871 3885 bool const fInEventDelivery = IEMGetCurrentXcpt(pVCpu, NULL, NULL, NULL, NULL); 3872 3886 if (fInEventDelivery) 3873 3887 enmAccess = VMXAPICACCESS_LINEAR_EVENT_DELIVERY; 3874 else if ( fAccess &IEM_ACCESS_INSTRUCTION)3888 else if ((fAccess & (IEM_ACCESS_WHAT_MASK | IEM_ACCESS_TYPE_MASK)) == IEM_ACCESS_INSTRUCTION) 3875 3889 enmAccess = VMXAPICACCESS_LINEAR_INSTR_FETCH; 3876 3890 else if (fAccess & IEM_ACCESS_TYPE_WRITE) … … 4127 4141 * @param offAccess The offset of the register being accessed. 4128 4142 * @param cbAccess The size of the access in bytes. 4129 * @param fAccess The type of access (must be IEM_ACCESS_TYPE_READ or 4130 * IEM_ACCESS_TYPE_WRITE). 4143 * @param fAccess The type of access, see IEM_ACCESS_XXX. 4131 4144 * 4132 4145 * @remarks This must not be used for MSR-based APIC-access page accesses! … … 4136 4149 { 4137 4150 PCVMXVVMCS const pVmcs = &pVCpu->cpum.GstCtx.hwvirt.vmx.Vmcs; 4138 Assert(fAccess == IEM_ACCESS_TYPE_READ || fAccess == IEM_ACCESS_TYPE_WRITE);4139 4151 4140 4152 /* … … 4297 4309 * 4298 4310 * @param pVCpu The cross context virtual CPU structure. 4299 * @param pGCPhysAccess Pointer to the guest-physical address used. 4300 */ 4301 IEM_STATIC VBOXSTRICTRC iemVmxVirtApicAccessUnused(PVMCPUCC pVCpu, PRTGCPHYS pGCPhysAccess) 4311 * @param pGCPhysAccess Pointer to the guest-physical address accessed. 4312 * @param fAccess The type of access, see IEM_ACCESS_XXX. 4313 */ 4314 IEM_STATIC VBOXSTRICTRC iemVmxVirtApicAccessUnused(PVMCPUCC pVCpu, PRTGCPHYS pGCPhysAccess, uint32_t fAccess) 4302 4315 { 4303 4316 Assert(pVCpu->cpum.GstCtx.hwvirt.vmx.Vmcs.u32ProcCtls2 & VMX_PROC_CTLS2_VIRT_APIC_ACCESS); … … 4311 4324 { 4312 4325 uint16_t const offAccess = *pGCPhysAccess & GUEST_PAGE_OFFSET_MASK; 4313 uint32_t const fAccess = IEM_ACCESS_TYPE_READ;4314 4326 uint16_t const cbAccess = 1; 4315 4327 bool const fIntercept = iemVmxVirtApicIsMemAccessIntercepted(pVCpu, offAccess, cbAccess, fAccess); … … 4338 4350 * @param pvData Pointer to the data being written or where to store the data 4339 4351 * being read. 4340 * @param fAccess The type of access (must contain IEM_ACCESS_TYPE_READ or 4341 * IEM_ACCESS_TYPE_WRITE or IEM_ACCESS_INSTRUCTION). 4352 * @param fAccess The type of access, see IEM_ACCESS_XXX. 4342 4353 */ 4343 4354 IEM_STATIC VBOXSTRICTRC iemVmxVirtApicAccessMem(PVMCPUCC pVCpu, uint16_t offAccess, size_t cbAccess, void *pvData, … … 4346 4357 Assert(pVCpu->cpum.GstCtx.hwvirt.vmx.Vmcs.u32ProcCtls2 & VMX_PROC_CTLS2_VIRT_APIC_ACCESS); 4347 4358 Assert(pvData); 4348 Assert( (fAccess & IEM_ACCESS_TYPE_READ)4349 || (fAccess & IEM_ACCESS_TYPE_WRITE)4350 || (fAccess & IEM_ACCESS_INSTRUCTION));4351 4359 4352 4360 bool const fIntercept = iemVmxVirtApicIsMemAccessIntercepted(pVCpu, offAccess, cbAccess, fAccess); … … 4389 4397 * See Intel spec. 29.4.2 "Virtualizing Reads from the APIC-Access Page". 4390 4398 */ 4399 Assert(fAccess & IEM_ACCESS_TYPE_READ); 4400 4391 4401 Assert(cbAccess <= 4); 4392 4402 Assert(offAccess < XAPIC_OFF_END + 4);
Note:
See TracChangeset
for help on using the changeset viewer.