VirtualBox

Changeset 60720 in vbox


Ignore:
Timestamp:
Apr 27, 2016 3:32:57 PM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
106907
Message:

VMM/APIC: Fixes for getting x2APIC mode working.

Location:
trunk/src/VBox/VMM
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/APICAll.cpp

    r60718 r60720  
    19751975    }
    19761976
     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
    19771984    /*
    19781985     * Act on state transition.
     
    19992006                APICR3Reset(pVCpu, false /* fResetApicBaseMsr */);
    20002007                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);
    20032009                LogRel(("APIC%u: Switched mode to disabled\n", pVCpu->idCpu));
    20042010                break;
     
    20132019                }
    20142020
    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));
    20242024                break;
    20252025            }
     
    20332033                }
    20342034
    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));
    20622057                break;
    20632058            }
     
    25742569
    25752570/**
    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 /**
    26102571 * Queues a pending interrupt as in-service.
    26112572 *
  • trunk/src/VBox/VMM/VMMR3/APIC.cpp

    r60717 r60720  
    244244
    245245    /* Construct. */
    246     PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
    247     uint64_t uApicBaseMsr = XAPIC_APICBASE_PHYSADDR
    248                           | 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;
    249249    if (pVCpu->idCpu == 0)
    250250        uApicBaseMsr |= MSR_APICBASE_BOOTSTRAP_CPU_BIT;
    251251
    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    }
    255261
    256262    /* Commit. */
     
    14521458    rc = CFGMR3QueryU8Def(pCfg, "Mode", &uOriginalMode, APICMODE_XAPIC);
    14531459    AssertLogRelRCReturn(rc, rc);
     1460
    14541461    /* Validate APIC modes. */
    1455     switch (uOriginalMode)
     1462    APICMODE const enmOriginalMode = (APICMODE)uOriginalMode;
     1463    switch (enmOriginalMode)
    14561464    {
    14571465        case APICMODE_DISABLED:
     1466            pApic->enmOriginalMode = enmOriginalMode;
     1467            CPUMClearGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_APIC);
     1468            CPUMClearGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_X2APIC);
     1469            break;
     1470
    14581471        case APICMODE_X2APIC:
     1472            pApic->enmOriginalMode = enmOriginalMode;
     1473            CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_X2APIC);
     1474            break;
     1475
    14591476        case APICMODE_XAPIC:
    1460             pApic->enmOriginalMode = (APICMODE)uOriginalMode;
     1477            pApic->enmOriginalMode = enmOriginalMode;
     1478            /* The CPUID bit will be updated in apicR3ResetBaseMsr(). */
    14611479            break;
     1480
    14621481        default:
    14631482            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.

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