VirtualBox

Changeset 108386 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Feb 26, 2025 9:14:34 AM (2 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
167750
Message:

VMMR3/VMEmt.cpp,VMMR3/TM.cpp,VMMR3/NEMR3Native-win-armv8.cpp: Workaround for Windows/ARM hosts to allow for guests to use more than 1 vCPU, bugref:10392

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

Legend:

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

    r108366 r108386  
    26982698
    26992699
     2700VMMR3_INT_DECL(int) NEMR3Halt(PVM pVM, PVMCPU pVCpu)
     2701{
     2702    /*
     2703     * Try switch to NEM runloop state.
     2704     */
     2705    if (VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED_HALTED))
     2706    { /* likely */ }
     2707    else
     2708    {
     2709        VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED_EXEC_NEM_CANCELED);
     2710        LogFlow(("NEM/%u: returning immediately because canceled\n", pVCpu->idCpu));
     2711        return VINF_SUCCESS;
     2712    }
     2713
     2714    VBOXSTRICTRC    rcStrict            = VINF_SUCCESS;
     2715
     2716    /* Ensure that Hyper-V has the whole state. */
     2717    int rc2 = nemHCWinCopyStateToHyperV(pVM, pVCpu);
     2718    AssertRCReturn(rc2, rc2);
     2719
     2720    if (   !VM_FF_IS_ANY_SET(pVM, VM_FF_EMT_RENDEZVOUS | VM_FF_TM_VIRTUAL_SYNC)
     2721        && !VMCPU_FF_IS_ANY_SET(pVCpu, VMCPU_FF_HM_TO_R3_MASK))
     2722    {
     2723        if (VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM_WAIT, VMCPUSTATE_STARTED_EXEC_NEM))
     2724        {
     2725            MY_WHV_RUN_VP_EXIT_CONTEXT ExitReason = {0};
     2726            HRESULT hrc = WHvRunVirtualProcessor(pVM->nem.s.hPartition, pVCpu->idCpu, &ExitReason, sizeof(ExitReason));
     2727            VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED_EXEC_NEM_WAIT);
     2728            TMNotifyEndOfExecution(pVM, pVCpu, ASMReadTSC());
     2729#ifdef LOG_ENABLED
     2730            LogFlow(("NEM/%u: Exit  @ @todo Reason=%#x\n", pVCpu->idCpu, ExitReason.ExitReason));
     2731#endif
     2732            if (SUCCEEDED(hrc))
     2733            {
     2734                /*
     2735                 * Deal with the message.
     2736                 */
     2737                rcStrict = nemR3WinHandleExit(pVM, pVCpu, &ExitReason);
     2738                LogFlow(("NEM/%u: breaking: nemHCWinHandleMessage -> %Rrc\n", pVCpu->idCpu, VBOXSTRICTRC_VAL(rcStrict) ));
     2739                STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatBreakOnStatus);
     2740            }
     2741            else
     2742                AssertLogRelMsgFailedReturn(("WHvRunVirtualProcessor failed for CPU #%u: %#x (%u)\n",
     2743                                             pVCpu->idCpu, hrc, GetLastError()),
     2744                                            VERR_NEM_IPE_0);
     2745
     2746            /** @todo Try handle pending flags, not just return to EM loops.  Take care
     2747             *        not to set important RCs here unless we've handled a message. */
     2748            LogFlow(("NEM/%u: breaking: pending FF (%#x / %#RX64)\n",
     2749                     pVCpu->idCpu, pVM->fGlobalForcedActions, (uint64_t)pVCpu->fLocalForcedActions));
     2750            STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatBreakOnFFPost);
     2751        }
     2752        else
     2753        {
     2754            LogFlow(("NEM/%u: breaking: canceled %d (pre exec)\n", pVCpu->idCpu, VMCPU_GET_STATE(pVCpu) ));
     2755            STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatBreakOnCancel);
     2756        }
     2757    }
     2758    else
     2759    {
     2760        LogFlow(("NEM/%u: breaking: pending FF (pre exec)\n", pVCpu->idCpu));
     2761        STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatBreakOnFFPre);
     2762    }
     2763
     2764    if (!VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_HALTED, VMCPUSTATE_STARTED_EXEC_NEM))
     2765        VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_HALTED, VMCPUSTATE_STARTED_EXEC_NEM_CANCELED);
     2766
     2767    return rcStrict;
     2768}
     2769
     2770
    27002771bool nemR3NativeSetSingleInstruction(PVM pVM, PVMCPU pVCpu, bool fEnable)
    27012772{
     
    32513322 *
    32523323 * Open questions:
    3253  *     - Why can't one read and write WHvArm64RegisterId*
    3254  *     - WHvArm64RegisterDbgbcr0El1 is not readable?
    3255  *     - Getting notified about system register reads/writes (GIC)?
    32563324 *     - InstructionByteCount and InstructionBytes for unmapped GPA exit are zero...
    3257  *     - Handling of (vTimer) interrupts, how is WHvRequestInterrupt() supposed to be used?
    3258  */
    3259 
     3325 */
     3326
  • trunk/src/VBox/VMM/VMMR3/TM.cpp

    r107227 r108386  
    225225     * Init the structure.
    226226     */
     227#if defined(VBOX_VMM_TARGET_ARMV8) && defined(RT_OS_WINDOWS)
     228    /*
     229     * Workaround for Hyper-V on Windows/ARM:
     230     *     On Windows/ARM EMTs of APs are waiting in Hyper-V because
     231     *     there is no way currently to get notified of PSCI calls to turn them
     232     *     on.
     233     *     However because they are suspended they can't handle timers, so
     234     *     this needs to be done by the boot processor.
     235     *     We hope that Microsoft lifts this restriction in the future, allowing us
     236     *     to use our already existing wait infrastructure for EMTs.
     237     */
     238    pVM->tm.s.idTimerCpu = 0;
     239#else
    227240    pVM->tm.s.idTimerCpu = pVM->cCpus - 1; /* The last CPU. */
     241#endif
    228242
    229243    int rc = PDMR3CritSectInit(pVM, &pVM->tm.s.VirtualSyncLock, RT_SRC_POS, "TM VirtualSync Lock");
  • trunk/src/VBox/VMM/VMMR3/VMEmt.cpp

    r107466 r108386  
    10681068
    10691069
     1070#if defined(VBOX_VMM_TARGET_ARMV8) && defined(RT_OS_WINDOWS)
     1071
     1072/**
     1073 * Method NEM - The host (NEM) does the halting.
     1074 */
     1075static DECLCALLBACK(int) vmR3HaltNemHalt(PUVMCPU pUVCpu, const uint64_t fMask, uint64_t u64Now)
     1076{
     1077    PVMCPU  pVCpu   = pUVCpu->pVCpu;
     1078
     1079    RT_NOREF(fMask, u64Now);
     1080    return NEMR3Halt(pUVCpu->pVM, pVCpu);
     1081}
     1082
     1083
     1084/**
     1085 * Default VMR3NotifyFF() worker.
     1086 *
     1087 * @param   pUVCpu          Pointer to the user mode VMCPU structure.
     1088 * @param   fFlags          Notification flags, VMNOTIFYFF_FLAGS_*.
     1089 */
     1090static DECLCALLBACK(void) vmR3NemNotifyCpuFF(PUVMCPU pUVCpu, uint32_t fFlags)
     1091{
     1092    PVMCPU pVCpu = pUVCpu->pVCpu;
     1093    if (pVCpu)
     1094        NEMR3NotifyFF(pUVCpu->pVM, pVCpu, fFlags);
     1095}
     1096#endif
     1097
     1098
    10701099/**
    10711100 * Array with halt method descriptors.
     
    10961125    { VMHALTMETHOD_1,         false, vmR3HaltMethod1Init, NULL,   vmR3HaltMethod1Halt, vmR3DefaultWait,     vmR3DefaultNotifyCpuFF,     NULL },
    10971126    { VMHALTMETHOD_GLOBAL_1,   true, vmR3HaltGlobal1Init, NULL,   vmR3HaltGlobal1Halt, vmR3HaltGlobal1Wait, vmR3HaltGlobal1NotifyCpuFF, NULL },
     1127#if defined(VBOX_VMM_TARGET_ARMV8) && defined(RT_OS_WINDOWS)
     1128    { VMHALTMETHOD_NEM,       false, NULL,                NULL,   vmR3HaltNemHalt,     vmR3DefaultWait,     vmR3NemNotifyCpuFF,         NULL },
     1129#endif
    10981130};
    10991131
     
    14181450        LogRel(("VMEmt: Halt method %s (%d) not available in driverless mode, using %s (%d) instead\n",
    14191451                vmR3GetHaltMethodName(enmHaltMethod), enmHaltMethod, vmR3GetHaltMethodName(VMHALTMETHOD_1), VMHALTMETHOD_1));
     1452#if defined(VBOX_VMM_TARGET_ARMV8) && defined(RT_OS_WINDOWS)
     1453        enmHaltMethod = VMHALTMETHOD_NEM;
     1454#else
    14201455        enmHaltMethod = VMHALTMETHOD_1;
     1456#endif
    14211457    }
    14221458
  • trunk/src/VBox/VMM/include/VMInternal.h

    r106061 r108386  
    155155    /** The first go at a more global approach. */
    156156    VMHALTMETHOD_GLOBAL_1,
     157#if defined(VBOX_VMM_TARGET_ARMV8) && defined(RT_OS_WINDOWS)
     158    /** NEM takes over halting. */
     159    VMHALTMETHOD_NEM,
     160#endif
    157161    /** The end of valid methods. (not inclusive of course) */
    158162    VMHALTMETHOD_END,
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