VirtualBox

Ignore:
Timestamp:
Nov 20, 2021 2:41:05 AM (3 years ago)
Author:
vboxsync
Message:

VMM/NEM-linux: Make sure to flush pending IO or MMIO exits before returning from the inner RUN loop to the EM loops, otherwise weird stuff may happen if someone else (IEM,TRPM,EM,Debugger) modified the CPU state before we get back and do the next KVM_RUN. bugref:9044

File:
1 edited

Legend:

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

    r92520 r92522  
    534534                        STAMR3RegisterF(pVM, &pNemCpu->StatImportPendingInterrupt, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of times an interrupt was pending when importing from KVM", "/NEM/CPU%u/ImportPendingInterrupt", idCpu);
    535535                        STAMR3RegisterF(pVM, &pNemCpu->StatExportPendingInterrupt, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of times an interrupt was pending when exporting to KVM", "/NEM/CPU%u/ExportPendingInterrupt", idCpu);
     536                        STAMR3RegisterF(pVM, &pNemCpu->StatFlushExitOnReturn,   STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of times a KVM_EXIT_IO or KVM_EXIT_MMIO was flushed before returning to EM", "/NEM/CPU%u/FlushExitOnReturn", idCpu);
    536537                        STAMR3RegisterF(pVM, &pNemCpu->StatQueryCpuTick,        STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of TSC queries",                  "/NEM/CPU%u/QueryCpuTick", idCpu);
    537538                        STAMR3RegisterF(pVM, &pNemCpu->StatExitTotal,           STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "All exits",                  "/NEM/CPU%u/Exit", idCpu);
     
    22472248
    22482249
    2249 static VBOXSTRICTRC nemHCLnxHandleExit(PVMCC pVM, PVMCPUCC pVCpu, struct kvm_run *pRun)
     2250static VBOXSTRICTRC nemHCLnxHandleExit(PVMCC pVM, PVMCPUCC pVCpu, struct kvm_run *pRun, bool *pfStatefulExit)
    22502251{
    22512252    STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExitTotal);
     
    22582259        case KVM_EXIT_IO:
    22592260            STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExitIo);
     2261            *pfStatefulExit = true;
    22602262            return nemHCLnxHandleExitIo(pVM, pVCpu, pRun);
    22612263
    22622264        case KVM_EXIT_MMIO:
    22632265            STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExitMmio);
     2266            *pfStatefulExit = true;
    22642267            return nemHCLnxHandleExitMmio(pVM, pVCpu, pRun);
    22652268
     
    24112414    const bool              fSingleStepping     = DBGFIsStepping(pVCpu);
    24122415    VBOXSTRICTRC            rcStrict            = VINF_SUCCESS;
     2416    bool                    fStatefulExit       = false;  /* For MMIO and IO exits. */
    24132417    for (unsigned iLoop = 0;; iLoop++)
    24142418    {
     
    24912495                }
    24922496#endif
     2497                fStatefulExit = false;
    24932498                if (RT_LIKELY(rcLnx == 0 || errno == EINTR))
    24942499                {
    24952500                    /*
    2496                      * Deal with the message.
     2501                     * Deal with the exit.
    24972502                     */
    2498                     rcStrict = nemHCLnxHandleExit(pVM, pVCpu, pRun);
     2503                    rcStrict = nemHCLnxHandleExit(pVM, pVCpu, pRun, &fStatefulExit);
    24992504                    if (rcStrict == VINF_SUCCESS)
    25002505                    { /* hopefully likely */ }
     
    25392544    } /* the run loop */
    25402545
     2546
     2547    /*
     2548     * If the last exit was stateful, commit the state we provided before
     2549     * returning to the EM loop so we have a consistent state and can safely
     2550     * be rescheduled and whatnot.  (There is no 'ing way to reset the kernel
     2551     * side completion callback for these stateful i/o exits.)
     2552     */
     2553    if (fStatefulExit)
     2554    {
     2555        pRun->immediate_exit = 1;
     2556        int rcLnx = ioctl(pVCpu->nem.s.fdVCpu, KVM_RUN, 0UL);
     2557        pRun->immediate_exit = 0;
     2558        Log(("NEM/%u: Flushed stateful exit -> %d/%d exit_reason=%d\n", pVCpu->idCpu, rcLnx, errno, pRun->exit_reason));
     2559        STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatFlushExitOnReturn);
     2560    }
    25412561
    25422562    /*
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