Changeset 46297 in vbox for trunk/src/VBox/VMM
- Timestamp:
- May 28, 2013 2:38:48 PM (12 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 1 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/HMAll.cpp
r45701 r46297 34 34 #include <iprt/string.h> 35 35 #include <iprt/x86.h> 36 #include <iprt/asm-amd64-x86.h> 36 37 37 38 … … 371 372 } 372 373 374 375 /** 376 * Checks if the current AMD CPU is subject to erratum 170 "In SVM mode, 377 * incorrect code bytes may be fetched after a world-switch". 378 * 379 * @param pu32Family Where to store the CPU family (can be NULL). 380 * @param pu32Model Where to store the CPU model (can be NULL). 381 * @param pu32Stepping Where to store the CPU stepping (can be NULL). 382 * @returns true if the erratum applies, false otherwise. 383 */ 384 VMM_INT_DECL(int) HMAmdIsSubjectToErratum170(uint32_t *pu32Family, uint32_t *pu32Model, uint32_t *pu32Stepping) 385 { 386 /* 387 * Erratum 170 which requires a forced TLB flush for each world switch: 388 * See AMD spec. "Revision Guide for AMD NPT Family 0Fh Processors". 389 * 390 * All BH-G1/2 and DH-G1/2 models include a fix: 391 * Athlon X2: 0x6b 1/2 392 * 0x68 1/2 393 * Athlon 64: 0x7f 1 394 * 0x6f 2 395 * Sempron: 0x7f 1/2 396 * 0x6f 2 397 * 0x6c 2 398 * 0x7c 2 399 * Turion 64: 0x68 2 400 */ 401 uint32_t u32Dummy; 402 uint32_t u32Version, u32Family, u32Model, u32Stepping, u32BaseFamily; 403 ASMCpuId(1, &u32Version, &u32Dummy, &u32Dummy, &u32Dummy); 404 u32BaseFamily = (u32Version >> 8) & 0xf; 405 u32Family = u32BaseFamily + (u32BaseFamily == 0xf ? ((u32Version >> 20) & 0x7f) : 0); 406 u32Model = ((u32Version >> 4) & 0xf); 407 u32Model = u32Model | ((u32BaseFamily == 0xf ? (u32Version >> 16) & 0x0f : 0) << 4); 408 u32Stepping = u32Version & 0xf; 409 410 bool fErratumApplies = false; 411 if ( u32Family == 0xf 412 && !((u32Model == 0x68 || u32Model == 0x6b || u32Model == 0x7f) && u32Stepping >= 1) 413 && !((u32Model == 0x6f || u32Model == 0x6c || u32Model == 0x7c) && u32Stepping >= 2)) 414 { 415 fErratumApplies = true; 416 } 417 418 if (pu32Family) 419 *pu32Family = u32Family; 420 if (pu32Model) 421 *pu32Model = u32Model; 422 if (pu32Stepping) 423 *pu32Stepping = u32Stepping; 424 425 return fErratumApplies; 426 } 427 -
trunk/src/VBox/VMM/VMMR0/HMR0.cpp
r45947 r46297 550 550 /** 551 551 * AMD-specific initialization code. 552 */ 553 static void hmR0InitAmd(uint32_t u32FeaturesEDX, uint32_t uMaxExtLeaf) 552 * 553 * @returns VBox status code. 554 */ 555 static int hmR0InitAmd(uint32_t u32FeaturesEDX, uint32_t uMaxExtLeaf) 554 556 { 555 557 /* … … 557 559 * We also assume all SVM-enabled CPUs support fxsave/fxrstor. 558 560 */ 561 int rc; 559 562 if ( (g_HvmR0.cpuid.u32AMDFeatureECX & X86_CPUID_AMD_FEATURE_ECX_SVM) 560 563 && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_MSR) … … 564 567 ) 565 568 { 569 /* Call the global AMD-V initialization routine. */ 570 rc = SVMR0GlobalInit(); 571 if (RT_FAILURE(rc)) 572 { 573 g_HvmR0.lLastError = rc; 574 return rc; 575 } 576 577 /* 578 * Install the AMD-V methods. 579 */ 566 580 g_HvmR0.pfnEnterSession = SVMR0Enter; 567 581 g_HvmR0.pfnLeaveSession = SVMR0Leave; … … 585 599 HMR0FIRSTRC FirstRc; 586 600 hmR0FirstRcInit(&FirstRc); 587 intrc = RTMpOnAll(hmR0InitAmdCpu, &FirstRc, NULL);601 rc = RTMpOnAll(hmR0InitAmdCpu, &FirstRc, NULL); 588 602 AssertRC(rc); 589 603 if (RT_SUCCESS(rc)) … … 603 617 } 604 618 else 605 g_HvmR0.lLastError = VERR_SVM_NO_SVM; 619 { 620 rc = VERR_SVM_NO_SVM; 621 g_HvmR0.lLastError = rc; 622 } 623 return rc; 606 624 } 607 625 … … 679 697 } 680 698 else if (ASMIsAmdCpuEx(u32VendorEBX, u32VendorECX, u32VendorEDX)) 681 hmR0InitAmd(u32FeaturesEDX, uMaxExtLeaf); 699 { 700 rc = hmR0InitAmd(u32FeaturesEDX, uMaxExtLeaf); 701 if (RT_FAILURE(rc)) 702 return rc; 703 } 682 704 else 683 705 g_HvmR0.lLastError = VERR_HM_UNKNOWN_CPU; … … 772 794 } 773 795 774 /** @todo This needs cleaning up. There's no matching hmR0TermIntel() and all775 * the VT-x/AMD-V specific bits should move into their respective776 * modules. */796 /** @todo This needs cleaning up. There's no matching 797 * hmR0TermIntel()/hmR0TermAmd() and all the VT-x/AMD-V specific bits 798 * should move into their respective modules. */ 777 799 /* Finally, call global VT-x/AMD-V termination. */ 778 800 if (g_HvmR0.vmx.fSupported) 779 801 VMXR0GlobalTerm(); 802 else if (g_HvmR0.svm.fSupported) 803 SVMR0GlobalTerm(); 780 804 781 805 return rc; … … 825 849 826 850 /** 827 * Worker function used by hmR0PowerCallback and HMR0Init to initalize828 * VT-x / AMD-Von a CPU.851 * Worker function used by hmR0PowerCallback() and HMR0Init() to initalize AMD-V 852 * on a CPU. 829 853 * 830 854 * @param idCpu The identifier for the CPU the function is called on. -
trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp
r45965 r46297 178 178 179 179 /** 180 * Does global AMD-V initialization (called during module initialization). 181 * 182 * @returns VBox status code. 183 */ 184 VMMR0DECL(int) SVMR0GlobalInit(void) 185 { 186 return VINF_SUCCESS; 187 } 188 189 190 /** 191 * Does global VT-x termination (called during module termination). 192 */ 193 VMMR0DECL(void) SVMR0GlobalTerm(void) 194 { 195 } 196 197 198 /** 180 199 * Does Ring-0 per VM AMD-V init. 181 200 * … … 199 218 ASMMemFill32(pVM->hm.s.svm.pvIOBitmap, 3 << PAGE_SHIFT, 0xffffffff); 200 219 201 /* 202 * Erratum 170 which requires a forced TLB flush for each world switch: 203 * See http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/33610.pdf 204 * 205 * All BH-G1/2 and DH-G1/2 models include a fix: 206 * Athlon X2: 0x6b 1/2 207 * 0x68 1/2 208 * Athlon 64: 0x7f 1 209 * 0x6f 2 210 * Sempron: 0x7f 1/2 211 * 0x6f 2 212 * 0x6c 2 213 * 0x7c 2 214 * Turion 64: 0x68 2 215 */ 216 uint32_t u32Dummy; 217 uint32_t u32Version, u32Family, u32Model, u32Stepping, u32BaseFamily; 218 ASMCpuId(1, &u32Version, &u32Dummy, &u32Dummy, &u32Dummy); 219 u32BaseFamily = (u32Version >> 8) & 0xf; 220 u32Family = u32BaseFamily + (u32BaseFamily == 0xf ? ((u32Version >> 20) & 0x7f) : 0); 221 u32Model = ((u32Version >> 4) & 0xf); 222 u32Model = u32Model | ((u32BaseFamily == 0xf ? (u32Version >> 16) & 0x0f : 0) << 4); 223 u32Stepping = u32Version & 0xf; 224 if ( u32Family == 0xf 225 && !((u32Model == 0x68 || u32Model == 0x6b || u32Model == 0x7f) && u32Stepping >= 1) 226 && !((u32Model == 0x6f || u32Model == 0x6c || u32Model == 0x7c) && u32Stepping >= 2)) 220 /* Check for an AMD CPU erratum which requires us to flush the TLB before every world-switch. */ 221 uint32_t u32Family; 222 uint32_t u32Model; 223 uint32_t u32Stepping; 224 if (HMAmdIsSubjectToErratum170(&u32Family, &u32Model, &u32Stepping)) 227 225 { 228 226 Log(("SVMR0InitVM: AMD cpu with erratum 170 family %x model %x stepping %x\n", u32Family, u32Model, u32Stepping)); -
trunk/src/VBox/VMM/VMMR0/HWSVMR0.h
r45786 r46297 38 38 #ifdef IN_RING0 39 39 40 /** 41 * Enters the AMD-V session 42 * 43 * @returns VBox status code. 44 * @param pVM Pointer to the VM. 45 * @param pVCpu Pointer to the VMCPU. 46 * @param pCpu Pointer to the CPU info struct. 47 */ 48 VMMR0DECL(int) SVMR0Enter(PVM pVM, PVMCPU pVCpu, PHMGLOBLCPUINFO pCpu); 49 50 /** 51 * Leaves the AMD-V session 52 * 53 * @returns VBox status code. 54 * @param pVM Pointer to the VM. 55 * @param pVCpu Pointer to the VMCPU. 56 * @param pCtx Pointer to the guest CPU context. 57 */ 58 VMMR0DECL(int) SVMR0Leave(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); 59 60 VMMR0DECL(int) SVMR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS HCPhysCpuPage, bool fEnabledBySystem); 61 62 /** 63 * Deactivates AMD-V on the current CPU 64 * 65 * @returns VBox status code. 66 * @param pCpu Pointer to the CPU info struct. 67 * @param pvPageCpu Pointer to the global CPU page. 68 * @param pPageCpuPhys Physical address of the global CPU page. 69 */ 70 VMMR0DECL(int) SVMR0DisableCpu(PHMGLOBLCPUINFO pCpu, void *pvPageCpu, RTHCPHYS pPageCpuPhys); 71 72 /** 73 * Does Ring-0 per VM AMD-V init. 74 * 75 * @returns VBox status code. 76 * @param pVM Pointer to the VM. 77 */ 78 VMMR0DECL(int) SVMR0InitVM(PVM pVM); 79 80 /** 81 * Does Ring-0 per VM AMD-V termination. 82 * 83 * @returns VBox status code. 84 * @param pVM Pointer to the VM. 85 */ 86 VMMR0DECL(int) SVMR0TermVM(PVM pVM); 87 88 /** 89 * Sets up AMD-V for the specified VM 90 * 91 * @returns VBox status code. 92 * @param pVM Pointer to the VM. 93 */ 94 VMMR0DECL(int) SVMR0SetupVM(PVM pVM); 95 96 97 /** 98 * Runs guest code in an AMD-V VM. 99 * 100 * @returns VBox status code. 101 * @param pVM Pointer to the VM. 102 * @param pVCpu Pointer to the VMCPU. 103 * @param pCtx Pointer to the guest CPU context. 104 */ 105 VMMR0DECL(int) SVMR0RunGuestCode(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); 106 107 108 /** 109 * Save the host state. 110 * 111 * @returns VBox status code. 112 * @param pVM Pointer to the VM. 113 * @param pVCpu Pointer to the VMCPU. 114 */ 115 VMMR0DECL(int) SVMR0SaveHostState(PVM pVM, PVMCPU pVCpu); 116 117 /** 118 * Loads the guest state. 119 * 120 * @returns VBox status code. 121 * @param pVM Pointer to the VM. 122 * @param pVCpu Pointer to the VMCPU. 123 * @param pCtx Pointer to the guest CPU context. 124 */ 125 VMMR0DECL(int) SVMR0LoadGuestState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); 126 40 VMMR0DECL(int) SVMR0GlobalInit(void); 41 VMMR0DECL(void) SVMR0GlobalTerm(void); 42 VMMR0DECL(int) SVMR0Enter(PVM pVM, PVMCPU pVCpu, PHMGLOBLCPUINFO pCpu); 43 VMMR0DECL(int) SVMR0Leave(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); 44 VMMR0DECL(int) SVMR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS HCPhysCpuPage, bool fEnabledBySystem); 45 VMMR0DECL(int) SVMR0DisableCpu(PHMGLOBLCPUINFO pCpu, void *pvPageCpu, RTHCPHYS pPageCpuPhys); 46 VMMR0DECL(int) SVMR0InitVM(PVM pVM); 47 VMMR0DECL(int) SVMR0TermVM(PVM pVM); 48 VMMR0DECL(int) SVMR0SetupVM(PVM pVM); 49 VMMR0DECL(int) SVMR0RunGuestCode(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); 50 VMMR0DECL(int) SVMR0SaveHostState(PVM pVM, PVMCPU pVCpu); 51 VMMR0DECL(int) SVMR0LoadGuestState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); 127 52 128 53 #if HC_ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL) -
trunk/src/VBox/VMM/VMMR3/HM.cpp
r46280 r46297 1359 1359 Log(("pVM->hm.s.svm.fSupported = %d\n", pVM->hm.s.svm.fSupported)); 1360 1360 1361 /* Erratum 170 which requires a forced TLB flush for each world switch: 1362 * See http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/33610.pdf 1363 * 1364 * All BH-G1/2 and DH-G1/2 models include a fix: 1365 * Athlon X2: 0x6b 1/2 1366 * 0x68 1/2 1367 * Athlon 64: 0x7f 1 1368 * 0x6f 2 1369 * Sempron: 0x7f 1/2 1370 * 0x6f 2 1371 * 0x6c 2 1372 * 0x7c 2 1373 * Turion 64: 0x68 2 1374 * 1375 */ 1376 uint32_t u32Dummy; 1377 uint32_t u32Version, u32Family, u32Model, u32Stepping, u32BaseFamily; 1378 ASMCpuId(1, &u32Version, &u32Dummy, &u32Dummy, &u32Dummy); 1379 u32BaseFamily= (u32Version >> 8) & 0xf; 1380 u32Family = u32BaseFamily + (u32BaseFamily == 0xf ? ((u32Version >> 20) & 0x7f) : 0); 1381 u32Model = ((u32Version >> 4) & 0xf); 1382 u32Model = u32Model | ((u32BaseFamily == 0xf ? (u32Version >> 16) & 0x0f : 0) << 4); 1383 u32Stepping = u32Version & 0xf; 1384 if ( u32Family == 0xf 1385 && !((u32Model == 0x68 || u32Model == 0x6b || u32Model == 0x7f) && u32Stepping >= 1) 1386 && !((u32Model == 0x6f || u32Model == 0x6c || u32Model == 0x7c) && u32Stepping >= 2)) 1387 { 1388 LogRel(("HM: AMD cpu with erratum 170 family %x model %x stepping %x\n", u32Family, u32Model, u32Stepping)); 1389 } 1390 1361 uint32_t u32Family; 1362 uint32_t u32Model; 1363 uint32_t u32Stepping; 1364 if (HMAmdIsSubjectToErratum170(&u32Family, &u32Model, &u32Stepping)) 1365 LogRel(("HM: AMD Cpu with erratum 170 family %#x model %#x stepping %#x\n", u32Family, u32Model, u32Stepping)); 1391 1366 LogRel(("HM: cpuid 0x80000001.u32AMDFeatureECX = %RX32\n", pVM->hm.s.cpuid.u32AMDFeatureECX)); 1392 1367 LogRel(("HM: cpuid 0x80000001.u32AMDFeatureEDX = %RX32\n", pVM->hm.s.cpuid.u32AMDFeatureEDX));
Note:
See TracChangeset
for help on using the changeset viewer.