VirtualBox

Changeset 108434 in vbox for trunk/src/VBox/VMM/VMMR3


Ignore:
Timestamp:
Mar 4, 2025 11:24:21 AM (2 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
167808
Message:

VMM/NEM/Hyper-V: Started implementing a NEM/Hyper-V specific APIC emulation utilizing the LocalApicEmulation feature of Hyper-V, bugref:9993

Location:
trunk/src/VBox/VMM/VMMR3
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp

    r107931 r108434  
    163163static decltype(WHvGetVirtualProcessorRegisters) *  g_pfnWHvGetVirtualProcessorRegisters;
    164164static decltype(WHvSetVirtualProcessorRegisters) *  g_pfnWHvSetVirtualProcessorRegisters;
     165static decltype(WHvSuspendPartitionTime) *          g_pfnWHvSuspendPartitionTime;
     166static decltype(WHvResumePartitionTime) *           g_pfnWHvResumePartitionTime;
     167decltype(WHvGetVirtualProcessorState) *             g_pfnWHvGetVirtualProcessorState = NULL;
     168decltype(WHvSetVirtualProcessorState) *             g_pfnWHvSetVirtualProcessorState = NULL;
     169decltype(WHvGetVirtualProcessorInterruptControllerState)  *g_pfnWHvGetVirtualProcessorInterruptControllerState = NULL;
     170decltype(WHvSetVirtualProcessorInterruptControllerState)  *g_pfnWHvSetVirtualProcessorInterruptControllerState = NULL;
     171decltype(WHvGetVirtualProcessorInterruptControllerState2) *g_pfnWHvGetVirtualProcessorInterruptControllerState2 = NULL;
     172decltype(WHvSetVirtualProcessorInterruptControllerState2) *g_pfnWHvSetVirtualProcessorInterruptControllerState2 = NULL;
     173decltype(WHvRequestInterrupt) *                     g_pfnWHvRequestInterrupt;
    165174/** @} */
    166175
     
    213222    NEM_WIN_IMPORT(0, false, WHvGetVirtualProcessorRegisters),
    214223    NEM_WIN_IMPORT(0, false, WHvSetVirtualProcessorRegisters),
     224    NEM_WIN_IMPORT(0, true,  WHvSuspendPartitionTime),
     225    NEM_WIN_IMPORT(0, true,  WHvResumePartitionTime),
     226    NEM_WIN_IMPORT(0, true,  WHvRequestInterrupt),
     227    NEM_WIN_IMPORT(0, true,  WHvGetVirtualProcessorState),
     228    NEM_WIN_IMPORT(0, true,  WHvSetVirtualProcessorState),
     229    NEM_WIN_IMPORT(0, true,  WHvGetVirtualProcessorInterruptControllerState),
     230    NEM_WIN_IMPORT(0, true,  WHvSetVirtualProcessorInterruptControllerState),
     231    NEM_WIN_IMPORT(0, true,  WHvGetVirtualProcessorInterruptControllerState2),
     232    NEM_WIN_IMPORT(0, true,  WHvSetVirtualProcessorInterruptControllerState2),
    215233
    216234    NEM_WIN_IMPORT(1, true,  VidGetHvPartitionId),
     
    285303# define WHvGetVirtualProcessorRegisters            g_pfnWHvGetVirtualProcessorRegisters
    286304# define WHvSetVirtualProcessorRegisters            g_pfnWHvSetVirtualProcessorRegisters
     305# define WHvSuspendPartitionTime                    g_pfnWHvSuspendPartitionTime
     306# define WHvResumePartitionTime                     g_pfnWHvResumePartitionTime
     307# define WHvRequestInterrupt                        g_pfnWHvRequestInterrupt
     308# define WHvGetVirtualProcessorState                g_pfnWHvGetVirtualProcessorState
     309# define WHvSetVirtualProcessorState                g_pfnWHvSetVirtualProcessorState
     310# define WHvGetVirtualProcessorInterruptControllerState     g_pfnWHvGetVirtualProcessorInterruptControllerState
     311# define WHvGetVirtualProcessorInterruptControllerState2    g_pfnWHvGetVirtualProcessorInterruptControllerState2
    287312
    288313# define VidMessageSlotHandleAndGetNext             g_pfnVidMessageSlotHandleAndGetNext
     
    585610                *g_aImports[i].ppfn = NULL;
    586611
    587                 LogRel(("NEM:  %s: Failed to import %s!%s: %Rrc",
     612                LogRel(("NEM:  %s: Failed to import %s!%s: %Rrc\n",
    588613                        g_aImports[i].fOptional ? "info" : fForced ? "fatal" : "error",
    589614                        s_apszDllNames[g_aImports[i].idxDll], g_aImports[i].pszName, rc2));
     
    740765        NEM_LOG_REL_CAP_SUB_EX("Unknown features", "%#RX64", Caps.ExtendedVmExits.AsUINT64 & ~fKnownVmExits);
    741766    pVM->nem.s.fSpeculationControl = RT_BOOL(Caps.Features.SpeculationControl);
     767    pVM->nem.s.fLocalApicEmulation = RT_BOOL(Caps.Features.LocalApicEmulation);
    742768    /** @todo RECHECK: WHV_CAPABILITY_FEATURES typedef. */
    743769
     
    12551281                             hrc, RTNtLastStatusValue(), RTNtLastErrorValue());
    12561282
    1257     int rc;
     1283    int rc = VINF_SUCCESS;
    12581284
    12591285    /*
     
    12811307        if (SUCCEEDED(hrc))
    12821308        {
     1309            RT_ZERO(Property);
    12831310            /*
    1284              * We'll continue setup in nemR3NativeInitAfterCPUM.
     1311             * If the APIC is enabled and LocalApicEmulation is supported we'll use Hyper-V's APIC emulation
     1312             * for best performance.
    12851313             */
    1286             pVM->nem.s.fCreatedEmts     = false;
    1287             pVM->nem.s.hPartition       = hPartition;
    1288             LogRel(("NEM: Created partition %p.\n", hPartition));
    1289             return VINF_SUCCESS;
     1314            PCFGMNODE pCfgmApic = CFGMR3GetChild(CFGMR3GetRoot(pVM), "/Devices/apic");
     1315            if (   pCfgmApic
     1316                && pVM->nem.s.fLocalApicEmulation
     1317                && 0) /** @todo Finish */
     1318            {
     1319                /* If setting this fails log an error but continue. */
     1320                Property.LocalApicEmulationMode = WHvX64LocalApicEmulationModeXApic;
     1321                hrc = WHvSetPartitionProperty(hPartition, WHvPartitionPropertyCodeLocalApicEmulationMode  , &Property, sizeof(Property));
     1322                if (FAILED(hrc))
     1323                {
     1324                    LogRel(("NEM: Failed setting WHvPartitionPropertyCodeLocalApicEmulationMode to WHvX64LocalApicEmulationModeXApic: %Rhrc (Last=%#x/%u)",
     1325                            hrc, RTNtLastStatusValue(), RTNtLastErrorValue()));
     1326                    pVM->nem.s.fLocalApicEmulation = false;
     1327                }
     1328                else
     1329                {
     1330                    /* Rewrite the configuration tree to point to our APIC emulation. */
     1331                    PCFGMNODE pCfgmDev = CFGMR3GetChild(CFGMR3GetRoot(pVM), "/Devices");
     1332                    Assert(pCfgmDev);
     1333
     1334                    PCFGMNODE pCfgmApicHv = NULL;
     1335                    rc = CFGMR3InsertNode(pCfgmDev, "apic-nem", &pCfgmApicHv);
     1336                    if (RT_SUCCESS(rc))
     1337                    {
     1338                        rc = CFGMR3CopyTree(pCfgmApicHv, pCfgmApic, CFGM_COPY_FLAGS_IGNORE_EXISTING_KEYS | CFGM_COPY_FLAGS_IGNORE_EXISTING_VALUES);
     1339                        if (RT_SUCCESS(rc))
     1340                            CFGMR3RemoveNode(pCfgmApic);
     1341                    }
     1342
     1343                    if (RT_FAILURE(rc))
     1344                        rc = RTErrInfoSetF(pErrInfo, rc, "Failed replace APIC device config with Hyper-V one");
     1345                }
     1346            }
     1347            else
     1348                pVM->nem.s.fLocalApicEmulation = false;
     1349
     1350
     1351            if (RT_SUCCESS(rc))
     1352            {
     1353                /*
     1354                 * We'll continue setup in nemR3NativeInitAfterCPUM.
     1355                 */
     1356                pVM->nem.s.fCreatedEmts     = false;
     1357                pVM->nem.s.hPartition       = hPartition;
     1358                LogRel(("NEM: Created partition %p.\n", hPartition));
     1359                return VINF_SUCCESS;
     1360            }
    12901361        }
    12911362
     
    13211392     */
    13221393    PCFGMNODE pCfg = CFGMR3GetChild(CFGMR3GetRoot(pVM), "/Devices/apic/0/Config");
     1394    if (!pCfg)
     1395        pCfg = CFGMR3GetChild(CFGMR3GetRoot(pVM), "/Devices/apic-nem/0/Config");
    13231396    if (pCfg)
    13241397    {
  • trunk/src/VBox/VMM/VMMR3/PDMDevice.cpp

    r107308 r108434  
    721721    int rc = pdmR3DevReg_Register(&RegCB.Core, &g_DeviceAPIC);
    722722    AssertRCReturn(rc, rc);
     723
     724# if defined(RT_OS_WINDOWS)
     725    /* Register the internal VMM APIC device for NEM mode. */
     726    rc = pdmR3DevReg_Register(&RegCB.Core, &g_DeviceAPICNem);
     727    AssertRCReturn(rc, rc);
     728# endif
    723729#endif
    724730
Note: See TracChangeset for help on using the changeset viewer.

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