Changeset 43307 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Sep 12, 2012 11:13:58 AM (13 years ago)
- svn:sync-xref-src-repo-rev:
- 80728
- Location:
- trunk/src/VBox/VMM/VMMR0
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp
r43303 r43307 91 91 DECLR0CALLBACKMEMBER(int, pfnLoadGuestState,(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)); 92 92 DECLR0CALLBACKMEMBER(int, pfnRunGuestCode,(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)); 93 DECLR0CALLBACKMEMBER(int, pfnEnableCpu,(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage)); 93 DECLR0CALLBACKMEMBER(int, pfnEnableCpu,(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage, 94 bool fEnabledByHost)); 94 95 DECLR0CALLBACKMEMBER(int, pfnDisableCpu,(PHMGLOBLCPUINFO pCpu, void *pvCpuPage, RTHCPHYS HCPhysCpuPage)); 95 96 DECLR0CALLBACKMEMBER(int, pfnInitVM,(PVM pVM)); … … 251 252 } 252 253 253 static DECLCALLBACK(int) hmR0DummyEnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage) 254 { 255 NOREF(pCpu); NOREF(pVM); NOREF(pvCpuPage); NOREF(HCPhysCpuPage); 254 static DECLCALLBACK(int) hmR0DummyEnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage, 255 bool fEnabledBySystem) 256 { 257 NOREF(pCpu); NOREF(pVM); NOREF(pvCpuPage); NOREF(HCPhysCpuPage); NOREF(fEnabledBySystem); 256 258 return VINF_SUCCESS; 257 259 } … … 467 469 g_HvmR0.vmx.fSupported = true; 468 470 VMXDisable(); 469 470 /*471 * Check for the VMX-Preemption Timer and adjust for the * "VMX-Preemption472 * Timer Does Not Count Down at the Rate Specified" erratum.473 */474 if ( g_HvmR0.vmx.msr.vmx_pin_ctls.n.allowed1475 & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER)476 {477 g_HvmR0.vmx.fUsePreemptTimer = true;478 g_HvmR0.vmx.cPreemptTimerShift = MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT(g_HvmR0.vmx.msr.vmx_misc);479 if (hmR0InitIntelIsSubjectToVmxPreemptionTimerErratum())480 g_HvmR0.vmx.cPreemptTimerShift = 0; /* This is about right most of the time here. */481 }482 471 } 483 472 else … … 512 501 } 513 502 514 /*515 * Install the VT-x methods.516 */517 503 if (g_HvmR0.vmx.fSupported) 518 504 { 505 /* 506 * Install the VT-x methods. 507 */ 519 508 g_HvmR0.pfnEnterSession = VMXR0Enter; 520 509 g_HvmR0.pfnLeaveSession = VMXR0Leave; … … 527 516 g_HvmR0.pfnTermVM = VMXR0TermVM; 528 517 g_HvmR0.pfnSetupVM = VMXR0SetupVM; 518 519 /* 520 * Check for the VMX-Preemption Timer and adjust for the * "VMX-Preemption 521 * Timer Does Not Count Down at the Rate Specified" erratum. 522 */ 523 if ( g_HvmR0.vmx.msr.vmx_pin_ctls.n.allowed1 524 & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER) 525 { 526 g_HvmR0.vmx.fUsePreemptTimer = true; 527 g_HvmR0.vmx.cPreemptTimerShift = MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT(g_HvmR0.vmx.msr.vmx_misc); 528 if (hmR0InitIntelIsSubjectToVmxPreemptionTimerErratum()) 529 g_HvmR0.vmx.cPreemptTimerShift = 0; /* This is about right most of the time here. */ 530 } 529 531 } 530 532 } … … 864 866 PHMGLOBLCPUINFO pCpu = &g_HvmR0.aCpuInfo[idCpu]; 865 867 866 Assert(!g_HvmR0.vmx.fSupported || !g_HvmR0.vmx.fUsingSUPR0EnableVTx);867 868 Assert(idCpu == (RTCPUID)RTMpCpuIdToSetIndex(idCpu)); /// @todo fix idCpu == index assumption (rainy day) 868 869 Assert(idCpu < RT_ELEMENTS(g_HvmR0.aCpuInfo)); … … 874 875 /* Do NOT reset cTLBFlushes here, see @bugref{6255}. */ 875 876 876 /* Should never happen */ 877 AssertLogRelMsgReturn(pCpu->hMemObj != NIL_RTR0MEMOBJ, ("hmR0EnableCpu failed idCpu=%u.\n", idCpu), VERR_HM_IPE_1); 878 879 void *pvCpuPage = RTR0MemObjAddress(pCpu->hMemObj); 880 RTHCPHYS HCPhysCpuPage = RTR0MemObjGetPagePhysAddr(pCpu->hMemObj, 0); 881 882 int rc = g_HvmR0.pfnEnableCpu(pCpu, pVM, pvCpuPage, HCPhysCpuPage); 877 int rc; 878 if (g_HvmR0.vmx.fSupported && g_HvmR0.vmx.fUsingSUPR0EnableVTx) 879 rc = g_HvmR0.pfnEnableCpu(pCpu, pVM, NULL, NIL_RTHCPHYS, true); 880 else 881 { 882 AssertLogRelMsgReturn(pCpu->hMemObj != NIL_RTR0MEMOBJ, ("hmR0EnableCpu failed idCpu=%u.\n", idCpu), VERR_HM_IPE_1); 883 void *pvCpuPage = RTR0MemObjAddress(pCpu->hMemObj); 884 RTHCPHYS HCPhysCpuPage = RTR0MemObjGetPagePhysAddr(pCpu->hMemObj, 0); 885 rc = g_HvmR0.pfnEnableCpu(pCpu, pVM, pvCpuPage, HCPhysCpuPage, false); 886 } 883 887 AssertRC(rc); 884 888 if (RT_SUCCESS(rc)) … … 932 936 g_HvmR0.fGlobalInit = pVM->hwaccm.s.fGlobalInit; 933 937 938 for (unsigned i = 0; i < RT_ELEMENTS(g_HvmR0.aCpuInfo); i++) 939 { 940 Assert(g_HvmR0.aCpuInfo[i].hMemObj == NIL_RTR0MEMOBJ); 941 g_HvmR0.aCpuInfo[i].fConfigured = false; 942 g_HvmR0.aCpuInfo[i].cTLBFlushes = 0; 943 } 944 934 945 int rc; 935 946 if ( g_HvmR0.vmx.fSupported … … 941 952 rc = SUPR0EnableVTx(true /* fEnable */); 942 953 if (RT_SUCCESS(rc)) 943 {944 for (unsigned iCpu = 0; iCpu < RT_ELEMENTS(g_HvmR0.aCpuInfo); iCpu++)945 {946 g_HvmR0.aCpuInfo[iCpu].fConfigured = true;947 g_HvmR0.aCpuInfo[iCpu].cTLBFlushes = 0;948 Assert(g_HvmR0.aCpuInfo[iCpu].hMemObj == NIL_RTR0MEMOBJ);949 }950 951 954 /* If the host provides a VT-x init API, then we'll rely on that for global init. */ 952 955 g_HvmR0.fGlobalInit = pVM->hwaccm.s.fGlobalInit = true; 953 }954 956 else 955 957 AssertMsgFailed(("hmR0EnableAllCpuOnce/SUPR0EnableVTx: rc=%Rrc\n", rc)); … … 973 975 ASMMemZeroPage(pvR0); 974 976 } 975 g_HvmR0.aCpuInfo[i].fConfigured = false;976 g_HvmR0.aCpuInfo[i].cTLBFlushes = 0;977 977 } 978 978 979 if (g_HvmR0.fGlobalInit)980 {981 /* First time, so initialize each cpu/core. */ 982 HMR0FIRSTRC FirstRc;983 hmR0FirstRcInit(&FirstRc);984 rc = RTMpOnAll(hmR0EnableCpuCallback, (void *)pVM, &FirstRc);985 if (RT_SUCCESS(rc))986 rc = hmR0FirstRcGetStatus(&FirstRc);987 AssertMsgRC(rc, ("hmR0EnableAllCpuOnce failed for cpu %d with rc=%d\n", hmR0FirstRcGetCpuId(&FirstRc), rc));988 }989 else990 rc = VINF_SUCCESS;979 rc = VINF_SUCCESS; 980 } 981 982 if (RT_SUCCESS(rc) && g_HvmR0.fGlobalInit) 983 { 984 /* First time, so initialize each cpu/core. */ 985 HMR0FIRSTRC FirstRc; 986 hmR0FirstRcInit(&FirstRc); 987 rc = RTMpOnAll(hmR0EnableCpuCallback, (void *)pVM, &FirstRc); 988 if (RT_SUCCESS(rc)) 989 rc = hmR0FirstRcGetStatus(&FirstRc); 990 AssertMsgRC(rc, ("hmR0EnableAllCpuOnce failed for cpu %d with rc=%d\n", hmR0FirstRcGetCpuId(&FirstRc), rc)); 991 991 } 992 992 … … 1754 1754 void *pvCpuPage = RTR0MemObjAddress(pCpu->hMemObj); 1755 1755 RTHCPHYS HCPhysCpuPage = RTR0MemObjGetPagePhysAddr(pCpu->hMemObj, 0); 1756 return VMXR0EnableCpu(pCpu, pVM, pvCpuPage, HCPhysCpuPage );1756 return VMXR0EnableCpu(pCpu, pVM, pvCpuPage, HCPhysCpuPage, false); 1757 1757 } 1758 1758 -
trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp
r43073 r43307 76 76 * @param HCPhysCpuPage Physical address of the global CPU page. 77 77 */ 78 VMMR0DECL(int) SVMR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage )78 VMMR0DECL(int) SVMR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage, bool fEnabledByHost) 79 79 { 80 AssertReturn(!fEnabledByHost, VERR_INVALID_PARAMETER); 80 81 AssertReturn(HCPhysCpuPage != 0 && HCPhysCpuPage != NIL_RTHCPHYS, VERR_INVALID_PARAMETER); 81 82 AssertReturn(pvCpuPage, VERR_INVALID_PARAMETER); -
trunk/src/VBox/VMM/VMMR0/HWSVMR0.h
r41906 r43307 58 58 VMMR0DECL(int) SVMR0Leave(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); 59 59 60 /** 61 * Sets up and activates AMD-V on the current CPU 62 * 63 * @returns VBox status code. 64 * @param pCpu Pointer to the CPU info struct. 65 * @param pVM Pointer to the VM (can be NULL after a resume!). 66 * @param pvPageCpu Pointer to the global CPU page. 67 * @param pPageCpuPhys Physical address of the global CPU page. 68 */ 69 VMMR0DECL(int) SVMR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS HCPhysCpuPage); 60 VMMR0DECL(int) SVMR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS HCPhysCpuPage, bool fEnabledBySystem); 70 61 71 62 /** -
trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp
r43150 r43307 117 117 * @param pvCpuPage Pointer to the global CPU page. 118 118 * @param HCPhysCpuPage Physical address of the global CPU page. 119 * @param fEnabledByHost Set if SUPR0EnableVTx or similar was used to enable 120 * VT-x/AMD-V on the host. 119 121 */ 120 VMMR0DECL(int) VMXR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage )122 VMMR0DECL(int) VMXR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage, bool fEnabledByHost) 121 123 { 122 AssertReturn(HCPhysCpuPage != 0 && HCPhysCpuPage != NIL_RTHCPHYS, VERR_INVALID_PARAMETER); 123 AssertReturn(pvCpuPage, VERR_INVALID_PARAMETER); 124 125 if (pVM) 126 { 127 /* Set revision dword at the beginning of the VMXON structure. */ 128 *(uint32_t *)pvCpuPage = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(pVM->hwaccm.s.vmx.msr.vmx_basic_info); 129 } 130 131 /** @todo we should unmap the two pages from the virtual address space in order to prevent accidental corruption. 132 * (which can have very bad consequences!!!) 133 */ 134 135 if (ASMGetCR4() & X86_CR4_VMXE) 136 return VERR_VMX_IN_VMX_ROOT_MODE; 137 138 ASMSetCR4(ASMGetCR4() | X86_CR4_VMXE); /* Make sure the VMX instructions don't cause #UD faults. */ 139 140 /* 141 * Enter VM root mode. 142 */ 143 int rc = VMXEnable(HCPhysCpuPage); 144 if (RT_FAILURE(rc)) 145 { 146 ASMSetCR4(ASMGetCR4() & ~X86_CR4_VMXE); 147 return VERR_VMX_VMXON_FAILED; 124 if (!fEnabledByHost) 125 { 126 AssertReturn(HCPhysCpuPage != 0 && HCPhysCpuPage != NIL_RTHCPHYS, VERR_INVALID_PARAMETER); 127 AssertReturn(pvCpuPage, VERR_INVALID_PARAMETER); 128 129 if (pVM) 130 { 131 /* Set revision dword at the beginning of the VMXON structure. */ 132 *(uint32_t *)pvCpuPage = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(pVM->hwaccm.s.vmx.msr.vmx_basic_info); 133 } 134 135 /** @todo we should unmap the two pages from the virtual address space in order to prevent accidental corruption. 136 * (which can have very bad consequences!!!) 137 */ 138 139 if (ASMGetCR4() & X86_CR4_VMXE) 140 return VERR_VMX_IN_VMX_ROOT_MODE; 141 142 ASMSetCR4(ASMGetCR4() | X86_CR4_VMXE); /* Make sure the VMX instructions don't cause #UD faults. */ 143 144 /* 145 * Enter VM root mode. 146 */ 147 int rc = VMXEnable(HCPhysCpuPage); 148 if (RT_FAILURE(rc)) 149 { 150 ASMSetCR4(ASMGetCR4() & ~X86_CR4_VMXE); 151 return VERR_VMX_VMXON_FAILED; 152 } 148 153 } 149 154 -
trunk/src/VBox/VMM/VMMR0/HWVMXR0.h
r41906 r43307 122 122 VMMR0DECL(int) VMXR0Leave(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); 123 123 124 125 /** 126 * Sets up and activates VT-x on the current CPU. 127 * 128 * @returns VBox status code. 129 * @param pCpu Pointer to the CPU info struct. 130 * @param pVM Pointer to the VM. (can be NULL after a resume) 131 * @param pvPageCpu Pointer to the global CPU page. 132 * @param pPageCpuPhys Physical address of the global CPU page. 133 */ 134 VMMR0DECL(int) VMXR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys); 124 VMMR0DECL(int) VMXR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys, bool fEnabledBySystem); 135 125 136 126 /**
Note:
See TracChangeset
for help on using the changeset viewer.