Changeset 60720 in vbox
- Timestamp:
- Apr 27, 2016 3:32:57 PM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 106907
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/APICAll.cpp
r60718 r60720 1975 1975 } 1976 1976 1977 /* Don't allow enabling xAPIC/x2APIC if the VM is configured with the APIC disabled. */ 1978 if (pApic->enmOriginalMode == APICMODE_DISABLED) 1979 { 1980 LogRel(("APIC%u: Disallowing APIC base MSR write as the VM config is configured with APIC disabled!\n")); 1981 return apicMsrAccessError(pVCpu, MSR_IA32_APICBASE, APICMSRACCESS_WRITE_DISALLOWED_CONFIG); 1982 } 1983 1977 1984 /* 1978 1985 * Act on state transition. … … 1999 2006 APICR3Reset(pVCpu, false /* fResetApicBaseMsr */); 2000 2007 uBaseMsr &= ~(MSR_APICBASE_XAPIC_ENABLE_BIT | MSR_APICBASE_X2APIC_ENABLE_BIT); 2001 2002 APICUpdateCpuIdForMode(pVCpu->CTX_SUFF(pVM), APICMODE_DISABLED); 2008 CPUMClearGuestCpuIdFeature(pVCpu->CTX_SUFF(pVM), CPUMCPUIDFEATURE_APIC); 2003 2009 LogRel(("APIC%u: Switched mode to disabled\n", pVCpu->idCpu)); 2004 2010 break; … … 2013 2019 } 2014 2020 2015 /* Don't allow enabling xAPIC if the VM is configured with a APIC disabled. */ 2016 if (pApic->enmOriginalMode != APICMODE_DISABLED) 2017 { 2018 uBaseMsr |= MSR_APICBASE_XAPIC_ENABLE_BIT; 2019 APICUpdateCpuIdForMode(pVCpu->CTX_SUFF(pVM), APICMODE_XAPIC); 2020 LogRel(("APIC%u: Switched mode to xAPIC\n", pVCpu->idCpu)); 2021 } 2022 else 2023 return apicMsrAccessError(pVCpu, MSR_IA32_APICBASE, APICMSRACCESS_WRITE_DISALLOWED_CONFIG); 2021 uBaseMsr |= MSR_APICBASE_XAPIC_ENABLE_BIT; 2022 CPUMSetGuestCpuIdFeature(pVCpu->CTX_SUFF(pVM), CPUMCPUIDFEATURE_APIC); 2023 LogRel(("APIC%u: Switched mode to xAPIC\n", pVCpu->idCpu)); 2024 2024 break; 2025 2025 } … … 2033 2033 } 2034 2034 2035 /* Don't allow enabling x2APIC if the VM is configured with a APIC disabled. */ 2036 if (pApic->enmOriginalMode != APICMODE_DISABLED) 2037 { 2038 uBaseMsr |= MSR_APICBASE_XAPIC_ENABLE_BIT | MSR_APICBASE_X2APIC_ENABLE_BIT; 2039 2040 /* 2041 * The APIC ID needs updating when entering x2APIC mode. 2042 * Software written APIC ID in xAPIC mode isn't preseved. 2043 * The APIC ID becomes read-only to software in x2APIC mode. 2044 * 2045 * See Intel spec. 10.12.5.1 "x2APIC States". 2046 */ 2047 PX2APICPAGE pX2ApicPage = VMCPU_TO_X2APICPAGE(pVCpu); 2048 ASMMemZero32(&pX2ApicPage->id, sizeof(pX2ApicPage->id)); 2049 pX2ApicPage->id.u32ApicId = pVCpu->idCpu; 2050 2051 /* 2052 * LDR initialization occurs when entering x2APIC mode. 2053 * See Intel spec. 10.12.10.2 "Deriving Logical x2APIC ID from the Local x2APIC ID". 2054 */ 2055 pX2ApicPage->ldr.u32LogicalApicId = ((pX2ApicPage->id.u32ApicId & UINT32_C(0xffff0)) << 16) 2056 | (UINT32_C(1) << pX2ApicPage->id.u32ApicId & UINT32_C(0xf)); 2057 2058 LogRel(("APIC%u: Switched mode to x2APIC\n", pVCpu->idCpu)); 2059 } 2060 else 2061 return apicMsrAccessError(pVCpu, MSR_IA32_APICBASE, APICMSRACCESS_WRITE_DISALLOWED_CONFIG); 2035 /* Don't allow enabling x2APIC if the VM is configured with the APIC disabled. */ 2036 uBaseMsr |= MSR_APICBASE_XAPIC_ENABLE_BIT | MSR_APICBASE_X2APIC_ENABLE_BIT; 2037 2038 /* 2039 * The APIC ID needs updating when entering x2APIC mode. 2040 * Software written APIC ID in xAPIC mode isn't preseved. 2041 * The APIC ID becomes read-only to software in x2APIC mode. 2042 * 2043 * See Intel spec. 10.12.5.1 "x2APIC States". 2044 */ 2045 PX2APICPAGE pX2ApicPage = VMCPU_TO_X2APICPAGE(pVCpu); 2046 ASMMemZero32(&pX2ApicPage->id, sizeof(pX2ApicPage->id)); 2047 pX2ApicPage->id.u32ApicId = pVCpu->idCpu; 2048 2049 /* 2050 * LDR initialization occurs when entering x2APIC mode. 2051 * See Intel spec. 10.12.10.2 "Deriving Logical x2APIC ID from the Local x2APIC ID". 2052 */ 2053 pX2ApicPage->ldr.u32LogicalApicId = ((pX2ApicPage->id.u32ApicId & UINT32_C(0xffff0)) << 16) 2054 | (UINT32_C(1) << pX2ApicPage->id.u32ApicId & UINT32_C(0xf)); 2055 2056 LogRel(("APIC%u: Switched mode to x2APIC\n", pVCpu->idCpu)); 2062 2057 break; 2063 2058 } … … 2574 2569 2575 2570 /** 2576 * Updates the CPUID bits necessary for the given APIC mode.2577 *2578 * @param pVM The cross context VM structure.2579 * @param enmMode The APIC mode.2580 */2581 VMM_INT_DECL(void) APICUpdateCpuIdForMode(PVM pVM, APICMODE enmMode)2582 {2583 LogFlow(("APIC: APICUpdateCpuIdForMode: enmMode=%d (%s)\n", enmMode, apicGetModeName(enmMode)));2584 2585 /* The CPUID bits being updated to reflect the current state is a bit vague. See @bugref{8245#c32}. */2586 /** @todo This needs to be done on a per-VCPU basis! */2587 switch (enmMode)2588 {2589 case APICMODE_DISABLED:2590 CPUMClearGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_APIC);2591 break;2592 2593 case APICMODE_XAPIC:2594 CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_APIC);2595 break;2596 2597 case APICMODE_X2APIC:2598 CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_APIC);2599 CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_X2APIC);2600 break;2601 2602 default:2603 AssertMsgFailed(("Invalid APIC mode: %d\n", (int)enmMode));2604 break;2605 }2606 }2607 2608 2609 /**2610 2571 * Queues a pending interrupt as in-service. 2611 2572 * -
trunk/src/VBox/VMM/VMMR3/APIC.cpp
r60717 r60720 244 244 245 245 /* Construct. */ 246 PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);247 uint64_t uApicBaseMsr = XAPIC_APICBASE_PHYSADDR248 | MSR_APICBASE_XAPIC_ENABLE_BIT;246 PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu); 247 PAPIC pApic = VM_TO_APIC(pVCpu->CTX_SUFF(pVM)); 248 uint64_t uApicBaseMsr = XAPIC_APICBASE_PHYSADDR; 249 249 if (pVCpu->idCpu == 0) 250 250 uApicBaseMsr |= MSR_APICBASE_BOOTSTRAP_CPU_BIT; 251 251 252 /* Update CPUID. */ 253 APICUpdateCpuIdForMode(pVCpu->CTX_SUFF(pVM), APICMODE_XAPIC); 254 LogRel(("APIC%u: Switched mode to xAPIC\n", pVCpu->idCpu)); 252 /* If the VM was configured with disabled mode, don't enable xAPIC mode. */ 253 if (pApic->enmOriginalMode != APICMODE_DISABLED) 254 { 255 uApicBaseMsr |= MSR_APICBASE_XAPIC_ENABLE_BIT; 256 257 /** @todo CPUID bits needs to be done on a per-VCPU basis! */ 258 CPUMSetGuestCpuIdFeature(pVCpu->CTX_SUFF(pVM), CPUMCPUIDFEATURE_APIC); 259 LogRel(("APIC%u: Switched mode to xAPIC\n", pVCpu->idCpu)); 260 } 255 261 256 262 /* Commit. */ … … 1452 1458 rc = CFGMR3QueryU8Def(pCfg, "Mode", &uOriginalMode, APICMODE_XAPIC); 1453 1459 AssertLogRelRCReturn(rc, rc); 1460 1454 1461 /* Validate APIC modes. */ 1455 switch (uOriginalMode) 1462 APICMODE const enmOriginalMode = (APICMODE)uOriginalMode; 1463 switch (enmOriginalMode) 1456 1464 { 1457 1465 case APICMODE_DISABLED: 1466 pApic->enmOriginalMode = enmOriginalMode; 1467 CPUMClearGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_APIC); 1468 CPUMClearGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_X2APIC); 1469 break; 1470 1458 1471 case APICMODE_X2APIC: 1472 pApic->enmOriginalMode = enmOriginalMode; 1473 CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_X2APIC); 1474 break; 1475 1459 1476 case APICMODE_XAPIC: 1460 pApic->enmOriginalMode = (APICMODE)uOriginalMode; 1477 pApic->enmOriginalMode = enmOriginalMode; 1478 /* The CPUID bit will be updated in apicR3ResetBaseMsr(). */ 1461 1479 break; 1480 1462 1481 default: 1463 1482 return VMR3SetError(pVM->pUVM, VERR_INVALID_STATE, RT_SRC_POS, "APIC mode %#x unknown.", uOriginalMode);
Note:
See TracChangeset
for help on using the changeset viewer.