VirtualBox

Changeset 60646 in vbox


Ignore:
Timestamp:
Apr 22, 2016 12:59:40 PM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
106813
Message:

VMM/APIC: Go back to ring-3 for all base MSR writes for now. Logging and a couple of Windows build fixes with size_t and '==' instead of '=' (thanks Michal).

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/apic.h

    r60601 r60646  
    926926 */
    927927VMMR3_INT_DECL(void)        APICR3InitIpi(PVMCPU pVCpu);
    928 VMMR3_INT_DECL(void)        APICR3Reset(PVMCPU pVCpu);
     928VMMR3_INT_DECL(void)        APICR3Reset(PVMCPU pVCpu, bool fResetApicBaseMsr);
    929929/** @} */
    930930#endif /* IN_RING3 */
  • trunk/src/VBox/VMM/VMMAll/APICAll.cpp

    r60632 r60646  
    373373 * @param   uApicBaseMsr        The APIC Base MSR value.
    374374 */
    375 static APICMODE apicGetMode(uint64_t uApicBaseMsr)
     375APICMODE apicGetMode(uint64_t uApicBaseMsr)
    376376{
    377377    uint32_t const uMode   = MSR_APICBASE_GET_MODE(uApicBaseMsr);
     
    19701970{
    19711971    Assert(pVCpu);
     1972    NOREF(pDevIns);
     1973
     1974#ifdef IN_RING3
    19721975    PAPICCPU pApicCpu   = VMCPU_TO_APICCPU(pVCpu);
    19731976    PAPIC    pApic      = VM_TO_APIC(pVCpu->CTX_SUFF(pVM));
     
    19761979    uint64_t uBaseMsr   = pApicCpu->uApicBaseMsr;
    19771980
    1978     /** @todo probably go back to ring-3 for all cases regardless of
    1979      *        fRZEnabled. Writing this MSR is not something guests
    1980      *        typically do often, and therefore is not performance
    1981      *        critical. We'll have better diagnostics in ring-3. */
    1982     if (!pApic->fRZEnabled)
    1983         return VINF_CPUM_R3_MSR_WRITE;
     1981    Log4(("APIC%u: ApicSetBaseMsr: u64BaseMsr=%#RX64 enmNewMode=%s enmOldMode=%s\n", pVCpu->idCpu, u64BaseMsr,
     1982          apicGetModeName(enmNewMode), apicGetModeName(enmOldMode)));
    19841983
    19851984    /*
     
    19931992    if (MSR_APICBASE_GET_PHYSADDR(uBaseMsr) != XAPIC_APICBASE_PHYSADDR)
    19941993    {
    1995 #ifdef IN_RING3
    19961994        LogRelMax(5, ("APIC%u: Attempt to relocate base to %#RGp, unsupported -> #GP(0)\n", pVCpu->idCpu,
    19971995                      MSR_APICBASE_GET_PHYSADDR(uBaseMsr)));
    19981996        return VERR_CPUM_RAISE_GP_0;
    1999 #else
    2000         return VINF_CPUM_R3_MSR_WRITE;
    2001 #endif
    20021997    }
    20031998
     
    20142009            case APICMODE_DISABLED:
    20152010            {
    2016 #ifdef IN_RING3
    20172011                /*
    20182012                 * The APIC state needs to be reset (especially the APIC ID as x2APIC APIC ID bit layout
     
    20212015                 * See Intel spec. 10.4.3 "Enabling or Disabling the Local APIC".
    20222016                 */
    2023                 APICR3Reset(pVCpu);
     2017                APICR3Reset(pVCpu, false /* fResetApicBaseMsr */);
    20242018                uBaseMsr &= ~(MSR_APICBASE_XAPIC_ENABLE_BIT | MSR_APICBASE_X2APIC_ENABLE_BIT);
    20252019                Log4(("APIC%u: Switched mode to disabled\n", pVCpu->idCpu));
    2026 #else
    2027                 return VINF_CPUM_R3_MSR_WRITE;
    2028 #endif
    20292020                break;
    20302021            }
     
    20442035            case APICMODE_X2APIC:
    20452036            {
    2046                 uBaseMsr |= MSR_APICBASE_X2APIC_ENABLE_BIT;
     2037                uBaseMsr |= MSR_APICBASE_XAPIC_ENABLE_BIT | MSR_APICBASE_X2APIC_ENABLE_BIT;
    20472038
    20482039                /*
     
    20782069    ASMAtomicWriteU64(&pApicCpu->uApicBaseMsr, uBaseMsr);
    20792070    return VINF_SUCCESS;
     2071#else  /* !IN_RING3 */
     2072    return VINF_CPUM_R3_MSR_WRITE;
     2073#endif /* IN_RING3 */
    20802074}
    20812075
     
    21952189            switch (enmDeliveryMode)
    21962190            {
     2191                case XAPICDELIVERYMODE_INIT:
     2192                {
     2193                    /** @todo won't work in R0/RC because callers don't care about rcRZ. */
     2194                    AssertMsgFailed(("INIT through LINT0/LINT1 is not yet supported\n"));
     2195                    /* fallthru */
     2196                }
    21972197                case XAPICDELIVERYMODE_FIXED:
    21982198                {
     
    22082208                case XAPICDELIVERYMODE_SMI:
    22092209                case XAPICDELIVERYMODE_NMI:
    2210                 case XAPICDELIVERYMODE_INIT:    /** @todo won't work in R0/RC because callers don't care about rcRZ. */
    22112210                {
    22122211                    VMCPUSET DestCpuSet;
     
    22212220                case XAPICDELIVERYMODE_EXTINT:
    22222221                {
    2223                     Log4(("APIC%u: APICLocalInterrupt: External interrupt. u8Pin=%u u8Level=%u\n", pVCpu->idCpu, u8Pin, u8Level));
     2222                    Log4(("APIC%u: APICLocalInterrupt: %s ExtINT through LINT%u\n", pVCpu->idCpu,
     2223                          u8Level ? "Raising" : "Lowering", u8Pin));
    22242224                    if (u8Level)
    22252225                        APICSetInterruptFF(pVCpu, PDMAPICIRQ_EXTINT);
     
    22442244    else
    22452245    {
    2246         /* The APIC is disabled, pass it through the CPU. */
    2247         LogFlow(("APIC%u: APICLocalInterrupt: APIC hardware-disabled, passing interrupt to CPU. u8Pin=%u u8Level=%u\n",
    2248                  pVCpu->idCpu, u8Pin, u8Level));
    2249         if (u8Level)
    2250             APICSetInterruptFF(pVCpu, PDMAPICIRQ_EXTINT);
     2246        /* The APIC is hardware disabled. The CPU behaves as though there is no on-chip APIC. */
     2247        if (u8Pin == 0)
     2248        {
     2249            /* LINT0 behaves as an external interrupt pin. */
     2250            Log4(("APIC%u: APICLocalInterrupt: APIC hardware-disabled, %s ExtINT through LINT0\n", pVCpu->idCpu,
     2251                  u8Level ? "raising" : "lowering"));
     2252            if (u8Level)
     2253                APICSetInterruptFF(pVCpu, PDMAPICIRQ_EXTINT);
     2254            else
     2255                APICClearInterruptFF(pVCpu, PDMAPICIRQ_EXTINT);
     2256        }
    22512257        else
    2252             APICClearInterruptFF(pVCpu, PDMAPICIRQ_EXTINT);
     2258        {
     2259            /* LINT1 behaves as NMI. */
     2260            Log4(("APIC%u: APICLocalInterrupt: APIC hardware-disabled, raising NMI through LINT1\n", pVCpu->idCpu));
     2261            APICSetInterruptFF(pVCpu, PDMAPICIRQ_NMI);
     2262        }
    22532263    }
    22542264
  • trunk/src/VBox/VMM/VMMR3/APIC.cpp

    r60632 r60646  
    253253 * reset.
    254254 *
    255  * @param   pVCpu           The cross context virtual CPU structure.
    256  */
    257 VMMR3_INT_DECL(void) APICR3Reset(PVMCPU pVCpu)
     255 * @param   pVCpu               The cross context virtual CPU structure.
     256 * @param   fResetApicBaseMsr   Whether to reset the APIC base MSR.
     257 */
     258VMMR3_INT_DECL(void) APICR3Reset(PVMCPU pVCpu, bool fResetApicBaseMsr)
    258259{
    259260    VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu);
     
    291292    /** @todo It isn't clear in the spec. where exactly the default base address
    292293     *        is (re)initialized, atm we do it here in Reset. */
    293     apicR3ResetBaseMsr(pVCpu);
     294    if (fResetApicBaseMsr)
     295        apicR3ResetBaseMsr(pVCpu);
    294296
    295297    /*
     
    373375    PCXAPICPAGE  pXApicPage  = VMCPU_TO_CXAPICPAGE(pVCpu);
    374376    PCX2APICPAGE pX2ApicPage = VMCPU_TO_CX2APICPAGE(pVCpu);
     377
     378    uint64_t const uBaseMsr  = pApicCpu->uApicBaseMsr;
     379    APICMODE const enmMode   = apicGetMode(uBaseMsr);
    375380    bool const   fX2ApicMode = XAPIC_IN_X2APIC_MODE(pVCpu);
    376381
    377     pHlp->pfnPrintf(pHlp, "VCPU[%u] APIC at %#RGp\n", pVCpu->idCpu, MSR_APICBASE_GET_PHYSADDR(pApicCpu->uApicBaseMsr));
    378     pHlp->pfnPrintf(pHlp, "  Mode                          = %s\n", fX2ApicMode ? "x2Apic" : "xApic");
     382    pHlp->pfnPrintf(pHlp, "VCPU[%u] APIC:\n", pVCpu->idCpu);
     383    pHlp->pfnPrintf(pHlp, "  APIC Base MSR                 = %#RX64 (Addr=%#RX64)\n", uBaseMsr,
     384                    MSR_APICBASE_GET_PHYSADDR(uBaseMsr));
     385    pHlp->pfnPrintf(pHlp, "  Mode                          = %#x (%s)\n", enmMode, apicGetModeName(enmMode));
    379386    if (fX2ApicMode)
    380387    {
     
    386393    pHlp->pfnPrintf(pHlp, "  Version                       = %#x\n",      pXApicPage->version.all.u32Version);
    387394    pHlp->pfnPrintf(pHlp, "    APIC Version                = %#x\n",      pXApicPage->version.u.u8Version);
    388     pHlp->pfnPrintf(pHlp, "    Max LVT entries             = %u\n",       pXApicPage->version.u.u8MaxLvtEntry);
     395    pHlp->pfnPrintf(pHlp, "    Max LVT entry index (0..N)  = %u\n",       pXApicPage->version.u.u8MaxLvtEntry);
    389396    pHlp->pfnPrintf(pHlp, "    EOI Broadcast supression    = %RTbool\n",  pXApicPage->version.u.fEoiBroadcastSupression);
    390397    if (!fX2ApicMode)
     
    929936            TMTimerStop(pApicCpu->pTimerR3);
    930937
    931         APICR3Reset(pVCpuDest);
     938        APICR3Reset(pVCpuDest, true /* fResetApicBaseMsr */);
    932939
    933940        /* Clear the interrupt pending force flag. */
     
    10701077        if (fNeedsGCMapping)
    10711078        {
    1072             pApic->pvApicPibRC == NIL_RTRCPTR;
     1079            pApic->pvApicPibRC = NIL_RTRCPTR;
    10731080            int rc = MMR3HyperMapHCPhys(pVM, (void *)pApic->pvApicPibR3, NIL_RTR0PTR, pApic->HCPhysApicPib, pApic->cbApicPib,
    10741081                                        "APIC PIB", (PRTGCPTR)&pApic->pvApicPibRC);
     
    11271134
    11281135                /* Associate the per-VCPU PIB pointers to the per-VM PIB mapping. */
    1129                 size_t const offApicPib    = idCpu * sizeof(APICPIB);
     1136                uint32_t const offApicPib  = idCpu * sizeof(APICPIB);
    11301137                pApicCpu->pvApicPibR0      = (RTR0PTR)((RTR0UINTPTR)pApic->pvApicPibR0 + offApicPib);
    11311138                pApicCpu->pvApicPibR3      = (RTR3PTR)((RTR3UINTPTR)pApic->pvApicPibR3 + offApicPib);
     
    11351142                /* Initialize the virtual-APIC state. */
    11361143                memset((void *)pApicCpu->pvApicPageR3, 0, pApicCpu->cbApicPage);
    1137                 APICR3Reset(pVCpu);
     1144                APICR3Reset(pVCpu, true /* fResetApicBaseMsr */);
    11381145
    11391146#ifdef DEBUG_ramshankar
  • trunk/src/VBox/VMM/include/APICInternal.h

    r60632 r60646  
    629629const char             *apicGetTimerModeName(XAPICTIMERMODE enmTimerMode);
    630630void                    apicHintTimerFreq(PAPICCPU pApicCpu, uint32_t uInitialCount, uint8_t uTimerShift);
     631APICMODE                apicGetMode(uint64_t uApicBaseMsr);
    631632
    632633VMMDECL(uint64_t)       APICGetBaseMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette