VirtualBox

Changeset 72484 in vbox


Ignore:
Timestamp:
Jun 8, 2018 5:05:40 PM (6 years ago)
Author:
vboxsync
Message:

IEM,NEM: Define minimum CPUMCTX set for IEM and hook it up to NEM for fetching missing bits as needed. bugref:9044

Location:
trunk
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/cpumctx.h

    r72415 r72484  
    781781/** The RIP register value is kept externally. */
    782782#define CPUMCTX_EXTRN_RIP                       UINT64_C(0x0000000000000004)
     783/** The RFLAGS register values are kept externally. */
     784#define CPUMCTX_EXTRN_RFLAGS                    UINT64_C(0x0000000000000008)
     785
     786/** The RAX register value is kept externally. */
     787#define CPUMCTX_EXTRN_RAX                       UINT64_C(0x0000000000000010)
     788/** The RCX register value is kept externally. */
     789#define CPUMCTX_EXTRN_RCX                       UINT64_C(0x0000000000000020)
     790/** The RDX register value is kept externally. */
     791#define CPUMCTX_EXTRN_RDX                       UINT64_C(0x0000000000000040)
     792/** The RBX register value is kept externally. */
     793#define CPUMCTX_EXTRN_RBX                       UINT64_C(0x0000000000000080)
     794/** The RSP register value is kept externally. */
     795#define CPUMCTX_EXTRN_RSP                       UINT64_C(0x0000000000000100)
     796/** The RBP register value is kept externally. */
     797#define CPUMCTX_EXTRN_RBP                       UINT64_C(0x0000000000000200)
     798/** The RSI register value is kept externally. */
     799#define CPUMCTX_EXTRN_RSI                       UINT64_C(0x0000000000000400)
     800/** The RDI register value is kept externally. */
     801#define CPUMCTX_EXTRN_RDI                       UINT64_C(0x0000000000000800)
     802/** The R8 thru R15 register values are kept externally. */
     803#define CPUMCTX_EXTRN_R8_R15                    UINT64_C(0x0000000000001000)
     804/** General purpose registers mask. */
     805#define CPUMCTX_EXTRN_GPRS_MASK                 UINT64_C(0x0000000000001ff0)
     806
     807/** The ES register values are kept externally. */
     808#define CPUMCTX_EXTRN_ES                        UINT64_C(0x0000000000002000)
    783809/** The CS register values are kept externally. */
    784 #define CPUMCTX_EXTRN_CS                        UINT64_C(0x0000000000000008)
    785 /** The RFLAGS register values are kept externally. */
    786 #define CPUMCTX_EXTRN_RFLAGS                    UINT64_C(0x0000000000000010)
    787 
    788 /** The RAX register value is kept externally. */
    789 #define CPUMCTX_EXTRN_RAX                       UINT64_C(0x0000000000000020)
    790 /** The RCX register value is kept externally. */
    791 #define CPUMCTX_EXTRN_RCX                       UINT64_C(0x0000000000000040)
    792 /** The RDX register value is kept externally. */
    793 #define CPUMCTX_EXTRN_RDX                       UINT64_C(0x0000000000000080)
    794 /** The RBX register value is kept externally. */
    795 #define CPUMCTX_EXTRN_RBX                       UINT64_C(0x0000000000000100)
    796 /** The RSP register value is kept externally. */
    797 #define CPUMCTX_EXTRN_RSP                       UINT64_C(0x0000000000000200)
    798 /** The RBP register value is kept externally. */
    799 #define CPUMCTX_EXTRN_RBP                       UINT64_C(0x0000000000000400)
    800 /** The RSI register value is kept externally. */
    801 #define CPUMCTX_EXTRN_RSI                       UINT64_C(0x0000000000000800)
    802 /** The RDI register value is kept externally. */
    803 #define CPUMCTX_EXTRN_RDI                       UINT64_C(0x0000000000001000)
    804 /** The R8 thru R15 register values are kept externally. */
    805 #define CPUMCTX_EXTRN_R8_R15                    UINT64_C(0x0000000000002000)
    806 /** General purpose registers mask. */
    807 #define CPUMCTX_EXTRN_GPRS_MASK                 UINT64_C(0x0000000000003fe0)
    808 
     810#define CPUMCTX_EXTRN_CS                        UINT64_C(0x0000000000004000)
    809811/** The SS register values are kept externally. */
    810 #define CPUMCTX_EXTRN_SS                        UINT64_C(0x0000000000004000)
     812#define CPUMCTX_EXTRN_SS                        UINT64_C(0x0000000000008000)
    811813/** The DS register values are kept externally. */
    812 #define CPUMCTX_EXTRN_DS                        UINT64_C(0x0000000000008000)
    813 /** The ES register values are kept externally. */
    814 #define CPUMCTX_EXTRN_ES                        UINT64_C(0x0000000000010000)
     814#define CPUMCTX_EXTRN_DS                        UINT64_C(0x0000000000010000)
    815815/** The FS register values are kept externally. */
    816816#define CPUMCTX_EXTRN_FS                        UINT64_C(0x0000000000020000)
     
    818818#define CPUMCTX_EXTRN_GS                        UINT64_C(0x0000000000040000)
    819819/** Segment registers (includes CS). */
    820 #define CPUMCTX_EXTRN_SREG_MASK                 UINT64_C(0x000000000007c008)
     820#define CPUMCTX_EXTRN_SREG_MASK                 UINT64_C(0x000000000007e000)
     821/** Converts a X86_XREG_XXX index to a CPUMCTX_EXTRN_xS mask. */
     822#define CPUMCTX_EXTRN_SREG_FROM_IDX(a_SRegIdx)  RT_BIT_64((a_SRegIdx) + 13)
     823#ifndef VBOX_FOR_DTRACE_LIB
     824AssertCompile(CPUMCTX_EXTRN_SREG_FROM_IDX(X86_SREG_ES) == CPUMCTX_EXTRN_ES);
     825AssertCompile(CPUMCTX_EXTRN_SREG_FROM_IDX(X86_SREG_CS) == CPUMCTX_EXTRN_CS);
     826AssertCompile(CPUMCTX_EXTRN_SREG_FROM_IDX(X86_SREG_DS) == CPUMCTX_EXTRN_DS);
     827AssertCompile(CPUMCTX_EXTRN_SREG_FROM_IDX(X86_SREG_FS) == CPUMCTX_EXTRN_FS);
     828AssertCompile(CPUMCTX_EXTRN_SREG_FROM_IDX(X86_SREG_GS) == CPUMCTX_EXTRN_GS);
     829#endif
    821830
    822831/** The GDTR register values are kept externally. */
     
    841850/** Control register mask. */
    842851#define CPUMCTX_EXTRN_CR_MASK                   UINT64_C(0x0000000007800000)
     852/** The TPR/CR8 register value is kept externally. */
     853#define CPUMCTX_EXTRN_APIC_TPR                  UINT64_C(0x0000000008000000)
    843854/** The EFER register value is kept externally. */
    844 #define CPUMCTX_EXTRN_EFER                      UINT64_C(0x0000000008000000)
     855#define CPUMCTX_EXTRN_EFER                      UINT64_C(0x0000000010000000)
    845856
    846857/** The DR0, DR1, DR2 and DR3 register values are kept externally. */
    847 #define CPUMCTX_EXTRN_DR0_DR3                   UINT64_C(0x0000000010000000)
     858#define CPUMCTX_EXTRN_DR0_DR3                   UINT64_C(0x0000000020000000)
    848859/** The DR6 register value is kept externally. */
    849 #define CPUMCTX_EXTRN_DR6                       UINT64_C(0x0000000020000000)
     860#define CPUMCTX_EXTRN_DR6                       UINT64_C(0x0000000040000000)
    850861/** The DR7 register value is kept externally. */
    851 #define CPUMCTX_EXTRN_DR7                       UINT64_C(0x0000000040000000)
     862#define CPUMCTX_EXTRN_DR7                       UINT64_C(0x0000000080000000)
    852863/** Debug register mask. */
    853 #define CPUMCTX_EXTRN_DR_MASK                   UINT64_C(0x0000000070000000)
     864#define CPUMCTX_EXTRN_DR_MASK                   UINT64_C(0x00000000e0000000)
    854865
    855866/** The XSAVE_C_X87 state is kept externally. */
    856 #define CPUMCTX_EXTRN_X87                       UINT64_C(0x0000000080000000)
     867#define CPUMCTX_EXTRN_X87                       UINT64_C(0x0000000100000000)
    857868/** The XSAVE_C_SSE, XSAVE_C_YMM, XSAVE_C_ZMM_HI256, XSAVE_C_ZMM_16HI and
    858869 * XSAVE_C_OPMASK state is kept externally. */
    859 #define CPUMCTX_EXTRN_SSE_AVX                   UINT64_C(0x0000000100000000)
     870#define CPUMCTX_EXTRN_SSE_AVX                   UINT64_C(0x0000000200000000)
    860871/** The state of XSAVE components not covered by CPUMCTX_EXTRN_X87 and
    861872 * CPUMCTX_EXTRN_SEE_AVX is kept externally. */
    862 #define CPUMCTX_EXTRN_OTHER_XSAVE               UINT64_C(0x0000000200000000)
     873#define CPUMCTX_EXTRN_OTHER_XSAVE               UINT64_C(0x0000000400000000)
    863874/** The state of XCR0 and XCR1 register values are kept externally. */
    864 #define CPUMCTX_EXTRN_XCRx                      UINT64_C(0x0000000400000000)
     875#define CPUMCTX_EXTRN_XCRx                      UINT64_C(0x0000000800000000)
     876
    865877
    866878/** The KERNEL GS BASE MSR value is kept externally. */
    867 #define CPUMCTX_EXTRN_KERNEL_GS_BASE            UINT64_C(0x0000000800000000)
     879#define CPUMCTX_EXTRN_KERNEL_GS_BASE            UINT64_C(0x0000001000000000)
    868880/** The STAR, LSTAR, CSTAR and SFMASK MSR values are kept externally. */
    869 #define CPUMCTX_EXTRN_SYSCALL_MSRS              UINT64_C(0x0000001000000000)
     881#define CPUMCTX_EXTRN_SYSCALL_MSRS              UINT64_C(0x0000002000000000)
    870882/** The SYSENTER_CS, SYSENTER_EIP and SYSENTER_ESP MSR values are kept externally. */
    871 #define CPUMCTX_EXTRN_SYSENTER_MSRS             UINT64_C(0x0000002000000000)
    872 /** The SYSENTER_CS, SYSENTER_EIP and SYSENTER_ESP MSR values are kept externally. */
    873 #define CPUMCTX_EXTRN_TSC_AUX                   UINT64_C(0x0000004000000000)
     883#define CPUMCTX_EXTRN_SYSENTER_MSRS             UINT64_C(0x0000004000000000)
     884/** The TSC_AUX MSR is kept externally. */
     885#define CPUMCTX_EXTRN_TSC_AUX                   UINT64_C(0x0000008000000000)
    874886/** All other stateful MSRs not covered by CPUMCTX_EXTRN_EFER,
    875887 * CPUMCTX_EXTRN_KERNEL_GS_BASE, CPUMCTX_EXTRN_SYSCALL_MSRS,
    876888 * CPUMCTX_EXTRN_SYSENTER_MSRS, and CPUMCTX_EXTRN_TSC_AUX.  */
    877 #define CPUMCTX_EXTRN_OTHER_MSRS                UINT64_C(0x0000008000000000)
     889#define CPUMCTX_EXTRN_OTHER_MSRS                UINT64_C(0x0000010000000000)
    878890
    879891/** Mask of all the MSRs. */
  • trunk/include/VBox/vmm/iem.h

    r72209 r72484  
    177177
    178178
     179/** The CPUMCTX_EXTRN_XXX mask required to be cleared when interpreting anything.
     180 * IEM will ASSUME the caller of IEM APIs has ensured these are already present. */
     181#define IEM_CPUMCTX_EXTRN_MUST_MASK    (  CPUMCTX_EXTRN_GPRS_MASK \
     182                                        | CPUMCTX_EXTRN_RIP \
     183                                        | CPUMCTX_EXTRN_RFLAGS \
     184                                        | CPUMCTX_EXTRN_SS \
     185                                        | CPUMCTX_EXTRN_CS \
     186                                        | CPUMCTX_EXTRN_CR0 \
     187                                        | CPUMCTX_EXTRN_CR3 \
     188                                        | CPUMCTX_EXTRN_CR4 \
     189                                        | CPUMCTX_EXTRN_APIC_TPR \
     190                                        | CPUMCTX_EXTRN_EFER \
     191                                        | CPUMCTX_EXTRN_DR7 )
     192/** The CPUMCTX_EXTRN_XXX mask needed when injecting an exception/interrupt.
     193 * IEM will import missing bits, callers are encouraged to make these registers
     194 * available prior to injection calls if fetching state anyway.  */
     195#define IEM_CPUMCTX_EXTRN_XCPT_MASK    (  IEM_CPUMCTX_EXTRN_MUST_MASK \
     196                                        | CPUMCTX_EXTRN_CR2 \
     197                                        | CPUMCTX_EXTRN_SREG_MASK \
     198                                        | CPUMCTX_EXTRN_TABLE_MASK )
     199
     200
    179201VMMDECL(VBOXSTRICTRC)       IEMExecOne(PVMCPU pVCpu);
    180202VMMDECL(VBOXSTRICTRC)       IEMExecOneEx(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, uint32_t *pcbWritten);
  • trunk/include/VBox/vmm/nem.h

    r72343 r72484  
    100100 */
    101101VMM_INT_DECL(bool) NEMHCIsLongModeAllowed(PVM pVM);
     102VMM_INT_DECL(int)  NEMImportStateOnDemand(PVMCPU pVCpu, PCPUMCTX pCtx, uint64_t fWhat);
     103
    102104VMM_INT_DECL(void) NEMHCNotifyHandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb);
    103105VMM_INT_DECL(void) NEMHCNotifyHandlerPhysicalDeregister(PVM pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb,
  • trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp

    r72358 r72484  
    600600    pVCpu->cpum.s.Guest.gdtr.cbGdt = cbLimit;
    601601    pVCpu->cpum.s.Guest.gdtr.pGdt  = GCPtrBase;
     602    pVCpu->cpum.s.Guest.fExtrn &= ~CPUMCTX_EXTRN_GDTR;
    602603    pVCpu->cpum.s.fChanged |= CPUM_CHANGED_GDTR;
    603604    return VINF_SUCCESS; /* formality, consider it void. */
     
    613614    pVCpu->cpum.s.Guest.idtr.cbIdt = cbLimit;
    614615    pVCpu->cpum.s.Guest.idtr.pIdt  = GCPtrBase;
     616    pVCpu->cpum.s.Guest.fExtrn &= ~CPUMCTX_EXTRN_IDTR;
    615617    pVCpu->cpum.s.fChanged |= CPUM_CHANGED_IDTR;
    616618    return VINF_SUCCESS; /* formality, consider it void. */
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r72451 r72484  
    102102#include <VBox/vmm/em.h>
    103103#include <VBox/vmm/hm.h>
     104#include <VBox/vmm/nem.h>
    104105#include <VBox/vmm/gim.h>
    105106#ifdef VBOX_WITH_NESTED_HWVIRT_SVM
     
    992993    PCPUMCTX const pCtx = IEM_GET_CTX(pVCpu);
    993994
     995    IEM_CTX_ASSERT(pCtx, IEM_CPUMCTX_EXTRN_MUST_MASK);
    994996    Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_IEM));
    995997
     
    11341136    PCPUMCTX const pCtx = IEM_GET_CTX(pVCpu);
    11351137
     1138    IEM_CTX_ASSERT(IEM_GET_CTX(pVCpu), IEM_CPUMCTX_EXTRN_MUST_MASK);
    11361139    Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_IEM));
    11371140
     
    16801683{
    16811684#ifdef IN_RING3
    1682 //__debugbreak();
    16831685    for (;;)
    16841686    {
     
    35173519    Assert(uCpl < 4);
    35183520
     3521    IEM_CTX_IMPORT_RET(pVCpu, (PCPUMCTX)pCtx, CPUMCTX_EXTRN_TR | CPUMCTX_EXTRN_GDTR | CPUMCTX_EXTRN_LDTR);
    35193522    switch (pCtx->tr.Attr.n.u4Type)
    35203523    {
     
    36013604    *puRsp  = 0; /* make gcc happy */
    36023605
     3606    IEM_CTX_IMPORT_RET(pVCpu, (PCPUMCTX)pCtx, CPUMCTX_EXTRN_TR | CPUMCTX_EXTRN_GDTR | CPUMCTX_EXTRN_LDTR);
    36033607    AssertReturn(pCtx->tr.Attr.n.u4Type == AMD64_SEL_TYPE_SYS_TSS_BUSY, VERR_IEM_IPE_5);
    36043608
     
    36293633    {
    36303634        case X86_XCPT_DB:
     3635            IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_DR7);
    36313636            pCtx->dr[7] &= ~X86_DR7_GD;
    36323637            break;
     
    36593664{
    36603665    NOREF(uErr); NOREF(uCr2);
     3666    IEM_CTX_ASSERT(pCtx, IEM_CPUMCTX_EXTRN_XCPT_MASK);
    36613667
    36623668    /*
     
    39293935    Assert(!IEM_IS_REAL_MODE(pVCpu));
    39303936    Assert(pVCpu->iem.s.enmCpuMode != IEMMODE_64BIT);
     3937    IEM_CTX_ASSERT(pCtx, IEM_CPUMCTX_EXTRN_XCPT_MASK);
    39313938
    39323939    uint32_t const uNewTSSType = pNewDescTSS->Legacy.Gate.u4Type;
     
    46864693                            uint64_t    uCr2)
    46874694{
     4695    IEM_CTX_ASSERT(pCtx, IEM_CPUMCTX_EXTRN_XCPT_MASK);
     4696
    46884697    /*
    46894698     * Read the IDT entry.
     
    51485157                            uint64_t    uCr2)
    51495158{
     5159    IEM_CTX_ASSERT(pCtx, IEM_CPUMCTX_EXTRN_XCPT_MASK);
     5160
    51505161    /*
    51515162     * Read the IDT entry.
     
    53985409{
    53995410    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     5411
     5412    /*
     5413     * Get all the state that we might need here.
     5414     */
    54005415#ifdef IN_RING0
    54015416    int rc = HMR0EnsureCompleteBasicContext(pVCpu, pCtx);
    54025417    AssertRCReturn(rc, rc);
    54035418#endif
     5419    IEM_CTX_IMPORT_RET(pVCpu, pCtx, IEM_CPUMCTX_EXTRN_XCPT_MASK);
     5420    IEM_CTX_ASSERT(pCtx, IEM_CPUMCTX_EXTRN_XCPT_MASK);
    54045421
    54055422#ifndef IEM_WITH_CODE_TLB /** @todo we're doing it afterwards too, that should suffice... */
     
    61306147    Assert(iSegReg < X86_SREG_COUNT);
    61316148    PCPUMCTX    pCtx = IEM_GET_CTX(pVCpu);
     6149    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    61326150    PCPUMSELREG pSReg = &pCtx->aSRegs[iSegReg];
    61336151
     
    61766194    Assert(iSegReg < X86_SREG_COUNT);
    61776195    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     6196    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    61786197    return &pCtx->aSRegs[iSegReg].Sel;
    61796198}
     
    61906209{
    61916210    Assert(iSegReg < X86_SREG_COUNT);
    6192     return IEM_GET_CTX(pVCpu)->aSRegs[iSegReg].Sel;
     6211    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     6212    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
     6213    return pCtx->aSRegs[iSegReg].Sel;
    61936214}
    61946215
     
    62046225{
    62056226    Assert(iSegReg < X86_SREG_COUNT);
    6206     return IEM_GET_CTX(pVCpu)->aSRegs[iSegReg].u64Base;
     6227    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     6228    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
     6229    return pCtx->aSRegs[iSegReg].u64Base;
    62076230}
    62086231
     
    63026325    Assert(iSegReg < X86_SREG_COUNT);
    63036326    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     6327    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    63046328    return &pCtx->aSRegs[iSegReg].u64Base;
    63056329}
     
    68786902    CPUMRZFpuStatePrepareHostCpuForUse(pVCpu);
    68796903#endif
     6904    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     6905    IEM_CTX_IMPORT_NORET(pVCpu, pCtx, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    68806906}
    68816907
     
    69216947    CPUMRZFpuStateActualizeForRead(pVCpu);
    69226948#endif
     6949    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     6950    IEM_CTX_IMPORT_NORET(pVCpu, pCtx, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    69236951}
    69246952
     
    69386966    CPUMRZFpuStateActualizeForChange(pVCpu);
    69396967#endif
     6968    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     6969    IEM_CTX_IMPORT_NORET(pVCpu, pCtx, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    69406970}
    69416971
     
    69566986    CPUMRZFpuStateActualizeSseForRead(pVCpu);
    69576987#endif
     6988    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     6989    IEM_CTX_IMPORT_NORET(pVCpu, pCtx, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    69586990}
    69596991
     
    69747006    CPUMRZFpuStateActualizeForChange(pVCpu);
    69757007#endif
     7008    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     7009    IEM_CTX_IMPORT_NORET(pVCpu, pCtx, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    69767010}
    69777011
     
    69927026    CPUMRZFpuStateActualizeAvxForRead(pVCpu);
    69937027#endif
     7028    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     7029    IEM_CTX_IMPORT_NORET(pVCpu, pCtx, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    69947030}
    69957031
     
    70107046    CPUMRZFpuStateActualizeForChange(pVCpu);
    70117047#endif
     7048    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     7049    IEM_CTX_IMPORT_NORET(pVCpu, pCtx, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    70127050}
    70137051
     
    79307968iemMemSegCheckWriteAccessEx(PVMCPU pVCpu, PCCPUMSELREGHID pHid, uint8_t iSegReg, uint64_t *pu64BaseAddr)
    79317969{
     7970    IEM_CTX_ASSERT(IEM_GET_CTX(pVCpu), CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
     7971
    79327972    if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
    79337973        *pu64BaseAddr = iSegReg < X86_SREG_FS ? 0 : pHid->u64Base;
     
    79688008iemMemSegCheckReadAccessEx(PVMCPU pVCpu, PCCPUMSELREGHID pHid, uint8_t iSegReg, uint64_t *pu64BaseAddr)
    79698009{
     8010    IEM_CTX_ASSERT(IEM_GET_CTX(pVCpu), CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
     8011
    79708012    if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
    79718013        *pu64BaseAddr = iSegReg < X86_SREG_FS ? 0 : pHid->u64Base;
     
    80108052        return VINF_SUCCESS;
    80118053
     8054    IEM_CTX_IMPORT_RET(pVCpu, IEM_GET_CTX(pVCpu), CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    80128055    PCPUMSELREGHID pSel = iemSRegGetHid(pVCpu, iSegReg);
    80138056    switch (pVCpu->iem.s.enmCpuMode)
     
    90909133}
    90919134
    9092 #endif
     9135#endif /* IEM_WITH_SETJMP */
    90939136
    90949137#ifndef IN_RING3
     
    92909333        if (iSegReg >= X86_SREG_FS)
    92919334        {
     9335            IEM_CTX_IMPORT_JMP(pVCpu, IEM_GET_CTX(pVCpu), CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    92929336            PCPUMSELREGHID pSel = iemSRegGetHid(pVCpu, iSegReg);
    92939337            GCPtrMem += pSel->u64Base;
     
    93029346    else
    93039347    {
     9348        IEM_CTX_IMPORT_JMP(pVCpu, IEM_GET_CTX(pVCpu), CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    93049349        PCPUMSELREGHID pSel = iemSRegGetHid(pVCpu, iSegReg);
    93059350        if (      (pSel->Attr.u & (X86DESCATTR_P | X86DESCATTR_UNUSABLE | X86_SEL_TYPE_CODE | X86_SEL_TYPE_DOWN))
     
    93449389        if (iSegReg >= X86_SREG_FS)
    93459390        {
     9391            IEM_CTX_IMPORT_JMP(pVCpu, IEM_GET_CTX(pVCpu), CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    93469392            PCPUMSELREGHID pSel = iemSRegGetHid(pVCpu, iSegReg);
    93479393            GCPtrMem += pSel->u64Base;
     
    93569402    else
    93579403    {
     9404        IEM_CTX_IMPORT_JMP(pVCpu, IEM_GET_CTX(pVCpu), CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    93589405        PCPUMSELREGHID pSel           = iemSRegGetHid(pVCpu, iSegReg);
    93599406        uint32_t const fRelevantAttrs = pSel->Attr.u & (  X86DESCATTR_P     | X86DESCATTR_UNUSABLE
     
    1099711044    AssertPtr(pDesc);
    1099811045    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     11046    IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_GDTR | CPUMCTX_EXTRN_LDTR);
    1099911047
    1100011048    /** @todo did the 286 require all 8 bytes to be accessible? */
     
    1133711385#define IEM_MC_FETCH_GREG_U64(a_u64Dst, a_iGReg)        (a_u64Dst) = iemGRegFetchU64(pVCpu, (a_iGReg))
    1133811386#define IEM_MC_FETCH_GREG_U64_ZX_U64                    IEM_MC_FETCH_GREG_U64
    11339 #define IEM_MC_FETCH_SREG_U16(a_u16Dst, a_iSReg)        (a_u16Dst) = iemSRegFetchU16(pVCpu, (a_iSReg))
    11340 #define IEM_MC_FETCH_SREG_ZX_U32(a_u32Dst, a_iSReg)     (a_u32Dst) = iemSRegFetchU16(pVCpu, (a_iSReg))
    11341 #define IEM_MC_FETCH_SREG_ZX_U64(a_u64Dst, a_iSReg)     (a_u64Dst) = iemSRegFetchU16(pVCpu, (a_iSReg))
    11342 #define IEM_MC_FETCH_SREG_BASE_U64(a_u64Dst, a_iSReg)   (a_u64Dst) = iemSRegBaseFetchU64(pVCpu, (a_iSReg));
    11343 #define IEM_MC_FETCH_SREG_BASE_U32(a_u32Dst, a_iSReg)   (a_u32Dst) = iemSRegBaseFetchU64(pVCpu, (a_iSReg));
     11387#define IEM_MC_FETCH_SREG_U16(a_u16Dst, a_iSReg) do { \
     11388        IEM_CTX_IMPORT_NORET(pVCpu, IEM_GET_CTX(pVCpu), CPUMCTX_EXTRN_SREG_FROM_IDX(a_iSReg)); \
     11389        (a_u16Dst) = iemSRegFetchU16(pVCpu, (a_iSReg)); \
     11390    } while (0)
     11391#define IEM_MC_FETCH_SREG_ZX_U32(a_u32Dst, a_iSReg) do { \
     11392        IEM_CTX_IMPORT_NORET(pVCpu, IEM_GET_CTX(pVCpu), CPUMCTX_EXTRN_SREG_FROM_IDX(a_iSReg)); \
     11393        (a_u32Dst) = iemSRegFetchU16(pVCpu, (a_iSReg)); \
     11394    } while (0)
     11395#define IEM_MC_FETCH_SREG_ZX_U64(a_u64Dst, a_iSReg) do { \
     11396        IEM_CTX_IMPORT_NORET(pVCpu, IEM_GET_CTX(pVCpu), CPUMCTX_EXTRN_SREG_FROM_IDX(a_iSReg)); \
     11397        (a_u64Dst) = iemSRegFetchU16(pVCpu, (a_iSReg)); \
     11398    } while (0)
     11399/** @todo IEM_MC_FETCH_SREG_BASE_U64 & IEM_MC_FETCH_SREG_BASE_U32 probably aren't worth it... */
     11400#define IEM_MC_FETCH_SREG_BASE_U64(a_u64Dst, a_iSReg) do { \
     11401        IEM_CTX_IMPORT_NORET(pVCpu, IEM_GET_CTX(pVCpu), CPUMCTX_EXTRN_SREG_FROM_IDX(a_iSReg)); \
     11402        (a_u64Dst) = iemSRegBaseFetchU64(pVCpu, (a_iSReg)); \
     11403    } while (0)
     11404#define IEM_MC_FETCH_SREG_BASE_U32(a_u32Dst, a_iSReg) do { \
     11405        IEM_CTX_IMPORT_NORET(pVCpu, IEM_GET_CTX(pVCpu), CPUMCTX_EXTRN_SREG_FROM_IDX(a_iSReg)); \
     11406        (a_u32Dst) = iemSRegBaseFetchU64(pVCpu, (a_iSReg)); \
     11407    } while (0)
    1134411408#define IEM_MC_FETCH_CR0_U16(a_u16Dst)                  (a_u16Dst) = (uint16_t)(pVCpu)->iem.s.CTX_SUFF(pCtx)->cr0
    1134511409#define IEM_MC_FETCH_CR0_U32(a_u32Dst)                  (a_u32Dst) = (uint32_t)(pVCpu)->iem.s.CTX_SUFF(pCtx)->cr0
    1134611410#define IEM_MC_FETCH_CR0_U64(a_u64Dst)                  (a_u64Dst) = (pVCpu)->iem.s.CTX_SUFF(pCtx)->cr0
    11347 #define IEM_MC_FETCH_LDTR_U16(a_u16Dst)                 (a_u16Dst) = (pVCpu)->iem.s.CTX_SUFF(pCtx)->ldtr.Sel
    11348 #define IEM_MC_FETCH_LDTR_U32(a_u32Dst)                 (a_u32Dst) = (pVCpu)->iem.s.CTX_SUFF(pCtx)->ldtr.Sel
    11349 #define IEM_MC_FETCH_LDTR_U64(a_u64Dst)                 (a_u64Dst) = (pVCpu)->iem.s.CTX_SUFF(pCtx)->ldtr.Sel
    11350 #define IEM_MC_FETCH_TR_U16(a_u16Dst)                   (a_u16Dst) = (pVCpu)->iem.s.CTX_SUFF(pCtx)->tr.Sel
    11351 #define IEM_MC_FETCH_TR_U32(a_u32Dst)                   (a_u32Dst) = (pVCpu)->iem.s.CTX_SUFF(pCtx)->tr.Sel
    11352 #define IEM_MC_FETCH_TR_U64(a_u64Dst)                   (a_u64Dst) = (pVCpu)->iem.s.CTX_SUFF(pCtx)->tr.Sel
     11411/** @todo IEM_MC_FETCH_LDTR_U16, IEM_MC_FETCH_LDTR_U32, IEM_MC_FETCH_LDTR_U64, IEM_MC_FETCH_TR_U16, IEM_MC_FETCH_TR_U32, and IEM_MC_FETCH_TR_U64 aren't worth it... */
     11412#define IEM_MC_FETCH_LDTR_U16(a_u16Dst) do { \
     11413        IEM_CTX_IMPORT_NORET(pVCpu, IEM_GET_CTX(pVCpu), CPUMCTX_EXTRN_LDTR); \
     11414        (a_u16Dst) = (pVCpu)->iem.s.CTX_SUFF(pCtx)->ldtr.Sel; \
     11415   } while (0)
     11416#define IEM_MC_FETCH_LDTR_U32(a_u32Dst) do { \
     11417        IEM_CTX_IMPORT_NORET(pVCpu, IEM_GET_CTX(pVCpu), CPUMCTX_EXTRN_LDTR); \
     11418        (a_u32Dst) = (pVCpu)->iem.s.CTX_SUFF(pCtx)->ldtr.Sel; \
     11419    } while (0)
     11420#define IEM_MC_FETCH_LDTR_U64(a_u64Dst) do { \
     11421        IEM_CTX_IMPORT_NORET(pVCpu, IEM_GET_CTX(pVCpu), CPUMCTX_EXTRN_LDTR); \
     11422        (a_u64Dst) = (pVCpu)->iem.s.CTX_SUFF(pCtx)->ldtr.Sel; \
     11423   } while (0)
     11424#define IEM_MC_FETCH_TR_U16(a_u16Dst) do { \
     11425        IEM_CTX_IMPORT_NORET(pVCpu, IEM_GET_CTX(pVCpu), CPUMCTX_EXTRN_TR); \
     11426        (a_u16Dst) = (pVCpu)->iem.s.CTX_SUFF(pCtx)->tr.Sel; \
     11427   } while (0)
     11428#define IEM_MC_FETCH_TR_U32(a_u32Dst) do { \
     11429        IEM_CTX_IMPORT_NORET(pVCpu, IEM_GET_CTX(pVCpu), CPUMCTX_EXTRN_TR); \
     11430        (a_u32Dst) = (pVCpu)->iem.s.CTX_SUFF(pCtx)->tr.Sel; \
     11431   } while (0)
     11432#define IEM_MC_FETCH_TR_U64(a_u64Dst) do { \
     11433        IEM_CTX_IMPORT_NORET(pVCpu, IEM_GET_CTX(pVCpu), CPUMCTX_EXTRN_TR); \
     11434        (a_u64Dst) = (pVCpu)->iem.s.CTX_SUFF(pCtx)->tr.Sel; \
     11435   } while (0)
    1135311436/** @note Not for IOPL or IF testing or modification. */
    1135411437#define IEM_MC_FETCH_EFLAGS(a_EFlags)                   (a_EFlags) = (pVCpu)->iem.s.CTX_SUFF(pCtx)->eflags.u
     
    1136711450#define IEM_MC_CLEAR_HIGH_GREG_U64(a_iGReg)             *iemGRegRefU64(pVCpu, (a_iGReg)) &= UINT32_MAX
    1136811451#define IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(a_pu32Dst)    do { (a_pu32Dst)[1] = 0; } while (0)
    11369 #define IEM_MC_STORE_SREG_BASE_U64(a_iSeg, a_u64Value)  *iemSRegBaseRefU64(pVCpu, (a_iSeg)) = (a_u64Value)
    11370 #define IEM_MC_STORE_SREG_BASE_U32(a_iSeg, a_u32Value)  *iemSRegBaseRefU64(pVCpu, (a_iSeg)) = (uint32_t)(a_u32Value) /* clear high bits. */
     11452/** @todo IEM_MC_STORE_SREG_BASE_U64 & IEM_MC_STORE_SREG_BASE_U32 aren't worth it... */
     11453#define IEM_MC_STORE_SREG_BASE_U64(a_iSReg, a_u64Value) do { \
     11454        IEM_CTX_IMPORT_NORET(pVCpu, IEM_GET_CTX(pVCpu), CPUMCTX_EXTRN_SREG_FROM_IDX(a_iSReg)); \
     11455        *iemSRegBaseRefU64(pVCpu, (a_iSReg)) = (a_u64Value); \
     11456    } while (0)
     11457#define IEM_MC_STORE_SREG_BASE_U32(a_iSReg, a_u32Value) do { \
     11458        IEM_CTX_IMPORT_NORET(pVCpu, IEM_GET_CTX(pVCpu), CPUMCTX_EXTRN_SREG_FROM_IDX(a_iSReg)); \
     11459        *iemSRegBaseRefU64(pVCpu, (a_iSReg)) = (uint32_t)(a_u32Value); /* clear high bits. */ \
     11460    } while (0)
    1137111461#define IEM_MC_STORE_FPUREG_R80_SRC_REF(a_iSt, a_pr80Src) \
    1137211462    do { IEM_GET_CTX(pVCpu)->CTX_SUFF(pXState)->x87.aRegs[a_iSt].r80 = *(a_pr80Src); } while (0)
     
    1380513895
    1380613896
     13897/**
     13898 * Used to dynamically imports state residing in NEM or HM.
     13899 *
     13900 * @returns VBox status code.
     13901 * @param   pVCpu           The cross context virtual CPU structure of the calling thread.
     13902 * @param   pCtx            The CPU context structure.
     13903 * @param   fExtrnImport    The fields to import.
     13904 */
     13905int iemCtxImport(PVMCPU pVCpu, PCPUMCTX pCtx, uint64_t fExtrnImport)
     13906{
     13907    switch (pCtx->fExtrn & CPUMCTX_EXTRN_KEEPER_MASK)
     13908    {
     13909#ifndef IN_RC
     13910        case CPUMCTX_EXTRN_KEEPER_NEM:
     13911        {
     13912            int rc = NEMImportStateOnDemand(pVCpu, pCtx, fExtrnImport);
     13913            Assert(rc == VINF_SUCCESS || RT_FAILURE_NP(rc));
     13914            return rc;
     13915        }
     13916
     13917        case CPUMCTX_EXTRN_KEEPER_HM: /** @todo make HM use CPUMCTX_EXTRN_XXX. */
     13918#endif
     13919
     13920        default:
     13921            AssertLogRelMsgFailed(("%RX64\n", fExtrnImport));
     13922#ifdef IN_RC
     13923            RT_NOREF_PV(pVCpu); RT_NOREF_PV(fExtrnImport);
     13924#endif
     13925            return VERR_IEM_IPE_9;
     13926    }
     13927}
     13928
     13929
    1380713930/** @}  */
    1380813931
     
    1440914532    PVMCPU pVCpu = pVCpu;
    1441014533    VBOXSTRICTRC rc = VERR_EM_CANNOT_EXEC_GUEST;
    14411 #ifdef IEM_VERIFICATION_MODE_FULL_HM
     14534#  ifdef IEM_VERIFICATION_MODE_FULL_HM
    1441214535    if (   HMIsEnabled(pVM)
    1441314536        && pVCpu->iem.s.cIOReads == 0
     
    1443114554            rc = VINF_SUCCESS;
    1443214555    }
    14433 #endif
     14556#  endif
    1443414557    if (   rc == VERR_EM_CANNOT_EXEC_GUEST
    1443514558        || rc == VINF_IOM_R3_IOPORT_READ
     
    1452514648        PX86XSAVEAREA pDebugXState = pDebugCtx->CTX_SUFF(pXState);
    1452614649
    14527 #if 1 /* The recompiler doesn't update these the intel way. */
     14650#  if 1 /* The recompiler doesn't update these the intel way. */
    1452814651        if (fRem)
    1452914652        {
     
    1453914662                pOrgXState->x87.FSW = pDebugXState->x87.FSW;
    1454014663        }
    14541 #endif
     14664#  endif
    1454214665        if (memcmp(&pOrgXState->x87, &pDebugXState->x87, sizeof(pDebugXState->x87)))
    1454314666        {
     
    1487014993    RT_NOREF_PV(pVCpu); RT_NOREF_PV(pCtx); RT_NOREF_PV(fSameCtx);
    1487114994}
    14872 #endif
     14995#endif /* LOG_ENABLED */
    1487314996
    1487414997
     
    1561915742    if (pVCpu->iem.s.cActiveMappings > 0)
    1562015743        iemMemRollback(pVCpu);
     15744
    1562115745    return rcStrict;
    1562215746}
     
    1564415768
    1564515769    VBOXSTRICTRC rcStrict = IEMInjectTrap(pVCpu, u8TrapNo, enmType, uErrCode, uCr2, cbInstr);
    15646 
    15647 #ifdef VBOX_WITH_NESTED_HWVIRT_SVM
     15770# ifdef VBOX_WITH_NESTED_HWVIRT_SVM
    1564815771    if (rcStrict == VINF_SVM_VMEXIT)
    1564915772        rcStrict = VINF_SUCCESS;
    15650 #endif
     15773# endif
    1565115774
    1565215775    /** @todo Are there any other codes that imply the event was successfully
     
    1565415777    if (   rcStrict == VINF_SUCCESS
    1565515778        || rcStrict == VINF_IEM_RAISED_XCPT)
    15656     {
    1565715779        TRPMResetTrap(pVCpu);
    15658     }
     15780
    1565915781    return rcStrict;
    1566015782#endif
     
    1620016322
    1620116323#ifdef VBOX_WITH_NESTED_HWVIRT_SVM
     16324
    1620216325/**
    1620316326 * Interface for HM and EM to emulate the CLGI instruction.
     
    1632016443VMM_INT_DECL(VBOXSTRICTRC) IEMExecSvmVmexit(PVMCPU pVCpu, uint64_t uExitCode, uint64_t uExitInfo1, uint64_t uExitInfo2)
    1632116444{
     16445    IEM_CTX_ASSERT(IEM_GET_CTX(pVCpu), IEM_CPUMCTX_EXTRN_MUST_MASK);
    1632216446    VBOXSTRICTRC rcStrict = iemSvmVmexit(pVCpu, IEM_GET_CTX(pVCpu), uExitCode, uExitInfo1, uExitInfo2);
    1632316447    return iemExecStatusCodeFiddling(pVCpu, rcStrict);
    1632416448}
     16449
    1632516450#endif /* VBOX_WITH_NESTED_HWVIRT_SVM */
    16326 
    1632716451#ifdef IN_RING3
    1632816452
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h

    r72451 r72484  
    4242    AssertCompileMembersAtSameOffset(X86TSS32, offIoBitmap, X86TSS64, offIoBitmap);
    4343    AssertCompile(sizeof(X86TSS32) == sizeof(X86TSS64));
     44
     45    IEM_CTX_IMPORT_RET(pVCpu, (PCPUMCTX)pCtx, CPUMCTX_EXTRN_TR);
    4446
    4547    /*
     
    229231    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, pSReg));
    230232#endif
     233    IEM_CTX_ASSERT(IEM_GET_CTX(pVCpu), CPUMCTX_EXTRN_SREG_MASK);
    231234
    232235    if (   uCpl > pSReg->Attr.n.u2Dpl
     
    990993           || pDesc->Legacy.Gate.u4Type == X86_SEL_TYPE_SYS_386_TSS_AVAIL);
    991994    RT_NOREF_PV(enmEffOpSize);
     995    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     996    IEM_CTX_ASSERT(pCtx, IEM_CPUMCTX_EXTRN_XCPT_MASK);
    992997
    993998    if (   pDesc->Legacy.Gate.u2Dpl < pVCpu->iem.s.uCpl
     
    10081013    }
    10091014
    1010     PCPUMCTX pCtx     = IEM_GET_CTX(pVCpu);
    10111015    uint32_t uNextEip = pCtx->eip + cbInstr;
    10121016    return iemTaskSwitch(pVCpu, pCtx, enmBranch == IEMBRANCH_JUMP ? IEMTASKSWITCH_JUMP : IEMTASKSWITCH_CALL,
     
    10321036    Assert(enmBranch == IEMBRANCH_JUMP || enmBranch == IEMBRANCH_CALL);
    10331037    RT_NOREF_PV(enmEffOpSize);
     1038    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     1039    IEM_CTX_ASSERT(pCtx, IEM_CPUMCTX_EXTRN_XCPT_MASK);
    10341040
    10351041    if (   pDesc->Legacy.Gate.u2Dpl < pVCpu->iem.s.uCpl
     
    10781084    }
    10791085
    1080     PCPUMCTX pCtx     = IEM_GET_CTX(pVCpu);
    10811086    uint32_t uNextEip = pCtx->eip + cbInstr;
    10821087    return iemTaskSwitch(pVCpu, pCtx, enmBranch == IEMBRANCH_JUMP ? IEMTASKSWITCH_JUMP : IEMTASKSWITCH_CALL,
     
    11021107#else
    11031108    RT_NOREF_PV(enmEffOpSize);
     1109    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     1110    IEM_CTX_ASSERT(pCtx, IEM_CPUMCTX_EXTRN_XCPT_MASK);
    11041111
    11051112    /* NB: Far jumps can only do intra-privilege transfers. Far calls support
     
    12211228        return iemRaiseSelectorNotPresentBySelector(pVCpu, uNewCS);
    12221229    }
    1223 
    1224     PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
    12251230
    12261231    if (enmBranch == IEMBRANCH_JUMP)
     
    17571762    Assert(enmBranch == IEMBRANCH_JUMP || enmBranch == IEMBRANCH_CALL);
    17581763    Assert((uSel & X86_SEL_MASK_OFF_RPL));
     1764    IEM_CTX_IMPORT_RET(pVCpu, IEM_GET_CTX(pVCpu), IEM_CPUMCTX_EXTRN_XCPT_MASK);
    17591765
    17601766    if (IEM_IS_LONG_MODE(pVCpu))
     
    22892295        return iemRaiseGeneralProtectionFault0(pVCpu);
    22902296    }
     2297
     2298    IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_SREG_MASK | CPUMCTX_EXTRN_GDTR | CPUMCTX_EXTRN_LDTR);
    22912299
    22922300    /* Fetch the descriptor. */
     
    30633071{
    30643072    RT_NOREF_PV(cbInstr);
     3073    IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_SREG_MASK);
    30653074
    30663075    /*
     
    38973906    if (IEM_IS_REAL_OR_V86_MODE(pVCpu))
    38983907        return IEM_CIMPL_CALL_1(iemCImpl_iret_real_v8086, enmEffOpSize);
     3908    IEM_CTX_IMPORT_RET(pVCpu, IEM_GET_CTX(pVCpu), CPUMCTX_EXTRN_SREG_MASK | CPUMCTX_EXTRN_GDTR | CPUMCTX_EXTRN_LDTR);
    38993909    if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
    39003910        return IEM_CIMPL_CALL_1(iemCImpl_iret_64bit, enmEffOpSize);
     
    39343944        return iemRaiseUndefinedOpcode(pVCpu);
    39353945    }
     3946
     3947    IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_SYSCALL_MSRS);
    39363948
    39373949    /** @todo verify RPL ignoring and CS=0xfff8 (i.e. SS == 0). */
     
    40474059    }
    40484060
     4061    IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_SYSCALL_MSRS);
     4062
    40494063    /** @todo Does SYSRET verify CS != 0 and SS != 0? Neither is valid in ring-3. */
    40504064    uint16_t uNewCs = (pCtx->msrSTAR >> MSR_K6_STAR_SYSRET_CS_SS_SHIFT) & X86_SEL_MASK_OFF_RPL;
     
    41274141IEM_CIMPL_DEF_2(iemCImpl_LoadSReg, uint8_t, iSegReg, uint16_t, uSel)
    41284142{
    4129     /*PCPUMCTX        pCtx = IEM_GET_CTX(pVCpu);*/
     4143    PCPUMCTX        pCtx = IEM_GET_CTX(pVCpu);
     4144    IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    41304145    uint16_t       *pSel = iemSRegRef(pVCpu, iSegReg);
    41314146    PCPUMSELREGHID  pHid = iemSRegGetHid(pVCpu, iSegReg);
     
    44494464    if (uSel & X86_SEL_LDT)
    44504465    {
     4466        IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_LDTR);
    44514467        if (   !pCtx->ldtr.Attr.n.u1Present
    44524468            || (uSel | X86_SEL_RPL_LDT) > pCtx->ldtr.u32Limit )
     
    44564472    else
    44574473    {
     4474        IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_GDTR);
    44584475        if ((uSel | X86_SEL_RPL_LDT) > pCtx->gdtr.cbGdt)
    44594476            return VINF_IEM_SELECTOR_NOT_OK;
     
    46934710                pCtx->gdtr.cbGdt = cbLimit;
    46944711                pCtx->gdtr.pGdt  = GCPtrBase;
     4712                pCtx->fExtrn     &= ~CPUMCTX_EXTRN_GDTR;
    46954713            }
    46964714            if (rcStrict == VINF_SUCCESS)
     
    47284746
    47294747    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     4748    IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_GDTR);
    47304749    VBOXSTRICTRC rcStrict = iemMemStoreDataXdtr(pVCpu, pCtx->gdtr.cbGdt, pCtx->gdtr.pGdt, iEffSeg, GCPtrEffDst);
    47314750    if (rcStrict == VINF_SUCCESS)
     
    47734792                pCtx->idtr.cbIdt = cbLimit;
    47744793                pCtx->idtr.pIdt  = GCPtrBase;
     4794                pCtx->fExtrn     &= ~CPUMCTX_EXTRN_IDTR;
    47754795            }
    47764796            iemRegAddToRipAndClearRF(pVCpu, cbInstr);
     
    48074827
    48084828    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     4829    IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_IDTR);
    48094830    VBOXSTRICTRC rcStrict = iemMemStoreDataXdtr(pVCpu, pCtx->idtr.cbIdt, pCtx->idtr.pIdt, iEffSeg, GCPtrEffDst);
    48104831    if (rcStrict == VINF_SUCCESS)
     
    48554876        }
    48564877
    4857         Log(("lldt %04x: Loading NULL selector.\n",  uNewLdt));
     4878        Log(("lldt %04x: Loading NULL selector.\n", uNewLdt));
     4879        pCtx->fExtrn &= ~CPUMCTX_EXTRN_LDTR;
    48584880        if (!IEM_FULL_VERIFICATION_ENABLED(pVCpu))
    48594881            CPUMSetGuestLDTR(pVCpu, uNewLdt);
     
    48874909     * Read the descriptor.
    48884910     */
     4911    IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_LDTR | CPUMCTX_EXTRN_GDTR);
    48894912    IEMSELDESC Desc;
    48904913    VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pVCpu, &Desc, uNewLdt, X86_XCPT_GP); /** @todo Correct exception? */
     
    49985021     * Read the descriptor.
    49995022     */
     5023    IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_LDTR | CPUMCTX_EXTRN_GDTR | CPUMCTX_EXTRN_TR);
    50005024    IEMSELDESC Desc;
    50015025    VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pVCpu, &Desc, uNewTr, X86_XCPT_GP); /** @todo Correct exception? */
     
    51085132    {
    51095133        case 0:
     5134            IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR0);
    51105135            crX = pCtx->cr0;
    51115136            if (IEM_GET_TARGET_CPU(pVCpu) <= IEMTARGETCPU_386)
    51125137                crX |= UINT32_C(0x7fffffe0); /* All reserved CR0 flags are set on a 386, just like MSW on 286. */
    51135138            break;
    5114         case 2: crX = pCtx->cr2; break;
    5115         case 3: crX = pCtx->cr3; break;
    5116         case 4: crX = pCtx->cr4; break;
     5139        case 2:
     5140            IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_CR2);
     5141            crX = pCtx->cr2;
     5142            break;
     5143        case 3:
     5144            IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR3);
     5145            crX = pCtx->cr3;
     5146            break;
     5147        case 4:
     5148            IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR4);
     5149            crX = pCtx->cr4;
     5150            break;
    51175151        case 8:
    51185152        {
     5153            IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_APIC_TPR);
    51195154#ifdef VBOX_WITH_NESTED_HWVIRT_SVM
    51205155            if (CPUMIsGuestInSvmNestedHwVirtMode(pCtx))
     
    51795214             * Perform checks.
    51805215             */
     5216            IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR0);
     5217            pCtx->fExtrn &= ~CPUMCTX_EXTRN_LDTR;
     5218
    51815219            uint64_t const uOldCrX = pCtx->cr0;
    51825220            uint32_t const fValid  = X86_CR0_PE | X86_CR0_MP | X86_CR0_EM | X86_CR0_TS
     
    53335371            }
    53345372            pCtx->cr2 = uNewCrX;
     5373            pCtx->fExtrn &= ~CPUMCTX_EXTRN_CR2;
    53355374            rcStrict  = VINF_SUCCESS;
    53365375            break;
     
    53485387        case 3:
    53495388        {
     5389            IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR3);
     5390
    53505391            /* clear bit 63 from the source operand and indicate no invalidations are required. */
    53515392            if (   (pCtx->cr4 & X86_CR4_PCIDE)
     
    54185459        case 4:
    54195460        {
     5461            IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR4);
    54205462            uint64_t const uOldCrX = pCtx->cr4;
    54215463
     
    55195561        case 8:
    55205562        {
     5563            IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_APIC_TPR);
    55215564            if (uNewCrX & ~(uint64_t)0xf)
    55225565            {
     
    56105653     * Compose the new CR0 value and call common worker.
    56115654     */
     5655    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR0);
    56125656    uint64_t uNewCr0 = pCtx->cr0     & ~(X86_CR0_MP | X86_CR0_EM | X86_CR0_TS);
    56135657    uNewCr0 |= u16NewMsw & (X86_CR0_PE | X86_CR0_MP | X86_CR0_EM | X86_CR0_TS);
     
    56255669
    56265670    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     5671    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR0);
    56275672    uint64_t uNewCr0 = pCtx->cr0;
    56285673    uNewCr0 &= ~X86_CR0_TS;
     
    56495694        return iemRaiseGeneralProtectionFault0(pVCpu);
    56505695    Assert(!pCtx->eflags.Bits.u1VM);
     5696    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_DR7 | CPUMCTX_EXTRN_CR0);
    56515697
    56525698    if (   (iDrReg == 4 || iDrReg == 5)
     
    56705716    switch (iDrReg)
    56715717    {
    5672         case 0: drX = pCtx->dr[0]; break;
    5673         case 1: drX = pCtx->dr[1]; break;
    5674         case 2: drX = pCtx->dr[2]; break;
    5675         case 3: drX = pCtx->dr[3]; break;
     5718        case 0:
     5719            IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_DR0_DR3);
     5720            drX = pCtx->dr[0];
     5721            break;
     5722        case 1:
     5723            IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_DR0_DR3);
     5724            drX = pCtx->dr[1];
     5725            break;
     5726        case 2:
     5727            IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_DR0_DR3);
     5728            drX = pCtx->dr[2];
     5729            break;
     5730        case 3:
     5731            IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_DR0_DR3);
     5732            drX = pCtx->dr[3];
     5733            break;
    56765734        case 6:
    56775735        case 4:
     5736            IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_DR6);
    56785737            drX = pCtx->dr[6];
    56795738            drX |= X86_DR6_RA1_MASK;
     
    56825741        case 7:
    56835742        case 5:
     5743            IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_DR7);
    56845744            drX = pCtx->dr[7];
    56855745            drX |=X86_DR7_RA1_MASK;
     
    57275787        return iemRaiseGeneralProtectionFault0(pVCpu);
    57285788    Assert(!pCtx->eflags.Bits.u1VM);
     5789    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_DR7 | CPUMCTX_EXTRN_CR4);
    57295790
    57305791    if (iDrReg == 4 || iDrReg == 5)
     
    58065867     * Do the actual setting.
    58075868     */
     5869    if (iDrReg < 4)
     5870        IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_DR0_DR3);
     5871    else if (iDrReg == 6)
     5872        IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_DR6);
    58085873    if (!IEM_VERIFICATION_ENABLED(pVCpu))
    58095874    {
     
    58315896        return iemRaiseGeneralProtectionFault0(pVCpu);
    58325897    Assert(!IEM_GET_CTX(pVCpu)->eflags.Bits.u1VM);
     5898    IEM_CTX_ASSERT(IEM_GET_CTX(pVCpu), CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_CR3 | CPUMCTX_EXTRN_CR4 | CPUMCTX_EXTRN_EFER);
    58335899
    58345900    if (IEM_IS_SVM_CTRL_INTERCEPT_SET(pVCpu, SVM_CTRL_INTERCEPT_INVLPG))
     
    58835949        return iemRaiseGeneralProtectionFault0(pVCpu);
    58845950    }
     5951    IEM_CTX_ASSERT(IEM_GET_CTX(pVCpu), CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_CR3 | CPUMCTX_EXTRN_CR4 | CPUMCTX_EXTRN_EFER);
    58855952
    58865953    /*
     
    59706037        return iemRaiseUndefinedOpcode(pVCpu);
    59716038
     6039    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR4);
    59726040    if (   (pCtx->cr4 & X86_CR4_TSD)
    59736041        && pVCpu->iem.s.uCpl != 0)
     
    60156083        return iemRaiseUndefinedOpcode(pVCpu);
    60166084
     6085    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR4);
    60176086    if (   (pCtx->cr4 & X86_CR4_TSD)
    60186087        && pVCpu->iem.s.uCpl != 0)
     
    60336102     * Query the MSR first in case of trips to ring-3.
    60346103     */
     6104    IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_TSC_AUX);
    60356105    VBOXSTRICTRC rcStrict = CPUMQueryGuestMsr(pVCpu, MSR_K8_TSC_AUX, &pCtx->rcx);
    60366106    if (rcStrict == VINF_SUCCESS)
     
    60606130{
    60616131    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     6132    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR4);
     6133
    60626134    if (   pVCpu->iem.s.uCpl != 0
    60636135        && !(pCtx->cr4 & X86_CR4_PCE))
     
    61116183    }
    61126184#endif
     6185
     6186    IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_ALL_MSRS);
    61136187
    61146188    rcStrict = CPUMQueryGuestMsr(pVCpu, pCtx->ecx, &uValue.u);
     
    61796253#endif
    61806254
     6255    IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_ALL_MSRS);
     6256
    61816257    if (!IEM_VERIFICATION_ENABLED(pVCpu))
    61826258        rcStrict = CPUMSetGuestMsr(pVCpu, pCtx->ecx, uValue.u);
     
    62956371                        || DBGFBpIsHwIoArmed(pVCpu->CTX_SUFF(pVM))))
    62966372        {
     6373            IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_DR0_DR3 | CPUMCTX_EXTRN_DR6);
    62976374            rcStrict = DBGFBpCheckIo(pVCpu->CTX_SUFF(pVM), pVCpu, pCtx, u16Port, cbReg);
    62986375            if (rcStrict == VINF_EM_RAW_GUEST_TRAP)
     
    63926469                        || DBGFBpIsHwIoArmed(pVCpu->CTX_SUFF(pVM))))
    63936470        {
     6471            IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_DR0_DR3 | CPUMCTX_EXTRN_DR6);
    63946472            rcStrict = DBGFBpCheckIo(pVCpu->CTX_SUFF(pVM), pVCpu, pCtx, u16Port, cbReg);
    63956473            if (rcStrict == VINF_EM_RAW_GUEST_TRAP)
     
    64206498    uint32_t        fEfl    = IEMMISC_GET_EFL(pVCpu, pCtx);
    64216499    uint32_t const  fEflOld = fEfl;
     6500
     6501    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_CR4);
    64226502    if (pCtx->cr0 & X86_CR0_PE)
    64236503    {
     
    64636543    uint32_t const  fEflOld = fEfl;
    64646544
     6545    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_CR4);
    64656546    if (pCtx->cr0 & X86_CR0_PE)
    64666547    {
     
    66756756     */
    66766757    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     6758    IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_OTHER_MSRS);
    66776759    uint64_t uOtherGsBase = pCtx->msrKERNELGSBASE;
    66786760    pCtx->msrKERNELGSBASE = pCtx->gs.u64Base;
     
    66986780    }
    66996781
     6782    IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_ALL_MSRS);
    67006783    CPUMGetGuestCpuId(pVCpu, pCtx->eax, pCtx->ecx, &pCtx->eax, &pCtx->ebx, &pCtx->ecx, &pCtx->edx);
    67016784    pCtx->rax &= UINT32_C(0xffffffff);
     
    70127095{
    70137096    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     7097    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR4);
    70147098    if (pCtx->cr4 & X86_CR4_OSXSAVE)
    70157099    {
     
    70267110
    70277111        }
     7112        IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_XCRx);
    70287113        pCtx->rax = RT_LO_U32(pCtx->aXcr[uEcx]);
    70297114        pCtx->rdx = RT_HI_U32(pCtx->aXcr[uEcx]);
     
    70547139        if (pVCpu->iem.s.uCpl == 0)
    70557140        {
     7141            IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_XCRx);
     7142
    70567143            uint32_t uEcx = pCtx->ecx;
    70577144            uint64_t uNewValue = RT_MAKE_U64(pCtx->eax, pCtx->edx);
     
    72017288{
    72027289    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     7290    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_X87);
    72037291
    72047292    if (pCtx->cr0 & (X86_CR0_EM | X86_CR0_TS))
     
    72387326{
    72397327    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     7328    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX);
    72407329
    72417330    /*
     
    73427431{
    73437432    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     7433    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX);
    73447434
    73457435    /*
     
    74567546{
    74577547    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     7548    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    74587549
    74597550    /*
     
    76127703{
    76137704    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     7705    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    76147706
    76157707    /*
     
    78167908{
    78177909    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     7910    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX);
    78187911
    78197912    /*
     
    78507943{
    78517944    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     7945    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_XCRx);
    78527946
    78537947    /*
     
    78867980{
    78877981    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     7982    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX);
    78887983
    78897984    /*
     
    79318026static void iemCImplCommonFpuStoreEnv(PVMCPU pVCpu, IEMMODE enmEffOpSize, RTPTRUNION uPtr, PCCPUMCTX pCtx)
    79328027{
     8028    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_X87);
    79338029    PCX86FXSTATE pSrcX87 = &pCtx->CTX_SUFF(pXState)->x87;
    79348030    if (enmEffOpSize == IEMMODE_16BIT)
     
    79948090static void iemCImplCommonFpuRestoreEnv(PVMCPU pVCpu, IEMMODE enmEffOpSize, RTCPTRUNION uPtr, PCPUMCTX pCtx)
    79958091{
     8092    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_X87);
    79968093    PX86FXSTATE pDstX87 = &pCtx->CTX_SUFF(pXState)->x87;
    79978094    if (enmEffOpSize == IEMMODE_16BIT)
     
    80948191{
    80958192    PCPUMCTX     pCtx = IEM_GET_CTX(pVCpu);
     8193    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_X87);
     8194
    80968195    RTPTRUNION   uPtr;
    80978196    VBOXSTRICTRC rcStrict = iemMemMap(pVCpu, &uPtr.pv, enmEffOpSize == IEMMODE_16BIT ? 94 : 108,
     
    82078306{
    82088307    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     8308    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_X87);
    82098309
    82108310    /** @todo Testcase: Check what happens when trying to load X86_FCW_PC_RSVD. */
     
    82338333{
    82348334    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     8335    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_X87);
    82358336
    82368337    PX86FXSTATE pFpuCtx = &pCtx->CTX_SUFF(pXState)->x87;
     
    82838384    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
    82848385    Assert(iStReg < 8);
     8386    IEM_CTX_ASSERT(pCtx, CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_X87);
    82858387
    82868388    /*
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImplStrInstr.cpp.h

    r72209 r72484  
    168168    }
    169169
     170    IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_SREG_FROM_IDX(iEffSeg) | CPUMCTX_EXTRN_ES);
     171
    170172    PCCPUMSELREGHID pSrc1Hid     = iemSRegGetHid(pVCpu, iEffSeg);
    171173    uint64_t        uSrc1Base;
     
    337339    }
    338340
     341    IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_SREG_FROM_IDX(iEffSeg) | CPUMCTX_EXTRN_ES);
     342
    339343    PCCPUMSELREGHID pSrc1Hid = iemSRegGetHid(pVCpu, iEffSeg);
    340344    uint64_t        uSrc1Base;
     
    506510    }
    507511
     512    IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_ES);
    508513    uint64_t        uBaseAddr;
    509514    VBOXSTRICTRC rcStrict = iemMemSegCheckReadAccessEx(pVCpu, iemSRegUpdateHid(pVCpu, &pCtx->es), X86_SREG_ES, &uBaseAddr);
     
    638643    }
    639644
     645    IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_ES);
    640646    uint64_t        uBaseAddr;
    641647    VBOXSTRICTRC rcStrict = iemMemSegCheckReadAccessEx(pVCpu, iemSRegUpdateHid(pVCpu, &pCtx->es), X86_SREG_ES, &uBaseAddr);
     
    771777    }
    772778
     779    IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_SREG_FROM_IDX(iEffSeg) | CPUMCTX_EXTRN_ES);
     780
    773781    PCCPUMSELREGHID pSrcHid = iemSRegGetHid(pVCpu, iEffSeg);
    774782    uint64_t        uSrcBase;
     
    945953    }
    946954
     955    IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_ES);
     956
    947957    uint64_t        uBaseAddr;
    948958    VBOXSTRICTRC rcStrict = iemMemSegCheckWriteAccessEx(pVCpu, iemSRegUpdateHid(pVCpu, &pCtx->es), X86_SREG_ES, &uBaseAddr);
     
    10781088    }
    10791089
     1090    IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_SREG_FROM_IDX(iEffSeg));
    10801091    PCCPUMSELREGHID pSrcHid = iemSRegGetHid(pVCpu, iEffSeg);
    10811092    uint64_t        uBaseAddr;
     
    12781289    PCPUMCTX    pCtx  = IEM_GET_CTX(pVCpu);
    12791290
     1291    IEM_CTX_IMPORT_RET(pVCpu, pCtx, CPUMCTX_EXTRN_ES | CPUMCTX_EXTRN_TR);
     1292
    12801293    /*
    12811294     * Setup.
     
    12851298    if (!fIoChecked)
    12861299    {
     1300/** @todo check if this is too early for ecx=0. */
    12871301        rcStrict = iemHlpCheckPortIOPermission(pVCpu, pCtx, u16Port, OP_SIZE / 8);
    12881302        if (rcStrict != VINF_SUCCESS)
     
    15501564    if (!fIoChecked)
    15511565    {
     1566/** @todo check if this is too early for ecx=0. */
    15521567        rcStrict = iemHlpCheckPortIOPermission(pVCpu, pCtx, u16Port, OP_SIZE / 8);
    15531568        if (rcStrict != VINF_SUCCESS)
  • trunk/src/VBox/VMM/VMMAll/NEMAll.cpp

    r72343 r72484  
    122122}
    123123
     124
     125#ifndef VBOX_WITH_NATIVE_NEM
     126VMM_INT_DECL(int) NEMImportStateOnDemand(PVMCPU pVCpu, PCPUMCTX pCtx, uint64_t fWhat)
     127{
     128    RT_NOREF(pVCpu, pCtx, fWhat);
     129    return VERR_NEM_IPE_9;
     130}
     131#endif
     132
  • trunk/src/VBox/VMM/VMMAll/NEMAllNativeTemplate-win.cpp.h

    r72472 r72484  
    238238            ADD_REG64(WHvX64RegisterCr4, pCtx->cr4);
    239239    }
    240 
    241     /** @todo CR8/TPR */
    242     ADD_REG64(WHvX64RegisterCr8, CPUMGetGuestCR8(pVCpu));
     240    if (fWhat & CPUMCTX_EXTRN_APIC_TPR)
     241        ADD_REG64(WHvX64RegisterCr8, CPUMGetGuestCR8(pVCpu));
    243242
    244243    /* Debug registers. */
     
    537536            aenmNames[iReg++] = WHvX64RegisterCr4;
    538537    }
    539     aenmNames[iReg++] = WHvX64RegisterCr8; /// @todo CR8/TPR
     538    if (fWhat & CPUMCTX_EXTRN_APIC_TPR)
     539        aenmNames[iReg++] = WHvX64RegisterCr8;
    540540
    541541    /* Debug registers. */
     
    830830        }
    831831    }
    832 
    833     /// @todo CR8/TPR
    834     Assert(aenmNames[iReg] == WHvX64RegisterCr8);
    835     APICSetTpr(pVCpu, (uint8_t)aValues[iReg].Reg64 << 4);
    836     iReg++;
     832    if (fWhat & CPUMCTX_EXTRN_APIC_TPR)
     833    {
     834        Assert(aenmNames[iReg] == WHvX64RegisterCr8);
     835        APICSetTpr(pVCpu, (uint8_t)aValues[iReg].Reg64 << 4);
     836        iReg++;
     837    }
    837838
    838839    /* Debug registers. */
     
    10631064
    10641065#endif /* !IN_RING0 */
     1066
     1067
     1068/**
     1069 * Interface for importing state on demand (used by IEM).
     1070 *
     1071 * @returns VBox status code.
     1072 * @param   pVCpu       The cross context CPU structure.
     1073 * @param   pCtx        The target CPU context.
     1074 * @param   fWhat       What to import, CPUMCTX_EXTRN_XXX.
     1075 */
     1076VMM_INT_DECL(int) NEMImportStateOnDemand(PVMCPU pVCpu, PCPUMCTX pCtx, uint64_t fWhat)
     1077{
     1078    STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatImportOnDemand);
     1079
     1080#ifdef IN_RING0
     1081    /** @todo improve and secure this translation */
     1082    PGVM pGVM = GVMMR0ByHandle(pVCpu->pVMR0->hSelf);
     1083    AssertReturn(pGVM, VERR_INVALID_VMCPU_HANDLE);
     1084    VMCPUID idCpu = pVCpu->idCpu;
     1085    ASMCompilerBarrier();
     1086    AssertReturn(idCpu < pGVM->cCpus, VERR_INVALID_VMCPU_HANDLE);
     1087
     1088    return nemR0WinImportState(pGVM, &pGVM->aCpus[idCpu], pCtx, fWhat);
     1089#else
     1090    return nemHCWinCopyStateFromHyperV(pVCpu->pVMR3, pVCpu, pCtx, fWhat);
     1091#endif
     1092}
    10651093
    10661094
     
    15991627#else
    16001628        RT_NOREF(pGVCpu, pszCaller);
    1601         int rc = nemHCWinCopyStateFromHyperV(pVCpu->pVMR3, pVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM);
     1629        int rc = nemHCWinCopyStateFromHyperV(pVCpu->pVMR3, pVCpu, pCtx, fWhat);
    16021630        AssertRCReturn(rc, rc);
    16031631#endif
     
    17591787    VBOXSTRICTRC rcStrict;
    17601788# ifdef IN_RING0
    1761     rcStrict = nemR0WinImportStateStrict(pGVCpu->pGVM, pGVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM, "MemExit");
     1789    rcStrict = nemR0WinImportStateStrict(pGVCpu->pGVM, pGVCpu, pCtx,
     1790                                         NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM | CPUMCTX_EXTRN_DS | CPUMCTX_EXTRN_ES, "MemExit");
    17621791    if (rcStrict != VINF_SUCCESS)
    17631792        return rcStrict;
    17641793# else
    1765     rc = nemHCWinCopyStateFromHyperV(pVM, pVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM);
     1794    rc = nemHCWinCopyStateFromHyperV(pVM, pVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM | CPUMCTX_EXTRN_DS | CPUMCTX_EXTRN_ES);
    17661795    AssertRCReturn(rc, rc);
    17671796    NOREF(pGVCpu);
     
    18451874     */
    18461875    nemR3WinCopyStateFromX64Header(pVCpu, pCtx, &pExit->VpContext);
    1847     rc = nemHCWinCopyStateFromHyperV(pVM, pVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM);
     1876    rc = nemHCWinCopyStateFromHyperV(pVM, pVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM | CPUMCTX_EXTRN_DS | CPUMCTX_EXTRN_ES);
    18481877    AssertRCReturn(rc, rc);
    18491878
     
    21142143}
    21152144#endif /* IN_RING3 && !NEM_WIN_USE_OUR_OWN_RUN_API */
     2145
    21162146
    21172147#ifdef NEM_WIN_USE_OUR_OWN_RUN_API
     
    23982428     * If we get down here, we're supposed to #GP(0).
    23992429     */
    2400     rcStrict = nemHCWinImportStateIfNeededStrict(pVCpu, pGVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM, "MSR");
     2430    rcStrict = nemHCWinImportStateIfNeededStrict(pVCpu, pGVCpu, pCtx,
     2431                                                 NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM | CPUMCTX_EXTRN_ALL_MSRS, "MSR");
    24012432    if (rcStrict == VINF_SUCCESS)
    24022433    {
     
    25052536     * If we get down here, we're supposed to #GP(0).
    25062537     */
    2507     rcStrict = nemHCWinImportStateIfNeededStrict(pVCpu, NULL, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM, "MSR");
     2538    rcStrict = nemHCWinImportStateIfNeededStrict(pVCpu, NULL, pCtx,
     2539                                                 NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM | CPUMCTX_EXTRN_ALL_MSRS, "MSR");
    25082540    if (rcStrict == VINF_SUCCESS)
    25092541    {
     
    26712703          pMsg->ExceptionVector, pMsg->ErrorCode, pMsg->ExceptionParameter));
    26722704    nemHCWinCopyStateFromExceptionMessage(pVCpu, pMsg, pCtx, true /*fClearXcpt*/);
    2673     VBOXSTRICTRC rcStrict = nemHCWinImportStateIfNeededStrict(pVCpu, pGVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM, "Xcpt");
     2705    uint64_t fWhat = NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM;
     2706    if (pMsg->ExceptionVector == X86_XCPT_DB)
     2707        fWhat |= CPUMCTX_EXTRN_DR0_DR3 | CPUMCTX_EXTRN_DR7 | CPUMCTX_EXTRN_DR6;
     2708    VBOXSTRICTRC rcStrict = nemHCWinImportStateIfNeededStrict(pVCpu, pGVCpu, pCtx, fWhat, "Xcpt");
    26742709    if (rcStrict != VINF_SUCCESS)
    26752710        return rcStrict;
     
    27662801          pExit->VpException.ErrorCode, pExit->VpException.ExceptionParameter ));
    27672802    nemR3WinCopyStateFromExceptionMessage(pVCpu, pExit, pCtx, true /*fClearXcpt*/);
    2768     VBOXSTRICTRC rcStrict = nemHCWinImportStateIfNeededStrict(pVCpu, NULL, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM, "Xcpt");
     2803    uint64_t fWhat = NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM;
     2804    if (pMsg->ExceptionVector == X86_XCPT_DB)
     2805        fWhat |= CPUMCTX_EXTRN_DR0_DR3 | CPUMCTX_EXTRN_DR7 | CPUMCTX_EXTRN_DR6;
     2806    VBOXSTRICTRC rcStrict = nemHCWinImportStateIfNeededStrict(pVCpu, NULL, pCtx, fWhat, "Xcpt");
    27692807    if (rcStrict != VINF_SUCCESS)
    27702808        return rcStrict;
     
    32593297    }
    32603298    else
     3299    {
     3300        STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatStopCpuPendingOdd);
    32613301        Log8(("nemHCWinStopCpu: Stopped the CPU (rcStrict=%Rrc) - 1st VidMessageSlotHandleAndGetNext got VidMessageStopRequestComplete.\n",
    32623302              VBOXSTRICTRC_VAL(rcStrict) ));
     3303    }
    32633304    return rcStrict;
    32643305}
     
    32843325
    32853326    /*
    3286      * First update APIC.
     3327     * First update APIC.  We ASSUME this won't need TPR/CR8.
    32873328     */
    32883329    if (VMCPU_FF_TEST_AND_CLEAR(pVCpu, VMCPU_FF_UPDATE_APIC))
     
    33093350    if (pCtx->fExtrn & fNeedExtrn)
    33103351    {
    3311         VBOXSTRICTRC rcStrict = nemHCWinImportStateIfNeededStrict(pVCpu, pGVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM, "IntFF");
     3352        VBOXSTRICTRC rcStrict = nemHCWinImportStateIfNeededStrict(pVCpu, pGVCpu, pCtx,
     3353                                                                  NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM_XCPT, "IntFF");
    33123354        if (rcStrict != VINF_SUCCESS)
    33133355            return rcStrict;
     
    33243366            && !VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_BLOCK_NMIS))
    33253367        {
    3326             VBOXSTRICTRC rcStrict = nemHCWinImportStateIfNeededStrict(pVCpu, pGVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM, "NMI");
     3368            VBOXSTRICTRC rcStrict = nemHCWinImportStateIfNeededStrict(pVCpu, pGVCpu, pCtx,
     3369                                                                      NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM_XCPT, "NMI");
    33273370            if (rcStrict == VINF_SUCCESS)
    33283371            {
     
    33453388            && pCtx->rflags.Bits.u1IF)
    33463389        {
    3347             VBOXSTRICTRC rcStrict = nemHCWinImportStateIfNeededStrict(pVCpu, pGVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM, "NMI");
     3390            AssertCompile(NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM_XCPT & CPUMCTX_EXTRN_APIC_TPR);
     3391            VBOXSTRICTRC rcStrict = nemHCWinImportStateIfNeededStrict(pVCpu, pGVCpu, pCtx,
     3392                                                                      NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM_XCPT, "NMI");
    33483393            if (rcStrict == VINF_SUCCESS)
    33493394            {
  • trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r72462 r72484  
    71547154             in the VT-x part of the sources instead of the generic stuff. */
    71557155    int rc;
    7156     if (pVCpu->CTX_SUFF(pVM)->hm.s.vmx.fSupported)
     7156    PVM pVM = pVCpu->CTX_SUFF(pVM);
     7157    if (   pVM->hm.s.vmx.fSupported
     7158        && VM_IS_HM_ENABLED(pVM))
    71577159        rc = hmR0VmxSaveGuestState(pVCpu, pMixedCtx);
    71587160    else
  • trunk/src/VBox/VMM/VMMR0/NEMR0Native-win.cpp

    r72412 r72484  
    831831        }
    832832    }
    833     /** @todo CR8/TPR */
    834     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
    835     pInput->Elements[iReg].Name                 = HvX64RegisterCr8;
    836     pInput->Elements[iReg].Value.Reg64          = CPUMGetGuestCR8(pVCpu);
    837     iReg++;
     833    if (fWhat & CPUMCTX_EXTRN_APIC_TPR)
     834    {
     835        HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     836        pInput->Elements[iReg].Name                 = HvX64RegisterCr8;
     837        pInput->Elements[iReg].Value.Reg64          = CPUMGetGuestCR8(pVCpu);
     838        iReg++;
     839    }
    838840
    839841    /** @todo does HvX64RegisterXfem mean XCR0? What about the related MSR. */
     
    13891391            pInput->Names[iReg++] = HvX64RegisterCr4;
    13901392    }
    1391     pInput->Names[iReg++] = HvX64RegisterCr8; /// @todo CR8/TPR
     1393    if (fWhat & CPUMCTX_EXTRN_APIC_TPR)
     1394        pInput->Names[iReg++] = HvX64RegisterCr8;
    13921395
    13931396    /* Debug registers. */
     
    17301733        }
    17311734    }
    1732 
    1733     /// @todo CR8/TPR
    1734     Assert(pInput->Names[iReg] == HvX64RegisterCr8);
    1735     APICSetTpr(pVCpu, (uint8_t)paValues[iReg].Reg64 << 4);
    1736     iReg++;
     1735    if (fWhat & CPUMCTX_EXTRN_APIC_TPR)
     1736    {
     1737        Assert(pInput->Names[iReg] == HvX64RegisterCr8);
     1738        APICSetTpr(pVCpu, (uint8_t)paValues[iReg].Reg64 << 4);
     1739        iReg++;
     1740    }
    17371741
    17381742    /* Debug registers. */
  • trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp

    r72475 r72484  
    12271227                            STAMR3RegisterF(pVM, &pNemCpu->StatStopCpuSuccess,      STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of successful CPU stops",         "/NEM/CPU%u/StopCpuSuccess", iCpu);
    12281228                            STAMR3RegisterF(pVM, &pNemCpu->StatStopCpuPending,      STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of pending CPU stops",            "/NEM/CPU%u/StopCpuPending", iCpu);
     1229                            STAMR3RegisterF(pVM, &pNemCpu->StatStopCpuPendingOdd,   STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of odd pending CPU stops (see code)", "/NEM/CPU%u/StopCpuPendingOdd", iCpu);
    12291230                            STAMR3RegisterF(pVM, &pNemCpu->StatCancelChangedState,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of cancel changed state",         "/NEM/CPU%u/CancelChangedState", iCpu);
    12301231                            STAMR3RegisterF(pVM, &pNemCpu->StatCancelAlertedThread, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of cancel alerted EMT",           "/NEM/CPU%u/CancelAlertedEMT", iCpu);
     
    12331234                            STAMR3RegisterF(pVM, &pNemCpu->StatBreakOnCancel,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of cancel execution breaks",      "/NEM/CPU%u/BreakOnCancel", iCpu);
    12341235                            STAMR3RegisterF(pVM, &pNemCpu->StatBreakOnStatus,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of status code breaks",           "/NEM/CPU%u/BreakOnStatus", iCpu);
     1236                            STAMR3RegisterF(pVM, &pNemCpu->StatImportOnDemand,      STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of on-demand state imports",      "/NEM/CPU%u/ImportOnDemand", iCpu);
    12351237                        }
    12361238
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r69111 r72484  
    789789#endif
    790790
     791/** @def IEM_CTX_ASSERT
     792 * Asserts that the @a a_fExtrnMbz is present in the CPU context.
     793 * @param   a_pCtx          The CPUMCTX structure.
     794 * @param   a_fExtrnMbz     The mask of CPUMCTX_EXTRN_XXX flags that must be zero.
     795 */
     796#define IEM_CTX_ASSERT(a_pCtx, a_fExtrnMbz)     Assert(!((a_pCtx)->fExtrn & (a_fExtrnMbz)))
     797
     798/** @def IEM_CTX_IMPORT_RET
     799 * Makes sure the CPU context bits given by @a a_fExtrnImport are imported.
     800 *
     801 * Will call the keep to import the bits as needed.
     802 *
     803 * Returns on import failure.
     804 *
     805 * @param   a_pVCpu         The cross context virtual CPU structure.
     806 * @param   a_pCtx          The CPUMCTX structure.
     807 * @param   a_fExtrnImport  The mask of CPUMCTX_EXTRN_XXX flags to import.
     808 */
     809#define IEM_CTX_IMPORT_RET(a_pVCpu, a_pCtx, a_fExtrnImport) \
     810    if (!((a_pCtx)->fExtrn & (a_fExtrnImport))) \
     811    { /* likely */ } \
     812    else do {  \
     813        int rcCtxImport = iemCtxImport(a_pVCpu, a_pCtx, a_fExtrnImport); \
     814        AssertRCReturn(rcCtxImport, rcCtxImport); \
     815    } while (0)
     816
     817/** @def IEM_CTX_IMPORT_NORET
     818 * Makes sure the CPU context bits given by @a a_fExtrnImport are imported.
     819 *
     820 * Will call the keep to import the bits as needed.
     821 *
     822 * @param   a_pVCpu         The cross context virtual CPU structure.
     823 * @param   a_pCtx          The CPUMCTX structure.
     824 * @param   a_fExtrnImport  The mask of CPUMCTX_EXTRN_XXX flags to import.
     825 */
     826#define IEM_CTX_IMPORT_NORET(a_pVCpu, a_pCtx, a_fExtrnImport) \
     827    if (!((a_pCtx)->fExtrn & (a_fExtrnImport))) \
     828    { /* likely */ } \
     829    else do {  \
     830        int rcCtxImport = iemCtxImport(a_pVCpu, a_pCtx, a_fExtrnImport); \
     831        AssertLogRelRC(rcCtxImport); \
     832    } while (0)
     833
     834/** @def IEM_CTX_IMPORT_JMP
     835 * Makes sure the CPU context bits given by @a a_fExtrnImport are imported.
     836 *
     837 * Will call the keep to import the bits as needed.
     838 *
     839 * Jumps on import failure.
     840 *
     841 * @param   a_pVCpu         The cross context virtual CPU structure.
     842 * @param   a_pCtx          The CPUMCTX structure.
     843 * @param   a_fExtrnImport  The mask of CPUMCTX_EXTRN_XXX flags to import.
     844 */
     845#define IEM_CTX_IMPORT_JMP(a_pVCpu, a_pCtx, a_fExtrnImport) \
     846    if (!((a_pCtx)->fExtrn & (a_fExtrnImport))) \
     847    { /* likely */ } \
     848    else do {  \
     849        int rcCtxImport = iemCtxImport(a_pVCpu, a_pCtx, a_fExtrnImport); \
     850        AssertRCStmt(rcCtxImport, longjmp(*pVCpu->iem.s.CTX_SUFF(pJmpBuf), rcCtxImport)); \
     851    } while (0)
     852
     853int iemCtxImport(PVMCPU pVCpu, PCPUMCTX pCtx, uint64_t fExtrnImport);
     854
     855
    791856/** Gets the current IEMTARGETCPU value.
    792857 * @returns IEMTARGETCPU value.
  • trunk/src/VBox/VMM/include/NEMInternal.h

    r72470 r72484  
    8080
    8181/** The CPUMCTX_EXTRN_XXX mask for IEM. */
    82 # define NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM     (CPUMCTX_EXTRN_ALL | CPUMCTX_EXTRN_NEM_WIN_INHIBIT_INT | CPUMCTX_EXTRN_NEM_WIN_INHIBIT_NMI)
     82# define NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM      (  IEM_CPUMCTX_EXTRN_MUST_MASK | CPUMCTX_EXTRN_NEM_WIN_INHIBIT_INT \
     83                                                  | CPUMCTX_EXTRN_NEM_WIN_INHIBIT_NMI )
     84/** The CPUMCTX_EXTRN_XXX mask for IEM when raising exceptions. */
     85# define NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM_XCPT (IEM_CPUMCTX_EXTRN_XCPT_MASK | NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM)
    8386
    8487/** @name Windows: Interrupt window flags (NEM_WIN_INTW_F_XXX).
     
    261264    STAMCOUNTER                 StatStopCpuSuccess;
    262265    STAMCOUNTER                 StatStopCpuPending;
     266    STAMCOUNTER                 StatStopCpuPendingOdd;
    263267    STAMCOUNTER                 StatCancelChangedState;
    264268    STAMCOUNTER                 StatCancelAlertedThread;
     
    267271    STAMCOUNTER                 StatBreakOnFFPost;
    268272    STAMCOUNTER                 StatBreakOnStatus;
     273    STAMCOUNTER                 StatImportOnDemand;
    269274    /** @} */
    270275#endif /* RT_OS_WINDOWS */
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