Changeset 74103 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Sep 6, 2018 4:57:57 AM (6 years ago)
- Location:
- trunk/src/VBox/VMM/VMMAll
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/HMVMXAll.cpp
r74073 r74103 142 142 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_EntryCtlsAllowed1 , "EntryCtlsAllowed1" ), 143 143 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_EntryCtlsDisallowed0 , "EntryCtlsDisallowed0" ), 144 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_EntryHostCr0Fixed0 , "EntryHostCr0Fixed0" ), 145 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_EntryHostCr0Fixed1 , "EntryHostCr0Fixed1" ), 146 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_EntryHostCr3 , "EntryHostCr3" ), 147 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_EntryHostCr4Fixed0 , "EntryHostCr4Fixed0" ), 148 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_EntryHostCr4Fixed1 , "EntryHostCr4Fixed1" ), 149 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_EntryHostSysenterEspEip , "EntryHostSysenterEspEip" ), 150 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_EntryHostPatMsr , "EntryHostPatMsr" ), 144 151 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_EntryInstrLen , "EntryInstrLen" ), 145 152 VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_EntryInstrLenZero , "EntryInstrLenZero" ), -
trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h
r74074 r74103 1004 1004 1005 1005 /* 1006 * Handle exceptions for certain instructions.1007 * (e.g. some instructions convey an instruction identity ).1006 * Handle exceptions to the norm for certain instructions. 1007 * (e.g. some instructions convey an instruction identity in place of iReg2). 1008 1008 */ 1009 1009 switch (uExitReason) … … 1092 1092 { 1093 1093 iemVmxVmFailValid(pVCpu, enmInsErr); 1094 /** @todo Set VM-instruction error field in the current virtual-VMCS. 1094 /** @todo Set VM-instruction error field in the current virtual-VMCS. */ 1095 1095 } 1096 1096 else … … 1576 1576 if (IEM_VMX_GET_CURRENT_VMCS(pVCpu) == GCPhysVmcs) 1577 1577 { 1578 Assert(GCPhysVmcs != NIL_RTGCPHYS); /* Paranoia. */ 1578 Assert(GCPhysVmcs != NIL_RTGCPHYS); /* Paranoia. */ 1579 Assert(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs)); 1579 1580 pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs)->fVmcsState = fVmcsStateClear; 1580 1581 iemVmxCommitCurrentVmcsToMemory(pVCpu); … … 1958 1959 1959 1960 /** 1961 * Clears the high 32-bits of all natural-width fields in the given VMCS. 1962 * 1963 * @param pVmcs Pointer to the virtual VMCS. 1964 */ 1965 IEM_STATIC void iemVmxVmcsFixNaturalWidthFields(PVMXVVMCS pVmcs) 1966 { 1967 /* Natural-width Control fields. */ 1968 pVmcs->u64Cr0Mask.s.Hi = 0; 1969 pVmcs->u64Cr4Mask.s.Hi = 0; 1970 pVmcs->u64Cr0ReadShadow.s.Hi = 0; 1971 pVmcs->u64Cr4ReadShadow.s.Hi = 0; 1972 pVmcs->u64Cr3Target0.s.Hi = 0; 1973 pVmcs->u64Cr3Target1.s.Hi = 0; 1974 pVmcs->u64Cr3Target2.s.Hi = 0; 1975 pVmcs->u64Cr3Target3.s.Hi = 0; 1976 1977 /* Natural-width Read-only data fields. */ 1978 pVmcs->u64ExitQual.s.Hi = 0; 1979 pVmcs->u64IoRcx.s.Hi = 0; 1980 pVmcs->u64IoRsi.s.Hi = 0; 1981 pVmcs->u64IoRdi.s.Hi = 0; 1982 pVmcs->u64IoRip.s.Hi = 0; 1983 pVmcs->u64GuestLinearAddr.s.Hi = 0; 1984 1985 /* Natural-width Guest-state Fields. */ 1986 pVmcs->u64GuestCr0.s.Hi = 0; 1987 pVmcs->u64GuestCr3.s.Hi = 0; 1988 pVmcs->u64GuestCr4.s.Hi = 0; 1989 pVmcs->u64GuestEsBase.s.Hi = 0; 1990 pVmcs->u64GuestCsBase.s.Hi = 0; 1991 pVmcs->u64GuestSsBase.s.Hi = 0; 1992 pVmcs->u64GuestDsBase.s.Hi = 0; 1993 pVmcs->u64GuestFsBase.s.Hi = 0; 1994 pVmcs->u64GuestGsBase.s.Hi = 0; 1995 pVmcs->u64GuestLdtrBase.s.Hi = 0; 1996 pVmcs->u64GuestTrBase.s.Hi = 0; 1997 pVmcs->u64GuestGdtrBase.s.Hi = 0; 1998 pVmcs->u64GuestIdtrBase.s.Hi = 0; 1999 pVmcs->u64GuestDr7.s.Hi = 0; 2000 pVmcs->u64GuestRsp.s.Hi = 0; 2001 pVmcs->u64GuestRip.s.Hi = 0; 2002 pVmcs->u64GuestRFlags.s.Hi = 0; 2003 pVmcs->u64GuestPendingDbgXcpt.s.Hi = 0; 2004 pVmcs->u64GuestSysenterEsp.s.Hi = 0; 2005 pVmcs->u64GuestSysenterEip.s.Hi = 0; 2006 2007 /* Natural-width Host-state fields. */ 2008 pVmcs->u64HostCr0.s.Hi = 0; 2009 pVmcs->u64HostCr3.s.Hi = 0; 2010 pVmcs->u64HostCr4.s.Hi = 0; 2011 pVmcs->u64HostFsBase.s.Hi = 0; 2012 pVmcs->u64HostGsBase.s.Hi = 0; 2013 pVmcs->u64HostTrBase.s.Hi = 0; 2014 pVmcs->u64HostGdtrBase.s.Hi = 0; 2015 pVmcs->u64HostIdtrBase.s.Hi = 0; 2016 pVmcs->u64HostSysenterEsp.s.Hi = 0; 2017 pVmcs->u64HostSysenterEip.s.Hi = 0; 2018 pVmcs->u64HostRsp.s.Hi = 0; 2019 pVmcs->u64HostRip.s.Hi = 0; 2020 } 2021 2022 2023 /** 2024 * Checks host state as part of VM-entry. 2025 * 2026 * @returns VBox status code. 2027 * @param pVCpu The cross context virtual CPU structure. 2028 * @param pszInstr The VMX instruction name (for logging purposes). 2029 */ 2030 IEM_STATIC VBOXSTRICTRC iemVmxVmentryCheckHostState(PVMCPU pVCpu, const char *pszInstr) 2031 { 2032 PCVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs); 2033 2034 /* CR0 reserved bits. */ 2035 { 2036 /* CR0 MB1 bits. */ 2037 uint64_t const u64Cr0Fixed0 = CPUMGetGuestIa32VmxCr0Fixed0(pVCpu); 2038 if (~pVmcs->u64HostCr0.u & u64Cr0Fixed0) 2039 { 2040 Log(("%s: Invalid host CR0 %#RX32 (fixed0) -> VMFail\n", pszInstr, pVmcs->u64HostCr0)); 2041 pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_EntryHostCr0Fixed0; 2042 return VERR_VMX_VMENTRY_FAILED; 2043 } 2044 2045 /* CR0 MBZ bits. */ 2046 uint64_t const u64Cr0Fixed1 = CPUMGetGuestIa32VmxCr0Fixed1(pVCpu); 2047 if (pVmcs->u64HostCr0.u & ~u64Cr0Fixed1) 2048 { 2049 Log(("%s: Invalid host CR0 %#RX32 (fixed1) -> VMFail\n", pszInstr, pVmcs->u64HostCr0)); 2050 pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_EntryHostCr0Fixed1; 2051 return VERR_VMX_VMENTRY_FAILED; 2052 } 2053 } 2054 2055 /* CR4 reserved bits. */ 2056 { 2057 /* CR4 MB1 bits. */ 2058 uint64_t const u64Cr4Fixed0 = CPUMGetGuestIa32VmxCr4Fixed0(pVCpu); 2059 if (~pVmcs->u64HostCr4.u & u64Cr4Fixed0) 2060 { 2061 Log(("%s: Invalid host CR4 %#RX64 (fixed0) -> VMFail\n", pszInstr, pVmcs->u64HostCr4)); 2062 pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_EntryHostCr4Fixed0; 2063 return VERR_VMX_VMENTRY_FAILED; 2064 } 2065 2066 /* CR4 MBZ bits. */ 2067 uint64_t const u64Cr4Fixed1 = CPUMGetGuestIa32VmxCr4Fixed1(pVCpu); 2068 if (pVmcs->u64HostCr4.u & ~u64Cr4Fixed1) 2069 { 2070 Log(("%s: Invalid host CR4 %#RX64 (fixed1) -> VMFail\n", pszInstr, pVmcs->u64HostCr4)); 2071 pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_EntryHostCr4Fixed1; 2072 return VERR_VMX_VMENTRY_FAILED; 2073 } 2074 } 2075 2076 if (IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fLongMode) 2077 { 2078 /* CR3 reserved bits. */ 2079 uint8_t const cMaxPhysAddrWidth = IEM_GET_GUEST_CPU_FEATURES(pVCpu)->cMaxPhysAddrWidth; 2080 if (pVmcs->u64HostCr3.u >> cMaxPhysAddrWidth) 2081 { 2082 Log(("%s: Invalid host CR3 %#RX64 -> VMFail\n", pszInstr, pVmcs->u64HostCr3)); 2083 pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_EntryHostCr3; 2084 return VERR_VMX_VMENTRY_FAILED; 2085 } 2086 2087 /* SYSENTER ESP and SYSENTER EIP. */ 2088 if ( X86_IS_CANONICAL(pVmcs->u64HostSysenterEsp.u) 2089 && X86_IS_CANONICAL(pVmcs->u64HostSysenterEip.u)) 2090 { /* likely */ } 2091 else 2092 { 2093 Log(("%s: Host Sysenter ESP (%#RX64) / EIP (%#RX64) not canonical -> VMFail\n", pszInstr, 2094 pVmcs->u64HostSysenterEsp.u, pVmcs->u64HostSysenterEip.u)); 2095 pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_EntryHostSysenterEspEip; 2096 return VERR_VMX_VMENTRY_FAILED; 2097 } 2098 } 2099 2100 /* PAT MSR. */ 2101 if ( IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fVmxExitLoadPatMsr 2102 && !CPUMIsPatMsrValid(pVmcs->u64HostPatMsr.u)) 2103 { 2104 Log(("%s: Host PAT MSR (%#RX64) invalid\n", pszInstr, pVmcs->u64HostPatMsr.u)); 2105 pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_EntryHostPatMsr; 2106 return VERR_VMX_VMENTRY_FAILED; 2107 } 2108 2109 /** @todo NSTVMX: EFER and others. */ 2110 2111 Assert(!(pVmcs->u32ExitCtls & VMX_EXIT_CTLS_LOAD_PERF_MSR)); /* We don't support loading IA32_PERF_GLOBAL_CTRL MSR yet. */ 2112 2113 NOREF(pszInstr); 2114 return VINF_SUCCESS; 2115 } 2116 2117 2118 /** 1960 2119 * Checks VM-entry controls fields as part of VM-entry. 1961 2120 * See Intel spec. 26.2.1.3 "VM-Entry Control Fields". … … 2056 2215 } 2057 2216 2058 /* Zero instruction length is only allowed when the CPU supports it explicitly.*/2217 /* Zero instruction length is allowed only when the CPU supports it explicitly. */ 2059 2218 if ( pVmcs->u32EntryInstrLen == 0 2060 2219 && !IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fVmxEntryInjectSoftInt) … … 2166 2325 * @param pVCpu The cross context virtual CPU structure. 2167 2326 * @param pszInstr The VMX instruction name (for logging purposes). 2327 * 2328 * @remarks This may update secondary-processor based VM-execution control fields 2329 * in the current VMCS if necessary. 2168 2330 */ 2169 2331 IEM_STATIC VBOXSTRICTRC iemVmxVmentryCheckExecCtls(PVMCPU pVCpu, const char *pszInstr) … … 2225 2387 } 2226 2388 else 2389 { 2390 /* 2391 * The guest is always capable of corrupting the VMCS by writing to the VMCS is guest 2392 * memory directly rather than follow the rules. So we don't make any assumptions that 2393 * u32ProcCtls2 will be 0 if no secondary-processor based VM-execution control support 2394 * is reported to the guest. 2395 */ 2227 2396 pVmcs->u32ProcCtls2 = 0; 2397 } 2228 2398 2229 2399 /* CR3-target count. */ … … 2287 2457 2288 2458 /* Read the Virtual-APIC page. */ 2459 Assert(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvVirtApicPage)); 2289 2460 int rc = PGMPhysSimpleReadGCPhys(pVCpu->CTX_SUFF(pVM), pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvVirtApicPage), 2290 2461 GCPhysVirtApic, VMX_V_VIRT_APIC_PAGES); … … 2441 2612 2442 2613 /* Read the VMREAD-bitmap. */ 2614 Assert(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvVmreadBitmap)); 2443 2615 int rc = PGMPhysSimpleReadGCPhys(pVCpu->CTX_SUFF(pVM), pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvVmreadBitmap), 2444 2616 GCPhysVmreadBitmap, VMX_V_VMREAD_VMWRITE_BITMAP_SIZE); … … 2451 2623 2452 2624 /* Read the VMWRITE-bitmap. */ 2625 Assert(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvVmwriteBitmap)); 2453 2626 rc = PGMPhysSimpleReadGCPhys(pVCpu->CTX_SUFF(pVM), pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvVmwriteBitmap), 2454 2627 GCPhysVmwriteBitmap, VMX_V_VMREAD_VMWRITE_BITMAP_SIZE); … … 2550 2723 * Load the current VMCS. 2551 2724 */ 2725 Assert(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs)); 2552 2726 int rc = PGMPhysSimpleReadGCPhys(pVCpu->CTX_SUFF(pVM), pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs), 2553 2727 IEM_VMX_GET_CURRENT_VMCS(pVCpu), VMX_V_VMCS_SIZE); … … 2558 2732 return rc; 2559 2733 } 2734 2735 /* 2736 * Clear the high 32-bits of all natural-width fields in the VMCS if the guest 2737 * does not support long mode. 2738 */ 2739 if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fLongMode) 2740 iemVmxVmcsFixNaturalWidthFields(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs)); 2560 2741 2561 2742 /* … … 2594 2775 { 2595 2776 iemVmxVmFail(pVCpu, VMXINSTRERR_VMENTRY_INVALID_CTLS); 2777 iemRegAddToRipAndClearRF(pVCpu, cbInstr); 2778 return VINF_SUCCESS; 2779 } 2780 2781 /* 2782 * Check host-state fields. 2783 */ 2784 rc = iemVmxVmentryCheckHostState(pVCpu, pszInstr); 2785 if (rc == VINF_SUCCESS) 2786 { /* likely */ } 2787 else 2788 { 2789 iemVmxVmFail(pVCpu, VMXINSTRERR_VMENTRY_INVALID_HOST_STATE); 2596 2790 iemRegAddToRipAndClearRF(pVCpu, cbInstr); 2597 2791 return VINF_SUCCESS;
Note:
See TracChangeset
for help on using the changeset viewer.