Changeset 7471 in vbox
- Timestamp:
- Mar 17, 2008 10:50:10 AM (17 years ago)
- Location:
- trunk
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/hwaccm.h
r5999 r7471 30 30 #include <VBox/types.h> 31 31 #include <VBox/pgm.h> 32 #include <iprt/mp.h> 32 33 33 34 … … 36 37 */ 37 38 39 /** 40 * HWACCM state 41 */ 42 typedef enum HWACCMSTATE 43 { 44 /* Not yet set */ 45 HWACCMSTATE_UNINITIALIZED = 0, 46 /* Enabled */ 47 HWACCMSTATE_ENABLED, 48 /* Disabled */ 49 HWACCMSTATE_DISABLED, 50 /** The usual 32-bit hack. */ 51 HWACCMSTATE_32BIT_HACK = 0x7fffffff 52 } HWACCMSTATE; 38 53 39 54 __BEGIN_DECLS … … 54 69 55 70 /** 56 * Does Ring-0 HWACCM initialization. 71 * Does global Ring-0 HWACCM initialization. 72 * 73 * @returns VBox status code. 74 */ 75 HWACCMR0DECL(int) HWACCMR0Init(); 76 77 /** 78 * Does global Ring-0 HWACCM termination. 79 * 80 * @returns VBox status code. 81 */ 82 HWACCMR0DECL(int) HWACCMR0Term(); 83 84 /** 85 * Does Ring-0 per VM HWACCM initialization. 57 86 * 58 87 * This is mainly to check that the Host CPU mode is compatible … … 62 91 * @param pVM The VM to operate on. 63 92 */ 64 HWACCMR0DECL(int) HWACCMR0Init(PVM pVM); 93 HWACCMR0DECL(int) HWACCMR0InitVM(PVM pVM); 94 95 /** 96 * Sets up HWACCM on all cpus. 97 * 98 * @returns VBox status code. 99 * @param pVM The VM to operate on. 100 * @param enmNewHwAccmState New hwaccm state 101 * 102 */ 103 HWACCMR0DECL(int) HWACCMR0EnableAllCpus(PVM pVM, HWACCMSTATE enmNewHwAccmState); 65 104 66 105 /** @} */ … … 91 130 92 131 /** 132 * Initialize VT-x or AMD-V 133 * 134 * @returns VBox status code. 135 * @param pVM The VM handle. 136 */ 137 HWACCMR3DECL(int) HWACCMR3InitFinalizeR0(PVM pVM); 138 139 /** 93 140 * Applies relocations to data and code managed by this 94 141 * component. This function will be called at init and … … 165 212 166 213 /** 167 * Does Ring-0 VMX initialization.168 * 169 * @returns VBox status code. 170 * @param pVM The VM to operate on. 171 */ 172 HWACCMR0DECL(int) HWACCMR0SetupVM X(PVM pVM);214 * Sets up a VT-x or AMD-V session 215 * 216 * @returns VBox status code. 217 * @param pVM The VM to operate on. 218 */ 219 HWACCMR0DECL(int) HWACCMR0SetupVM(PVM pVM); 173 220 174 221 … … 182 229 183 230 /** 184 * En able VMX or SVN185 * 186 * @returns VBox status code. 187 * @param pVM The VM to operate on. 188 */ 189 HWACCMR0DECL(int) HWACCMR0En able(PVM pVM);190 191 192 /** 193 * Disable VMX or SVN194 * 195 * @returns VBox status code. 196 * @param pVM The VM to operate on. 197 */ 198 HWACCMR0DECL(int) HWACCMR0 Disable(PVM pVM);231 * Enters the VT-x or AMD-V session 232 * 233 * @returns VBox status code. 234 * @param pVM The VM to operate on. 235 */ 236 HWACCMR0DECL(int) HWACCMR0Enter(PVM pVM); 237 238 239 /** 240 * Leaves the VT-x or AMD-V session 241 * 242 * @returns VBox status code. 243 * @param pVM The VM to operate on. 244 */ 245 HWACCMR0DECL(int) HWACCMR0Leave(PVM pVM); 199 246 200 247 -
trunk/src/VBox/VMM/HWACCM.cpp
r5999 r7471 91 91 return rc; 92 92 93 /** @todo Make sure both pages are either not accessible or readonly! */94 /* Allocate one page for VMXON. */95 pVM->hwaccm.s.vmx.pVMXON = SUPContAlloc(1, &pVM->hwaccm.s.vmx.pVMXONPhys);96 if (pVM->hwaccm.s.vmx.pVMXON == 0)97 {98 AssertMsgFailed(("SUPContAlloc failed!!\n"));99 return VERR_NO_MEMORY;100 }101 memset(pVM->hwaccm.s.vmx.pVMXON, 0, PAGE_SIZE);102 103 93 /* Allocate one page for the VM control structure (VMCS). */ 104 94 pVM->hwaccm.s.vmx.pVMCS = SUPContAlloc(1, &pVM->hwaccm.s.vmx.pVMCSPhys); … … 121 111 122 112 /* Reuse those three pages for AMD SVM. (one is active; never both) */ 123 pVM->hwaccm.s.svm.pHState = pVM->hwaccm.s.vmx.pVMXON;124 pVM->hwaccm.s.svm.pHStatePhys = pVM->hwaccm.s.vmx.pVMXONPhys;125 113 pVM->hwaccm.s.svm.pVMCB = pVM->hwaccm.s.vmx.pVMCS; 126 114 pVM->hwaccm.s.svm.pVMCBPhys = pVM->hwaccm.s.vmx.pVMCSPhys; … … 262 250 263 251 /** 264 * Applies relocations to data and code managed by this 265 * component. This function will be called at init and 266 * whenever the VMM need to relocate it self inside the GC. 267 * 268 * @param pVM The VM. 269 */ 270 HWACCMR3DECL(void) HWACCMR3Relocate(PVM pVM) 271 { 272 #ifdef LOG_ENABLED 273 Log(("HWACCMR3Relocate to %VGv\n", MMHyperGetArea(pVM, 0))); 274 #endif 252 * Initialize VT-x or AMD-V. 253 * 254 * @returns VBox status code. 255 * @param pVM The VM handle. 256 */ 257 HWACCMR3DECL(int) HWACCMR3InitFinalizeR0(PVM pVM) 258 { 259 int rc; 260 261 /* 262 * Note that we have a global setting for VT-x/AMD-V usage. VMX root mode changes the way the CPU operates. Our 64 bits switcher will trap 263 * because it turns off paging, which is not allowed in VMX root mode. 264 * 265 * To simplify matters we'll just force all running VMs to either use raw or hwaccm mode. No mixing allowed. 266 * 267 */ 268 269 /* If we enabled or disabled hwaccm mode, then it can't be changed until all the VMs are shutdown. */ 270 rc = SUPCallVMMR0Ex(pVM->pVMR0, VMMR0_DO_HWACC_ENABLE, (pVM->hwaccm.s.fAllowed) ? HWACCMSTATE_ENABLED : HWACCMSTATE_DISABLED, NULL); 271 if (VBOX_FAILURE(rc)) 272 { 273 LogRel(("HWACCMR3InitFinalize: SUPCallVMMR0Ex VMMR0_DO_HWACC_ENABLE failed with %Vrc\n", rc)); 274 LogRel(("HWACCMR3InitFinalize: disallowed %s of HWACCM\n", pVM->hwaccm.s.fAllowed ? "enabling" : "disabling")); 275 /* Invert the selection */ 276 pVM->hwaccm.s.fAllowed ^= 1; 277 LogRel(("HWACCMR3InitFinalize: new HWACCM status = %s\n", pVM->hwaccm.s.fAllowed ? "enabled" : "disabled")); 278 } 275 279 276 280 if (pVM->hwaccm.s.fAllowed == false) 277 return ; 281 return VINF_SUCCESS; /* disabled */ 282 283 Assert(!pVM->fHWACCMEnabled); 278 284 279 285 if (pVM->hwaccm.s.vmx.fSupported) … … 424 430 memset(pVM->hwaccm.s.vmx.pRealModeTSS->IntRedirBitmap, 0x0, sizeof(pVM->hwaccm.s.vmx.pRealModeTSS->IntRedirBitmap)); 425 431 426 intrc = SUPCallVMMR0Ex(pVM->pVMR0, VMMR0_DO_HWACC_SETUP_VM, 0, NULL);432 rc = SUPCallVMMR0Ex(pVM->pVMR0, VMMR0_DO_HWACC_SETUP_VM, 0, NULL); 427 433 AssertRC(rc); 428 434 if (rc == VINF_SUCCESS) … … 458 464 pVM->hwaccm.s.fInitialized = true; 459 465 460 intrc = SUPCallVMMR0Ex(pVM->pVMR0, VMMR0_DO_HWACC_SETUP_VM, 0, NULL);466 rc = SUPCallVMMR0Ex(pVM->pVMR0, VMMR0_DO_HWACC_SETUP_VM, 0, NULL); 461 467 AssertRC(rc); 462 468 if (rc == VINF_SUCCESS) … … 480 486 LogRel(("HWACCM: VMX MSR_IA32_FEATURE_CONTROL=%VX64\n", pVM->hwaccm.s.vmx.msr.feature_ctrl)); 481 487 } 482 488 return VINF_SUCCESS; 489 } 490 491 /** 492 * Applies relocations to data and code managed by this 493 * component. This function will be called at init and 494 * whenever the VMM need to relocate it self inside the GC. 495 * 496 * @param pVM The VM. 497 */ 498 HWACCMR3DECL(void) HWACCMR3Relocate(PVM pVM) 499 { 500 Log(("HWACCMR3Relocate to %VGv\n", MMHyperGetArea(pVM, 0))); 501 return; 483 502 } 484 503 … … 526 545 } 527 546 528 if (pVM->hwaccm.s.vmx.pVMXON)529 {530 SUPContFree(pVM->hwaccm.s.vmx.pVMXON, 1);531 pVM->hwaccm.s.vmx.pVMXON = 0;532 }533 547 if (pVM->hwaccm.s.vmx.pVMCS) 534 548 { -
trunk/src/VBox/VMM/HWACCMInternal.h
r5999 r7471 154 154 void *pVMCS; 155 155 156 /** Physical address of the VMXON page. */157 RTHCPHYS pVMXONPhys;158 /** Virtual address of the VMXON page. */159 void *pVMXON;160 161 156 /** Physical address of the TSS page used for real mode emulation. */ 162 157 RTHCPHYS pRealModeTSSPhys; … … 165 160 166 161 /** Host CR4 value (set by ring-0 VMX init) */ 167 uint 32_t hostCR4;162 uint64_t hostCR4; 168 163 169 164 /** Current VMX_VMCS_CTRL_PROC_EXEC_CONTROLS. */ … … 216 211 /** Virtual address of the host VM control block (VMCB). */ 217 212 void *pVMCBHost; 218 219 /** Physical address of the Host State page. */220 RTHCPHYS pHStatePhys;221 /** Virtual address of the Host State page. */222 void *pHState;223 213 224 214 /** Physical address of the IO bitmap (12kb). */ -
trunk/src/VBox/VMM/VM.cpp
r6799 r7471 694 694 if (VBOX_SUCCESS(rc)) 695 695 rc = vmR3InitDoCompleted(pVM, VMINITCOMPLETED_RING0); 696 697 /** todo: move this to the VMINITCOMPLETED_RING0 notification handler once implemented */ 698 if (VBOX_SUCCESS(rc)) 699 rc = HWACCMR3InitFinalizeR0(pVM); 700 696 701 LogFlow(("vmR3InitRing0: returns %Vrc\n", rc)); 697 702 return rc; -
trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp
r7105 r7471 36 36 #include <iprt/assert.h> 37 37 #include <iprt/asm.h> 38 #include <iprt/string.h> 39 #include <iprt/memobj.h> 40 #include <iprt/cpuset.h> 38 41 #include "HWVMXR0.h" 39 42 #include "HWSVMR0.h" 40 43 41 /** 42 * Does Ring-0 HWACCM initialization. 43 * 44 * This is mainly to check that the Host CPU mode is compatible 45 * with VMX. 44 /******************************************************************************* 45 * Internal Functions * 46 *******************************************************************************/ 47 static DECLCALLBACK(void) HWACCMR0EnableCPU(RTCPUID idCpu, void *pvUser1, void *pvUser2); 48 static DECLCALLBACK(void) HWACCMR0DisableCPU(RTCPUID idCpu, void *pvUser1, void *pvUser2); 49 50 /******************************************************************************* 51 * Local Variables * 52 *******************************************************************************/ 53 static struct 54 { 55 struct 56 { 57 RTR0MEMOBJ pMemObj; 58 bool fVMXConfigured; 59 bool fSVMConfigured; 60 } aCpuInfo[RTCPUSET_MAX_CPUS]; 61 62 struct 63 { 64 /** Set by the ring-0 driver to indicate VMX is supported by the CPU. */ 65 bool fSupported; 66 67 /** Host CR4 value (set by ring-0 VMX init) */ 68 uint64_t hostCR4; 69 70 /** VMX MSR values */ 71 struct 72 { 73 uint64_t feature_ctrl; 74 uint64_t vmx_basic_info; 75 uint64_t vmx_pin_ctls; 76 uint64_t vmx_proc_ctls; 77 uint64_t vmx_exit; 78 uint64_t vmx_entry; 79 uint64_t vmx_misc; 80 uint64_t vmx_cr0_fixed0; 81 uint64_t vmx_cr0_fixed1; 82 uint64_t vmx_cr4_fixed0; 83 uint64_t vmx_cr4_fixed1; 84 uint64_t vmx_vmcs_enum; 85 } msr; 86 /* Last instruction error */ 87 uint32_t ulLastInstrError; 88 } vmx; 89 struct 90 { 91 /** Set by the ring-0 driver to indicate SVM is supported by the CPU. */ 92 bool fSupported; 93 94 /** SVM revision. */ 95 uint32_t u32Rev; 96 97 /** Maximum ASID allowed. */ 98 uint32_t u32MaxASID; 99 } svm; 100 /** Saved error from detection */ 101 int32_t lLastError; 102 103 struct 104 { 105 uint32_t u32AMDFeatureECX; 106 uint32_t u32AMDFeatureEDX; 107 } cpuid; 108 109 HWACCMSTATE enmHwAccmState; 110 } HWACCMR0Globals; 111 112 113 114 /** 115 * Does global Ring-0 HWACCM initialization. 46 116 * 47 117 * @returns VBox status code. 48 * @param pVM The VM to operate on. 49 */ 50 HWACCMR0DECL(int) HWACCMR0Init(PVM pVM) 51 { 52 LogComFlow(("HWACCMR0Init: %p\n", pVM)); 53 54 pVM->hwaccm.s.vmx.fSupported = false;; 55 pVM->hwaccm.s.svm.fSupported = false;; 118 */ 119 HWACCMR0DECL(int) HWACCMR0Init() 120 { 121 int rc; 122 RTR0MEMOBJ pScatchMemObj; 123 void *pvScatchPage; 124 RTHCPHYS pScatchPagePhys; 125 126 memset(&HWACCMR0Globals, 0, sizeof(HWACCMR0Globals)); 127 HWACCMR0Globals.enmHwAccmState = HWACCMSTATE_UNINITIALIZED; 128 129 rc = RTR0MemObjAllocCont(&pScatchMemObj, 1 << PAGE_SHIFT, true /* executable R0 mapping */); 130 if (RT_FAILURE(rc)) 131 return rc; 132 133 pvScatchPage = RTR0MemObjAddress(pScatchMemObj); 134 pScatchPagePhys = RTR0MemObjGetPagePhysAddr(pScatchMemObj, 0); 135 memset(pvScatchPage, 0, PAGE_SIZE); 136 137 /* Assume success */ 138 rc = VINF_SUCCESS; 56 139 57 140 #ifndef VBOX_WITH_HYBIRD_32BIT_KERNEL /* paranoia */ 58 141 59 pVM->hwaccm.s.fHWACCMR0Init = true;60 pVM->hwaccm.s.lLastError = VINF_SUCCESS;61 62 142 /* 63 * Check for V MXcapabilities143 * Check for VT-x and AMD-V capabilities 64 144 */ 65 145 if (ASMHasCpuId()) … … 70 150 uint32_t u32VendorEBX, u32VendorECX, u32VendorEDX; 71 151 152 /* Make sure we don't get rescheduled to another cpu during this probe. */ 153 RTCCUINTREG fFlags = ASMIntDisableFlags(); 154 72 155 ASMCpuId(0, &u32Dummy, &u32VendorEBX, &u32VendorECX, &u32VendorEDX); 73 156 ASMCpuId(1, &u32Dummy, &u32Dummy, &u32FeaturesECX, &u32FeaturesEDX); 74 157 /* Query AMD features. */ 75 ASMCpuId(0x80000001, &u32Dummy, &u32Dummy, & pVM->hwaccm.s.cpuid.u32AMDFeatureECX, &pVM->hwaccm.s.cpuid.u32AMDFeatureEDX);158 ASMCpuId(0x80000001, &u32Dummy, &u32Dummy, &HWACCMR0Globals.cpuid.u32AMDFeatureECX, &HWACCMR0Globals.cpuid.u32AMDFeatureEDX); 76 159 77 160 if ( u32VendorEBX == X86_CPUID_VENDOR_INTEL_EBX … … 89 172 ) 90 173 { 91 pVM->hwaccm.s.vmx.msr.feature_ctrl = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);174 HWACCMR0Globals.vmx.msr.feature_ctrl = ASMRdMsr(MSR_IA32_FEATURE_CONTROL); 92 175 /* 93 176 * Both the LOCK and VMXON bit must be set; otherwise VMXON will generate a #GP. … … 95 178 */ 96 179 /** @todo need to check this for each cpu/core in the system!!!) */ 97 if (!( pVM->hwaccm.s.vmx.msr.feature_ctrl & (MSR_IA32_FEATURE_CONTROL_VMXON|MSR_IA32_FEATURE_CONTROL_LOCK)))180 if (!(HWACCMR0Globals.vmx.msr.feature_ctrl & (MSR_IA32_FEATURE_CONTROL_VMXON|MSR_IA32_FEATURE_CONTROL_LOCK))) 98 181 { 99 182 /* MSR is not yet locked; we can change it ourselves here */ 100 pVM->hwaccm.s.vmx.msr.feature_ctrl |= (MSR_IA32_FEATURE_CONTROL_VMXON|MSR_IA32_FEATURE_CONTROL_LOCK);101 ASMWrMsr(MSR_IA32_FEATURE_CONTROL, pVM->hwaccm.s.vmx.msr.feature_ctrl);183 HWACCMR0Globals.vmx.msr.feature_ctrl |= (MSR_IA32_FEATURE_CONTROL_VMXON|MSR_IA32_FEATURE_CONTROL_LOCK); 184 ASMWrMsr(MSR_IA32_FEATURE_CONTROL, HWACCMR0Globals.vmx.msr.feature_ctrl); 102 185 } 103 186 104 if ( ( pVM->hwaccm.s.vmx.msr.feature_ctrl & (MSR_IA32_FEATURE_CONTROL_VMXON|MSR_IA32_FEATURE_CONTROL_LOCK))187 if ( (HWACCMR0Globals.vmx.msr.feature_ctrl & (MSR_IA32_FEATURE_CONTROL_VMXON|MSR_IA32_FEATURE_CONTROL_LOCK)) 105 188 == (MSR_IA32_FEATURE_CONTROL_VMXON|MSR_IA32_FEATURE_CONTROL_LOCK)) 106 189 { 107 pVM->hwaccm.s.vmx.fSupported = true;108 pVM->hwaccm.s.vmx.msr.vmx_basic_info = ASMRdMsr(MSR_IA32_VMX_BASIC_INFO);109 pVM->hwaccm.s.vmx.msr.vmx_pin_ctls = ASMRdMsr(MSR_IA32_VMX_PINBASED_CTLS);110 pVM->hwaccm.s.vmx.msr.vmx_proc_ctls = ASMRdMsr(MSR_IA32_VMX_PROCBASED_CTLS);111 pVM->hwaccm.s.vmx.msr.vmx_exit = ASMRdMsr(MSR_IA32_VMX_EXIT_CTLS);112 pVM->hwaccm.s.vmx.msr.vmx_entry = ASMRdMsr(MSR_IA32_VMX_ENTRY_CTLS);113 pVM->hwaccm.s.vmx.msr.vmx_misc = ASMRdMsr(MSR_IA32_VMX_MISC);114 pVM->hwaccm.s.vmx.msr.vmx_cr0_fixed0 = ASMRdMsr(MSR_IA32_VMX_CR0_FIXED0);115 pVM->hwaccm.s.vmx.msr.vmx_cr0_fixed1 = ASMRdMsr(MSR_IA32_VMX_CR0_FIXED1);116 pVM->hwaccm.s.vmx.msr.vmx_cr4_fixed0 = ASMRdMsr(MSR_IA32_VMX_CR4_FIXED0);117 pVM->hwaccm.s.vmx.msr.vmx_cr4_fixed1 = ASMRdMsr(MSR_IA32_VMX_CR4_FIXED1);118 pVM->hwaccm.s.vmx.msr.vmx_vmcs_enum = ASMRdMsr(MSR_IA32_VMX_VMCS_ENUM);190 HWACCMR0Globals.vmx.fSupported = true; 191 HWACCMR0Globals.vmx.msr.vmx_basic_info = ASMRdMsr(MSR_IA32_VMX_BASIC_INFO); 192 HWACCMR0Globals.vmx.msr.vmx_pin_ctls = ASMRdMsr(MSR_IA32_VMX_PINBASED_CTLS); 193 HWACCMR0Globals.vmx.msr.vmx_proc_ctls = ASMRdMsr(MSR_IA32_VMX_PROCBASED_CTLS); 194 HWACCMR0Globals.vmx.msr.vmx_exit = ASMRdMsr(MSR_IA32_VMX_EXIT_CTLS); 195 HWACCMR0Globals.vmx.msr.vmx_entry = ASMRdMsr(MSR_IA32_VMX_ENTRY_CTLS); 196 HWACCMR0Globals.vmx.msr.vmx_misc = ASMRdMsr(MSR_IA32_VMX_MISC); 197 HWACCMR0Globals.vmx.msr.vmx_cr0_fixed0 = ASMRdMsr(MSR_IA32_VMX_CR0_FIXED0); 198 HWACCMR0Globals.vmx.msr.vmx_cr0_fixed1 = ASMRdMsr(MSR_IA32_VMX_CR0_FIXED1); 199 HWACCMR0Globals.vmx.msr.vmx_cr4_fixed0 = ASMRdMsr(MSR_IA32_VMX_CR4_FIXED0); 200 HWACCMR0Globals.vmx.msr.vmx_cr4_fixed1 = ASMRdMsr(MSR_IA32_VMX_CR4_FIXED1); 201 HWACCMR0Globals.vmx.msr.vmx_vmcs_enum = ASMRdMsr(MSR_IA32_VMX_VMCS_ENUM); 119 202 120 203 /* 121 204 * Check CR4.VMXE 122 205 */ 123 pVM->hwaccm.s.vmx.hostCR4 = ASMGetCR4();124 if (!( pVM->hwaccm.s.vmx.hostCR4 & X86_CR4_VMXE))206 HWACCMR0Globals.vmx.hostCR4 = ASMGetCR4(); 207 if (!(HWACCMR0Globals.vmx.hostCR4 & X86_CR4_VMXE)) 125 208 { 126 209 /* In theory this bit could be cleared behind our back. Which would cause #UD faults when we 127 210 * try to execute the VMX instructions... 128 211 */ 129 ASMSetCR4( pVM->hwaccm.s.vmx.hostCR4 | X86_CR4_VMXE);212 ASMSetCR4(HWACCMR0Globals.vmx.hostCR4 | X86_CR4_VMXE); 130 213 } 131 214 132 if ( pVM->hwaccm.s.vmx.pVMXONPhys 133 && pVM->hwaccm.s.vmx.pVMXON) 215 /* Set revision dword at the beginning of the structure. */ 216 *(uint32_t *)pvScatchPage = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(HWACCMR0Globals.vmx.msr.vmx_basic_info); 217 218 #if HC_ARCH_BITS == 64 219 /* Enter VMX Root Mode */ 220 rc = VMXEnable(pScatchPagePhys); 221 if (VBOX_FAILURE(rc)) 134 222 { 135 /* Set revision dword at the beginning of the structure. */ 136 *(uint32_t *)pVM->hwaccm.s.vmx.pVMXON = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(pVM->hwaccm.s.vmx.msr.vmx_basic_info); 137 138 #if HC_ARCH_BITS == 64 139 /* Enter VMX Root Mode */ 140 int rc = VMXEnable(pVM->hwaccm.s.vmx.pVMXONPhys); 141 if (VBOX_FAILURE(rc)) 142 { 143 /* KVM leaves the CPU in VMX root mode. Not only is this not allowed, it will crash the host when we enter raw mode, because 144 * (a) clearing X86_CR4_VMXE in CR4 causes a #GP (we no longer modify this bit) 145 * (b) turning off paging causes a #GP (unavoidable when switching from long to 32 bits mode) 146 * 147 * They should fix their code, but until they do we simply refuse to run. 148 */ 149 return VERR_VMX_IN_VMX_ROOT_MODE; 150 } 223 /* KVM leaves the CPU in VMX root mode. Not only is this not allowed, it will crash the host when we enter raw mode, because 224 * (a) clearing X86_CR4_VMXE in CR4 causes a #GP (we no longer modify this bit) 225 * (b) turning off paging causes a #GP (unavoidable when switching from long to 32 bits mode) 226 * 227 * They should fix their code, but until they do we simply refuse to run. 228 */ 229 rc = VERR_VMX_IN_VMX_ROOT_MODE; 230 } 231 else 151 232 VMXDisable(); 152 233 #endif 153 }154 234 /* Restore CR4 again; don't leave the X86_CR4_VMXE flag set if it wasn't so before (some software could incorrectly think it's in VMX mode) */ 155 ASMSetCR4( pVM->hwaccm.s.vmx.hostCR4);235 ASMSetCR4(HWACCMR0Globals.vmx.hostCR4); 156 236 } 157 237 else 158 pVM->hwaccm.s.lLastError = VERR_VMX_ILLEGAL_FEATURE_CONTROL_MSR;238 HWACCMR0Globals.lLastError = VERR_VMX_ILLEGAL_FEATURE_CONTROL_MSR; 159 239 } 160 240 else 161 pVM->hwaccm.s.lLastError = VERR_VMX_NO_VMX;241 HWACCMR0Globals.lLastError = VERR_VMX_NO_VMX; 162 242 } 163 243 else … … 171 251 * We also assume all SVM-enabled CPUs support fxsave/fxrstor. 172 252 */ 173 if ( ( pVM->hwaccm.s.cpuid.u32AMDFeatureECX & X86_CPUID_AMD_FEATURE_ECX_SVM)253 if ( (HWACCMR0Globals.cpuid.u32AMDFeatureECX & X86_CPUID_AMD_FEATURE_ECX_SVM) 174 254 && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_MSR) 175 255 && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_FXSR) … … 193 273 { 194 274 /* Query AMD features. */ 195 ASMCpuId(0x8000000A, & pVM->hwaccm.s.svm.u32Rev, &pVM->hwaccm.s.svm.u32MaxASID, &u32Dummy, &u32Dummy);196 197 pVM->hwaccm.s.svm.fSupported = true;275 ASMCpuId(0x8000000A, &HWACCMR0Globals.svm.u32Rev, &HWACCMR0Globals.svm.u32MaxASID, &u32Dummy, &u32Dummy); 276 277 HWACCMR0Globals.svm.fSupported = true; 198 278 } 199 279 else 200 280 { 201 pVM->hwaccm.s.lLastError = VERR_SVM_ILLEGAL_EFER_MSR;281 HWACCMR0Globals.lLastError = VERR_SVM_ILLEGAL_EFER_MSR; 202 282 AssertFailed(); 203 283 } 204 284 } 205 285 else 206 pVM->hwaccm.s.lLastError = VERR_SVM_DISABLED;286 HWACCMR0Globals.lLastError = VERR_SVM_DISABLED; 207 287 } 208 288 else 209 pVM->hwaccm.s.lLastError = VERR_SVM_NO_SVM;289 HWACCMR0Globals.lLastError = VERR_SVM_NO_SVM; 210 290 } 211 291 else 212 pVM->hwaccm.s.lLastError = VERR_HWACCM_UNKNOWN_CPU; 213 } 214 else 215 pVM->hwaccm.s.lLastError = VERR_HWACCM_NO_CPUID; 292 HWACCMR0Globals.lLastError = VERR_HWACCM_UNKNOWN_CPU; 293 294 ASMSetFlags(fFlags); 295 } 296 else 297 HWACCMR0Globals.lLastError = VERR_HWACCM_NO_CPUID; 216 298 217 299 #endif /* !VBOX_WITH_HYBIRD_32BIT_KERNEL */ 218 300 219 return VINF_SUCCESS; 220 } 221 222 223 /** 224 * Sets up and activates VMX 301 RTR0MemObjFree(pScatchMemObj, false); 302 return rc; 303 } 304 305 /** 306 * Does global Ring-0 HWACCM termination. 307 * 308 * @returns VBox status code. 309 */ 310 HWACCMR0DECL(int) HWACCMR0Term() 311 { 312 int aRc[RTCPUSET_MAX_CPUS]; 313 314 memset(aRc, 0, sizeof(aRc)); 315 int rc = RTMpOnAll(HWACCMR0DisableCPU, aRc, NULL); 316 AssertRC(rc); 317 318 /* Free the per-cpu pages used for VT-x and AMD-V */ 319 for (unsigned i=0;i<RT_ELEMENTS(HWACCMR0Globals.aCpuInfo);i++) 320 { 321 AssertMsg(VBOX_SUCCESS(aRc[i]), ("HWACCMR0DisableCPU failed for cpu %d with rc=%d\n", i, aRc[i])); 322 if (HWACCMR0Globals.aCpuInfo[i].pMemObj) 323 { 324 RTR0MemObjFree(HWACCMR0Globals.aCpuInfo[i].pMemObj, false); 325 HWACCMR0Globals.aCpuInfo[i].pMemObj = NULL; 326 } 327 } 328 return rc; 329 } 330 331 /** 332 * Sets up HWACCM on all cpus. 333 * 334 * @returns VBox status code. 335 * @param pVM The VM to operate on. 336 * @param enmNewHwAccmState New hwaccm state 337 * 338 */ 339 HWACCMR0DECL(int) HWACCMR0EnableAllCpus(PVM pVM, HWACCMSTATE enmNewHwAccmState) 340 { 341 Assert(sizeof(HWACCMR0Globals.enmHwAccmState) == sizeof(uint32_t)); 342 if (ASMAtomicCmpXchgU32((volatile uint32_t *)&HWACCMR0Globals.enmHwAccmState, enmNewHwAccmState, HWACCMSTATE_UNINITIALIZED)) 343 { 344 int aRc[RTCPUSET_MAX_CPUS]; 345 memset(aRc, 0, sizeof(aRc)); 346 347 /* Allocate one page per cpu for the global vt-x and amd-v pages */ 348 for (unsigned i=0;i<RT_ELEMENTS(HWACCMR0Globals.aCpuInfo);i++) 349 { 350 Assert(!HWACCMR0Globals.aCpuInfo[i].pMemObj); 351 352 /** @todo this is rather dangerous if cpus can be taken offline; we don't care for now */ 353 if (RTMpIsCpuOnline(i)) 354 { 355 int rc = RTR0MemObjAllocCont(&HWACCMR0Globals.aCpuInfo[i].pMemObj, 1 << PAGE_SHIFT, true /* executable R0 mapping */); 356 if (RT_FAILURE(rc)) 357 return rc; 358 359 void *pvR0 = RTR0MemObjAddress(HWACCMR0Globals.aCpuInfo[i].pMemObj); 360 memset(pvR0, 0, PAGE_SIZE); 361 } 362 } 363 364 /* First time, so initialize each cpu/core */ 365 int rc = RTMpOnAll(HWACCMR0EnableCPU, (void *)pVM, aRc); 366 if (VBOX_SUCCESS(rc)) 367 { 368 for (unsigned i=0;i<RT_ELEMENTS(aRc);i++) 369 { 370 if (RTMpIsCpuOnline(i)) 371 { 372 AssertMsg(VBOX_SUCCESS(aRc[i]), ("HWACCMR0EnableCPU failed for cpu %d with rc=%d\n", i, aRc[i])); 373 if (VBOX_FAILURE(aRc[i])) 374 { 375 rc = aRc[i]; 376 break; 377 } 378 } 379 } 380 } 381 return rc; 382 } 383 384 if (HWACCMR0Globals.enmHwAccmState == enmNewHwAccmState) 385 return VINF_SUCCESS; 386 387 /* Request to change the mode is not allowed */ 388 return VERR_ACCESS_DENIED; 389 } 390 391 /** 392 * Worker function passed to RTMpOnAll, RTMpOnOthers and RTMpOnSpecific that 393 * is to be called on the target cpus. 394 * 395 * @param idCpu The identifier for the CPU the function is called on. 396 * @param pvUser1 The 1st user argument. 397 * @param pvUser2 The 2nd user argument. 398 */ 399 static DECLCALLBACK(void) HWACCMR0EnableCPU(RTCPUID idCpu, void *pvUser1, void *pvUser2) 400 { 401 PVM pVM = (PVM)pvUser1; 402 int *paRc = (int *)pvUser2; 403 void *pvPageCpu; 404 RTHCPHYS pPageCpuPhys; 405 406 Assert(pVM); 407 Assert(idCpu < RT_ELEMENTS(HWACCMR0Globals.aCpuInfo)); 408 409 /* Should never happen */ 410 if (!HWACCMR0Globals.aCpuInfo[idCpu].pMemObj) 411 { 412 AssertFailed(); 413 return; 414 } 415 416 pvPageCpu = RTR0MemObjAddress(HWACCMR0Globals.aCpuInfo[idCpu].pMemObj); 417 pPageCpuPhys = RTR0MemObjGetPagePhysAddr(HWACCMR0Globals.aCpuInfo[idCpu].pMemObj, 0); 418 419 if (pVM->hwaccm.s.vmx.fSupported) 420 { 421 paRc[idCpu] = VMXR0EnableCpu(idCpu, pVM, pvPageCpu, pPageCpuPhys); 422 if (VBOX_SUCCESS(paRc[idCpu])) 423 HWACCMR0Globals.aCpuInfo[idCpu].fVMXConfigured = true; 424 } 425 else 426 { 427 Assert(pVM->hwaccm.s.svm.fSupported); 428 paRc[idCpu] = SVMR0EnableCpu(idCpu, pVM, pvPageCpu, pPageCpuPhys); 429 if (VBOX_SUCCESS(paRc[idCpu])) 430 HWACCMR0Globals.aCpuInfo[idCpu].fSVMConfigured = true; 431 } 432 return; 433 } 434 435 /** 436 * Worker function passed to RTMpOnAll, RTMpOnOthers and RTMpOnSpecific that 437 * is to be called on the target cpus. 438 * 439 * @param idCpu The identifier for the CPU the function is called on. 440 * @param pvUser1 The 1st user argument. 441 * @param pvUser2 The 2nd user argument. 442 */ 443 static DECLCALLBACK(void) HWACCMR0DisableCPU(RTCPUID idCpu, void *pvUser1, void *pvUser2) 444 { 445 void *pvPageCpu; 446 RTHCPHYS pPageCpuPhys; 447 int *paRc = (int *)pvUser1; 448 449 Assert(idCpu < RT_ELEMENTS(HWACCMR0Globals.aCpuInfo)); 450 451 /* Should never happen */ 452 if (!HWACCMR0Globals.aCpuInfo[idCpu].pMemObj) 453 { 454 AssertFailed(); 455 return; 456 } 457 458 pvPageCpu = RTR0MemObjAddress(HWACCMR0Globals.aCpuInfo[idCpu].pMemObj); 459 pPageCpuPhys = RTR0MemObjGetPagePhysAddr(HWACCMR0Globals.aCpuInfo[idCpu].pMemObj, 0); 460 461 if (HWACCMR0Globals.aCpuInfo[idCpu].fVMXConfigured) 462 { 463 paRc[idCpu] = VMXR0DisableCpu(idCpu, pvPageCpu, pPageCpuPhys); 464 AssertRC(paRc[idCpu]); 465 HWACCMR0Globals.aCpuInfo[idCpu].fVMXConfigured = false; 466 } 467 else 468 if (HWACCMR0Globals.aCpuInfo[idCpu].fSVMConfigured) 469 { 470 paRc[idCpu] = SVMR0DisableCpu(idCpu, pvPageCpu, pPageCpuPhys); 471 AssertRC(paRc[idCpu]); 472 HWACCMR0Globals.aCpuInfo[idCpu].fSVMConfigured = false; 473 } 474 return; 475 } 476 477 478 /** 479 * Does Ring-0 per VM HWACCM initialization. 480 * 481 * This is mainly to check that the Host CPU mode is compatible 482 * with VMX. 225 483 * 226 484 * @returns VBox status code. 227 485 * @param pVM The VM to operate on. 228 486 */ 229 HWACCMR0DECL(int) HWACCMR0SetupVMX(PVM pVM) 487 HWACCMR0DECL(int) HWACCMR0InitVM(PVM pVM) 488 { 489 LogComFlow(("HWACCMR0Init: %p\n", pVM)); 490 491 pVM->hwaccm.s.vmx.fSupported = false; 492 pVM->hwaccm.s.svm.fSupported = false; 493 494 if (HWACCMR0Globals.vmx.fSupported) 495 { 496 pVM->hwaccm.s.vmx.fSupported = true; 497 pVM->hwaccm.s.vmx.hostCR4 = HWACCMR0Globals.vmx.hostCR4; 498 pVM->hwaccm.s.vmx.msr.feature_ctrl = HWACCMR0Globals.vmx.msr.feature_ctrl; 499 pVM->hwaccm.s.vmx.msr.vmx_basic_info = HWACCMR0Globals.vmx.msr.vmx_basic_info; 500 pVM->hwaccm.s.vmx.msr.vmx_pin_ctls = HWACCMR0Globals.vmx.msr.vmx_pin_ctls; 501 pVM->hwaccm.s.vmx.msr.vmx_proc_ctls = HWACCMR0Globals.vmx.msr.vmx_proc_ctls; 502 pVM->hwaccm.s.vmx.msr.vmx_exit = HWACCMR0Globals.vmx.msr.vmx_exit; 503 pVM->hwaccm.s.vmx.msr.vmx_entry = HWACCMR0Globals.vmx.msr.vmx_entry; 504 pVM->hwaccm.s.vmx.msr.vmx_misc = HWACCMR0Globals.vmx.msr.vmx_misc; 505 pVM->hwaccm.s.vmx.msr.vmx_cr0_fixed0 = HWACCMR0Globals.vmx.msr.vmx_cr0_fixed0; 506 pVM->hwaccm.s.vmx.msr.vmx_cr0_fixed1 = HWACCMR0Globals.vmx.msr.vmx_cr0_fixed1; 507 pVM->hwaccm.s.vmx.msr.vmx_cr4_fixed0 = HWACCMR0Globals.vmx.msr.vmx_cr4_fixed0; 508 pVM->hwaccm.s.vmx.msr.vmx_cr4_fixed1 = HWACCMR0Globals.vmx.msr.vmx_cr4_fixed1; 509 pVM->hwaccm.s.vmx.msr.vmx_vmcs_enum = HWACCMR0Globals.vmx.msr.vmx_vmcs_enum; 510 511 } 512 else 513 if (HWACCMR0Globals.svm.fSupported) 514 { 515 pVM->hwaccm.s.svm.fSupported = true; 516 pVM->hwaccm.s.svm.u32Rev = HWACCMR0Globals.svm.u32Rev; 517 pVM->hwaccm.s.svm.u32MaxASID = HWACCMR0Globals.svm.u32MaxASID; 518 } 519 520 pVM->hwaccm.s.lLastError = HWACCMR0Globals.lLastError; 521 pVM->hwaccm.s.cpuid.u32AMDFeatureECX = HWACCMR0Globals.cpuid.u32AMDFeatureECX; 522 pVM->hwaccm.s.cpuid.u32AMDFeatureEDX = HWACCMR0Globals.cpuid.u32AMDFeatureEDX; 523 524 return VINF_SUCCESS; 525 } 526 527 528 529 /** 530 * Sets up a VT-x or AMD-V session 531 * 532 * @returns VBox status code. 533 * @param pVM The VM to operate on. 534 */ 535 HWACCMR0DECL(int) HWACCMR0SetupVM(PVM pVM) 230 536 { 231 537 int rc = VINF_SUCCESS; … … 236 542 /* Setup Intel VMX. */ 237 543 if (pVM->hwaccm.s.vmx.fSupported) 238 rc = VMXR0Setup (pVM);239 else 240 rc = SVMR0Setup (pVM);544 rc = VMXR0SetupVM(pVM); 545 else 546 rc = SVMR0SetupVM(pVM); 241 547 242 548 return rc; … … 245 551 246 552 /** 247 * En able VMX or SVN553 * Enters the VT-x or AMD-V session 248 554 * 249 555 * @returns VBox status code. 250 556 * @param pVM The VM to operate on. 251 557 */ 252 HWACCMR0DECL(int) HWACCMR0En able(PVM pVM)558 HWACCMR0DECL(int) HWACCMR0Enter(PVM pVM) 253 559 { 254 560 CPUMCTX *pCtx; … … 267 573 if (pVM->hwaccm.s.vmx.fSupported) 268 574 { 269 rc = VMXR0En able(pVM);575 rc = VMXR0Enter(pVM); 270 576 AssertRC(rc); 271 577 rc |= VMXR0SaveHostState(pVM); … … 279 585 { 280 586 Assert(pVM->hwaccm.s.svm.fSupported); 281 rc = SVMR0En able(pVM);587 rc = SVMR0Enter(pVM); 282 588 AssertRC(rc); 283 589 rc |= SVMR0LoadGuestState(pVM, pCtx); … … 292 598 293 599 /** 294 * Disable VMX or SVN600 * Leaves the VT-x or AMD-V session 295 601 * 296 602 * @returns VBox status code. 297 603 * @param pVM The VM to operate on. 298 604 */ 299 HWACCMR0DECL(int) HWACCMR0 Disable(PVM pVM)605 HWACCMR0DECL(int) HWACCMR0Leave(PVM pVM) 300 606 { 301 607 CPUMCTX *pCtx; … … 323 629 if (pVM->hwaccm.s.vmx.fSupported) 324 630 { 325 return VMXR0 Disable(pVM);631 return VMXR0Leave(pVM); 326 632 } 327 633 else 328 634 { 329 635 Assert(pVM->hwaccm.s.svm.fSupported); 330 return SVMR0 Disable(pVM);636 return SVMR0Leave(pVM); 331 637 } 332 638 } -
trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp
r5999 r7471 43 43 44 44 /** 45 * Sets up and activates SVM 45 * Sets up and activates AMD-V on the current CPU 46 * 47 * @returns VBox status code. 48 * @param idCpu The identifier for the CPU the function is called on. 49 * @param pVM The VM to operate on. 50 * @param pvPageCpu Pointer to the global cpu page 51 * @param pPageCpuPhys Physical address of the global cpu page 52 */ 53 HWACCMR0DECL(int) SVMR0EnableCpu(RTCPUID idCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys) 54 { 55 AssertReturn(pPageCpuPhys, VERR_INVALID_PARAMETER); 56 AssertReturn(pVM, VERR_INVALID_PARAMETER); 57 AssertReturn(pvPageCpu, VERR_INVALID_PARAMETER); 58 59 /* We must turn on AMD-V and setup the host state physical address, as those MSRs are per-cpu/core. */ 60 61 /* Turn on AMD-V in the EFER MSR. */ 62 uint64_t val = ASMRdMsr(MSR_K6_EFER); 63 if (!(val & MSR_K6_EFER_SVME)) 64 ASMWrMsr(MSR_K6_EFER, val | MSR_K6_EFER_SVME); 65 66 /* Write the physical page address where the CPU will store the host state while executing the VM. */ 67 ASMWrMsr(MSR_K8_VM_HSAVE_PA, pPageCpuPhys); 68 return VINF_SUCCESS; 69 } 70 71 /** 72 * Deactivates AMD-V on the current CPU 73 * 74 * @returns VBox status code. 75 * @param idCpu The identifier for the CPU the function is called on. 76 * @param pvPageCpu Pointer to the global cpu page 77 * @param pPageCpuPhys Physical address of the global cpu page 78 */ 79 HWACCMR0DECL(int) SVMR0DisableCpu(RTCPUID idCpu, void *pvPageCpu, RTHCPHYS pPageCpuPhys) 80 { 81 AssertReturn(pPageCpuPhys, VERR_INVALID_PARAMETER); 82 AssertReturn(pvPageCpu, VERR_INVALID_PARAMETER); 83 84 /* Turn off AMD-V in the EFER MSR. */ 85 uint64_t val = ASMRdMsr(MSR_K6_EFER); 86 ASMWrMsr(MSR_K6_EFER, val & ~MSR_K6_EFER_SVME); 87 88 /* Invalidate host state physical address. */ 89 ASMWrMsr(MSR_K8_VM_HSAVE_PA, 0); 90 return VINF_SUCCESS; 91 } 92 93 /** 94 * Sets up SVM for the specified VM 46 95 * 47 96 * @returns VBox status code. 48 97 * @param pVM The VM to operate on. 49 98 */ 50 HWACCMR0DECL(int) SVMR0Setup (PVM pVM)99 HWACCMR0DECL(int) SVMR0SetupVM(PVM pVM) 51 100 { 52 101 int rc = VINF_SUCCESS; … … 1413 1462 1414 1463 /** 1415 * En able SVM1464 * Enters the AMD-V session 1416 1465 * 1417 1466 * @returns VBox status code. 1418 1467 * @param pVM The VM to operate on. 1419 1468 */ 1420 HWACCMR0DECL(int) SVMR0En able(PVM pVM)1469 HWACCMR0DECL(int) SVMR0Enter(PVM pVM) 1421 1470 { 1422 1471 uint64_t val; … … 1424 1473 Assert(pVM->hwaccm.s.svm.fSupported); 1425 1474 1426 /* We must turn on SVM and setup the host state physical address, as those MSRs are per-cpu/core. */1427 1428 /* Turn on SVM in the EFER MSR. */1429 val = ASMRdMsr(MSR_K6_EFER);1430 if (!(val & MSR_K6_EFER_SVME))1431 ASMWrMsr(MSR_K6_EFER, val | MSR_K6_EFER_SVME);1432 1433 /* Write the physical page address where the CPU will store the host state while executing the VM. */1434 ASMWrMsr(MSR_K8_VM_HSAVE_PA, pVM->hwaccm.s.svm.pHStatePhys);1435 1436 1475 /* Force a TLB flush on VM entry. */ 1437 1476 pVM->hwaccm.s.svm.fResumeVM = false; … … 1445 1484 1446 1485 /** 1447 * Disable SVM1486 * Leaves the AMD-V session 1448 1487 * 1449 1488 * @returns VBox status code. 1450 1489 * @param pVM The VM to operate on. 1451 1490 */ 1452 HWACCMR0DECL(int) SVMR0 Disable(PVM pVM)1491 HWACCMR0DECL(int) SVMR0Leave(PVM pVM) 1453 1492 { 1454 /** @todo hopefully this is not very expensive. */1455 1456 /* Turn off SVM in the EFER MSR. */1457 uint64_t val = ASMRdMsr(MSR_K6_EFER);1458 ASMWrMsr(MSR_K6_EFER, val & ~MSR_K6_EFER_SVME);1459 1460 /* Invalidate host state physical address. */1461 ASMWrMsr(MSR_K8_VM_HSAVE_PA, 0);1462 1463 1493 Assert(pVM->hwaccm.s.svm.fSupported); 1464 1494 return VINF_SUCCESS; -
trunk/src/VBox/VMM/VMMR0/HWSVMR0.h
r5999 r7471 1 1 /* $Id$ */ 2 2 /** @file 3 * HWACCM SVM- Internal header file.3 * HWACCM AMD-V - Internal header file. 4 4 */ 5 5 … … 39 39 40 40 /** 41 * En able SVM41 * Enters the AMD-V session 42 42 * 43 43 * @returns VBox status code. 44 44 * @param pVM The VM to operate on. 45 45 */ 46 HWACCMR0DECL(int) SVMR0En able(PVM pVM);46 HWACCMR0DECL(int) SVMR0Enter(PVM pVM); 47 47 48 48 /** 49 * Disable SVM49 * Leaves the AMD-V session 50 50 * 51 51 * @returns VBox status code. 52 52 * @param pVM The VM to operate on. 53 53 */ 54 HWACCMR0DECL(int) SVMR0 Disable(PVM pVM);54 HWACCMR0DECL(int) SVMR0Leave(PVM pVM); 55 55 56 56 /** 57 * Sets up and activates SVM 57 * Sets up and activates AMD-V on the current CPU 58 * 59 * @returns VBox status code. 60 * @param idCpu The identifier for the CPU the function is called on. 61 * @param pVM The VM to operate on. 62 * @param pvPageCpu Pointer to the global cpu page 63 * @param pPageCpuPhys Physical address of the global cpu page 64 */ 65 HWACCMR0DECL(int) SVMR0EnableCpu(RTCPUID idCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys); 66 67 /** 68 * Deactivates AMD-V on the current CPU 69 * 70 * @returns VBox status code. 71 * @param idCpu The identifier for the CPU the function is called on. 72 * @param pvPageCpu Pointer to the global cpu page 73 * @param pPageCpuPhys Physical address of the global cpu page 74 */ 75 HWACCMR0DECL(int) SVMR0DisableCpu(RTCPUID idCpu, void *pvPageCpu, RTHCPHYS pPageCpuPhys); 76 77 /** 78 * Sets up AMD-V for the specified VM 58 79 * 59 80 * @returns VBox status code. 60 81 * @param pVM The VM to operate on. 61 82 */ 62 HWACCMR0DECL(int) SVMR0Setup (PVM pVM);83 HWACCMR0DECL(int) SVMR0SetupVM(PVM pVM); 63 84 64 85 65 86 /** 66 * Runs guest code in a SVMVM.87 * Runs guest code in an AMD-V VM. 67 88 * 68 89 * @note NEVER EVER turn on interrupts here. Due to our illegal entry into the kernel, it might mess things up. (XP kernel traps have been frequently observed) -
trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp
r5999 r7471 49 49 50 50 VMXReadVMCS(VMX_VMCS_RO_VM_INSTR_ERROR, &instrError); 51 Log(("VMXR0CheckError -> generic error %x\n", instrError));52 53 51 pVM->hwaccm.s.vmx.ulLastInstrError = instrError; 54 }55 else56 {57 Log(("VMXR0CheckError failed with %Vrc\n", rc));58 52 } 59 53 pVM->hwaccm.s.lLastError = rc; … … 61 55 62 56 /** 63 * Sets up and activates VMX 57 * Sets up and activates VT-x on the current CPU 58 * 59 * @returns VBox status code. 60 * @param idCpu The identifier for the CPU the function is called on. 61 * @param pVM The VM to operate on. 62 * @param pvPageCpu Pointer to the global cpu page 63 * @param pPageCpuPhys Physical address of the global cpu page 64 */ 65 HWACCMR0DECL(int) VMXR0EnableCpu(RTCPUID idCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys) 66 { 67 AssertReturn(pPageCpuPhys, VERR_INVALID_PARAMETER); 68 AssertReturn(pVM, VERR_INVALID_PARAMETER); 69 AssertReturn(pvPageCpu, VERR_INVALID_PARAMETER); 70 71 /* Setup Intel VMX. */ 72 Assert(pVM->hwaccm.s.vmx.fSupported); 73 74 /* Set revision dword at the beginning of the VMXON structure. */ 75 *(uint32_t *)pvPageCpu = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(pVM->hwaccm.s.vmx.msr.vmx_basic_info); 76 77 /* @todo we should unmap the two pages from the virtual address space in order to prevent accidental corruption. 78 * (which can have very bad consequences!!!) 79 */ 80 81 /* Make sure the VMX instructions don't cause #UD faults. */ 82 ASMSetCR4(ASMGetCR4() | X86_CR4_VMXE); 83 84 /* Enter VMX Root Mode */ 85 int rc = VMXEnable(pPageCpuPhys); 86 if (VBOX_FAILURE(rc)) 87 { 88 VMXR0CheckError(pVM, rc); 89 ASMSetCR4(ASMGetCR4() & ~X86_CR4_VMXE); 90 return VERR_VMX_VMXON_FAILED; 91 } 92 93 return VINF_SUCCESS; 94 } 95 96 /** 97 * Deactivates VT-x on the current CPU 98 * 99 * @returns VBox status code. 100 * @param idCpu The identifier for the CPU the function is called on. 101 * @param pvPageCpu Pointer to the global cpu page 102 * @param pPageCpuPhys Physical address of the global cpu page 103 */ 104 HWACCMR0DECL(int) VMXR0DisableCpu(RTCPUID idCpu, void *pvPageCpu, RTHCPHYS pPageCpuPhys) 105 { 106 AssertReturn(pPageCpuPhys, VERR_INVALID_PARAMETER); 107 AssertReturn(pvPageCpu, VERR_INVALID_PARAMETER); 108 109 /* Leave VMX Root Mode. */ 110 VMXDisable(); 111 112 /* And clear the X86_CR4_VMXE bit */ 113 ASMSetCR4(ASMGetCR4() & ~X86_CR4_VMXE); 114 return VINF_SUCCESS; 115 } 116 117 /** 118 * Sets up VT-x for the specified VM 64 119 * 65 120 * @returns VBox status code. 66 121 * @param pVM The VM to operate on. 67 122 */ 68 HWACCMR0DECL(int) VMXR0Setup (PVM pVM)123 HWACCMR0DECL(int) VMXR0SetupVM(PVM pVM) 69 124 { 70 125 int rc = VINF_SUCCESS; … … 74 129 return VERR_INVALID_PARAMETER; 75 130 76 /* Setup Intel VMX. */ 77 Assert(pVM->hwaccm.s.vmx.fSupported); 78 79 /* Set revision dword at the beginning of both structures. */ 131 /* Set revision dword at the beginning of the VMCS structure. */ 80 132 *(uint32_t *)pVM->hwaccm.s.vmx.pVMCS = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(pVM->hwaccm.s.vmx.msr.vmx_basic_info); 81 *(uint32_t *)pVM->hwaccm.s.vmx.pVMXON = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(pVM->hwaccm.s.vmx.msr.vmx_basic_info);82 83 /* @todo we should unmap the two pages from the virtual address space in order to prevent accidental corruption.84 * (which can have very bad consequences!!!)85 */86 87 /* Make sure the VMX instructions don't cause #UD faults. */88 ASMSetCR4(ASMGetCR4() | X86_CR4_VMXE);89 90 /* Enter VMX Root Mode */91 Log(("pVMXONPhys = %VHp\n", pVM->hwaccm.s.vmx.pVMXONPhys));92 rc = VMXEnable(pVM->hwaccm.s.vmx.pVMXONPhys);93 if (VBOX_FAILURE(rc))94 {95 VMXR0CheckError(pVM, rc);96 return VERR_VMX_VMXON_FAILED;97 }98 133 99 134 /* Clear VM Control Structure. */ … … 274 309 vmx_end: 275 310 VMXR0CheckError(pVM, rc); 276 /* Leave VMX Root Mode. */277 VMXDisable();278 311 return rc; 279 312 } … … 1939 1972 1940 1973 /** 1941 * En able VMX1974 * Enters the VT-x session 1942 1975 * 1943 1976 * @returns VBox status code. 1944 1977 * @param pVM The VM to operate on. 1945 1978 */ 1946 HWACCMR0DECL(int) VMXR0En able(PVM pVM)1979 HWACCMR0DECL(int) VMXR0Enter(PVM pVM) 1947 1980 { 1948 1981 Assert(pVM->hwaccm.s.vmx.fSupported); 1949 1982 1950 /* Make sure the VMX instructions don't cause #UD faults. */ 1951 ASMSetCR4(ASMGetCR4() | X86_CR4_VMXE); 1952 1953 /* Enter VMX Root Mode */ 1954 int rc = VMXEnable(pVM->hwaccm.s.vmx.pVMXONPhys); 1983 unsigned cr4 = ASMGetCR4(); 1984 if (!(cr4 & X86_CR4_VMXE)) 1985 { 1986 AssertMsgFailed(("X86_CR4_VMXE should be set!\n")); 1987 return VERR_VMX_X86_CR4_VMXE_CLEARED; 1988 } 1989 1990 /* Activate the VM Control Structure. */ 1991 int rc = VMXActivateVMCS(pVM->hwaccm.s.vmx.pVMCSPhys); 1955 1992 if (VBOX_FAILURE(rc)) 1956 1993 return rc; 1957 1994 1958 /* Activate the VM Control Structure. */1959 rc = VMXActivateVMCS(pVM->hwaccm.s.vmx.pVMCSPhys);1960 if (VBOX_FAILURE(rc))1961 {1962 /* Leave VMX Root Mode. */1963 VMXDisable();1964 return rc;1965 }1966 1995 pVM->hwaccm.s.vmx.fResumeVM = false; 1967 1996 return VINF_SUCCESS; … … 1970 1999 1971 2000 /** 1972 * Disable VMX2001 * Leaves the VT-x session 1973 2002 * 1974 2003 * @returns VBox status code. 1975 2004 * @param pVM The VM to operate on. 1976 2005 */ 1977 HWACCMR0DECL(int) VMXR0 Disable(PVM pVM)2006 HWACCMR0DECL(int) VMXR0Leave(PVM pVM) 1978 2007 { 1979 2008 Assert(pVM->hwaccm.s.vmx.fSupported); … … 1983 2012 AssertRC(rc); 1984 2013 1985 /* Leave VMX Root Mode. */1986 VMXDisable();1987 1988 2014 return VINF_SUCCESS; 1989 2015 } -
trunk/src/VBox/VMM/VMMR0/HWVMXR0.h
r5999 r7471 1 1 /* $Id$ */ 2 2 /** @file 3 * HWACCM SVM- Internal header file.3 * HWACCM VT-x - Internal header file. 4 4 */ 5 5 … … 39 39 40 40 /** 41 * En able VMX41 * Enters the VT-x session 42 42 * 43 43 * @returns VBox status code. 44 44 * @param pVM The VM to operate on. 45 45 */ 46 HWACCMR0DECL(int) VMXR0En able(PVM pVM);46 HWACCMR0DECL(int) VMXR0Enter(PVM pVM); 47 47 48 48 /** 49 * Disable VMX49 * Leaves the VT-x session 50 50 * 51 51 * @returns VBox status code. 52 52 * @param pVM The VM to operate on. 53 53 */ 54 HWACCMR0DECL(int) VMXR0Disable(PVM pVM); 54 HWACCMR0DECL(int) VMXR0Leave(PVM pVM); 55 55 56 56 57 /** 57 * Sets up and activates VMX 58 * Sets up and activates VT-x on the current CPU 59 * 60 * @returns VBox status code. 61 * @param idCpu The identifier for the CPU the function is called on. 62 * @param pVM The VM to operate on. 63 * @param pvPageCpu Pointer to the global cpu page 64 * @param pPageCpuPhys Physical address of the global cpu page 65 */ 66 HWACCMR0DECL(int) VMXR0EnableCpu(RTCPUID idCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys); 67 68 /** 69 * Deactivates VT-x on the current CPU 70 * 71 * @returns VBox status code. 72 * @param idCpu The identifier for the CPU the function is called on. 73 * @param pvPageCpu Pointer to the global cpu page 74 * @param pPageCpuPhys Physical address of the global cpu page 75 */ 76 HWACCMR0DECL(int) VMXR0DisableCpu(RTCPUID idCpu, void *pvPageCpu, RTHCPHYS pPageCpuPhys); 77 78 /** 79 * Sets up VT-x for the specified VM 58 80 * 59 81 * @returns VBox status code. 60 82 * @param pVM The VM to operate on. 61 83 */ 62 HWACCMR0DECL(int) VMXR0Setup (PVM pVM);84 HWACCMR0DECL(int) VMXR0SetupVM(PVM pVM); 63 85 64 86 … … 82 104 83 105 /** 84 * Runs guest code in a V MXVM.106 * Runs guest code in a VT-x VM. 85 107 * 86 108 * @note NEVER EVER turn on interrupts here. Due to our illegal entry into the kernel, it might mess things up. (XP kernel traps have been frequently observed) -
trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
r6801 r7471 40 40 #include <iprt/assert.h> 41 41 #include <iprt/stdarg.h> 42 #include <iprt/mp.h> 42 43 43 44 #if defined(_MSC_VER) && defined(RT_ARCH_AMD64) /** @todo check this with with VC7! */ … … 65 66 #endif 66 67 68 /******************************************************************************* 69 * Local Variables * 70 *******************************************************************************/ 67 71 68 72 /** … … 78 82 79 83 /* 80 * Initialize the GVMM and GMM.84 * Initialize the GVMM, GMM.& HWACCM 81 85 */ 82 86 int rc = GVMMR0Init(); … … 86 90 if (RT_SUCCESS(rc)) 87 91 { 92 rc = HWACCMR0Init(); 93 if (RT_SUCCESS(rc)) 94 { 88 95 #ifdef VBOX_WITH_INTERNAL_NETWORKING 89 LogFlow(("ModuleInit: g_pIntNet=%p\n", g_pIntNet)); 90 g_pIntNet = NULL; 91 LogFlow(("ModuleInit: g_pIntNet=%p should be NULL now...\n", g_pIntNet)); 92 rc = INTNETR0Create(&g_pIntNet); 93 if (VBOX_SUCCESS(rc)) 94 { 95 LogFlow(("ModuleInit: returns success. g_pIntNet=%p\n", g_pIntNet)); 96 LogFlow(("ModuleInit: g_pIntNet=%p\n", g_pIntNet)); 97 g_pIntNet = NULL; 98 LogFlow(("ModuleInit: g_pIntNet=%p should be NULL now...\n", g_pIntNet)); 99 rc = INTNETR0Create(&g_pIntNet); 100 if (VBOX_SUCCESS(rc)) 101 { 102 LogFlow(("ModuleInit: returns success. g_pIntNet=%p\n", g_pIntNet)); 103 return VINF_SUCCESS; 104 } 105 g_pIntNet = NULL; 106 LogFlow(("ModuleTerm: returns %Vrc\n", rc)); 107 #else 108 LogFlow(("ModuleInit: returns success.\n")); 96 109 return VINF_SUCCESS; 110 #endif 97 111 } 98 g_pIntNet = NULL;99 LogFlow(("ModuleTerm: returns %Vrc\n", rc));100 #else101 LogFlow(("ModuleInit: returns success.\n"));102 return VINF_SUCCESS;103 #endif104 112 } 105 113 } … … 128 136 } 129 137 #endif 138 139 /* Global HWACCM cleanup */ 140 HWACCMR0Term(); 130 141 131 142 /* … … 212 223 * Init HWACCM. 213 224 */ 214 RTCCUINTREG fFlags = ASMIntDisableFlags(); 215 rc = HWACCMR0Init(pVM); 216 ASMSetFlags(fFlags); 225 rc = HWACCMR0InitVM(pVM); 217 226 if (RT_SUCCESS(rc)) 218 227 { … … 609 618 RTCCUINTREG uFlags = ASMIntDisableFlags(); 610 619 #endif 611 int rc = HWACCMR0En able(pVM);620 int rc = HWACCMR0Enter(pVM); 612 621 if (VBOX_SUCCESS(rc)) 613 622 { 614 623 rc = vmmR0CallHostSetJmp(&pVM->vmm.s.CallHostR0JmpBuf, HWACCMR0RunGuestCode, pVM); /* this may resume code. */ 615 int rc2 = HWACCMR0 Disable(pVM);624 int rc2 = HWACCMR0Leave(pVM); 616 625 AssertRC(rc2); 617 626 } … … 732 741 733 742 /* 743 * Attempt to enable hwacc mode and check the current setting. 744 * 745 */ 746 case VMMR0_DO_HWACC_ENABLE: 747 return HWACCMR0EnableAllCpus(pVM, (HWACCMSTATE)u64Arg); 748 749 /* 734 750 * Setup the hardware accelerated raw-mode session. 735 751 */ … … 737 753 { 738 754 RTCCUINTREG fFlags = ASMIntDisableFlags(); 739 int rc = HWACCMR0SetupVM X(pVM);755 int rc = HWACCMR0SetupVM(pVM); 740 756 ASMSetFlags(fFlags); 741 757 return rc; … … 747 763 case VMMR0_DO_CALL_HYPERVISOR: 748 764 { 749 /* Safety precaution as VMX disablesthe switcher. */765 /* Safety precaution as HWACCM can disable the switcher. */ 750 766 Assert(!pVM->vmm.s.fSwitcherDisabled); 751 if ( pVM->vmm.s.fSwitcherDisabled)767 if (RT_UNLIKELY(pVM->vmm.s.fSwitcherDisabled)) 752 768 return VERR_NOT_SUPPORTED; 753 769
Note:
See TracChangeset
for help on using the changeset viewer.