- Timestamp:
- Apr 7, 2016 3:53:36 PM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 106461
- Location:
- trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/apic.h
r60307 r60377 38 38 #define XAPIC_HARDWARE_VERSION XAPIC_HARDWARE_VERSION_P4 39 39 40 /** The APIC base physical address. */ 41 #define MSR_APICBASE_PHYSADDR(a) ((a) >> 12) 42 /** The APIC base physical address shift. */ 43 #define MSR_APICBASE_PHYSADDR_SHIFT 12 44 /** The APIC base MSR mode shift. */ 45 #define MSR_APICBASE_MODE_SHIFT 10 40 /** Gets the APIC base physical address. */ 41 #define MSR_APICBASE_GET_PHYSADDR(a) ((a) & PAGE_BASE_GC_MASK) 42 /** Gets the APIC mode. */ 43 #define MSR_APICBASE_GET_MODE(a) (((a) >> 10) & UINT64_C(3)) 46 44 /** The APIC global enable bit. */ 47 45 #define MSR_APICBASE_XAPIC_ENABLE_BIT RT_BIT_64(11) … … 51 49 #define MSR_APICBASE_BOOTSTRAP_CPU_BIT RT_BIT_64(8) 52 50 /** The default APIC base address. */ 53 #define XAPIC_APICBASE_PHYSADDR UINT64_C(0xfee00000)51 #define XAPIC_APICBASE_PHYSADDR (UINT64_C(0xfee00000) << PAGE_SHIFT) 54 52 /** The APIC base MSR - Is the APIC enabled? */ 55 #define MSR_APICBASE_IS_ENABLED(a_Msr) RT_BOOL((a_Msr) & MSR_APICBASE_XAPIC_ENABLE_BIT)53 #define MSR_APICBASE_IS_ENABLED(a_Msr) RT_BOOL((a_Msr) & MSR_APICBASE_XAPIC_ENABLE_BIT) 56 54 57 55 /** Offset of APIC ID Register. */ -
trunk/include/VBox/vmm/cpum.h
r58996 r60377 31 31 #include <VBox/vmm/cpumctx.h> 32 32 #include <VBox/vmm/stam.h> 33 #include <VBox/vmm/vmapi.h> 33 34 34 35 RT_C_DECLS_BEGIN … … 1383 1384 1384 1385 VMMR3DECL(int) CPUMR3Init(PVM pVM); 1385 VMMR3DECL(int) CPUMR3InitCompleted(PVM pVM );1386 VMMR3DECL(int) CPUMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat); 1386 1387 VMMR3DECL(void) CPUMR3LogCpuIds(PVM pVM); 1387 1388 VMMR3DECL(void) CPUMR3Relocate(PVM pVM); -
trunk/include/VBox/vmm/pdmapi.h
r60307 r60377 50 50 VMM_INT_DECL(int) PDMApicHasPendingIrq(PVM pVM, bool *pfPending); 51 51 VMMDECL(VBOXSTRICTRC) PDMApicSetBaseMsr(PVMCPU pVCpu, uint64_t u64Base); 52 VMMDECL(VBOXSTRICTRC) PDMApicGetBaseMsr(PVMCPU pVCpu, uint64_t *pu64Base );52 VMMDECL(VBOXSTRICTRC) PDMApicGetBaseMsr(PVMCPU pVCpu, uint64_t *pu64Base, bool fIgnoreErrors); 53 53 VMMDECL(int) PDMApicSetTPR(PVMCPU pVCpu, uint8_t u8TPR); 54 54 VMMDECL(int) PDMApicGetTPR(PVMCPU pVCpu, uint8_t *pu8TPR, bool *pfPending, uint8_t *pu8PendingIrq); -
trunk/src/VBox/VMM/VMMAll/APICAll.cpp
r60345 r60377 223 223 static APICMODE apicGetMode(uint64_t uApicBaseMsr) 224 224 { 225 uint32_t const uMode = ((uint32_t)uApicBaseMsr >> MSR_APICBASE_MODE_SHIFT) & UINT32_C(0x3);225 uint32_t const uMode = MSR_APICBASE_GET_MODE(uApicBaseMsr); 226 226 APICMODE const enmMode = (APICMODE)uMode; 227 227 #ifdef VBOX_STRICT … … 1012 1012 } 1013 1013 1014 /** @todo Signal next interrupt? Most likely not as1015 * APICUpdatePendingInterrupts() will be called before next VM-entry. */1016 1014 apicSignalNextPendingIntr(pVCpu); 1017 1015 } … … 1793 1791 */ 1794 1792 /** @todo Handle per-VCPU APIC base relocation. */ 1795 if (MSR_APICBASE_ PHYSADDR(uBaseMsr) != XAPIC_APICBASE_PHYSADDR)1793 if (MSR_APICBASE_GET_PHYSADDR(uBaseMsr) != XAPIC_APICBASE_PHYSADDR) 1796 1794 { 1797 1795 #ifdef IN_RING3 1798 1796 LogRelMax(5, ("APIC%u: Attempt to relocate base to %#RGp, unsupported -> #GP(0)\n", pVCpu->idCpu, 1799 MSR_APICBASE_ PHYSADDR(uBaseMsr)));1797 MSR_APICBASE_GET_PHYSADDR(uBaseMsr))); 1800 1798 return VERR_CPUM_RAISE_GP_0; 1801 1799 #else … … 1964 1962 AssertReturn(u8Level <= 1, VERR_INVALID_PARAMETER); 1965 1963 1966 PCXAPICPAGE 1967 VBOXSTRICTRC 1964 PCXAPICPAGE pXApicPage = VMCPU_TO_CXAPICPAGE(pVCpu); 1965 VBOXSTRICTRC rcStrict = VINF_SUCCESS; 1968 1966 1969 1967 /* If the APIC is enabled, the interrupt is subject to LVT programming. */ … … 2058 2056 && pXApicPage->svr.u.fApicSoftwareEnable) 2059 2057 { 2058 APICUpdatePendingInterrupts(pVCpu); 2060 2059 int const irrv = apicGetLastSetBit(&pXApicPage->irr, -1); 2061 2060 if (irrv >= 0) … … 2066 2065 /** @todo this cannot possibly happen for anything other than ExtINT 2067 2066 * interrupts right? */ 2068 uint8_t uTpr = pXApicPage->tpr.u8Tpr;2067 uint8_t const uTpr = pXApicPage->tpr.u8Tpr; 2069 2068 if (uTpr > 0 && uVector <= uTpr) 2070 {2071 *puTagSrc = 0;2072 2069 return pXApicPage->svr.u.u8SpuriousVector; 2073 }2074 2070 2075 2071 apicClearVectorInReg(&pXApicPage->irr, uVector); 2076 2072 apicSetVectorInReg(&pXApicPage->isr, uVector); 2077 2073 apicUpdatePpr(pVCpu); 2078 2079 /** @todo Signal next interrupt? Most likely not as 2080 * APICUpdatePendingInterrupts() will be called before next VM-entry. */ 2074 apicSignalNextPendingIntr(pVCpu); 2081 2075 return uVector; 2082 2076 } 2083 2077 } 2084 /** @todo */2085 2078 2086 2079 return -1; … … 2093 2086 VMMDECL(int) APICReadMmio(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb) 2094 2087 { 2088 NOREF(pvUser); 2095 2089 Assert(!(GCPhysAddr & 0xf)); 2096 2090 Assert(cb == 4); … … 2115 2109 VMMDECL(int) APICWriteMmio(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb) 2116 2110 { 2111 NOREF(pvUser); 2117 2112 Assert(!(GCPhysAddr & 0xf)); 2118 2113 Assert(cb == 4); … … 2303 2298 * @param u8PendingIntr The pending interrupt to queue as 2304 2299 * in-service. 2300 * 2301 * @remarks This assumes the caller has done the necessary checks and 2302 * is ready to take actually service the interrupt (TPR, 2303 * interrupt shadow etc.) 2305 2304 */ 2306 2305 VMMDECL(bool) APICQueueInterruptToService(PVMCPU pVCpu, uint8_t u8PendingIntr) -
trunk/src/VBox/VMM/VMMAll/CPUMAllMsrs.cpp
r60307 r60377 205 205 static DECLCALLBACK(VBOXSTRICTRC) cpumMsrRd_Ia32ApicBase(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue) 206 206 { 207 return PDMApicGetBaseMsr(pVCpu, puValue );207 return PDMApicGetBaseMsr(pVCpu, puValue, false /* fIgnoreErrors */); 208 208 } 209 209 -
trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp
r58170 r60377 1391 1391 1392 1392 pVM->cpum.s.GuestFeatures.fApic = 1; 1393 LogRel(("CPUM: SetGuestCpuIdFeature: Enabled APIC\n"));1393 LogRel(("CPUM: SetGuestCpuIdFeature: Enabled xAPIC\n")); 1394 1394 break; 1395 1395 … … 1688 1688 1689 1689 pVM->cpum.s.GuestFeatures.fApic = 0; 1690 Log(("CPUM: ClearGuestCpuIdFeature: Disabled APIC\n"));1690 Log(("CPUM: ClearGuestCpuIdFeature: Disabled xAPIC\n")); 1691 1691 break; 1692 1692 -
trunk/src/VBox/VMM/VMMAll/PDMAll.cpp
r60309 r60377 47 47 PVM pVM = pVCpu->CTX_SUFF(pVM); 48 48 49 #ifndef VBOX_WITH_NEW_APIC 49 50 pdmLock(pVM); 51 #endif 50 52 51 53 /* … … 62 64 if (i >= 0) 63 65 { 66 #ifndef VBOX_WITH_NEW_APIC 64 67 pdmUnlock(pVM); 68 #endif 65 69 *pu8Interrupt = (uint8_t)i; 66 70 VBOXVMM_PDM_IRQ_GET(pVCpu, RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc), i); … … 68 72 } 69 73 } 74 75 #ifdef VBOX_WITH_NEW_APIC 76 pdmLock(pVM); 77 #endif 70 78 71 79 /* … … 236 244 { 237 245 Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnSetBaseMsr)); 246 #ifndef VBOX_WITH_NEW_APIC 238 247 pdmLock(pVM); 248 #endif 239 249 VBOXSTRICTRC rcStrict = pVM->pdm.s.Apic.CTX_SUFF(pfnSetBaseMsr)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu, u64Base); 240 250 … … 244 254 pCtx->msrApicBase = pVM->pdm.s.Apic.CTX_SUFF(pfnGetBaseMsr)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu); 245 255 256 #ifndef VBOX_WITH_NEW_APIC 246 257 pdmUnlock(pVM); 258 #endif 247 259 return rcStrict; 248 260 } … … 262 274 * 263 275 * @returns Strict VBox status code. 264 * @param pVCpu The cross context virtual CPU structure. 265 * @param pu64Base Where to store the APIC base. 266 */ 267 VMMDECL(VBOXSTRICTRC) PDMApicGetBaseMsr(PVMCPU pVCpu, uint64_t *pu64Base) 276 * @param pVCpu The cross context virtual CPU structure. 277 * @param pu64Base Where to store the APIC base. 278 * @param fIgnoreErrors Whether to ignore errors (i.e. not a real guest MSR 279 * access). 280 */ 281 VMMDECL(VBOXSTRICTRC) PDMApicGetBaseMsr(PVMCPU pVCpu, uint64_t *pu64Base, bool fIgnoreErrors) 268 282 { 269 283 PVM pVM = pVCpu->CTX_SUFF(pVM); … … 272 286 Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnGetBaseMsr)); 273 287 #ifdef VBOX_WITH_NEW_APIC 288 VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu); 274 289 *pu64Base = pVM->pdm.s.Apic.CTX_SUFF(pfnGetBaseMsr)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu); 275 290 #else … … 282 297 283 298 *pu64Base = 0; 299 if (fIgnoreErrors) 300 return VINF_SUCCESS; 301 284 302 #ifdef IN_RING3 285 303 LogRelMax(5, ("PDM: APIC%u: Reading APIC base MSR (%#x) invalid without an APIC instance -> #GP(0)\n", pVCpu->idCpu, -
trunk/src/VBox/VMM/VMMR0/APICR0.cpp
r60364 r60377 76 76 77 77 /* 78 * Allocate and map the virtual-APIC page .78 * Allocate and map the virtual-APIC pages. 79 79 */ 80 80 for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++) … … 110 110 const size_t offApicPib = idCpu * sizeof(APICPIB); 111 111 pApicCpu->HCPhysApicPib = pApic->HCPhysApicPib + offApicPib; 112 pApicCpu->pvApicPibR0 = (RTR0PTR)(( uint8_t *)pApic->pvApicPibR0 + offApicPib);113 pApicCpu->pvApicPibR3 = (RTR3PTR)(( uint8_t *)pApic->pvApicPibR3 + offApicPib);112 pApicCpu->pvApicPibR0 = (RTR0PTR)((const uint8_t *)pApic->pvApicPibR0 + offApicPib); 113 pApicCpu->pvApicPibR3 = (RTR3PTR)((const uint8_t *)pApic->pvApicPibR3 + offApicPib); 114 114 } 115 115 else -
trunk/src/VBox/VMM/VMMR3/CPUM.cpp
r60307 r60377 1082 1082 * continues to reside in the APIC device and we cache it here in the VCPU for all further accesses. 1083 1083 */ 1084 PDMApicGetBaseMsr(pVCpu, &pCtx->msrApicBase); 1084 PDMApicGetBaseMsr(pVCpu, &pCtx->msrApicBase, true /* fIgnoreErrors */); 1085 #ifdef VBOX_WITH_NEW_APIC 1086 LogRel(("CPUM: VCPU%3d: Cached APIC base MSR = %#RX64\n", pVCpu->idCpu, pVCpu->cpum.s.Guest.msrApicBase)); 1087 #endif 1085 1088 } 1086 1089 … … 1531 1534 1532 1535 /* Cache the local APIC base from the APIC device. During init. this is done in CPUMR3ResetCpu(). */ 1533 PDMApicGetBaseMsr(pVCpu, &pVCpu->cpum.s.Guest.msrApicBase); 1536 PDMApicGetBaseMsr(pVCpu, &pVCpu->cpum.s.Guest.msrApicBase, true /* fIgnoreErrors */); 1537 #ifdef VBOX_WITH_NEW_APIC 1538 LogRel(("CPUM: VCPU%3d: Cached APIC base MSR = %#RX64\n", idCpu, pVCpu->cpum.s.Guest.msrApicBase)); 1539 #endif 1534 1540 1535 1541 /* During init. this is done in CPUMR3InitCompleted(). */ … … 2410 2416 * @returns VBox status code. 2411 2417 * @param pVM The cross context VM structure. 2412 */ 2413 VMMR3DECL(int) CPUMR3InitCompleted(PVM pVM) 2414 { 2415 /* 2416 * Figure out if the guest uses 32-bit or 64-bit FPU state at runtime for 64-bit capable VMs. 2417 * Only applicable/used on 64-bit hosts, refer CPUMR0A.asm. See @bugref{7138}. 2418 */ 2419 bool const fSupportsLongMode = VMR3IsLongModeAllowed(pVM); 2420 for (VMCPUID i = 0; i < pVM->cCpus; i++) 2421 { 2422 PVMCPU pVCpu = &pVM->aCpus[i]; 2423 2424 /* Cache the APIC base (from the APIC device) once it has been initialized. */ 2425 PDMApicGetBaseMsr(pVCpu, &pVCpu->cpum.s.Guest.msrApicBase); 2426 Log(("CPUMR3InitCompleted pVM=%p APIC base[%u]=%RX64\n", pVM, (unsigned)i, pVCpu->cpum.s.Guest.msrApicBase)); 2427 2428 /* While loading a saved-state we fix it up in, cpumR3LoadDone(). */ 2429 if (fSupportsLongMode) 2430 pVCpu->cpum.s.fUseFlags |= CPUM_USE_SUPPORTS_LONGMODE; 2431 } 2432 2433 cpumR3MsrRegStats(pVM); 2418 * @param enmWhat Which init phase. 2419 */ 2420 VMMR3DECL(int) CPUMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat) 2421 { 2422 switch (enmWhat) 2423 { 2424 case VMINITCOMPLETED_RING3: 2425 { 2426 /* 2427 * Figure out if the guest uses 32-bit or 64-bit FPU state at runtime for 64-bit capable VMs. 2428 * Only applicable/used on 64-bit hosts, refer CPUMR0A.asm. See @bugref{7138}. 2429 */ 2430 bool const fSupportsLongMode = VMR3IsLongModeAllowed(pVM); 2431 for (VMCPUID i = 0; i < pVM->cCpus; i++) 2432 { 2433 PVMCPU pVCpu = &pVM->aCpus[i]; 2434 /* While loading a saved-state we fix it up in, cpumR3LoadDone(). */ 2435 if (fSupportsLongMode) 2436 pVCpu->cpum.s.fUseFlags |= CPUM_USE_SUPPORTS_LONGMODE; 2437 } 2438 2439 cpumR3MsrRegStats(pVM); 2440 break; 2441 } 2442 2443 case VMINITCOMPLETED_RING0: 2444 { 2445 /* Cache the APIC base (from the APIC device) once it has been initialized. */ 2446 for (VMCPUID i = 0; i < pVM->cCpus; i++) 2447 { 2448 PVMCPU pVCpu = &pVM->aCpus[i]; 2449 PDMApicGetBaseMsr(pVCpu, &pVCpu->cpum.s.Guest.msrApicBase, true /* fIgnoreErrors */); 2450 #ifdef VBOX_WITH_NEW_APIC 2451 LogRel(("CPUM: VCPU%3d: Cached APIC base MSR = %#RX64\n", i, pVCpu->cpum.s.Guest.msrApicBase)); 2452 #endif 2453 } 2454 break; 2455 } 2456 2457 default: 2458 break; 2459 } 2434 2460 return VINF_SUCCESS; 2435 2461 } -
trunk/src/VBox/VMM/VMMR3/VM.cpp
r60364 r60377 1183 1183 rc = APICR3InitCompleted(pVM, enmWhat); 1184 1184 #endif 1185 if (RT_SUCCESS(rc)) 1186 rc = CPUMR3InitCompleted(pVM, enmWhat); 1185 1187 #ifndef VBOX_WITH_RAW_MODE 1186 1188 if (enmWhat == VMINITCOMPLETED_RING3) … … 2813 2815 #endif 2814 2816 IOMR3Reset(pVM); 2815 CPUMR3Reset(pVM); 2817 CPUMR3Reset(pVM); /* This must come *after* PDM (due to APIC base MSR caching). */ 2816 2818 TMR3Reset(pVM); 2817 2819 EMR3Reset(pVM); -
trunk/src/VBox/VMM/VMMR3/VMM.cpp
r60307 r60377 687 687 { 688 688 /* 689 * CPUM's post-initialization (APIC base MSR caching).690 */691 rc = CPUMR3InitCompleted(pVM);692 AssertRCReturn(rc, rc);693 694 /*695 689 * Set page attributes to r/w for stack pages. 696 690 */
Note:
See TracChangeset
for help on using the changeset viewer.