VirtualBox

Changeset 92519 in vbox for trunk/src


Ignore:
Timestamp:
Nov 20, 2021 12:09:58 AM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
148394
Message:

VMM/NEM-linux,EM: Deal with internal errors due to complicated MMIO instructions; made the VERR_NEM_IPE_X statuses trigger guru meditation w/o asserting in debug builds; sync interrupts with TRPM. bugref:9044

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

Legend:

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

    r92515 r92519  
    2727#include <VBox/vmm/apic.h>
    2828#include <VBox/vmm/pdm.h>
     29#include <VBox/vmm/trpm.h>
    2930#include "NEMInternal.h"
    3031#include <VBox/vmm/vmcc.h>
     
    4041#include <sys/mman.h>
    4142#include <linux/kvm.h>
     43
     44/*
     45 * Supply stuff missing from the kvm.h on the build box.
     46 */
     47#ifndef KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON /* since 5.4 */
     48# define KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON 4
     49#endif
    4250
    4351
     
    524532                        STAMR3RegisterF(pVM, &pNemCpu->StatImportOnReturn,      STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of state imports on loop return", "/NEM/CPU%u/ImportOnReturn", idCpu);
    525533                        STAMR3RegisterF(pVM, &pNemCpu->StatImportOnReturnSkipped, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of skipped state imports on loop return", "/NEM/CPU%u/ImportOnReturnSkipped", idCpu);
     534                        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);
     535                        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);
    526536                        STAMR3RegisterF(pVM, &pNemCpu->StatQueryCpuTick,        STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of TSC queries",                  "/NEM/CPU%u/QueryCpuTick", idCpu);
    527537                        STAMR3RegisterF(pVM, &pNemCpu->StatExitTotal,           STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "All exits",                  "/NEM/CPU%u/Exit", idCpu);
     
    538548                        STAMR3RegisterF(pVM, &pNemCpu->StatExitDebug,           STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "KVM_EXIT_DEBUG",             "/NEM/CPU%u/Exit/Debug", idCpu);
    539549                        STAMR3RegisterF(pVM, &pNemCpu->StatExitBusLock,         STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "KVM_EXIT_BUS_LOCK",          "/NEM/CPU%u/Exit/BusLock", idCpu);
     550                        STAMR3RegisterF(pVM, &pNemCpu->StatExitInternalErrorEmulation, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "KVM_EXIT_INTERNAL_ERROR/EMULATION", "/NEM/CPU%u/Exit/InternalErrorEmulation", idCpu);
     551                        STAMR3RegisterF(pVM, &pNemCpu->StatExitInternalErrorFatal,     STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "KVM_EXIT_INTERNAL_ERROR/*", "/NEM/CPU%u/Exit/InternalErrorFatal", idCpu);
    540552                    }
    541553
     
    13581370
    13591371    /*
    1360      * Interruptibility state.
     1372     * Interruptibility state and pending interrupts.
    13611373     */
    13621374    if (fWhat & (CPUMCTX_EXTRN_INHIBIT_INT | CPUMCTX_EXTRN_INHIBIT_NMI))
     
    13801392        else if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_BLOCK_NMIS))
    13811393            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_BLOCK_NMIS);
     1394
     1395        if (KvmEvents.interrupt.injected)
     1396        {
     1397            STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatImportPendingInterrupt);
     1398            TRPMAssertTrap(pVCpu, KvmEvents.interrupt.nr, !KvmEvents.interrupt.soft ? TRPM_HARDWARE_INT : TRPM_SOFTWARE_INT);
     1399        }
     1400
     1401        Assert(KvmEvents.nmi.injected == 0);
     1402        Assert(KvmEvents.nmi.pending  == 0);
    13821403    }
    13831404
     
    17581779            KvmEvents.nmi.masked = 1;
    17591780
     1781        if (TRPMHasTrap(pVCpu))
     1782        {
     1783            TRPMEVENT enmType = TRPM_32BIT_HACK;
     1784            uint8_t   bTrapNo = 0;
     1785            TRPMQueryTrap(pVCpu, &bTrapNo, &enmType);
     1786            Log(("nemHCLnxExportState: Pending trap: bTrapNo=%#x enmType=%d\n", bTrapNo, enmType));
     1787            if (   enmType == TRPM_HARDWARE_INT
     1788                || enmType == TRPM_SOFTWARE_INT)
     1789            {
     1790                KvmEvents.interrupt.soft     = enmType == TRPM_SOFTWARE_INT;
     1791                KvmEvents.interrupt.nr       = bTrapNo;
     1792                KvmEvents.interrupt.injected = 1;
     1793                STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExportPendingInterrupt);
     1794                TRPMResetTrap(pVCpu);
     1795            }
     1796            else
     1797                AssertFailed();
     1798        }
     1799
    17601800        int rcLnx = ioctl(pVCpu->nem.s.fdVCpu, KVM_SET_VCPU_EVENTS, &KvmEvents);
    17611801        AssertLogRelMsgReturn(rcLnx == 0, ("rcLnx=%d errno=%d\n", rcLnx, errno), VERR_NEM_IPE_3);
     
    19632003                if (RT_SUCCESS(rc))
    19642004                {
     2005                    Assert(KvmEvents.interrupt.injected == false);
    19652006#if 0
    19662007                    int rcLnx = ioctl(pVCpu->nem.s.fdVm, KVM_INTERRUPT, (unsigned long)bInterrupt);
     
    20042045
    20052046/**
     2047 * Handles KVM_EXIT_INTERNAL_ERROR.
     2048 */
     2049static VBOXSTRICTRC nemR3LnxHandleInternalError(PVMCPU pVCpu, struct kvm_run *pRun)
     2050{
     2051    Log(("NEM: KVM_EXIT_INTERNAL_ERROR! suberror=%#x (%d) ndata=%u data=%.*Rhxs\n", pRun->internal.suberror,
     2052         pRun->internal.suberror, pRun->internal.ndata, sizeof(pRun->internal.data), &pRun->internal.data[0]));
     2053
     2054    EMHistoryAddExit(pVCpu, EMEXIT_MAKE_FT(EMEXIT_F_KIND_NEM, KVM_EXIT_INTERNAL_ERROR),
     2055                     pRun->s.regs.regs.rip + pRun->s.regs.sregs.cs.base, ASMReadTSC());
     2056
     2057    /*
     2058     * Deal with each suberror, returning if we don't want IEM to handle it.
     2059     */
     2060    switch (pRun->internal.suberror)
     2061    {
     2062        case KVM_INTERNAL_ERROR_EMULATION:
     2063        {
     2064            STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExitInternalErrorEmulation);
     2065            break;
     2066        }
     2067
     2068        case KVM_INTERNAL_ERROR_SIMUL_EX:
     2069        case KVM_INTERNAL_ERROR_DELIVERY_EV:
     2070        case KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON:
     2071        default:
     2072        {
     2073            const char *pszName;
     2074            switch (pRun->internal.suberror)
     2075            {
     2076                case KVM_INTERNAL_ERROR_EMULATION:              pszName = "KVM_INTERNAL_ERROR_EMULATION"; break;
     2077                case KVM_INTERNAL_ERROR_SIMUL_EX:               pszName = "KVM_INTERNAL_ERROR_SIMUL_EX"; break;
     2078                case KVM_INTERNAL_ERROR_DELIVERY_EV:            pszName = "KVM_INTERNAL_ERROR_DELIVERY_EV"; break;
     2079                case KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON: pszName = "KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON"; break;
     2080                default:                                        pszName = "unknown"; break;
     2081            }
     2082            STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExitInternalErrorFatal);
     2083            LogRel(("NEM: KVM_EXIT_INTERNAL_ERROR! suberror=%#x (%s) ndata=%u data=%.*Rhxs\n", pRun->internal.suberror, pszName,
     2084                    pRun->internal.ndata, sizeof(pRun->internal.data), &pRun->internal.data[0]));
     2085            return VERR_NEM_IPE_0;
     2086        }
     2087    }
     2088
     2089    /*
     2090     * Execute instruction in IEM and try get on with it.
     2091     */
     2092    Log2(("nemR3LnxHandleInternalError: Executing instruction at %04x:%08RX64 in IEM\n",
     2093          pRun->s.regs.sregs.cs.selector, pRun->s.regs.regs.rip));
     2094    VBOXSTRICTRC rcStrict = nemHCLnxImportState(pVCpu,
     2095                                                IEM_CPUMCTX_EXTRN_MUST_MASK | CPUMCTX_EXTRN_INHIBIT_INT
     2096                                                 | CPUMCTX_EXTRN_INHIBIT_NMI,
     2097                                                &pVCpu->cpum.GstCtx, pRun);
     2098    if (RT_SUCCESS(rcStrict))
     2099        rcStrict = IEMExecOne(pVCpu);
     2100    return rcStrict;
     2101}
     2102
     2103
     2104/**
    20062105 * Handles KVM_EXIT_IO.
    20072106 */
     
    22312330
    22322331        case KVM_EXIT_FAIL_ENTRY:
    2233             AssertFailed();
    2234             break;
     2332            LogRel(("NEM: KVM_EXIT_FAIL_ENTRY! hardware_entry_failure_reason=%#x cpu=%#x\n",
     2333                    pRun->fail_entry.hardware_entry_failure_reason, pRun->fail_entry.cpu));
     2334            return VERR_NEM_IPE_1;
     2335
    22352336        case KVM_EXIT_INTERNAL_ERROR:
    2236             AssertFailed();
    2237             break;
     2337            /* we're counting sub-reasons inside the function. */
     2338            return nemR3LnxHandleInternalError(pVCpu, pRun);
    22382339
    22392340        /*
  • trunk/src/VBox/VMM/include/EMHandleRCTmpl.h

    r92493 r92519  
    230230#endif
    231231
     232#ifdef EMHANDLERC_WITH_NEM
     233        /* Fatal stuff, up a level. */
     234        case VERR_NEM_IPE_0:
     235        case VERR_NEM_IPE_1:
     236        case VERR_NEM_IPE_2:
     237        case VERR_NEM_IPE_3:
     238        case VERR_NEM_IPE_4:
     239        case VERR_NEM_IPE_5:
     240        case VERR_NEM_IPE_6:
     241        case VERR_NEM_IPE_7:
     242        case VERR_NEM_IPE_8:
     243        case VERR_NEM_IPE_9:
     244            break;
     245#endif
     246
    232247        /*
    233248         * These two should be handled via the force flag already, but just in
  • trunk/src/VBox/VMM/include/NEMInternal.h

    r92508 r92519  
    351351    STAMCOUNTER                 StatExitDebug;
    352352    STAMCOUNTER                 StatExitBusLock;
     353    STAMCOUNTER                 StatExitInternalErrorEmulation;
     354    STAMCOUNTER                 StatExitInternalErrorFatal;
    353355# if 0
    354356    STAMCOUNTER                 StatExitCpuId;
     
    369371    STAMCOUNTER                 StatImportOnReturn;
    370372    STAMCOUNTER                 StatImportOnReturnSkipped;
     373    STAMCOUNTER                 StatImportPendingInterrupt;
     374    STAMCOUNTER                 StatExportPendingInterrupt;
    371375    STAMCOUNTER                 StatQueryCpuTick;
    372376    /** @} */
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