VirtualBox

Changeset 92120 in vbox for trunk/src


Ignore:
Timestamp:
Oct 28, 2021 12:31:35 AM (3 years ago)
Author:
vboxsync
Message:

VMM/NEM/win: New approach to A20: Reschedule to IEM. Logging. bugref:10122

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/NEMAllNativeTemplate-win.cpp.h

    r91958 r92120  
    16571657    uint8_t  u2State = pInfo->u2NemState;
    16581658    RTGCPHYS GCPhysSrc;
     1659# ifdef NEM_WIN_WITH_A20
    16591660    if (   pVM->nem.s.fA20Enabled
    16601661        || !NEM_WIN_IS_SUBJECT_TO_A20(GCPhys))
     1662# endif
    16611663        GCPhysSrc = GCPhys;
     1664# ifdef NEM_WIN_WITH_A20
    16621665    else
    16631666    {
     
    16701673        pInfo->u2NemState = u2State;
    16711674    }
     1675# endif
    16721676
    16731677    /*
     
    41384142                if (RT_SUCCESS(rc))
    41394143                {
     4144                    Log8(("Injecting interrupt %#x on %u: %04x:%08RX64 efl=%#x\n", bInterrupt, pVCpu->idCpu, pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, pVCpu->cpum.GstCtx.eflags));
    41404145                    rcStrict = IEMInjectTrap(pVCpu, bInterrupt, TRPM_HARDWARE_INT, 0, 0, 0);
    41414146                    Log8(("Injected interrupt %#x on %u (%d)\n", bInterrupt, pVCpu->idCpu, VBOXSTRICTRC_VAL(rcStrict) ));
     
    41474152                }
    41484153                else
    4149                     Log8(("PDMGetInterrupt failed -> %d\n", rc));
     4154                    Log8(("PDMGetInterrupt failed -> %Rrc\n", rc));
    41504155            }
    41514156            return rcStrict;
    41524157        }
    4153         else if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC) && !VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC))
     4158
     4159        if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC) && !VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC))
    41544160        {
    41554161            /* If only an APIC interrupt is pending, we need to know its priority. Otherwise we'll
    41564162             * likely get pointless deliverability notifications with IF=1 but TPR still too high.
    41574163             */
    4158             bool fPendingIntr;
    4159             uint8_t u8Tpr, u8PendingIntr;
    4160             int rc = APICGetTpr(pVCpu, &u8Tpr, &fPendingIntr, &u8PendingIntr);
     4164            bool    fPendingIntr = false;
     4165            uint8_t bTpr = 0;
     4166            uint8_t bPendingIntr = 0;
     4167            int rc = APICGetTpr(pVCpu, &bTpr, &fPendingIntr, &bPendingIntr);
    41614168            AssertRC(rc);
    4162             *pfInterruptWindows |= (u8PendingIntr >> 4) << NEM_WIN_INTW_F_PRIO_SHIFT;
    4163         }
    4164         *pfInterruptWindows |= NEM_WIN_INTW_F_REGULAR;
    4165         Log8(("Interrupt window pending on %u\n", pVCpu->idCpu));
     4169            *pfInterruptWindows |= (bPendingIntr >> 4) << NEM_WIN_INTW_F_PRIO_SHIFT;
     4170            Log8(("Interrupt window pending on %u: %#x (bTpr=%#x fPendingIntr=%d bPendingIntr=%#x)\n",
     4171                  pVCpu->idCpu, *pfInterruptWindows, bTpr, fPendingIntr, bPendingIntr));
     4172        }
     4173        else
     4174        {
     4175            *pfInterruptWindows |= NEM_WIN_INTW_F_REGULAR;
     4176            Log8(("Interrupt window pending on %u: %#x\n", pVCpu->idCpu, *pfInterruptWindows));
     4177        }
    41664178    }
    41674179
     
    42644276            }
    42654277        }
     4278
     4279# ifndef NEM_WIN_WITH_A20
     4280        /*
     4281         * Do not execute in hyper-V if the A20 isn't enabled.
     4282         */
     4283        if (PGMPhysIsA20Enabled(pVCpu))
     4284        { /* likely */ }
     4285        else
     4286        {
     4287            rcStrict = VINF_EM_RESCHEDULE_REM;
     4288            LogFlow(("NEM/%u: breaking: A20 disabled\n", pVCpu->idCpu));
     4289            break;
     4290        }
     4291# endif
    42664292
    42674293        /*
     
    43654391#  endif
    43664392# else
    4367                 WHV_RUN_VP_EXIT_CONTEXT ExitReason;
    4368                 RT_ZERO(ExitReason);
    4369                 LogFlow(("NEM/%u: Entry @ %04X:%08RX64 IF=%d (~~may be stale~~)\n", pVCpu->idCpu, pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, pVCpu->cpum.GstCtx.rflags.Bits.u1IF));
     4393#  ifdef LOG_ENABLED
     4394                if (LogIsFlowEnabled())
     4395                {
     4396                    static const WHV_REGISTER_NAME s_aNames[6] = { WHvX64RegisterCs, WHvX64RegisterRip, WHvX64RegisterRflags,
     4397                                                                   WHvX64RegisterSs, WHvX64RegisterRsp, WHvX64RegisterCr0 };
     4398                    WHV_REGISTER_VALUE aRegs[RT_ELEMENTS(s_aNames)] = {0};
     4399                    WHvGetVirtualProcessorRegisters(pVM->nem.s.hPartition, pVCpu->idCpu, s_aNames, RT_ELEMENTS(s_aNames), aRegs);
     4400                    LogFlow(("NEM/%u: Entry @ %04x:%08RX64 IF=%d EFL=%#RX64 SS:RSP=%04x:%08RX64 cr0=%RX64\n",
     4401                             pVCpu->idCpu, aRegs[0].Segment.Selector, aRegs[1].Reg64, RT_BOOL(aRegs[2].Reg64 & X86_EFL_IF),
     4402                             aRegs[2].Reg64, aRegs[3].Segment.Selector, aRegs[4].Reg64, aRegs[5].Reg64));
     4403                }
     4404#  endif
     4405                WHV_RUN_VP_EXIT_CONTEXT ExitReason = {0};
    43704406                TMNotifyStartOfExecution(pVM, pVCpu);
     4407
    43714408                HRESULT hrc = WHvRunVirtualProcessor(pVM->nem.s.hPartition, pVCpu->idCpu, &ExitReason, sizeof(ExitReason));
     4409
    43724410                VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED_EXEC_NEM_WAIT);
    43734411                TMNotifyEndOfExecution(pVM, pVCpu, ASMReadTSC());
    4374                 LogFlow(("NEM/%u: Exit  @ %04X:%08RX64 IF=%d CR8=%#x \n", pVCpu->idCpu, ExitReason.VpContext.Cs.Selector, ExitReason.VpContext.Rip, RT_BOOL(ExitReason.VpContext.Rflags & X86_EFL_IF), ExitReason.VpContext.Cr8));
     4412#  ifdef LOG_ENABLED
     4413                LogFlow(("NEM/%u: Exit  @ %04X:%08RX64 IF=%d CR8=%#x Reason=%#x\n", pVCpu->idCpu, ExitReason.VpContext.Cs.Selector,
     4414                         ExitReason.VpContext.Rip, RT_BOOL(ExitReason.VpContext.Rflags & X86_EFL_IF), ExitReason.VpContext.Cr8,
     4415                         ExitReason.ExitReason));
     4416#  endif
    43754417                if (SUCCEEDED(hrc))
    43764418# endif
     
    49524994#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
    49534995    PVMCPUCC pVCpu = VMMGetCpu(pVM);
     4996# ifdef NEM_WIN_WITH_A20
    49544997    if (   pVM->nem.s.fA20Enabled
    49554998        || !NEM_WIN_IS_RELEVANT_TO_A20(GCPhys))
     4999# endif
    49565000        rc = nemHCNativeSetPhysPage(pVM, pVCpu, GCPhys, GCPhys, fPageProt, pu2State, true /*fBackingChanged*/);
     5001# ifdef NEM_WIN_WITH_A20
    49575002    else
    49585003    {
     
    49635008
    49645009    }
     5010# endif
    49655011#else
    49665012    RT_NOREF_PV(fPageProt);
     5013# ifdef NEM_WIN_WITH_A20
    49675014    if (   pVM->nem.s.fA20Enabled
    49685015        || !NEM_WIN_IS_RELEVANT_TO_A20(GCPhys))
     5016# endif
    49695017        rc = nemHCJustUnmapPageFromHyperV(pVM, GCPhys, pu2State);
     5018# ifdef NEM_WIN_WITH_A20
    49705019    else if (!NEM_WIN_IS_SUBJECT_TO_A20(GCPhys))
    49715020        rc = nemHCJustUnmapPageFromHyperV(pVM, GCPhys, pu2State);
    49725021    else
    49735022        rc = VINF_SUCCESS; /* ignore since we've got the alias page at this address. */
     5023# endif
    49745024#endif
    49755025    return rc;
     
    49875037#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
    49885038    PVMCPUCC pVCpu = VMMGetCpu(pVM);
     5039# ifdef NEM_WIN_WITH_A20
    49895040    if (   pVM->nem.s.fA20Enabled
    49905041        || !NEM_WIN_IS_RELEVANT_TO_A20(GCPhys))
     5042# endif
    49915043        nemHCNativeSetPhysPage(pVM, pVCpu, GCPhys, GCPhys, fPageProt, pu2State, false /*fBackingChanged*/);
     5044# ifdef NEM_WIN_WITH_A20
    49925045    else
    49935046    {
     
    49975050            nemHCNativeSetPhysPage(pVM, pVCpu, GCPhys, GCPhys, fPageProt, pu2State, false /*fBackingChanged*/);
    49985051    }
     5052# endif
    49995053#else
    50005054    RT_NOREF_PV(fPageProt);
     5055# ifdef NEM_WIN_WITH_A20
    50015056    if (   pVM->nem.s.fA20Enabled
    50025057        || !NEM_WIN_IS_RELEVANT_TO_A20(GCPhys))
     5058# endif
    50035059        nemHCJustUnmapPageFromHyperV(pVM, GCPhys, pu2State);
     5060# ifdef NEM_WIN_WITH_A20
    50045061    else if (!NEM_WIN_IS_SUBJECT_TO_A20(GCPhys))
    50055062        nemHCJustUnmapPageFromHyperV(pVM, GCPhys, pu2State);
    50065063    /* else: ignore since we've got the alias page at this address. */
     5064# endif
    50075065#endif
    50085066}
     
    50195077#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
    50205078    PVMCPUCC pVCpu = VMMGetCpu(pVM);
     5079# ifdef NEM_WIN_WITH_A20
    50215080    if (   pVM->nem.s.fA20Enabled
    50225081        || !NEM_WIN_IS_RELEVANT_TO_A20(GCPhys))
     5082# endif
    50235083        nemHCNativeSetPhysPage(pVM, pVCpu, GCPhys, GCPhys, fPageProt, pu2State, true /*fBackingChanged*/);
     5084# ifdef NEM_WIN_WITH_A20
    50245085    else
    50255086    {
     
    50295090            nemHCNativeSetPhysPage(pVM, pVCpu, GCPhys, GCPhys, fPageProt, pu2State, true /*fBackingChanged*/);
    50305091    }
     5092# endif
    50315093#else
    50325094    RT_NOREF_PV(fPageProt);
     5095# ifdef NEM_WIN_WITH_A20
    50335096    if (   pVM->nem.s.fA20Enabled
    50345097        || !NEM_WIN_IS_RELEVANT_TO_A20(GCPhys))
     5098# endif
    50355099        nemHCJustUnmapPageFromHyperV(pVM, GCPhys, pu2State);
     5100# ifdef NEM_WIN_WITH_A20
    50365101    else if (!NEM_WIN_IS_SUBJECT_TO_A20(GCPhys))
    50375102        nemHCJustUnmapPageFromHyperV(pVM, GCPhys, pu2State);
    50385103    /* else: ignore since we've got the alias page at this address. */
     5104# endif
    50395105#endif
    50405106}
  • trunk/src/VBox/VMM/VMMR3/NEMR3.cpp

    r91848 r92120  
    406406
    407407
     408#ifndef VBOX_WITH_NATIVE_NEM
    408409VMMR3_INT_DECL(bool) NEMR3CanExecuteGuest(PVM pVM, PVMCPU pVCpu)
    409410{
    410     Assert(VM_IS_NEM_ENABLED(pVM));
    411 #ifdef VBOX_WITH_NATIVE_NEM
    412     return nemR3NativeCanExecuteGuest(pVM, pVCpu);
    413 #else
    414     NOREF(pVM); NOREF(pVCpu);
     411    RT_NOREF(pVM, pVCpu);
    415412    return false;
    416 #endif
    417 }
     413}
     414#endif
    418415
    419416
     
    441438
    442439
     440#ifndef VBOX_WITH_NATIVE_NEM
    443441VMMR3_INT_DECL(void) NEMR3NotifySetA20(PVMCPU pVCpu, bool fEnabled)
    444442{
    445 #ifdef VBOX_WITH_NATIVE_NEM
    446     if (pVCpu->pVMR3->bMainExecutionEngine == VM_EXEC_ENGINE_NATIVE_API)
    447         nemR3NativeNotifySetA20(pVCpu, fEnabled);
    448 #else
    449     NOREF(pVCpu); NOREF(fEnabled);
    450 #endif
    451 }
    452 
     443    RT_NOREF(pVCpu, fEnabled);
     444}
     445#endif
     446
  • trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp

    r91958 r92120  
    12791279     * Some state init.
    12801280     */
     1281#ifdef NEM_WIN_WITH_A20
    12811282    pVM->nem.s.fA20Enabled = true;
     1283#endif
    12821284#if 0
    12831285    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     
    18141816void nemR3NativeReset(PVM pVM)
    18151817{
     1818#if 0
    18161819    /* Unfix the A20 gate. */
    18171820    pVM->nem.s.fA20Fixed = false;
     1821#else
     1822    RT_NOREF(pVM);
     1823#endif
    18181824}
    18191825
     
    18281834void nemR3NativeResetCpu(PVMCPU pVCpu, bool fInitIpi)
    18291835{
     1836#ifdef NEM_WIN_WITH_A20
    18301837    /* Lock the A20 gate if INIT IPI, make sure it's enabled.  */
    18311838    if (fInitIpi && pVCpu->idCpu > 0)
     
    18371844        pVM->nem.s.fA20Fixed   = true;
    18381845    }
     1846#else
     1847    RT_NOREF(pVCpu, fInitIpi);
     1848#endif
    18391849}
    18401850
     
    18861896
    18871897
    1888 bool nemR3NativeCanExecuteGuest(PVM pVM, PVMCPU pVCpu)
    1889 {
    1890     NOREF(pVM); NOREF(pVCpu);
     1898VMMR3_INT_DECL(bool) NEMR3CanExecuteGuest(PVM pVM, PVMCPU pVCpu)
     1899{
     1900    Assert(VM_IS_NEM_ENABLED(pVM));
     1901
     1902#ifndef NEM_WIN_WITH_A20
     1903    /*
     1904     * Only execute when the A20 gate is enabled because this lovely Hyper-V
     1905     * blackbox does not seem to have any way to enable or disable A20.
     1906     */
     1907    RT_NOREF(pVM);
     1908    return PGMPhysIsA20Enabled(pVCpu);
     1909#else
     1910    RT_NOREF(pVM, pVCpu);
    18911911    return true;
     1912#endif
    18921913}
    18931914
     
    20232044        *pu2State = NEM_WIN_PAGE_STATE_UNMAPPED;
    20242045    }
     2046    RT_NOREF(pvRam);
    20252047
    20262048#else
     
    22062228
    22072229
     2230#ifdef NEM_WIN_WITH_A20
    22082231/**
    22092232 * Unmaps a page from Hyper-V for the purpose of emulating A20 gate behavior.
     
    22202243                                     nemR3WinUnsetForA20CheckerCallback, NULL);
    22212244}
     2245#endif
    22222246
    22232247
     
    22322256 * @param   fEnabled        Whether it was enabled (true) or disabled.
    22332257 */
    2234 void nemR3NativeNotifySetA20(PVMCPU pVCpu, bool fEnabled)
     2258VMMR3_INT_DECL(void) NEMR3NotifySetA20(PVMCPU pVCpu, bool fEnabled)
    22352259{
    22362260    Log(("nemR3NativeNotifySetA20: fEnabled=%RTbool\n", fEnabled));
     2261    Assert(VM_IS_NEM_ENABLED(pVCpu->CTX_SUFF(pVM)));
     2262#ifdef NEM_WIN_WITH_A20
    22372263    PVM pVM = pVCpu->CTX_SUFF(pVM);
    22382264    if (!pVM->nem.s.fA20Fixed)
     
    22422268            nemR3WinUnmapPageForA20Gate(pVM, pVCpu, GCPhys);
    22432269    }
     2270#else
     2271    RT_NOREF(pVCpu, fEnabled);
     2272#endif
    22442273}
    22452274
     
    24462475 *   (e.g. possiblity of two CPUs with different A20 status).
    24472476 *
    2448  *   Workaround: Only do A20 on CPU 0, restricting the emulation to HMA.  We
    2449  *   unmap all pages related to HMA (0x100000..0x10ffff) when the A20 state
    2450  *   changes, lazily syncing the right pages back when accessed.
     2477 *   Workaround #1 (obsolete): Only do A20 on CPU 0, restricting the emulation
     2478 *   to HMA. We unmap all pages related to HMA (0x100000..0x10ffff) when the A20
     2479 *   state changes, lazily syncing the right pages back when accessed.
     2480 *
     2481 *   Workaround #2 (used): Use IEM when the A20 gate is disabled.
    24512482 *
    24522483 *
  • trunk/src/VBox/VMM/include/NEMInternal.h

    r91958 r92120  
    167167    /** Set if we're using the ring-0 API to do the work. */
    168168    bool                        fUseRing0Runloop : 1;
     169# ifdef NEM_WIN_WITH_A20
    169170    /** Set if we've started more than one CPU and cannot mess with A20. */
    170171    bool                        fA20Fixed : 1;
    171172    /** Set if A20 is enabled. */
    172173    bool                        fA20Enabled : 1;
     174# endif
    173175    /** The reported CPU vendor.   */
    174176    CPUMCPUVENDOR               enmCpuVendor;
     
    459461bool            nemR3NativeSetSingleInstruction(PVM pVM, PVMCPU pVCpu, bool fEnable);
    460462void            nemR3NativeNotifyFF(PVM pVM, PVMCPU pVCpu, uint32_t fFlags);
    461 
    462 void    nemR3NativeNotifySetA20(PVMCPU pVCpu, bool fEnabled);
    463463#endif
    464464
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