VirtualBox

Changeset 25817 in vbox for trunk/src/VBox/Devices/PC


Ignore:
Timestamp:
Jan 13, 2010 10:08:17 PM (15 years ago)
Author:
vboxsync
Message:

CPU hotplug: Merge the second patch. ACPI changes to support CPU hotplugging. ACPI table changes are in a separate file which is used if CPU hotplugging is enabled for a VM to not break untested guests

Location:
trunk/src/VBox/Devices/PC
Files:
2 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/ACPI/VBoxAcpi.cpp

    r20920 r25817  
    2929#include <VBox/log.h>
    3030#include <VBox/param.h>
     31#include <VBox/cfgm.h>
    3132#include <iprt/assert.h>
    3233#include <iprt/alloc.h>
     
    3940/* Statically compiled AML */
    4041# include <vboxaml.hex>
     42# include <vboxaml-cpuhotplug.hex>
    4143#endif
    4244
     
    140142    return prepareDynamicDsdt(pDevIns, ppPtr, puDsdtLen);
    141143#else
    142     patchAml(pDevIns, AmlCode, sizeof(AmlCode));
    143     *ppPtr = AmlCode;
    144     *puDsdtLen = sizeof(AmlCode);
     144    unsigned char *pbAmlCode = NULL;
     145    size_t cbAmlCode = 0;
     146    bool fCpuHotplug = false;
     147    int rc = CFGMR3QueryBoolDef(pDevIns->pCfgHandle, "CpuHotplug", &fCpuHotplug, false);
     148    if (RT_FAILURE(rc))
     149        return PDMDEV_SET_ERROR(pDevIns, rc,
     150                                N_("Configuration error: Failed to read \"CpuHotplug\""));
     151
     152    if (fCpuHotplug)
     153    {
     154        pbAmlCode = AmlCodeCpuHotplug;
     155        cbAmlCode = sizeof(AmlCodeCpuHotplug);
     156    }
     157    else
     158    {
     159        pbAmlCode = AmlCode;
     160        cbAmlCode = sizeof(AmlCode);
     161    }
     162
     163    patchAml(pDevIns, pbAmlCode, cbAmlCode);
     164    *ppPtr = pbAmlCode;
     165    *puDsdtLen = cbAmlCode;
    145166    return 0;
    146167#endif
  • trunk/src/VBox/Devices/PC/DevACPI.cpp

    r25226 r25817  
    149149    SYSTEM_INFO_INDEX_HIGH_MEMORY_LENGTH= 9,
    150150    SYSTEM_INFO_INDEX_RTC_STATUS        = 10,
    151     SYSTEM_INFO_INDEX_END               = 11,
     151    SYSTEM_INFO_INDEX_CPU_LOCKED        = 11,
     152    SYSTEM_INFO_INDEX_MADT_ADDR         = 12,
     153    SYSTEM_INFO_INDEX_MADT_SIZE         = 13,
     154    SYSTEM_INFO_INDEX_END               = 14,
    152155    SYSTEM_INFO_INDEX_INVALID           = 0x80,
    153156    SYSTEM_INFO_INDEX_VALID             = 0x200
     
    230233    /** Flag whether the R0 part of the device is enabled. */
    231234    bool                fR0Enabled;
     235    /** Physical base address of the MADT table. */
     236    RTGCPHYS32          GCPhysMADTBase;
     237    /** Size of the MADT table */
     238    uint32_t            cbMADT;
     239    /** Array of flags of attached CPUs */
     240    bool                afCpuAttached[32]; /* Maximum we support atm */
     241    /** Mask of locked CPUs (used by the guest) */
     242    uint32_t            uCpusLocked;
     243    /** Flag whether CPU hotplugging is enabled */
     244    bool                fCpuHotplug;
    232245    /** Aligning IBase. */
    233246    bool                afAlignment[4];
     
    716729                                            | FADT_FL_FIX_RTC
    717730                                            | FADT_FL_TMR_VAL_EXT);
     731
     732    /* We have to force physical APIC mode or Linux can't use more than 8 CPUs */
     733    if (s->fCpuHotplug)
     734        fadt.u32Flags |= RT_H2LE_U32(FADT_FL_FORCE_APIC_PHYS_DEST_MODE);
     735
    718736    acpiWriteGenericAddr(&fadt.ResetReg,     1,  8, 0, 1, ACPI_RESET_BLK);
    719737    fadt.u8ResetVal           = ACPI_RESET_REG_VAL;
     
    829847        lapic->u8ProcId    = i;
    830848        lapic->u8ApicId    = i;
    831         lapic->u32Flags    = RT_H2LE_U32(LAPIC_ENABLED);
     849        lapic->u32Flags    = s->afCpuAttached[i] ? RT_H2LE_U32(LAPIC_ENABLED) : 0;
    832850        lapic++;
    833851    }
     
    845863    madt.header_addr()->u8Checksum = acpiChecksum(madt.data(), madt.size());
    846864    acpiPhyscpy(s, addr, madt.data(), madt.size());
     865
     866    /* Save for attach/detach notifications. */
     867    s->GCPhysMADTBase = addr;
     868    s->cbMADT         = madt.size();
    847869}
    848870
     
    958980    ACPIState *s = IACPIPORT_2_ACPISTATE(pInterface);
    959981    *pfEntered = (s->pm1a_ctl & SCI_EN) != 0;
     982    return VINF_SUCCESS;
     983}
     984
     985static DECLCALLBACK(int) acpiGetCpuStatus(PPDMIACPIPORT pInterface, unsigned uCpu, bool *pfLocked)
     986{
     987    ACPIState *s = IACPIPORT_2_ACPISTATE(pInterface);
     988    *pfLocked = (s->uCpusLocked & RT_BIT(uCpu)) != 0;
    960989    return VINF_SUCCESS;
    961990}
     
    13771406                  *pu32 = s->fShowCpu
    13781407                    && s->uSystemInfoIndex - SYSTEM_INFO_INDEX_CPU0_STATUS < s->cCpus
     1408                    && s->afCpuAttached[s->uSystemInfoIndex - SYSTEM_INFO_INDEX_CPU0_STATUS]
    13791409                    ?
    13801410                      STA_DEVICE_PRESENT_MASK
     
    13921422                    break;
    13931423
     1424                case SYSTEM_INFO_INDEX_CPU_LOCKED:
     1425                {
     1426                    *pu32 = s->uCpusLocked;
     1427                    break;
     1428                }
     1429
     1430                case SYSTEM_INFO_INDEX_MADT_ADDR:
     1431                {
     1432                    *pu32 = s->GCPhysMADTBase;
     1433                    break;
     1434                }
     1435
     1436                case SYSTEM_INFO_INDEX_MADT_SIZE:
     1437                {
     1438                    *pu32 = s->cbMADT;
     1439                    break;
     1440                }
     1441
    13941442                /* Solaris 9 tries to read from this index */
    13951443                case SYSTEM_INFO_INDEX_INVALID:
     
    14171465    Log(("addr=%#x cb=%d u32=%#x si=%#x\n", Port, cb, u32, s->uSystemInfoIndex));
    14181466
    1419     if (cb == 4 && u32 == 0xbadc0de)
     1467    if (cb == 4)
    14201468    {
    14211469        switch (s->uSystemInfoIndex)
    14221470        {
    14231471            case SYSTEM_INFO_INDEX_INVALID:
     1472                AssertMsg(u32 == 0xbadc0de, ("u32=%u\n", u32));
    14241473                s->u8IndexShift = 0;
    14251474                break;
    14261475
    14271476            case SYSTEM_INFO_INDEX_VALID:
     1477                AssertMsg(u32 == 0xbadc0de, ("u32=%u\n", u32));
    14281478                s->u8IndexShift = 2;
     1479                break;
     1480
     1481            case SYSTEM_INFO_INDEX_CPU_LOCKED:
     1482                s->uCpusLocked &= ~u32; /* Unlock the CPU */
    14291483                break;
    14301484
     
    20092063}
    20102064
     2065/**
     2066 * Attach a new CPU.
     2067 *
     2068 * @returns VBox status code.
     2069 * @param   pDevIns     The device instance.
     2070 * @param   iLUN        The logical unit which is being attached.
     2071 * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
     2072 *
     2073 * @remarks This code path is not used during construction.
     2074 */
     2075static DECLCALLBACK(int) acpiAttach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
     2076{
     2077    ACPIState *s = PDMINS_2_DATA(pDevIns, ACPIState *);
     2078
     2079    LogFlow(("acpiAttach: pDevIns=%p iLUN=%u fFlags=%#x\n", pDevIns, iLUN, fFlags));
     2080
     2081    /* Check if it was already attached */
     2082    if (s->afCpuAttached[iLUN])
     2083        return VINF_SUCCESS;
     2084
     2085    PPDMIBASE IBaseTmp;
     2086    int rc = PDMDevHlpDriverAttach(pDevIns, iLUN, &s->IBase, &IBaseTmp, "ACPI CPU");
     2087
     2088    if (RT_SUCCESS(rc))
     2089    {
     2090        /* Enable the CPU */
     2091        s->afCpuAttached[iLUN] = true;
     2092
     2093        /* Enable the lapic */
     2094        acpiSetupMADT(s, s->GCPhysMADTBase);
     2095        /*
     2096         * Lock the CPU because we don't know if the guest will use it or not.
     2097         * Prevents ejection while the CPU is still used
     2098         */
     2099        s->uCpusLocked |= RT_BIT(iLUN);
     2100
     2101        /* Notify the guest */
     2102        update_gpe0(s, s->gpe0_sts | 0x2, s->gpe0_en);
     2103    }
     2104    return rc;
     2105}
     2106
     2107/**
     2108 * Detach notification.
     2109 *
     2110 * @param   pDevIns     The device instance.
     2111 * @param   iLUN        The logical unit which is being detached.
     2112 * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
     2113 */
     2114static DECLCALLBACK(void) acpiDetach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
     2115{
     2116    ACPIState *s = PDMINS_2_DATA(pDevIns, ACPIState *);
     2117
     2118    LogFlow(("acpiDetach: pDevIns=%p iLUN=%u fFlags=%#x\n", pDevIns, iLUN, fFlags));
     2119
     2120    /* Check if it was already detached */
     2121    if (s->afCpuAttached[iLUN])
     2122    {
     2123        /* Disable the CPU */
     2124        s->afCpuAttached[iLUN] = false;
     2125
     2126        AssertMsg(!(s->uCpusLocked & RT_BIT(iLUN)), ("CPU is still locked by the guest\n"));
     2127
     2128        /* Update the lapic state */
     2129        acpiSetupMADT(s, s->GCPhysMADTBase);
     2130
     2131        /* Notify the guest */
     2132        update_gpe0(s, s->gpe0_sts | 0x2, s->gpe0_en);
     2133    }
     2134}
     2135
    20112136static DECLCALLBACK(void) acpiReset(PPDMDEVINS pDevIns)
    20122137{
     
    20702195                              "ShowRtc\0"
    20712196                              "ShowCpu\0"
     2197                              "CpuHotplug\0"
    20722198                              ))
    20732199        return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
     
    21162242                                N_("Configuration error: Failed to read \"ShowCpu\""));
    21172243
     2244    /* query whether we are allow CPU hotplugging */
     2245    rc = CFGMR3QueryBoolDef(pCfgHandle, "CpuHotplug", &s->fCpuHotplug, false);
     2246    if (RT_FAILURE(rc))
     2247        return PDMDEV_SET_ERROR(pDevIns, rc,
     2248                                N_("Configuration error: Failed to read \"CpuHotplug\""));
     2249
    21182250    rc = CFGMR3QueryBool(pCfgHandle, "GCEnabled", &s->fGCEnabled);
    21192251    if (rc == VERR_CFGM_VALUE_NOT_FOUND)
     
    21292261        return PDMDEV_SET_ERROR(pDevIns, rc,
    21302262                                N_("configuration error: failed to read R0Enabled as boolean"));
     2263
     2264    /*
     2265     * Interfaces
     2266     */
     2267    /* IBase */
     2268    s->IBase.pfnQueryInterface              = acpiQueryInterface;
     2269    /* IACPIPort */
     2270    s->IACPIPort.pfnSleepButtonPress        = acpiSleepButtonPress;
     2271    s->IACPIPort.pfnPowerButtonPress        = acpiPowerButtonPress;
     2272    s->IACPIPort.pfnGetPowerButtonHandled   = acpiGetPowerButtonHandled;
     2273    s->IACPIPort.pfnGetGuestEnteredACPIMode = acpiGetGuestEnteredACPIMode;
     2274    s->IACPIPort.pfnGetCpuStatus            = acpiGetCpuStatus;
     2275
     2276    /* The first CPU can't be attached/detached */
     2277    s->afCpuAttached[0] = true;
     2278    s->uCpusLocked |= RT_BIT(0);
     2279
     2280    /* Try to attach the other CPUs */
     2281    for (unsigned i = 1; i < s->cCpus; i++)
     2282    {
     2283        PPDMIBASE IBaseTmp;
     2284        rc = PDMDevHlpDriverAttach(pDevIns, i, &s->IBase, &IBaseTmp, "ACPI CPU");
     2285
     2286        if (RT_SUCCESS(rc))
     2287        {
     2288            s->afCpuAttached[i] = true;
     2289            s->uCpusLocked |= RT_BIT(i);
     2290            Log(("acpi: Attached CPU %u\n", i));
     2291        }
     2292        else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
     2293        {
     2294            Log(("acpi: CPU %u not attached yet\n", i));
     2295            s->afCpuAttached[i] = false;
     2296        }
     2297        else
     2298            return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to attach CPU object\n"));
     2299    }
     2300
    21312301
    21322302    /* Set default port base */
     
    22232393    if (RT_FAILURE(rc))
    22242394        return rc;
    2225 
    2226     /*
    2227      * Interfaces
    2228      */
    2229     /* IBase */
    2230     s->IBase.pfnQueryInterface              = acpiQueryInterface;
    2231     /* IACPIPort */
    2232     s->IACPIPort.pfnSleepButtonPress        = acpiSleepButtonPress;
    2233     s->IACPIPort.pfnPowerButtonPress        = acpiPowerButtonPress;
    2234     s->IACPIPort.pfnGetPowerButtonHandled   = acpiGetPowerButtonHandled;
    2235     s->IACPIPort.pfnGetGuestEnteredACPIMode = acpiGetGuestEnteredACPIMode;
    22362395
    22372396   /*
     
    22982457    NULL,
    22992458    /* pfnAttach */
    2300     NULL,
     2459    acpiAttach,
    23012460    /* pfnDetach */
    2302     NULL,
     2461    acpiDetach,
    23032462    /* pfnQueryInterface. */
    23042463    NULL,
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