VirtualBox

Changeset 71184 in vbox for trunk


Ignore:
Timestamp:
Mar 3, 2018 3:01:59 PM (7 years ago)
Author:
vboxsync
Message:

CPUM,NEM: Introduced CPUMCTX field for tracking state that's not in the structure. Made NEM/win only get/set the register it needs. New NEM runloop based on low level messages, skipping translations. bugref:9044

Location:
trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/cpum.mac

    r70732 r71184  
    257257    .aoffXState         resw    64
    258258    .fWorldSwitcher     resd    1
     259    .fExtrn             resq    1
    259260    alignb 8
    260261    .hwvirt.svm.uMsrHSavePa            resq          1
    261262    .hwvirt.svm.GCPhysVmcb             resq          1
    262263    .hwvirt.svm.pVmcbR0                RTR0PTR_RES   1
     264    alignb 8
    263265    .hwvirt.svm.pVmcbR3                RTR3PTR_RES   1
    264 %if HC_ARCH_BITS == 32
    265     .hwvirt.svm.abPadding0             resb          8
    266 %endif
     266    alignb 8
    267267    .hwvirt.svm.HostState              resb        184
    268268    .hwvirt.svm.u16Padding0            resw          1
     
    271271    .hwvirt.svm.fInterceptEvents       resb          1
    272272    .hwvirt.svm.fHMCachedVmcb          resb          1
     273    alignb 8
    273274    .hwvirt.svm.pvMsrBitmapR0          RTR0PTR_RES   1
     275    alignb 8
    274276    .hwvirt.svm.pvMsrBitmapR3          RTR3PTR_RES   1
     277    alignb 8
    275278    .hwvirt.svm.pvIoBitmapR0           RTR0PTR_RES   1
     279    alignb 8
    276280    .hwvirt.svm.pvIoBitmapR3           RTR3PTR_RES   1
     281    alignb 8
    277282    .hwvirt.svm.HCPhysVmcb             RTHCPHYS_RES  1
    278 %if HC_ARCH_BITS == 32
    279     .hwvirt.svm.abPadding2             resb          16
    280 %endif
    281283    .hwvirt.fLocalForcedActions        resd          1
    282284    .hwvirt.fGif                       resb          1
  • trunk/include/VBox/vmm/cpumctx.h

    r70913 r71184  
    473473    /** 0x2d4 - World switcher flags, CPUMCTX_WSF_XXX. */
    474474    uint32_t                    fWorldSwitcher;
    475 
    476     /** 728 - Hardware virtualization state.   */
     475    /** 0x2d8 - Externalized state tracker, CPUMCTX_EXTRN_XXX.
     476     * Currently only used internally in NEM/win.  */
     477    uint64_t                    fExtrn;
     478
     479    /** 0x2e0 - Hardware virtualization state.   */
    477480    struct
    478481    {
     
    481484            struct
    482485            {
    483                 /** 728 - MSR holding physical address of the Guest's Host-state. */
     486                /** 0x2e0 - MSR holding physical address of the Guest's Host-state. */
    484487                uint64_t            uMsrHSavePa;
    485                 /** 736 - Guest physical address of the nested-guest VMCB. */
     488                /** 0x2e8 - Guest physical address of the nested-guest VMCB. */
    486489                RTGCPHYS            GCPhysVmcb;
    487                 /** 744 - Cache of the nested-guest VMCB - R0 ptr. */
     490                /** 0x2f0 - Cache of the nested-guest VMCB - R0 ptr. */
    488491                R0PTRTYPE(PSVMVMCB) pVmcbR0;
    489                 /** 752 / 748 - Cache of the nested-guest VMCB - R3 ptr. */
     492#if HC_ARCH_BITS == 32
     493                uint32_t            uVmcbR0Padding;
     494#endif
     495                /** 0x2f8 - Cache of the nested-guest VMCB - R3 ptr. */
    490496                R3PTRTYPE(PSVMVMCB) pVmcbR3;
    491497#if HC_ARCH_BITS == 32
    492                 /** NA / 752 - Padding. */
    493                 uint8_t             abPadding0[8];
    494 #endif
    495                 /** 760 - Guest's host-state save area. */
     498                uint32_t            uVmcbR3Padding;
     499#endif
     500                /** 0x300 - Guest's host-state save area. */
    496501                SVMHOSTSTATE        HostState;
    497                 /** 944 - Padding. */
     502                /** 0x3b8 - Padding. */
    498503                uint16_t            u16Padding0;
    499                 /** 946 - Pause filter count. */
     504                /** 0x3ba - Pause filter count. */
    500505                uint16_t            cPauseFilter;
    501                 /** 948 - Pause filter count. */
     506                /** 0x3bc - Pause filter count. */
    502507                uint16_t            cPauseFilterThreshold;
    503                 /** 950 - Whether the injected event is subject to event intercepts. */
     508                /** 0x3be - Whether the injected event is subject to event intercepts. */
    504509                bool                fInterceptEvents;
    505                 /** 951 - Whether parts of the VMCB are cached (and potentially modified) by HM. */
     510                /** 0x3bf - Whether parts of the VMCB are cached (and potentially modified) by HM. */
    506511                bool                fHMCachedVmcb;
    507                 /** 952 - MSR permission bitmap - R0 ptr. */
     512                /** 0x3c0 - MSR permission bitmap - R0 ptr. */
    508513                R0PTRTYPE(void *)   pvMsrBitmapR0;
    509                 /** 960 / 956 - MSR permission bitmap - R3 ptr. */
     514#if HC_ARCH_BITS == 32
     515                uint32_t            uvMsrBitmapR0Padding;
     516#endif
     517                /** 0x3c8 - MSR permission bitmap - R3 ptr. */
    510518                R3PTRTYPE(void *)   pvMsrBitmapR3;
    511                 /** 968 / 960 - IO permission bitmap - R0 ptr. */
     519#if HC_ARCH_BITS == 32
     520                uint32_t            uvMsrBitmapR3Padding;
     521#endif
     522                /** 0x3d0 - IO permission bitmap - R0 ptr. */
    512523                R0PTRTYPE(void *)   pvIoBitmapR0;
    513                 /** 976 / 964 - IO permission bitmap - R3 ptr. */
     524#if HC_ARCH_BITS == 32
     525                uint32_t            uIoBitmapR0Padding;
     526#endif
     527                /** 0x3d8 - IO permission bitmap - R3 ptr. */
    514528                R3PTRTYPE(void *)   pvIoBitmapR3;
    515                 /** 984 / 968 - Host physical address of the nested-guest VMCB.  */
     529#if HC_ARCH_BITS == 32
     530                uint32_t            uIoBitmapR3Padding;
     531#endif
     532                /** 0x3e0 - Host physical address of the nested-guest VMCB.  */
    516533                RTHCPHYS            HCPhysVmcb;
    517 #if HC_ARCH_BITS == 32
    518                 /** NA / 976 - Padding. */
    519                 uint8_t             abPadding2[16];
    520 #endif
    521534            } svm;
    522535#if 0
     
    527540        } CPUM_UNION_NM(s);
    528541
    529         /** 992 - A subset of force flags that are preserved while running
    530          *  the nested-guest. */
     542        /** 0x3e8 - A subset of force flags that are preserved while running the nested-guest. */
    531543        uint32_t                fLocalForcedActions;
    532         /** 996 - Global interrupt flag (always true on nested VMX). */
     544        /** 0x3f0 - Global interrupt flag (always true on nested VMX). */
    533545        bool                    fGif;
    534         /** 997 - Padding. */
    535         uint8_t                 abPadding1[27];
     546        /** 0x3f1 - Padding. */
     547        uint8_t                 abPadding1[19];
    536548    } hwvirt;
    537549    /** @} */
     
    588600AssertCompileMemberOffset(CPUMCTX,                  pXStateRC, 592);
    589601AssertCompileMemberOffset(CPUMCTX,                 aoffXState, 596);
    590 AssertCompileMemberOffset(CPUMCTX, hwvirt, 728);
    591 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.uMsrHSavePa,            728);
    592 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.GCPhysVmcb,             736);
    593 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pVmcbR0,                744);
    594 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pVmcbR3,                HC_ARCH_BITS == 64 ? 752 : 748);
    595 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.HostState,              760);
    596 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.cPauseFilter,           946);
    597 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.cPauseFilterThreshold,  948);
    598 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.fInterceptEvents,       950);
    599 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pvMsrBitmapR0,          952);
    600 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pvMsrBitmapR3,          HC_ARCH_BITS == 64 ? 960 : 956);
    601 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pvIoBitmapR0,           HC_ARCH_BITS == 64 ? 968 : 960);
    602 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pvIoBitmapR3,           HC_ARCH_BITS == 64 ? 976 : 964);
    603 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.HCPhysVmcb,             HC_ARCH_BITS == 64 ? 984 : 968);
    604 AssertCompileMemberOffset(CPUMCTX, hwvirt.fLocalForcedActions,        992);
    605 AssertCompileMemberOffset(CPUMCTX, hwvirt.fGif,                       996);
     602AssertCompileMemberOffset(CPUMCTX, hwvirt, 0x2e0);
     603AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.uMsrHSavePa,            0x2e0);
     604AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pVmcbR0,                0x2f0);
     605AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pVmcbR3,                0x2f8);
     606AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.HostState,              0x300);
     607AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.cPauseFilter,           0x3ba);
     608AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pvMsrBitmapR0,          0x3c0);
     609AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pvIoBitmapR3,           0x3d8);
     610AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.HCPhysVmcb,             0x3e0);
     611AssertCompileMemberOffset(CPUMCTX, hwvirt.fLocalForcedActions,        0x3e8);
    606612AssertCompileMemberAlignment(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pVmcbR0,       8);
    607613AssertCompileMemberAlignment(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pvMsrBitmapR0, 8);
     
    752758/** @} */
    753759
     760/** @name CPUMCTX_EXTRN_XXX
     761 * Used to parts of the CPUM state that is externalized and needs fetching
     762 * before use.
     763 *
     764 * @{ */
     765/** External state keeper: Invalid.  */
     766#define CPUMCTX_EXTRN_KEEPER_INVALID            UINT64_C(0x0000000000000000)
     767/** External state keeper: HM. */
     768#define CPUMCTX_EXTRN_KEEPER_HM                 UINT64_C(0x0000000000000001)
     769/** External state keeper: NEM. */
     770#define CPUMCTX_EXTRN_KEEPER_NEM                UINT64_C(0x0000000000000002)
     771/** External state keeper: REM. */
     772#define CPUMCTX_EXTRN_KEEPER_REM                UINT64_C(0x0000000000000003)
     773/** External state keeper mask. */
     774#define CPUMCTX_EXTRN_KEEPER_MASK               UINT64_C(0x0000000000000003)
     775
     776/** The RIP register value is kept externally. */
     777#define CPUMCTX_EXTRN_RIP                       UINT64_C(0x0000000000000004)
     778/** The CS register values are kept externally. */
     779#define CPUMCTX_EXTRN_CS                        UINT64_C(0x0000000000000008)
     780/** The RFLAGS register values are kept externally. */
     781#define CPUMCTX_EXTRN_RFLAGS                    UINT64_C(0x0000000000000010)
     782
     783/** The RAX register value is kept externally. */
     784#define CPUMCTX_EXTRN_RAX                       UINT64_C(0x0000000000000020)
     785/** The RCX register value is kept externally. */
     786#define CPUMCTX_EXTRN_RCX                       UINT64_C(0x0000000000000040)
     787/** The RDX register value is kept externally. */
     788#define CPUMCTX_EXTRN_RDX                       UINT64_C(0x0000000000000080)
     789/** The RBX register value is kept externally. */
     790#define CPUMCTX_EXTRN_RBX                       UINT64_C(0x0000000000000100)
     791/** The RSP register value is kept externally. */
     792#define CPUMCTX_EXTRN_RSP                       UINT64_C(0x0000000000000200)
     793/** The RBP register value is kept externally. */
     794#define CPUMCTX_EXTRN_RBP                       UINT64_C(0x0000000000000400)
     795/** The RSI register value is kept externally. */
     796#define CPUMCTX_EXTRN_RSI                       UINT64_C(0x0000000000000800)
     797/** The RDI register value is kept externally. */
     798#define CPUMCTX_EXTRN_RDI                       UINT64_C(0x0000000000001000)
     799/** The R8 thru R15 register values are kept externally. */
     800#define CPUMCTX_EXTRN_R8_R15                    UINT64_C(0x0000000000002000)
     801/** General purpose registers mask. */
     802#define CPUMCTX_EXTRN_GPRS_MASK                 UINT64_C(0x0000000000003fe0)
     803
     804/** The SS register values are kept externally. */
     805#define CPUMCTX_EXTRN_SS                        UINT64_C(0x0000000000004000)
     806/** The DS register values are kept externally. */
     807#define CPUMCTX_EXTRN_DS                        UINT64_C(0x0000000000008000)
     808/** The ES register values are kept externally. */
     809#define CPUMCTX_EXTRN_ES                        UINT64_C(0x0000000000010000)
     810/** The FS register values are kept externally. */
     811#define CPUMCTX_EXTRN_FS                        UINT64_C(0x0000000000020000)
     812/** The GS register values are kept externally. */
     813#define CPUMCTX_EXTRN_GS                        UINT64_C(0x0000000000040000)
     814/** Segment registers (includes CS). */
     815#define CPUMCTX_EXTRN_SREG_MASK                 UINT64_C(0x000000000007c008)
     816
     817/** The GDTR register values are kept externally. */
     818#define CPUMCTX_EXTRN_GDTR                      UINT64_C(0x0000000000080000)
     819/** The IDTR register values are kept externally. */
     820#define CPUMCTX_EXTRN_IDTR                      UINT64_C(0x0000000000100000)
     821/** The LDTR register values are kept externally. */
     822#define CPUMCTX_EXTRN_LDTR                      UINT64_C(0x0000000000200000)
     823/** The TR register values are kept externally. */
     824#define CPUMCTX_EXTRN_TR                        UINT64_C(0x0000000000400000)
     825/** Table register mask. */
     826#define CPUMCTX_EXTRN_TABLE_MASK                UINT64_C(0x0000000000780000)
     827
     828/** The CR0 register value is kept externally. */
     829#define CPUMCTX_EXTRN_CR0                       UINT64_C(0x0000000000800000)
     830/** The CR2 register value is kept externally. */
     831#define CPUMCTX_EXTRN_CR2                       UINT64_C(0x0000000001000000)
     832/** The CR3 register value is kept externally. */
     833#define CPUMCTX_EXTRN_CR3                       UINT64_C(0x0000000002000000)
     834/** The CR4 register value is kept externally. */
     835#define CPUMCTX_EXTRN_CR4                       UINT64_C(0x0000000004000000)
     836/** Control register mask. */
     837#define CPUMCTX_EXTRN_CR_MASK                   UINT64_C(0x0000000007800000)
     838/** The EFER register value is kept externally. */
     839#define CPUMCTX_EXTRN_EFER                      UINT64_C(0x0000000008000000)
     840
     841/** The DR0, DR1, DR2 and DR3 register values are kept externally. */
     842#define CPUMCTX_EXTRN_DR0_DR3                   UINT64_C(0x0000000010000000)
     843/** The DR6 register value is kept externally. */
     844#define CPUMCTX_EXTRN_DR6                       UINT64_C(0x0000000020000000)
     845/** The DR7 register value is kept externally. */
     846#define CPUMCTX_EXTRN_DR7                       UINT64_C(0x0000000040000000)
     847/** Debug register mask. */
     848#define CPUMCTX_EXTRN_DR_MASK                   UINT64_C(0x0000000070000000)
     849
     850/** The XSAVE_C_X87 state is kept externally. */
     851#define CPUMCTX_EXTRN_X87                       UINT64_C(0x0000000080000000)
     852/** The XSAVE_C_SSE, XSAVE_C_YMM, XSAVE_C_ZMM_HI256, XSAVE_C_ZMM_16HI and
     853 * XSAVE_C_OPMASK state is kept externally. */
     854#define CPUMCTX_EXTRN_SSE_AVX                   UINT64_C(0x0000000100000000)
     855/** The state of XSAVE components not covered by CPUMCTX_EXTRN_X87 and
     856 * CPUMCTX_EXTRN_SEE_AVX is kept externally. */
     857#define CPUMCTX_EXTRN_OTHER_XSAVE               UINT64_C(0x0000000200000000)
     858/** The state of XCR0 and XCR1 register values are kept externally. */
     859#define CPUMCTX_EXTRN_XCRx                      UINT64_C(0x0000000400000000)
     860
     861/** The KERNEL GS BASE MSR value is kept externally. */
     862#define CPUMCTX_EXTRN_KERNEL_GS_BASE            UINT64_C(0x0000000800000000)
     863/** The STAR, LSTAR, CSTAR and SFMASK MSR values are kept externally. */
     864#define CPUMCTX_EXTRN_SYSCALL_MSRS              UINT64_C(0x0000001000000000)
     865/** The SYSENTER_CS, SYSENTER_EIP and SYSENTER_ESP MSR values are kept externally. */
     866#define CPUMCTX_EXTRN_SYSENTER_MSRS             UINT64_C(0x0000002000000000)
     867/** The SYSENTER_CS, SYSENTER_EIP and SYSENTER_ESP MSR values are kept externally. */
     868#define CPUMCTX_EXTRN_TSC_AUX                   UINT64_C(0x0000004000000000)
     869/** All other stateful MSRs not covered by CPUMCTX_EXTRN_EFER,
     870 * CPUMCTX_EXTRN_KERNEL_GS_BASE, CPUMCTX_EXTRN_SYSCALL_MSRS,
     871 * CPUMCTX_EXTRN_SYSENTER_MSRS, and CPUMCTX_EXTRN_TSC_AUX.  */
     872#define CPUMCTX_EXTRN_OTHER_MSRS                UINT64_C(0x0000008000000000)
     873
     874/** Mask of bits the keepers can use for state tracking. */
     875#define CPUMCTX_EXTRN_KEEPER_STATE_MASK         UINT64_C(0xffff000000000000)
     876
     877/** NEM/Win: Event injection (known was interruption) pending state. */
     878#define CPUMCTX_EXTRN_NEM_WIN_EVENT_INJECT      UINT64_C(0x0001000000000000)
     879/** NEM/Win: Mask. */
     880#define CPUMCTX_EXTRN_NEM_WIN_MASK              UINT64_C(0x0001000000000000)
     881
     882/** All CPUM state bits, not including keeper specific ones. */
     883#define CPUMCTX_EXTRN_ALL                       UINT64_C(0x000000fffffffffc)
     884/** @} */
     885
    754886
    755887/**
  • trunk/include/VBox/vmm/nem.h

    r71136 r71184  
    8888VMMR0_INT_DECL(int)  NEMR0MapPages(PGVM pGVM, PVM pVM, VMCPUID idCpu);
    8989VMMR0_INT_DECL(int)  NEMR0UnmapPages(PGVM pGVM, PVM pVM, VMCPUID idCpu);
    90 VMMR0_INT_DECL(int)  NEMR0ExportState(PGVM pGVM, PVM pVM, VMCPUID idCpu, uint64_t fWhat);
     90VMMR0_INT_DECL(int)  NEMR0ExportState(PGVM pGVM, PVM pVM, VMCPUID idCpu);
    9191VMMR0_INT_DECL(int)  NEMR0ImportState(PGVM pGVM, PVM pVM, VMCPUID idCpu, uint64_t fWhat);
    9292/** @} */
  • trunk/include/iprt/nt/hyperv.h

    r71129 r71184  
    14401440        HV_X64_INTERCEPT_MESSAGE_HEADER     X64InterceptHeader;
    14411441        /** HvMessageTypeGpaIntercept, HvMessageTypeUnmappedGpa. */
    1442         HV_X64_MEMORY_INTERCEPT_MESSAGE     X86MemoryIntercept;
     1442        HV_X64_MEMORY_INTERCEPT_MESSAGE     X64MemoryIntercept;
    14431443        /** HvMessageTypeX64IoPortIntercept */
    14441444        HV_X64_IO_PORT_INTERCEPT_MESSAGE    X64IoPortIntercept;
  • trunk/src/VBox/VMM/VMMAll/NEMAllNativeTemplate-win.cpp.h

    r71152 r71184  
    1515 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
    1616 */
     17
     18
     19/*********************************************************************************************************************************
     20*   Defined Constants And Macros                                                                                                 *
     21*********************************************************************************************************************************/
     22/** Copy back a segment from hyper-V. */
     23#define NEM_WIN_COPY_BACK_SEG(a_Dst, a_Src) \
     24            do { \
     25                (a_Dst).u64Base  = (a_Src).Base; \
     26                (a_Dst).u32Limit = (a_Src).Limit; \
     27                (a_Dst).ValidSel = (a_Dst).Sel = (a_Src).Selector; \
     28                (a_Dst).Attr.u   = (a_Src).Attributes; \
     29                (a_Dst).fFlags   = CPUMSELREG_FLAGS_VALID; \
     30            } while (0)
     31
     32/** The CPUMCTX_EXTRN_XXX mask for IEM. */
     33#define NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM      CPUMCTX_EXTRN_ALL
    1734
    1835
     
    91108#ifdef NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS
    92109    NOREF(pCtx);
    93     int rc = VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_NEM_EXPORT_STATE, UINT64_MAX, NULL);
     110    int rc = VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_NEM_EXPORT_STATE, 0, NULL);
    94111    AssertLogRelRCReturn(rc, rc);
    95112    return rc;
     
    389406
    390407
    391 NEM_TMPL_STATIC int nemHCWinCopyStateFromHyperV(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
     408NEM_TMPL_STATIC int nemHCWinCopyStateFromHyperV(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, uint64_t fWhat)
    392409{
    393410#ifdef NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS
     411    /* See NEMR0ImportState */
    394412    NOREF(pCtx);
    395     int rc = VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_NEM_IMPORT_STATE, UINT64_MAX, NULL);
     413    int rc = VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_NEM_IMPORT_STATE, fWhat, NULL);
    396414    if (RT_SUCCESS(rc))
    397415        return rc;
     
    552570            do { \
    553571                Assert(aenmNames[a_idx] == a_enmName); \
    554                 (a_SReg).u64Base  = aValues[a_idx].Segment.Base; \
    555                 (a_SReg).u32Limit = aValues[a_idx].Segment.Limit; \
    556                 (a_SReg).ValidSel = (a_SReg).Sel = aValues[a_idx].Segment.Selector; \
    557                 (a_SReg).Attr.u   = aValues[a_idx].Segment.Attributes; \
    558                 (a_SReg).fFlags   = CPUMSELREG_FLAGS_VALID; \
     572                NEM_WIN_COPY_BACK_SEG(a_SReg, aValues[a_idx]); \
    559573            } while (0)
    560574        COPY_BACK_SEG(18, WHvX64RegisterEs,   pCtx->es);
     
    740754        /// @todo WHvRegisterPendingEvent1
    741755
     756        pCtx->fExtrn = 0;
    742757
    743758        if (fMaybeChangedMode)
     
    792807
    793808#ifdef NEM_WIN_USE_OUR_OWN_RUN_API
    794 
    795809# ifdef IN_RING3 /* hopefully not needed in ring-0, as we'd need KTHREADs and KeAlertThread. */
    796810/**
     
    851865}
    852866# endif /* IN_RING3 */
    853 
    854 
    855 /**
    856  * Fills in WHV_VP_EXIT_CONTEXT from HV_X64_INTERCEPT_MESSAGE_HEADER.
    857  */
    858 DECLINLINE(void) nemHCWinConvertX64MsgHdrToVpExitCtx(HV_X64_INTERCEPT_MESSAGE_HEADER const *pHdr, WHV_VP_EXIT_CONTEXT *pCtx)
    859 {
    860     pCtx->ExecutionState.AsUINT16   = pHdr->ExecutionState.AsUINT16;
    861     pCtx->InstructionLength         = pHdr->InstructionLength;
    862     pCtx->Cs.Base                   = pHdr->CsSegment.Base;
    863     pCtx->Cs.Limit                  = pHdr->CsSegment.Limit;
    864     pCtx->Cs.Selector               = pHdr->CsSegment.Selector;
    865     pCtx->Cs.Attributes             = pHdr->CsSegment.Attributes;
    866     pCtx->Rip                       = pHdr->Rip;
    867     pCtx->Rflags                    = pHdr->Rflags;
    868 }
    869 
    870 
    871 /**
    872  * Convert hyper-V exit message to the WinHvPlatform structures.
    873  *
    874  * @returns VBox status code
    875  * @param   pMsgHdr         The message to convert.
    876  * @param   pExitCtx        The output structure. Assumes zeroed.
    877  */
    878 NEM_TMPL_STATIC int nemHCWinRunVirtualProcessorConvertPending(HV_MESSAGE_HEADER const *pMsgHdr, WHV_RUN_VP_EXIT_CONTEXT *pExitCtx)
    879 {
    880     switch (pMsgHdr->MessageType)
    881     {
    882         case HvMessageTypeUnmappedGpa:
    883         case HvMessageTypeGpaIntercept:
    884         {
    885             PCHV_X64_MEMORY_INTERCEPT_MESSAGE pMemMsg = (PCHV_X64_MEMORY_INTERCEPT_MESSAGE)(pMsgHdr + 1);
    886             Assert(pMsgHdr->PayloadSize == RT_UOFFSETOF(HV_X64_MEMORY_INTERCEPT_MESSAGE, DsSegment));
    887 
    888             pExitCtx->ExitReason                            = WHvRunVpExitReasonMemoryAccess;
    889             nemHCWinConvertX64MsgHdrToVpExitCtx(&pMemMsg->Header, &pExitCtx->MemoryAccess.VpContext);
    890             pExitCtx->MemoryAccess.InstructionByteCount     = pMemMsg->InstructionByteCount;
    891             ((uint64_t *)pExitCtx->MemoryAccess.InstructionBytes)[0] = ((uint64_t const *)pMemMsg->InstructionBytes)[0];
    892             ((uint64_t *)pExitCtx->MemoryAccess.InstructionBytes)[1] = ((uint64_t const *)pMemMsg->InstructionBytes)[1];
    893 
    894             pExitCtx->MemoryAccess.AccessInfo.AccessType    = pMemMsg->Header.InterceptAccessType;
    895             pExitCtx->MemoryAccess.AccessInfo.GpaUnmapped   = pMsgHdr->MessageType == HvMessageTypeUnmappedGpa;
    896             pExitCtx->MemoryAccess.AccessInfo.GvaValid      = pMemMsg->MemoryAccessInfo.GvaValid;
    897             pExitCtx->MemoryAccess.AccessInfo.Reserved      = pMemMsg->MemoryAccessInfo.Reserved;
    898             pExitCtx->MemoryAccess.Gpa                      = pMemMsg->GuestPhysicalAddress;
    899             pExitCtx->MemoryAccess.Gva                      = pMemMsg->GuestVirtualAddress;
    900             return VINF_SUCCESS;
    901         }
    902 
    903         case HvMessageTypeX64IoPortIntercept:
    904         {
    905             PCHV_X64_IO_PORT_INTERCEPT_MESSAGE pPioMsg= (PCHV_X64_IO_PORT_INTERCEPT_MESSAGE)(pMsgHdr + 1);
    906             Assert(pMsgHdr->PayloadSize == sizeof(*pPioMsg));
    907 
    908             pExitCtx->ExitReason                            = WHvRunVpExitReasonX64IoPortAccess;
    909             nemHCWinConvertX64MsgHdrToVpExitCtx(&pPioMsg->Header, &pExitCtx->IoPortAccess.VpContext);
    910             pExitCtx->IoPortAccess.InstructionByteCount     = pPioMsg->InstructionByteCount;
    911             ((uint64_t *)pExitCtx->IoPortAccess.InstructionBytes)[0] = ((uint64_t const *)pPioMsg->InstructionBytes)[0];
    912             ((uint64_t *)pExitCtx->IoPortAccess.InstructionBytes)[1] = ((uint64_t const *)pPioMsg->InstructionBytes)[1];
    913 
    914             pExitCtx->IoPortAccess.AccessInfo.IsWrite       = pPioMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_WRITE;
    915             pExitCtx->IoPortAccess.AccessInfo.AccessSize    = pPioMsg->AccessInfo.AccessSize;
    916             pExitCtx->IoPortAccess.AccessInfo.StringOp      = pPioMsg->AccessInfo.StringOp;
    917             pExitCtx->IoPortAccess.AccessInfo.RepPrefix     = pPioMsg->AccessInfo.RepPrefix;
    918             pExitCtx->IoPortAccess.AccessInfo.Reserved      = pPioMsg->AccessInfo.Reserved;
    919             pExitCtx->IoPortAccess.PortNumber               = pPioMsg->PortNumber;
    920             pExitCtx->IoPortAccess.Rax                      = pPioMsg->Rax;
    921             pExitCtx->IoPortAccess.Rcx                      = pPioMsg->Rcx;
    922             pExitCtx->IoPortAccess.Rsi                      = pPioMsg->Rsi;
    923             pExitCtx->IoPortAccess.Rdi                      = pPioMsg->Rdi;
    924             pExitCtx->IoPortAccess.Ds.Base                  = pPioMsg->DsSegment.Base;
    925             pExitCtx->IoPortAccess.Ds.Limit                 = pPioMsg->DsSegment.Limit;
    926             pExitCtx->IoPortAccess.Ds.Selector              = pPioMsg->DsSegment.Selector;
    927             pExitCtx->IoPortAccess.Ds.Attributes            = pPioMsg->DsSegment.Attributes;
    928             pExitCtx->IoPortAccess.Es.Base                  = pPioMsg->EsSegment.Base;
    929             pExitCtx->IoPortAccess.Es.Limit                 = pPioMsg->EsSegment.Limit;
    930             pExitCtx->IoPortAccess.Es.Selector              = pPioMsg->EsSegment.Selector;
    931             pExitCtx->IoPortAccess.Es.Attributes            = pPioMsg->EsSegment.Attributes;
    932             return VINF_SUCCESS;
    933         }
    934 
    935         case HvMessageTypeX64Halt:
    936         {
    937             PCHV_X64_HALT_MESSAGE pHaltMsg = (PCHV_X64_HALT_MESSAGE)(pMsgHdr + 1);
    938             AssertMsg(pHaltMsg->u64Reserved == 0, ("HALT reserved: %#RX64\n", pHaltMsg->u64Reserved));
    939             pExitCtx->ExitReason = WHvRunVpExitReasonX64Halt;
    940             return VINF_SUCCESS;
    941         }
    942 
    943         case HvMessageTypeX64InterruptWindow:
    944             AssertLogRelMsgFailedReturn(("Message type %#x not implemented!\n", pMsgHdr->MessageType), VERR_INTERNAL_ERROR_2);
    945 
    946         case HvMessageTypeInvalidVpRegisterValue:
    947         case HvMessageTypeUnrecoverableException:
    948         case HvMessageTypeUnsupportedFeature:
    949         case HvMessageTypeTlbPageSizeMismatch:
    950             AssertLogRelMsgFailedReturn(("Message type %#x not implemented!\n", pMsgHdr->MessageType), VERR_INTERNAL_ERROR_2);
    951 
    952         case HvMessageTypeX64MsrIntercept:
    953         case HvMessageTypeX64CpuidIntercept:
    954         case HvMessageTypeX64ExceptionIntercept:
    955         case HvMessageTypeX64ApicEoi:
    956         case HvMessageTypeX64LegacyFpError:
    957         case HvMessageTypeX64RegisterIntercept:
    958         case HvMessageTypeApicEoi:
    959         case HvMessageTypeFerrAsserted:
    960         case HvMessageTypeEventLogBufferComplete:
    961         case HvMessageTimerExpired:
    962             AssertLogRelMsgFailedReturn(("Unexpected message type #x!\n", pMsgHdr->MessageType), VERR_INTERNAL_ERROR_2);
    963 
    964         default:
    965             AssertLogRelMsgFailedReturn(("Unknown message type #x!\n", pMsgHdr->MessageType), VERR_INTERNAL_ERROR_2);
    966     }
    967 }
    968 
    969 
    970 /**
    971  * Our own WHvRunVirtualProcessor that can later be moved to ring-0.
    972  *
    973  * This is an experiment only.
    974  *
    975  * @returns VBox status code.
    976  * @param   pVM             The cross context VM structure.
    977  * @param   pVCpu           The cross context virtual CPU structure of the
    978  *                          calling EMT.
    979  * @param   pExitCtx        Where to return exit information.
    980  * @param   cbExitCtx       Size of the exit information area.
    981  */
    982 NEM_TMPL_STATIC int nemHCWinRunVirtualProcessor(PVM pVM, PVMCPU pVCpu, WHV_RUN_VP_EXIT_CONTEXT *pExitCtx, size_t cbExitCtx)
    983 {
    984     RT_BZERO(pExitCtx, cbExitCtx);
    985 
    986     /*
    987      * Tell the CPU to execute stuff if we haven't got a pending message.
    988      */
    989     VID_MESSAGE_MAPPING_HEADER volatile *pMappingHeader = (VID_MESSAGE_MAPPING_HEADER volatile *)pVCpu->nem.s.pvMsgSlotMapping;
    990     uint32_t                             fHandleAndGetFlags;
    991     if (VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED))
    992     {
    993         uint8_t const bMsgState = pVCpu->nem.s.bMsgState;
    994         if (bMsgState == NEM_WIN_MSG_STATE_PENDING_MSG)
    995         {
    996             Assert(pMappingHeader->enmVidMsgType == VidMessageHypervisorMessage);
    997             fHandleAndGetFlags = VID_MSHAGN_F_GET_NEXT_MESSAGE | VID_MSHAGN_F_HANDLE_MESSAGE;
    998             Log8(("nemHCWinRunVirtualProcessor: #1: msg pending, no need to start CPU (cpu state %u)\n", nemHCWinCpuGetRunningStatus(pVCpu) ));
    999         }
    1000         else if (bMsgState != NEM_WIN_MSG_STATE_STARTED)
    1001         {
    1002             if (bMsgState == NEM_WIN_MSG_STATE_PENDING_STOP_AND_MSG)
    1003             {
    1004                 Log8(("nemHCWinRunVirtualProcessor: #0: pending stop+message (cpu status %u)\n", nemHCWinCpuGetRunningStatus(pVCpu) ));
    1005                 /* ACK the pending message and get the stop message. */
    1006                 BOOL fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu,
    1007                                                                  VID_MSHAGN_F_HANDLE_MESSAGE | VID_MSHAGN_F_GET_NEXT_MESSAGE, 5000);
    1008                 AssertLogRelMsg(fWait, ("dwErr=%u (%#x) rcNt=%#x\n", RTNtLastErrorValue(), RTNtLastErrorValue(), RTNtLastStatusValue()));
    1009 
    1010                 /* ACK the stop message. */
    1011                 fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu,
    1012                                                             VID_MSHAGN_F_HANDLE_MESSAGE, 5000);
    1013                 AssertLogRelMsg(fWait, ("dwErr=%u (%#x) rcNt=%#x\n", RTNtLastErrorValue(), RTNtLastErrorValue(), RTNtLastStatusValue()));
    1014 
    1015                 pVCpu->nem.s.bMsgState = NEM_WIN_MSG_STATE_STOPPED;
    1016             }
    1017 
    1018             Log8(("nemHCWinRunVirtualProcessor: #1: starting CPU (cpu status %u)\n", nemHCWinCpuGetRunningStatus(pVCpu) ));
    1019             if (g_pfnVidStartVirtualProcessor(pVM->nem.s.hPartitionDevice, pVCpu->idCpu))
    1020                 pVCpu->nem.s.bMsgState = NEM_WIN_MSG_STATE_STARTED;
    1021             else
    1022             {
    1023                 VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM);
    1024                 AssertLogRelMsgFailedReturn(("VidStartVirtualProcessor failed for CPU #%u: rcNt=%#x dwErr=%u\n",
    1025                                              pVCpu->idCpu, RTNtLastStatusValue(), RTNtLastErrorValue()),
    1026                                             VERR_INTERNAL_ERROR_3);
    1027             }
    1028             fHandleAndGetFlags = VID_MSHAGN_F_GET_NEXT_MESSAGE;
    1029         }
    1030         else
    1031         {
    1032             /* This shouldn't happen. */
    1033             fHandleAndGetFlags = VID_MSHAGN_F_GET_NEXT_MESSAGE;
    1034             Log8(("nemHCWinRunVirtualProcessor: #1: NO MSG PENDING! No need to start CPU (cpu state %u)\n", nemHCWinCpuGetRunningStatus(pVCpu) ));
    1035         }
    1036     }
    1037     else
    1038     {
    1039         Log8(("nemHCWinRunVirtualProcessor: #1: state=%u -> canceled (cpu status %u)\n",
    1040               VMCPU_GET_STATE(pVCpu), nemHCWinCpuGetRunningStatus(pVCpu)));
    1041         pExitCtx->ExitReason = WHvRunVpExitReasonCanceled;
    1042         return VINF_SUCCESS;
    1043     }
    1044 
    1045     /*
    1046      * Wait for it to stop and give us a reason to work with.
    1047      */
    1048     uint32_t cMillies = 5000; // Starting low so we can experiment without getting stuck.
    1049     for (;;)
    1050     {
    1051         if (VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM_WAIT, VMCPUSTATE_STARTED_EXEC_NEM))
    1052         {
    1053             Log8(("nemHCWinRunVirtualProcessor: #2: Waiting %#x (cpu status %u)...\n",
    1054                   fHandleAndGetFlags, nemHCWinCpuGetRunningStatus(pVCpu)));
    1055             BOOL fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu,
    1056                                                              fHandleAndGetFlags, cMillies);
    1057             if (fWait)
    1058             {
    1059                 /* Not sure yet, but we have to check whether there is anything pending
    1060                    and retry if there isn't. */
    1061                 VID_MESSAGE_TYPE const enmVidMsgType = pMappingHeader->enmVidMsgType;
    1062                 if (enmVidMsgType == VidMessageHypervisorMessage)
    1063                 {
    1064                     if (!VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM_WAIT))
    1065                         VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM_CANCELED);
    1066                     Log8(("nemHCWinRunVirtualProcessor: #3: wait succeeded: %#x / %#x (cpu status %u)\n",
    1067                           enmVidMsgType, ((HV_MESSAGE_HEADER const *)(pMappingHeader + 1))->MessageType,
    1068                           nemHCWinCpuGetRunningStatus(pVCpu) ));
    1069                     pVCpu->nem.s.bMsgState = NEM_WIN_MSG_STATE_PENDING_MSG;
    1070                     return nemHCWinRunVirtualProcessorConvertPending((HV_MESSAGE_HEADER const *)(pMappingHeader + 1), pExitCtx);
    1071                 }
    1072 
    1073                 /* This shouldn't happen, and I think its wrong. */
    1074                 VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED_EXEC_NEM_WAIT);
    1075 #ifdef DEBUG_bird
    1076                 __debugbreak();
    1077 #endif
    1078                 Log8(("nemHCWinRunVirtualProcessor: #3: wait succeeded, but nothing pending: %#x / %#x (cpu status %u)\n",
    1079                       enmVidMsgType, ((HV_MESSAGE_HEADER const *)(pMappingHeader + 1))->MessageType, nemHCWinCpuGetRunningStatus(pVCpu) ));
    1080                 pVCpu->nem.s.bMsgState = NEM_WIN_MSG_STATE_STARTED;
    1081                 AssertLogRelMsgReturnStmt(enmVidMsgType == VidMessageStopRequestComplete,
    1082                                           ("enmVidMsgType=%#x\n", enmVidMsgType),
    1083                                           g_pfnVidStopVirtualProcessor(pVM->nem.s.hPartitionDevice, pVCpu->idCpu),
    1084                                           VERR_INTERNAL_ERROR_3);
    1085                 fHandleAndGetFlags &= ~VID_MSHAGN_F_HANDLE_MESSAGE;
    1086             }
    1087             else
    1088             {
    1089                 VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED_EXEC_NEM_WAIT);
    1090 
    1091                 /* Note! VID.SYS merges STATUS_ALERTED and STATUS_USER_APC into STATUS_TIMEOUT. */
    1092                 DWORD const dwErr = RTNtLastErrorValue();
    1093                 AssertLogRelMsgReturnStmt(   dwErr == STATUS_TIMEOUT
    1094                                           || dwErr == STATUS_ALERTED || dwErr == STATUS_USER_APC, /* just in case */
    1095                                           ("dwErr=%u (%#x) (cpu status %u)\n", dwErr, dwErr, nemHCWinCpuGetRunningStatus(pVCpu)),
    1096                                           g_pfnVidStopVirtualProcessor(pVM->nem.s.hPartitionDevice, pVCpu->idCpu),
    1097                                           VERR_INTERNAL_ERROR_3);
    1098                 Log8(("nemHCWinRunVirtualProcessor: #3: wait timed out (cpu status %u)\n", nemHCWinCpuGetRunningStatus(pVCpu) ));
    1099                 pVCpu->nem.s.bMsgState = NEM_WIN_MSG_STATE_STARTED;
    1100                 fHandleAndGetFlags &= ~VID_MSHAGN_F_HANDLE_MESSAGE;
    1101             }
    1102         }
    1103         else
    1104         {
    1105             /*
    1106              * State changed and we need to return.
    1107              *
    1108              * We must ensure that the processor is not running while we
    1109              * return, and that can be a bit complicated.
    1110              */
    1111             Log8(("nemHCWinRunVirtualProcessor: #4: state changed to %u (cpu status %u)\n",
    1112                   VMCPU_GET_STATE(pVCpu), nemHCWinCpuGetRunningStatus(pVCpu) ));
    1113             VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM_CANCELED);
    1114 
    1115             /* If we haven't marked the pervious message as handled, simply return
    1116                without doing anything special. */
    1117             if (fHandleAndGetFlags & VID_MSHAGN_F_HANDLE_MESSAGE)
    1118             {
    1119                 Log8(("nemHCWinRunVirtualProcessor: #5: Didn't resume previous message.\n"));
    1120                 pVCpu->nem.s.bMsgState = NEM_WIN_MSG_STATE_PENDING_MSG;
    1121                 pExitCtx->ExitReason = WHvRunVpExitReasonCanceled;
    1122                 return VINF_SUCCESS;
    1123             }
    1124 
    1125             /* The processor is running, so try stop it. */
    1126             BOOL fStop = g_pfnVidStopVirtualProcessor(pVM->nem.s.hPartitionDevice, pVCpu->idCpu);
    1127             if (fStop)
    1128             {
    1129                 Log8(("nemHCWinRunVirtualProcessor: #5: Stopping CPU succeeded (cpu status %u)\n", nemHCWinCpuGetRunningStatus(pVCpu) ));
    1130                 pVCpu->nem.s.bMsgState = NEM_WIN_MSG_STATE_STOPPED;
    1131                 pExitCtx->ExitReason = WHvRunVpExitReasonCanceled;
    1132                 return VINF_SUCCESS;
    1133             }
    1134 
    1135             /* Dang, the CPU stopped by itself with a message pending. */
    1136             DWORD dwErr = RTNtLastErrorValue();
    1137             Log8(("nemHCWinRunVirtualProcessor: #5: Stopping CPU failed (%u/%#x) - cpu status %u\n",
    1138                   dwErr, dwErr, nemHCWinCpuGetRunningStatus(pVCpu) ));
    1139             pExitCtx->ExitReason = WHvRunVpExitReasonCanceled;
    1140             AssertLogRelMsgReturn(dwErr == ERROR_VID_STOP_PENDING, ("dwErr=%#u\n", dwErr), VERR_INTERNAL_ERROR_3);
    1141 
    1142             /* Get the pending message. */
    1143             BOOL fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu,
    1144                                                              VID_MSHAGN_F_GET_NEXT_MESSAGE, 5000);
    1145             AssertLogRelMsgReturn(fWait, ("error=%#u\n", RTNtLastErrorValue()), VERR_INTERNAL_ERROR_3);
    1146 
    1147             VID_MESSAGE_TYPE const enmVidMsgType = pMappingHeader->enmVidMsgType;
    1148             if (enmVidMsgType == VidMessageHypervisorMessage)
    1149             {
    1150                 Log8(("nemHCWinRunVirtualProcessor: #6: wait succeeded: %#x / %#x (cpu status %u)\n", enmVidMsgType,
    1151                       ((HV_MESSAGE_HEADER const *)(pMappingHeader + 1))->MessageType, nemHCWinCpuGetRunningStatus(pVCpu) ));
    1152                 pVCpu->nem.s.bMsgState = NEM_WIN_MSG_STATE_PENDING_STOP_AND_MSG;
    1153                 return nemHCWinRunVirtualProcessorConvertPending((HV_MESSAGE_HEADER const *)(pMappingHeader + 1), pExitCtx);
    1154             }
    1155 
    1156             /* ACK the stop message, if that's what it is.  Don't think we'll ever get here. */
    1157             Log8(("nemHCWinRunVirtualProcessor: #6b: wait succeeded: %#x / %#x (cpu status %u)\n", enmVidMsgType,
    1158                   ((HV_MESSAGE_HEADER const *)(pMappingHeader + 1))->MessageType, nemHCWinCpuGetRunningStatus(pVCpu) ));
    1159             AssertLogRelMsgReturn(enmVidMsgType == VidMessageStopRequestComplete, ("enmVidMsgType=%#x\n", enmVidMsgType),
    1160                                   VERR_INTERNAL_ERROR_3);
    1161             fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu,
    1162                                                         VID_MSHAGN_F_HANDLE_MESSAGE, 5000);
    1163             AssertLogRelMsgReturn(fWait, ("dwErr=%#u\n", RTNtLastErrorValue()), VERR_INTERNAL_ERROR_3);
    1164 
    1165             pVCpu->nem.s.bMsgState = NEM_WIN_MSG_STATE_STOPPED;
    1166             pExitCtx->ExitReason = WHvRunVpExitReasonCanceled;
    1167             return VINF_SUCCESS;
    1168         }
    1169 
    1170         /** @todo check flags and stuff? */
    1171     }
    1172 }
    1173 
    1174867#endif /* NEM_WIN_USE_OUR_OWN_RUN_API */
     868
    1175869
    1176870#ifdef LOG_ENABLED
     
    1234928 * @param   pExitCtx        The exit context.
    1235929 */
    1236 DECLINLINE(void) nemHCWinAdvanceGuestRipAndClearRF(PVMCPU pVCpu, PCPUMCTX pCtx, WHV_VP_EXIT_CONTEXT const *pExitCtx)
    1237 {
     930DECLINLINE(void) nemHCWinAdvanceGuestRipAndClearRF(PVMCPU pVCpu, PCPUMCTX pCtx, HV_X64_INTERCEPT_MESSAGE_HEADER const *pMsgHdr)
     931{
     932    Assert(!(pCtx->fExtrn & (CPUMCTX_EXTRN_RIP | CPUMCTX_EXTRN_RFLAGS)));
     933
    1238934    /* Advance the RIP. */
    1239     Assert(pExitCtx->InstructionLength > 0 && pExitCtx->InstructionLength < 16);
    1240     pCtx->rip += pExitCtx->InstructionLength;
     935    Assert(pMsgHdr->InstructionLength > 0 && pMsgHdr->InstructionLength < 16);
     936    pCtx->rip += pMsgHdr->InstructionLength;
    1241937    pCtx->rflags.Bits.u1RF = 0;
    1242938
     
    14761172}
    14771173
    1478 
    1479 #if 0 /* later */
    1480 NEM_TMPL_STATIC nemHCWinRunGC(PVM pVM, PVMCPU pVCpu)
    1481 {
     1174#ifdef IN_RING3
     1175
     1176/**
     1177 * Copies register state from the X64 intercept message header.
     1178 *
     1179 * ASSUMES no state copied yet.
     1180 *
     1181 * @param   pCtx            The registe rcontext.
     1182 * @param   pHdr            The X64 intercept message header.
     1183 */
     1184DECLINLINE(void) nemHCWinCopyStateFromX64Header(PCPUMCTX pCtx, HV_X64_INTERCEPT_MESSAGE_HEADER const *pHdr)
     1185{
     1186    Assert(    (pCtx->fExtrn & (CPUMCTX_EXTRN_RIP | CPUMCTX_EXTRN_RFLAGS | CPUMCTX_EXTRN_CS))
     1187            ==                 (CPUMCTX_EXTRN_RIP | CPUMCTX_EXTRN_RFLAGS | CPUMCTX_EXTRN_CS));
     1188    NEM_WIN_COPY_BACK_SEG(pCtx->cs, pHdr->CsSegment);
     1189    pCtx->rip    = pHdr->Rip;
     1190    pCtx->rflags.u = pHdr->Rflags;
     1191    pCtx->fExtrn &= ~(CPUMCTX_EXTRN_RIP | CPUMCTX_EXTRN_RFLAGS | CPUMCTX_EXTRN_CS);
     1192}
     1193
     1194
     1195/**
     1196 * Deals with memory intercept message.
     1197 *
     1198 * @returns Strict VBox status code.
     1199 * @param   pVM             The cross context VM structure.
     1200 * @param   pVCpu           The cross context per CPU structure.
     1201 * @param   pMsg            The message.
     1202 * @param   pCtx            The register context.
     1203 */
     1204NEM_TMPL_STATIC VBOXSTRICTRC nemHCWinHandleMessageMemory(PVM pVM, PVMCPU pVCpu, HV_X64_MEMORY_INTERCEPT_MESSAGE const *pMsg,
     1205                                                         PCPUMCTX pCtx)
     1206{
     1207    /*
     1208     * Whatever we do, we must clear pending event ejection upon resume.
     1209     */
     1210    if (pMsg->Header.ExecutionState.InterruptionPending)
     1211        pCtx->fExtrn &= ~CPUMCTX_EXTRN_NEM_WIN_MASK;
     1212
     1213    /*
     1214     * Ask PGM for information about the given GCPhys.  We need to check if we're
     1215     * out of sync first.
     1216     */
     1217    NEMHCWINHMACPCCSTATE State = { pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_WRITE, false, false };
     1218    PGMPHYSNEMPAGEINFO   Info;
     1219    int rc = PGMPhysNemPageInfoChecker(pVM, pVCpu, pMsg->GuestPhysicalAddress, State.fWriteAccess, &Info,
     1220                                       nemHCWinHandleMemoryAccessPageCheckerCallback, &State);
     1221    if (RT_SUCCESS(rc))
     1222    {
     1223        if (Info.fNemProt & (  pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_WRITE
     1224                             ? NEM_PAGE_PROT_WRITE : NEM_PAGE_PROT_READ))
     1225        {
     1226            if (State.fCanResume)
     1227            {
     1228                Log4(("MemExit: %RGp (=>%RHp) %s fProt=%u%s%s%s; restarting (%s)\n",
     1229                      pMsg->GuestPhysicalAddress, Info.HCPhys, g_apszPageStates[Info.u2NemState], Info.fNemProt,
     1230                      Info.fHasHandlers ? " handlers" : "", Info.fZeroPage    ? " zero-pg" : "",
     1231                      State.fDidSomething ? "" : " no-change", g_apszWHvMemAccesstypes[pMsg->Header.InterceptAccessType]));
     1232                return VINF_SUCCESS;
     1233            }
     1234        }
     1235        Log4(("MemExit: %RGp (=>%RHp) %s fProt=%u%s%s%s; emulating (%s)\n",
     1236              pMsg->GuestPhysicalAddress, Info.HCPhys, g_apszPageStates[Info.u2NemState], Info.fNemProt,
     1237              Info.fHasHandlers ? " handlers" : "", Info.fZeroPage    ? " zero-pg" : "",
     1238              State.fDidSomething ? "" : " no-change", g_apszWHvMemAccesstypes[pMsg->Header.InterceptAccessType]));
     1239    }
     1240    else
     1241        Log4(("MemExit: %RGp rc=%Rrc%s; emulating (%s)\n", pMsg->GuestPhysicalAddress, rc,
     1242              State.fDidSomething ? " modified-backing" : "", g_apszWHvMemAccesstypes[pMsg->Header.InterceptAccessType]));
     1243
     1244    /*
     1245     * Emulate the memory access, either access handler or special memory.
     1246     */
     1247    nemHCWinCopyStateFromX64Header(pCtx, &pMsg->Header);
     1248    rc = nemHCWinCopyStateFromHyperV(pVM, pVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM);
     1249    AssertRCReturn(rc, rc);
     1250
     1251    VBOXSTRICTRC rcStrict;
     1252    if (pMsg->InstructionByteCount > 0)
     1253        rcStrict = IEMExecOneWithPrefetchedByPC(pVCpu, CPUMCTX2CORE(pCtx), pMsg->Header.Rip,
     1254                                                pMsg->InstructionBytes, pMsg->InstructionByteCount);
     1255    else
     1256        rcStrict = IEMExecOne(pVCpu);
     1257    /** @todo do we need to do anything wrt debugging here?   */
     1258    return rcStrict;
     1259
     1260}
     1261
     1262
     1263/**
     1264 * Deals with I/O port intercept message.
     1265 *
     1266 * @returns Strict VBox status code.
     1267 * @param   pVM             The cross context VM structure.
     1268 * @param   pVCpu           The cross context per CPU structure.
     1269 * @param   pMsg            The message.
     1270 */
     1271NEM_TMPL_STATIC VBOXSTRICTRC nemHCWinHandleMessageIoPort(PVM pVM, PVMCPU pVCpu, HV_X64_IO_PORT_INTERCEPT_MESSAGE const *pMsg,
     1272                                                         PCPUMCTX pCtx)
     1273{
     1274    Assert(   pMsg->AccessInfo.AccessSize == 1
     1275           || pMsg->AccessInfo.AccessSize == 2
     1276           || pMsg->AccessInfo.AccessSize == 4);
     1277
     1278    /*
     1279     * Whatever we do, we must clear pending event ejection upon resume.
     1280     */
     1281    if (pMsg->Header.ExecutionState.InterruptionPending)
     1282        pCtx->fExtrn &= ~CPUMCTX_EXTRN_NEM_WIN_MASK;
     1283
     1284    VBOXSTRICTRC rcStrict;
     1285    if (!pMsg->AccessInfo.StringOp)
     1286    {
     1287        /*
     1288         * Simple port I/O.
     1289         */
     1290        static uint32_t const s_fAndMask[8] =
     1291        {   UINT32_MAX, UINT32_C(0xff), UINT32_C(0xffff), UINT32_MAX,   UINT32_MAX, UINT32_MAX, UINT32_MAX, UINT32_MAX   };
     1292        uint32_t const        fAndMask      = s_fAndMask[pMsg->AccessInfo.AccessSize];
     1293        if (pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_WRITE)
     1294        {
     1295            rcStrict = IOMIOPortWrite(pVM, pVCpu, pMsg->PortNumber, (uint32_t)pMsg->Rax & fAndMask, pMsg->AccessInfo.AccessSize);
     1296            Log4(("IOExit: %04x:%08RX64: OUT %#x, %#x LB %u rcStrict=%Rrc\n", pMsg->Header.CsSegment.Selector, pMsg->Header.Rip,
     1297                  pMsg->PortNumber, (uint32_t)pMsg->Rax & fAndMask, pMsg->AccessInfo.AccessSize, VBOXSTRICTRC_VAL(rcStrict) ));
     1298            if (IOM_SUCCESS(rcStrict))
     1299            {
     1300                nemHCWinCopyStateFromX64Header(pCtx, &pMsg->Header);
     1301                nemHCWinAdvanceGuestRipAndClearRF(pVCpu, pCtx, &pMsg->Header);
     1302            }
     1303        }
     1304        else
     1305        {
     1306            uint32_t uValue = 0;
     1307            rcStrict = IOMIOPortRead(pVM, pVCpu, pMsg->PortNumber, &uValue, pMsg->AccessInfo.AccessSize);
     1308            Log4(("IOExit: %04x:%08RX64: IN %#x LB %u -> %#x, rcStrict=%Rrc\n", pMsg->Header.CsSegment.Selector, pMsg->Header.Rip,
     1309                  pMsg->PortNumber, pMsg->AccessInfo.AccessSize, uValue, VBOXSTRICTRC_VAL(rcStrict) ));
     1310            if (IOM_SUCCESS(rcStrict))
     1311            {
     1312                if (pMsg->AccessInfo.AccessSize != 4)
     1313                    pCtx->rax = (pMsg->Rax & ~(uint64_t)fAndMask) | (uValue & fAndMask);
     1314                else
     1315                    pCtx->rax = uValue;
     1316                pCtx->fExtrn &= ~CPUMCTX_EXTRN_RAX;
     1317                Log4(("IOExit: RAX %#RX64 -> %#RX64\n", pMsg->Rax, pCtx->rax));
     1318                nemHCWinCopyStateFromX64Header(pCtx, &pMsg->Header);
     1319                nemHCWinAdvanceGuestRipAndClearRF(pVCpu, pCtx, &pMsg->Header);
     1320            }
     1321        }
     1322    }
     1323    else
     1324    {
     1325        /*
     1326         * String port I/O.
     1327         */
     1328        /** @todo Someone at Microsoft please explain how we can get the address mode
     1329         * from the IoPortAccess.VpContext.  CS.Attributes is only sufficient for
     1330         * getting the default mode, it can always be overridden by a prefix.   This
     1331         * forces us to interpret the instruction from opcodes, which is suboptimal.
     1332         * Both AMD-V and VT-x includes the address size in the exit info, at least on
     1333         * CPUs that are reasonably new.
     1334         *
     1335         * Of course, it's possible this is an undocumented and we just need to do some
     1336         * experiments to figure out how it's communicated.  Alternatively, we can scan
     1337         * the opcode bytes for possible evil prefixes.
     1338         */
     1339        nemHCWinCopyStateFromX64Header(pCtx, &pMsg->Header);
     1340        pCtx->fExtrn &= ~(  CPUMCTX_EXTRN_RAX | CPUMCTX_EXTRN_RCX | CPUMCTX_EXTRN_RDI | CPUMCTX_EXTRN_RSI
     1341                          | CPUMCTX_EXTRN_DS  | CPUMCTX_EXTRN_ES);
     1342        NEM_WIN_COPY_BACK_SEG(pCtx->ds, pMsg->DsSegment);
     1343        NEM_WIN_COPY_BACK_SEG(pCtx->es, pMsg->EsSegment);
     1344        pCtx->rax = pMsg->Rax;
     1345        pCtx->rcx = pMsg->Rcx;
     1346        pCtx->rdi = pMsg->Rdi;
     1347        pCtx->rsi = pMsg->Rsi;
     1348        int rc = nemHCWinCopyStateFromHyperV(pVM, pVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM);
     1349        AssertRCReturn(rc, rc);
     1350
     1351        Log4(("IOExit: %04x:%08RX64: %s%s %#x LB %u (emulating)\n", pMsg->Header.CsSegment.Selector, pMsg->Header.Rip,
     1352              pMsg->AccessInfo.RepPrefix ? "REP " : "",
     1353              pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_WRITE ? "OUTS" : "INS",
     1354              pMsg->PortNumber, pMsg->AccessInfo.AccessSize ));
     1355        rcStrict = IEMExecOne(pVCpu);
     1356    }
     1357    if (IOM_SUCCESS(rcStrict))
     1358    {
     1359        /*
     1360         * Do debug checks.
     1361         */
     1362        if (   pMsg->Header.ExecutionState.DebugActive /** @todo Microsoft: Does DebugActive this only reflext DR7? */
     1363            || (pMsg->Header.Rflags & X86_EFL_TF)
     1364            || DBGFBpIsHwIoArmed(pVM) )
     1365        {
     1366            /** @todo Debugging. */
     1367        }
     1368    }
     1369    return rcStrict;
     1370}
     1371
     1372
     1373/**
     1374 * Handles messages (VM exits).
     1375 *
     1376 * @returns Strict VBox status code.
     1377 * @param   pVM             The cross context VM structure.
     1378 * @param   pVCpu           The cross context per CPU structure.
     1379 * @param   pMappingHeader  The message slot mapping.
     1380 * @param   pCtx            The register context.
     1381 */
     1382NEM_TMPL_STATIC VBOXSTRICTRC nemHCWinHandleMessage(PVM pVM, PVMCPU pVCpu, VID_MESSAGE_MAPPING_HEADER volatile *pMappingHeader,
     1383                                                   PCPUMCTX pCtx)
     1384{
     1385    if (pMappingHeader->enmVidMsgType == VidMessageHypervisorMessage)
     1386    {
     1387        AssertMsg(pMappingHeader->cbMessage == HV_MESSAGE_SIZE, ("%#x\n", pMappingHeader->cbMessage));
     1388        HV_MESSAGE const *pMsg = (HV_MESSAGE const *)(pMappingHeader + 1);
     1389        switch (pMsg->Header.MessageType)
     1390        {
     1391            case HvMessageTypeUnmappedGpa:
     1392                Assert(pMsg->Header.PayloadSize == RT_UOFFSETOF(HV_X64_MEMORY_INTERCEPT_MESSAGE, DsSegment));
     1393                return nemHCWinHandleMessageMemory(pVM, pVCpu, &pMsg->X64MemoryIntercept, pCtx);
     1394
     1395            case HvMessageTypeGpaIntercept:
     1396                Assert(pMsg->Header.PayloadSize == RT_UOFFSETOF(HV_X64_MEMORY_INTERCEPT_MESSAGE, DsSegment));
     1397                return nemHCWinHandleMessageMemory(pVM, pVCpu, &pMsg->X64MemoryIntercept, pCtx);
     1398
     1399            case HvMessageTypeX64IoPortIntercept:
     1400                Assert(pMsg->Header.PayloadSize == sizeof(pMsg->X64IoPortIntercept));
     1401                return nemHCWinHandleMessageIoPort(pVM, pVCpu, &pMsg->X64IoPortIntercept, pCtx);
     1402
     1403            case HvMessageTypeX64Halt:
     1404                return VINF_EM_HALT;
     1405
     1406            case HvMessageTypeX64InterruptWindow:
     1407                AssertLogRelMsgFailedReturn(("Message type %#x not implemented!\n", pMsg->Header.MessageType),
     1408                                            VERR_INTERNAL_ERROR_2);
     1409
     1410            case HvMessageTypeInvalidVpRegisterValue:
     1411            case HvMessageTypeUnrecoverableException:
     1412            case HvMessageTypeUnsupportedFeature:
     1413            case HvMessageTypeTlbPageSizeMismatch:
     1414                AssertLogRelMsgFailedReturn(("Message type %#x not implemented!\n", pMsg->Header.MessageType),
     1415                                            VERR_INTERNAL_ERROR_2);
     1416
     1417            case HvMessageTypeX64MsrIntercept:
     1418            case HvMessageTypeX64CpuidIntercept:
     1419            case HvMessageTypeX64ExceptionIntercept:
     1420            case HvMessageTypeX64ApicEoi:
     1421            case HvMessageTypeX64LegacyFpError:
     1422            case HvMessageTypeX64RegisterIntercept:
     1423            case HvMessageTypeApicEoi:
     1424            case HvMessageTypeFerrAsserted:
     1425            case HvMessageTypeEventLogBufferComplete:
     1426            case HvMessageTimerExpired:
     1427                AssertLogRelMsgFailedReturn(("Unexpected message on CPU #%u: #x\n", pVCpu->idCpu, pMsg->Header.MessageType),
     1428                                            VERR_INTERNAL_ERROR_2);
     1429
     1430            default:
     1431                AssertLogRelMsgFailedReturn(("Unknown message on CPU #%u: #x\n", pVCpu->idCpu, pMsg->Header.MessageType),
     1432                                            VERR_INTERNAL_ERROR_2);
     1433        }
     1434    }
     1435    else
     1436        AssertLogRelMsgFailedReturn(("Unexpected VID message type on CPU #%u: %#x LB %u\n",
     1437                                     pVCpu->idCpu, pMappingHeader->enmVidMsgType, pMappingHeader->cbMessage),
     1438                                    VERR_INTERNAL_ERROR_3);
     1439}
     1440
     1441
     1442/**
     1443 * Worker for nemHCWinRunGC that stops the execution on the way out.
     1444 *
     1445 * The CPU was running the last time we checked, no there are no messages that
     1446 * needs being marked handled/whatever.  Caller checks this.
     1447 *
     1448 * @returns rcStrict on success, error status on failure.
     1449 * @param   pVM             The cross context VM structure.
     1450 * @param   pVCpu           The cross context per CPU structure.
     1451 * @param   rcStrict        The nemHCWinRunGC return status.  This is a little
     1452 *                          bit unnecessary, except in internal error cases,
     1453 *                          since we won't need to stop the CPU if we took an
     1454 *                          exit.
     1455 * @param   pMappingHeader  The message slot mapping.
     1456 */
     1457NEM_TMPL_STATIC VBOXSTRICTRC nemHCWinStopCpu(PVM pVM, PVMCPU pVCpu, VBOXSTRICTRC rcStrict,
     1458                                             VID_MESSAGE_MAPPING_HEADER volatile *pMappingHeader)
     1459{
     1460    /*
     1461     * Try stopping the processor.  If we're lucky we manage to do this before it
     1462     * does another VM exit.
     1463     */
     1464    BOOL fRet = VidStopVirtualProcessor(pVM->nem.s.hPartitionDevice, pVCpu->idCpu);
     1465    if (fRet)
     1466    {
     1467        Log8(("nemHCWinStopCpu: Stopping CPU succeeded (cpu status %u)\n", nemHCWinCpuGetRunningStatus(pVCpu) ));
     1468        return rcStrict;
     1469    }
     1470
     1471    /*
     1472     * Dang. The CPU stopped by itself and we got a couple of message to deal with.
     1473     */
     1474    DWORD dwErr = RTNtLastErrorValue();
     1475    AssertLogRelMsgReturn(dwErr == ERROR_VID_STOP_PENDING, ("dwErr=%#u\n", dwErr),
     1476                          RT_SUCCESS(rcStrict) ?  VERR_INTERNAL_ERROR_3 : rcStrict);
     1477    Log8(("nemHCWinStopCpu: Stopping CPU pending...\n"));
     1478
     1479    /*
     1480     * First message: Exit or similar.
     1481     * Note! We can safely ASSUME that rcStrict isn't an important information one.
     1482     */
     1483    BOOL fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu,
     1484                                                     VID_MSHAGN_F_GET_NEXT_MESSAGE, 30000 /*ms*/);
     1485    AssertLogRelMsgReturn(fWait,
     1486                          ("1st VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %u\n", RTNtLastErrorValue()),
     1487                          RT_SUCCESS(rcStrict) ? VERR_INTERNAL_ERROR_3 : rcStrict);
     1488
     1489    /* It should be a hypervisor message and definitely not a stop request completed message. */
     1490    VID_MESSAGE_TYPE enmVidMsgType = pMappingHeader->enmVidMsgType;
     1491    AssertLogRelMsgReturn(enmVidMsgType != VidMessageStopRequestComplete,
     1492                          ("Unexpected 1st message following ERROR_VID_STOP_PENDING: %#x LB %#x\n",
     1493                           enmVidMsgType, pMappingHeader->cbMessage),
     1494                          RT_SUCCESS(rcStrict) ? VERR_INTERNAL_ERROR_3 : rcStrict);
     1495
     1496    VBOXSTRICTRC rcStrict2 = nemHCWinHandleMessage(pVM, pVCpu, pMappingHeader, CPUMQueryGuestCtxPtr(pVCpu));
     1497    if (rcStrict2 != VINF_SUCCESS && RT_SUCCESS(rcStrict))
     1498        rcStrict = rcStrict2;
     1499
     1500    /*
     1501     * Mark it as handled and get the stop request completed message, then mark
     1502     * that as handled too.  CPU is back into fully stopped stated then.
     1503     */
     1504    fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu,
     1505                                                VID_MSHAGN_F_HANDLE_MESSAGE | VID_MSHAGN_F_GET_NEXT_MESSAGE, 30000 /*ms*/);
     1506    AssertLogRelMsgReturn(fWait,
     1507                          ("2nd VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %u\n", RTNtLastErrorValue()),
     1508                          RT_SUCCESS(rcStrict) ? VERR_INTERNAL_ERROR_3 : rcStrict);
     1509
     1510    /* It should be a stop request completed message. */
     1511    enmVidMsgType = pMappingHeader->enmVidMsgType;
     1512    AssertLogRelMsgReturn(enmVidMsgType == VidMessageStopRequestComplete,
     1513                          ("Unexpected 2nd message following ERROR_VID_STOP_PENDING: %#x LB %#x\n",
     1514                           enmVidMsgType, pMappingHeader->cbMessage),
     1515                          RT_SUCCESS(rcStrict) ? VERR_INTERNAL_ERROR_3 : rcStrict);
     1516
     1517    /* Mark this as handled. */
     1518    fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu,
     1519                                                VID_MSHAGN_F_HANDLE_MESSAGE, 30000 /*ms*/);
     1520    AssertLogRelMsgReturn(fWait,
     1521                          ("3rd VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %u\n", RTNtLastErrorValue()),
     1522                          RT_SUCCESS(rcStrict) ? VERR_INTERNAL_ERROR_3 : rcStrict);
     1523    Log8(("nemHCWinStopCpu: Stopped the CPU (rcStrict=%Rrc)\n", VBOXSTRICTRC_VAL(rcStrict) ));
     1524    return rcStrict;
     1525}
     1526
     1527
     1528NEM_TMPL_STATIC VBOXSTRICTRC nemHCWinRunGC(PVM pVM, PVMCPU pVCpu)
     1529{
     1530    PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu);
     1531    LogFlow(("nemHCWinRunGC: Entering #%u cs:rip=%04x:%08RX64 efl=%#08RX64\n", pVCpu->idCpu, pCtx->cs.Sel, pCtx->rip, pCtx->rflags));
    14821532#ifdef LOG_ENABLED
    14831533    if (LogIs3Enabled())
    1484     {
    1485         Log3(("nemR3NativeRunGC: Entering #%u\n", pVCpu->idCpu));
    1486         nemR3WinLogState(pVM, pVCpu);
    1487     }
     1534        nemHCWinLogState(pVM, pVCpu);
    14881535#endif
    14891536
     
    14941541     * everything every time.  This will be optimized later.
    14951542     */
    1496     const bool   fSingleStepping = false; /** @todo get this from somewhere. */
    1497     VBOXSTRICTRC rcStrict = VINF_SUCCESS;
     1543    VID_MESSAGE_MAPPING_HEADER volatile *pMappingHeader = (VID_MESSAGE_MAPPING_HEADER volatile *)pVCpu->nem.s.pvMsgSlotMapping;
     1544    uint32_t     cMillies           = 5000; /** @todo lower this later... */
     1545    const bool   fSingleStepping    = false; /** @todo get this from somewhere. */
     1546    VBOXSTRICTRC rcStrict           = VINF_SUCCESS;
    14981547    for (unsigned iLoop = 0;;iLoop++)
    14991548    {
    15001549        /*
    1501          * Copy the state.
     1550         * Ensure that hyper-V has the whole state.
    15021551         */
    1503         PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu);
    1504         int rc2 = nemHCWinCopyStateToHyperV(pVM, pVCpu, pCtx);
    1505         AssertRCBreakStmt(rc2, rcStrict = rc2);
     1552        if ((pCtx->fExtrn & (CPUMCTX_EXTRN_ALL | CPUMCTX_EXTRN_NEM_WIN_MASK)) != (CPUMCTX_EXTRN_ALL | CPUMCTX_EXTRN_NEM_WIN_MASK))
     1553        {
     1554            int rc2 = nemHCWinCopyStateToHyperV(pVM, pVCpu, pCtx);
     1555            AssertRCReturn(rc2, rc2);
     1556        }
    15061557
    15071558        /*
    15081559         * Run a bit.
    15091560         */
    1510         WHV_RUN_VP_EXIT_CONTEXT ExitReason;
    1511         RT_ZERO(ExitReason);
    15121561        if (   !VM_FF_IS_PENDING(pVM, VM_FF_EMT_RENDEZVOUS | VM_FF_TM_VIRTUAL_SYNC)
    15131562            && !VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_TO_R3_MASK))
    15141563        {
    1515 #ifdef NEM_WIN_USE_OUR_OWN_RUN_API
    1516             int rc2 = nemR3WinRunVirtualProcessor(pVM, pVCpu, &ExitReason, sizeof(ExitReason));
    1517             AssertRCBreakStmt(rc2, rcStrict = rc2);
    1518 #else
    1519             Log8(("Calling WHvRunVirtualProcessor\n"));
    1520             VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED);
    1521             HRESULT hrc = WHvRunVirtualProcessor(pVM->nem.s.hPartition, pVCpu->idCpu, &ExitReason, sizeof(ExitReason));
    1522             VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM);
    1523             AssertLogRelMsgBreakStmt(SUCCEEDED(hrc),
    1524                                      ("WHvRunVirtualProcessor(%p, %u,,) -> %Rhrc (Last=%#x/%u)\n", pVM->nem.s.hPartition, pVCpu->idCpu,
    1525                                       hrc, RTNtLastStatusValue(), RTNtLastErrorValue()),
    1526                                      rcStrict = VERR_INTERNAL_ERROR);
    1527             Log2(("WHvRunVirtualProcessor -> %#x; exit code %#x (%d) (cpu status %u)\n",
    1528                   hrc, ExitReason.ExitReason, ExitReason.ExitReason, nemR3WinCpuGetRunningStatus(pVCpu) ));
     1564            if (pVCpu->nem.s.fHandleAndGetFlags)
     1565            { /* Very likely that the CPU does NOT need starting (pending msg, running). */ }
     1566            else
     1567            {
     1568                if (g_pfnVidStartVirtualProcessor(pVM->nem.s.hPartitionDevice, pVCpu->idCpu))
     1569                    pVCpu->nem.s.fHandleAndGetFlags = VID_MSHAGN_F_GET_NEXT_MESSAGE;
     1570                else
     1571                    AssertLogRelMsgFailedReturn(("VidStartVirtualProcessor failed for CPU #%u: %u (%#x, rcNt=%#x)\n",
     1572                                                 pVCpu->idCpu, RTNtLastErrorValue(), RTNtLastErrorValue(), RTNtLastStatusValue()),
     1573                                                VERR_INTERNAL_ERROR_3);
     1574            }
     1575
     1576            if (VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED))
     1577            {
     1578                BOOL fRet = VidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu,
     1579                                                           pVCpu->nem.s.fHandleAndGetFlags, cMillies);
     1580                VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM);
     1581                if (fRet)
     1582                {
     1583                    /*
     1584                     * Deal with the message.
     1585                     */
     1586                    rcStrict = nemHCWinHandleMessage(pVM, pVCpu, pMappingHeader, pCtx);
     1587                    pVCpu->nem.s.fHandleAndGetFlags |= VID_MSHAGN_F_HANDLE_MESSAGE;
     1588                }
     1589                else
     1590                {
     1591                    /* VID.SYS merges STATUS_ALERTED and STATUS_USER_APC into STATUS_TIMEOUT,
     1592                       so after NtAlertThread we end up here with a STATUS_TIMEOUT.  And yeah,
     1593                       the error code conversion is into WAIT_XXX, i.e. NT status codes. */
     1594                    DWORD dwErr = GetLastError();
     1595                    if (   dwErr == STATUS_TIMEOUT
     1596                        || dwErr == STATUS_ALERTED  /* just in case */
     1597                        || dwErr == STATUS_USER_APC /* ditto */ )
     1598                        pVCpu->nem.s.fHandleAndGetFlags = VID_MSHAGN_F_GET_NEXT_MESSAGE; /* exits are likely */
     1599                    else
     1600                        AssertLogRelMsgFailedReturn(("VidMessageSlotHandleAndGetNext failed for CPU #%u: %u (%#x, rcNt=%#x)\n",
     1601                                                     pVCpu->idCpu, dwErr, dwErr, RTNtLastStatusValue()),
     1602                                                    VERR_INTERNAL_ERROR_3);
     1603                }
     1604
     1605                /*
     1606                 * If no relevant FFs are pending, loop.
     1607                 */
     1608                if (   !VM_FF_IS_PENDING(   pVM,   !fSingleStepping ? VM_FF_HP_R0_PRE_HM_MASK    : VM_FF_HP_R0_PRE_HM_STEP_MASK)
     1609                    && !VMCPU_FF_IS_PENDING(pVCpu, !fSingleStepping ? VMCPU_FF_HP_R0_PRE_HM_MASK : VMCPU_FF_HP_R0_PRE_HM_STEP_MASK) )
     1610                    continue;
     1611
     1612                /** @todo Try handle pending flags, not just return to EM loops.  Take care
     1613                 *        not to set important RCs here unless we've handled a message. */
     1614                LogFlow(("nemHCWinRunGC: returning: pending FF (%#x / %#x)\n", pVM->fGlobalForcedActions, pVCpu->fLocalForcedActions));
     1615            }
     1616            else
     1617                LogFlow(("nemHCWinRunGC: returning: canceled %d (pre exec)\n", VMCPU_GET_STATE(pVCpu) ));
     1618        }
     1619        else
     1620            LogFlow(("nemHCWinRunGC: returning: pending FF (pre exec)\n"));
     1621        break;
     1622    } /* the run loop */
     1623
     1624
     1625    /*
     1626     * If the CPU is running, make sure to stop it before we try sync back the
     1627     * state and return to EM.
     1628     */
     1629    if (pVCpu->nem.s.fHandleAndGetFlags == VID_MSHAGN_F_GET_NEXT_MESSAGE)
     1630    {
     1631        pVCpu->nem.s.fHandleAndGetFlags = 0;
     1632        rcStrict = nemHCWinStopCpu(pVM, pVCpu, rcStrict, pMappingHeader);
     1633    }
     1634
     1635    VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM_CANCELED);
     1636
     1637    if (pCtx->fExtrn & (CPUMCTX_EXTRN_ALL | (CPUMCTX_EXTRN_NEM_WIN_MASK & ~CPUMCTX_EXTRN_NEM_WIN_EVENT_INJECT)))
     1638    {
     1639        int rc2 = nemHCWinCopyStateFromHyperV(pVM, pVCpu, pCtx, CPUMCTX_EXTRN_ALL | CPUMCTX_EXTRN_NEM_WIN_MASK);
     1640        if (RT_SUCCESS(rc2))
     1641            pCtx->fExtrn = 0;
     1642        else if (RT_SUCCESS(rcStrict))
     1643            rcStrict = rc2;
     1644    }
     1645    else
     1646        pCtx->fExtrn = 0;
     1647
     1648    LogFlow(("nemHCWinRunGC: Leaving #%u cs:rip=%04x:%08RX64 efl=%#08RX64\n", pVCpu->idCpu, pCtx->cs.Sel, pCtx->rip, pCtx->rflags));
     1649    return rcStrict;
     1650}
    15291651#endif
    1530         }
    1531         else
    1532         {
    1533             LogFlow(("nemR3NativeRunGC: returning: pending FF (pre exec)\n"));
    1534             break;
    1535         }
    1536 
    1537         /*
    1538          * Copy back the state.
    1539          */
    1540         rc2 = nemR3WinCopyStateFromHyperV(pVM, pVCpu, pCtx);
    1541         AssertRCBreakStmt(rc2, rcStrict = rc2);
    1542 
    1543 #ifdef LOG_ENABLED
    1544         /*
    1545          * Do some logging.
    1546          */
    1547         if (LogIs2Enabled())
    1548             nemR3WinLogExitReason(&ExitReason);
    1549         if (LogIs3Enabled())
    1550             nemR3WinLogState(pVM, pVCpu);
    1551 #endif
    1552 
    1553 #ifdef VBOX_STRICT
    1554         /* Assert that the VpContext field makes sense. */
    1555         switch (ExitReason.ExitReason)
    1556         {
    1557             case WHvRunVpExitReasonMemoryAccess:
    1558             case WHvRunVpExitReasonX64IoPortAccess:
    1559             case WHvRunVpExitReasonX64MsrAccess:
    1560             case WHvRunVpExitReasonX64Cpuid:
    1561             case WHvRunVpExitReasonException:
    1562             case WHvRunVpExitReasonUnrecoverableException:
    1563                 Assert(   ExitReason.IoPortAccess.VpContext.InstructionLength > 0
    1564                        || (   ExitReason.ExitReason == WHvRunVpExitReasonMemoryAccess
    1565                            && ExitReason.MemoryAccess.AccessInfo.AccessType == WHvMemoryAccessExecute));
    1566                 Assert(ExitReason.IoPortAccess.VpContext.InstructionLength < 16);
    1567                 Assert(ExitReason.IoPortAccess.VpContext.ExecutionState.Cpl == CPUMGetGuestCPL(pVCpu));
    1568                 Assert(ExitReason.IoPortAccess.VpContext.ExecutionState.Cr0Pe == RT_BOOL(pCtx->cr0 & X86_CR0_PE));
    1569                 Assert(ExitReason.IoPortAccess.VpContext.ExecutionState.Cr0Am == RT_BOOL(pCtx->cr0 & X86_CR0_AM));
    1570                 Assert(ExitReason.IoPortAccess.VpContext.ExecutionState.EferLma == RT_BOOL(pCtx->msrEFER & MSR_K6_EFER_LMA));
    1571                 Assert(ExitReason.IoPortAccess.VpContext.ExecutionState.DebugActive == RT_BOOL(pCtx->dr[7] & X86_DR7_ENABLED_MASK));
    1572                 Assert(ExitReason.IoPortAccess.VpContext.ExecutionState.Reserved0 == 0);
    1573                 Assert(ExitReason.IoPortAccess.VpContext.ExecutionState.Reserved1 == 0);
    1574                 Assert(ExitReason.IoPortAccess.VpContext.Rip == pCtx->rip);
    1575                 Assert(ExitReason.IoPortAccess.VpContext.Rflags == pCtx->rflags.u);
    1576                 Assert(   ExitReason.IoPortAccess.VpContext.Cs.Base     == pCtx->cs.u64Base
    1577                        && ExitReason.IoPortAccess.VpContext.Cs.Limit    == pCtx->cs.u32Limit
    1578                        && ExitReason.IoPortAccess.VpContext.Cs.Selector == pCtx->cs.Sel);
    1579                 break;
    1580             default: break; /* shut up compiler. */
    1581         }
    1582 #endif
    1583 
    1584         /*
    1585          * Deal with the exit.
    1586          */
    1587         switch (ExitReason.ExitReason)
    1588         {
    1589             /* Frequent exits: */
    1590             case WHvRunVpExitReasonCanceled:
    1591             case WHvRunVpExitReasonAlerted:
    1592                 rcStrict = VINF_SUCCESS;
    1593                 break;
    1594 
    1595             case WHvRunVpExitReasonX64Halt:
    1596                 rcStrict = nemR3WinHandleHalt(pVM, pVCpu, pCtx);
    1597                 break;
    1598 
    1599             case WHvRunVpExitReasonMemoryAccess:
    1600                 rcStrict = nemR3WinHandleMemoryAccess(pVM, pVCpu, pCtx, &ExitReason.MemoryAccess);
    1601                 break;
    1602 
    1603             case WHvRunVpExitReasonX64IoPortAccess:
    1604                 rcStrict = nemR3WinHandleIoPortAccess(pVM, pVCpu, pCtx, &ExitReason.IoPortAccess);
    1605                 break;
    1606 
    1607             case WHvRunVpExitReasonX64InterruptWindow:
    1608                 rcStrict = nemR3WinHandleInterruptWindow(pVM, pVCpu, pCtx, &ExitReason);
    1609                 break;
    1610 
    1611             case WHvRunVpExitReasonX64MsrAccess: /* needs configuring */
    1612                 rcStrict = nemR3WinHandleMsrAccess(pVM, pVCpu, pCtx, &ExitReason);
    1613                 break;
    1614 
    1615             case WHvRunVpExitReasonX64Cpuid: /* needs configuring */
    1616                 rcStrict = nemR3WinHandleCpuId(pVM, pVCpu, pCtx, &ExitReason);
    1617                 break;
    1618 
    1619             case WHvRunVpExitReasonException: /* needs configuring */
    1620                 rcStrict = nemR3WinHandleException(pVM, pVCpu, pCtx, &ExitReason);
    1621                 break;
    1622 
    1623             /* Unlikely exits: */
    1624             case WHvRunVpExitReasonUnsupportedFeature:
    1625                 rcStrict = nemR3WinHandleUD(pVM, pVCpu, pCtx, &ExitReason);
    1626                 break;
    1627 
    1628             case WHvRunVpExitReasonUnrecoverableException:
    1629                 rcStrict = nemR3WinHandleTripleFault(pVM, pVCpu, pCtx, &ExitReason);
    1630                 break;
    1631 
    1632             case WHvRunVpExitReasonInvalidVpRegisterValue:
    1633                 rcStrict = nemR3WinHandleInvalidState(pVM, pVCpu, pCtx, &ExitReason);
    1634                 break;
    1635 
    1636             /* Undesired exits: */
    1637             case WHvRunVpExitReasonNone:
    1638             default:
    1639                 AssertLogRelMsgFailed(("Unknown ExitReason: %#x\n", ExitReason.ExitReason));
    1640                 rcStrict = VERR_INTERNAL_ERROR_3;
    1641                 break;
    1642         }
    1643         if (rcStrict != VINF_SUCCESS)
    1644         {
    1645             LogFlow(("nemR3NativeRunGC: returning: %Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    1646             break;
    1647         }
    1648 
    1649 #ifndef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
    1650         /* Hack alert! */
    1651         uint32_t const cMappedPages = pVM->nem.s.cMappedPages;
    1652         if (cMappedPages < 4000)
    1653         { /* likely */ }
    1654         else
    1655         {
    1656             PGMPhysNemEnumPagesByState(pVM, pVCpu, NEM_WIN_PAGE_STATE_READABLE, nemR3WinUnmapOnePageCallback, NULL);
    1657             Log(("nemR3NativeRunGC: Unmapped all; cMappedPages=%u -> %u\n", cMappedPages, pVM->nem.s.cMappedPages));
    1658         }
    1659 #endif
    1660 
    1661         /* If any FF is pending, return to the EM loops.  That's okay for the
    1662            current sledgehammer approach. */
    1663         if (   VM_FF_IS_PENDING(   pVM,   !fSingleStepping ? VM_FF_HP_R0_PRE_HM_MASK    : VM_FF_HP_R0_PRE_HM_STEP_MASK)
    1664             || VMCPU_FF_IS_PENDING(pVCpu, !fSingleStepping ? VMCPU_FF_HP_R0_PRE_HM_MASK : VMCPU_FF_HP_R0_PRE_HM_STEP_MASK) )
    1665         {
    1666             LogFlow(("nemR3NativeRunGC: returning: pending FF (%#x / %#x)\n", pVM->fGlobalForcedActions, pVCpu->fLocalForcedActions));
    1667             break;
    1668         }
    1669     }
    1670 
    1671     return rcStrict;
    1672 }
    1673 #endif /* later */
    1674 
    16751652
    16761653#endif /* IN_RING0 */
  • trunk/src/VBox/VMM/VMMR0/NEMR0Native-win.cpp

    r71152 r71184  
    497497 * @param   fWhat       What to export. To be defined, UINT64_MAX for now.
    498498 */
    499 static int nemR0WinExportState(PGVM pGVM, PGVMCPU pGVCpu, PCPUMCTX pCtx, uint64_t fWhat)
     499static int nemR0WinExportState(PGVM pGVM, PGVMCPU pGVCpu, PCPUMCTX pCtx)
    500500{
    501501    PVMCPU                     pVCpu  = &pGVM->pVM->aCpus[pGVCpu->idCpu];
     
    507507    pInput->RsvdZ       = 0;
    508508
    509     RT_NOREF_PV(fWhat); /** @todo group selection. */
     509    uint64_t const fWhat = ~pCtx->fExtrn & (CPUMCTX_EXTRN_ALL | CPUMCTX_EXTRN_NEM_WIN_MASK);
     510    if (!fWhat)
     511        return VINF_SUCCESS;
     512    uintptr_t iReg = 0;
    510513
    511514    /* GPRs */
    512     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[0]);
    513     pInput->Elements[0].Name                = HvX64RegisterRax;
    514     pInput->Elements[0].Value.Reg64         = pCtx->rax;
    515     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[1]);
    516     pInput->Elements[1].Name                = HvX64RegisterRcx;
    517     pInput->Elements[1].Value.Reg64         = pCtx->rcx;
    518     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[2]);
    519     pInput->Elements[2].Name                = HvX64RegisterRdx;
    520     pInput->Elements[2].Value.Reg64         = pCtx->rdx;
    521     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[3]);
    522     pInput->Elements[3].Name                = HvX64RegisterRbx;
    523     pInput->Elements[3].Value.Reg64         = pCtx->rbx;
    524     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[4]);
    525     pInput->Elements[4].Name                = HvX64RegisterRsp;
    526     pInput->Elements[4].Value.Reg64         = pCtx->rsp;
    527     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[5]);
    528     pInput->Elements[5].Name                = HvX64RegisterRbp;
    529     pInput->Elements[5].Value.Reg64         = pCtx->rbp;
    530     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[6]);
    531     pInput->Elements[6].Name                = HvX64RegisterRsi;
    532     pInput->Elements[6].Value.Reg64         = pCtx->rsi;
    533     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[7]);
    534     pInput->Elements[7].Name                = HvX64RegisterRdi;
    535     pInput->Elements[7].Value.Reg64         = pCtx->rdi;
    536     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[8]);
    537     pInput->Elements[8].Name                = HvX64RegisterR8;
    538     pInput->Elements[8].Value.Reg64         = pCtx->r8;
    539     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[9]);
    540     pInput->Elements[9].Name                = HvX64RegisterR9;
    541     pInput->Elements[9].Value.Reg64         = pCtx->r9;
    542     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[10]);
    543     pInput->Elements[10].Name                = HvX64RegisterR10;
    544     pInput->Elements[10].Value.Reg64         = pCtx->r10;
    545     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[11]);
    546     pInput->Elements[11].Name                = HvX64RegisterR11;
    547     pInput->Elements[11].Value.Reg64         = pCtx->r11;
    548     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[12]);
    549     pInput->Elements[12].Name                = HvX64RegisterR12;
    550     pInput->Elements[12].Value.Reg64         = pCtx->r12;
    551     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[13]);
    552     pInput->Elements[13].Name                = HvX64RegisterR13;
    553     pInput->Elements[13].Value.Reg64         = pCtx->r13;
    554     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[14]);
    555     pInput->Elements[14].Name                = HvX64RegisterR14;
    556     pInput->Elements[14].Value.Reg64         = pCtx->r14;
    557     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[15]);
    558     pInput->Elements[15].Name                = HvX64RegisterR15;
    559     pInput->Elements[15].Value.Reg64         = pCtx->r15;
     515    if (fWhat & CPUMCTX_EXTRN_GPRS_MASK)
     516    {
     517        if (fWhat & CPUMCTX_EXTRN_RAX)
     518        {
     519            HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     520            pInput->Elements[iReg].Name                = HvX64RegisterRax;
     521            pInput->Elements[iReg].Value.Reg64         = pCtx->rax;
     522            iReg++;
     523        }
     524        if (fWhat & CPUMCTX_EXTRN_RCX)
     525        {
     526            HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     527            pInput->Elements[iReg].Name                = HvX64RegisterRcx;
     528            pInput->Elements[iReg].Value.Reg64         = pCtx->rcx;
     529            iReg++;
     530        }
     531        if (fWhat & CPUMCTX_EXTRN_RDX)
     532        {
     533            HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     534            pInput->Elements[iReg].Name                = HvX64RegisterRdx;
     535            pInput->Elements[iReg].Value.Reg64         = pCtx->rdx;
     536            iReg++;
     537        }
     538        if (fWhat & CPUMCTX_EXTRN_RBX)
     539        {
     540            HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     541            pInput->Elements[iReg].Name                = HvX64RegisterRbx;
     542            pInput->Elements[iReg].Value.Reg64         = pCtx->rbx;
     543            iReg++;
     544        }
     545        if (fWhat & CPUMCTX_EXTRN_RSP)
     546        {
     547            HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     548            pInput->Elements[iReg].Name                = HvX64RegisterRsp;
     549            pInput->Elements[iReg].Value.Reg64         = pCtx->rsp;
     550            iReg++;
     551        }
     552        if (fWhat & CPUMCTX_EXTRN_RBP)
     553        {
     554            HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     555            pInput->Elements[iReg].Name                = HvX64RegisterRbp;
     556            pInput->Elements[iReg].Value.Reg64         = pCtx->rbp;
     557            iReg++;
     558        }
     559        if (fWhat & CPUMCTX_EXTRN_RSI)
     560        {
     561            HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     562            pInput->Elements[iReg].Name                = HvX64RegisterRsi;
     563            pInput->Elements[iReg].Value.Reg64         = pCtx->rsi;
     564            iReg++;
     565        }
     566        if (fWhat & CPUMCTX_EXTRN_RDI)
     567        {
     568            HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     569            pInput->Elements[iReg].Name                = HvX64RegisterRdi;
     570            pInput->Elements[iReg].Value.Reg64         = pCtx->rdi;
     571            iReg++;
     572        }
     573        if (fWhat & CPUMCTX_EXTRN_R8_R15)
     574        {
     575            HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     576            pInput->Elements[iReg].Name                = HvX64RegisterR8;
     577            pInput->Elements[iReg].Value.Reg64         = pCtx->r8;
     578            iReg++;
     579            HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     580            pInput->Elements[iReg].Name                = HvX64RegisterR9;
     581            pInput->Elements[iReg].Value.Reg64         = pCtx->r9;
     582            iReg++;
     583            HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     584            pInput->Elements[iReg].Name                = HvX64RegisterR10;
     585            pInput->Elements[iReg].Value.Reg64         = pCtx->r10;
     586            iReg++;
     587            HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     588            pInput->Elements[iReg].Name                = HvX64RegisterR11;
     589            pInput->Elements[iReg].Value.Reg64         = pCtx->r11;
     590            iReg++;
     591            HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     592            pInput->Elements[iReg].Name                = HvX64RegisterR12;
     593            pInput->Elements[iReg].Value.Reg64         = pCtx->r12;
     594            iReg++;
     595            HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     596            pInput->Elements[iReg].Name                = HvX64RegisterR13;
     597            pInput->Elements[iReg].Value.Reg64         = pCtx->r13;
     598            iReg++;
     599            HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     600            pInput->Elements[iReg].Name                = HvX64RegisterR14;
     601            pInput->Elements[iReg].Value.Reg64         = pCtx->r14;
     602            iReg++;
     603            HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     604            pInput->Elements[iReg].Name                = HvX64RegisterR15;
     605            pInput->Elements[iReg].Value.Reg64         = pCtx->r15;
     606            iReg++;
     607        }
     608    }
    560609
    561610    /* RIP & Flags */
    562     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[16]);
    563     pInput->Elements[16].Name                = HvX64RegisterRip;
    564     pInput->Elements[16].Value.Reg64         = pCtx->rip;
    565     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[17]);
    566     pInput->Elements[17].Name                = HvX64RegisterRflags;
    567     pInput->Elements[17].Value.Reg64         = pCtx->rflags.u;
     611    if (fWhat & CPUMCTX_EXTRN_RIP)
     612    {
     613        HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     614        pInput->Elements[iReg].Name                = HvX64RegisterRip;
     615        pInput->Elements[iReg].Value.Reg64         = pCtx->rip;
     616        iReg++;
     617    }
     618    if (fWhat & CPUMCTX_EXTRN_RFLAGS)
     619    {
     620        HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     621        pInput->Elements[iReg].Name                = HvX64RegisterRflags;
     622        pInput->Elements[iReg].Value.Reg64         = pCtx->rflags.u;
     623        iReg++;
     624    }
    568625
    569626    /* Segments */
     
    577634            pInput->Elements[a_idx].Value.Segment.Attributes = (a_SReg).Attr.u; \
    578635        } while (0)
    579     COPY_OUT_SEG(18, HvX64RegisterEs,   pCtx->es);
    580     COPY_OUT_SEG(19, HvX64RegisterCs,   pCtx->cs);
    581     COPY_OUT_SEG(20, HvX64RegisterSs,   pCtx->ss);
    582     COPY_OUT_SEG(21, HvX64RegisterDs,   pCtx->ds);
    583     COPY_OUT_SEG(22, HvX64RegisterFs,   pCtx->fs);
    584     COPY_OUT_SEG(23, HvX64RegisterGs,   pCtx->gs);
    585     COPY_OUT_SEG(24, HvX64RegisterLdtr, pCtx->ldtr);
    586     COPY_OUT_SEG(25, HvX64RegisterTr,   pCtx->tr);
    587 
    588     uintptr_t iReg = 26;
    589     /* Descriptor tables. */
    590     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    591     pInput->Elements[iReg].Value.Table.Pad[0]   = 0;
    592     pInput->Elements[iReg].Value.Table.Pad[1]   = 0;
    593     pInput->Elements[iReg].Value.Table.Pad[2]   = 0;
    594     pInput->Elements[iReg].Name                 = HvX64RegisterIdtr;
    595     pInput->Elements[iReg].Value.Table.Limit    = pCtx->idtr.cbIdt;
    596     pInput->Elements[iReg].Value.Table.Base     = pCtx->idtr.pIdt;
    597     iReg++;
    598     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    599     pInput->Elements[iReg].Value.Table.Pad[0]   = 0;
    600     pInput->Elements[iReg].Value.Table.Pad[1]   = 0;
    601     pInput->Elements[iReg].Value.Table.Pad[2]   = 0;
    602     pInput->Elements[iReg].Name                 = HvX64RegisterGdtr;
    603     pInput->Elements[iReg].Value.Table.Limit    = pCtx->gdtr.cbGdt;
    604     pInput->Elements[iReg].Value.Table.Base     = pCtx->gdtr.pGdt;
    605     iReg++;
     636    if (fWhat & CPUMCTX_EXTRN_SREG_MASK)
     637    {
     638        if (fWhat & CPUMCTX_EXTRN_CS)
     639        {
     640            COPY_OUT_SEG(iReg, HvX64RegisterCs,   pCtx->cs);
     641            iReg++;
     642        }
     643        if (fWhat & CPUMCTX_EXTRN_ES)
     644        {
     645            COPY_OUT_SEG(iReg, HvX64RegisterEs,   pCtx->es);
     646            iReg++;
     647        }
     648        if (fWhat & CPUMCTX_EXTRN_SS)
     649        {
     650            COPY_OUT_SEG(iReg, HvX64RegisterSs,   pCtx->ss);
     651            iReg++;
     652        }
     653        if (fWhat & CPUMCTX_EXTRN_DS)
     654        {
     655            COPY_OUT_SEG(iReg, HvX64RegisterDs,   pCtx->ds);
     656            iReg++;
     657        }
     658        if (fWhat & CPUMCTX_EXTRN_FS)
     659        {
     660            COPY_OUT_SEG(iReg, HvX64RegisterFs,   pCtx->fs);
     661            iReg++;
     662        }
     663        if (fWhat & CPUMCTX_EXTRN_GS)
     664        {
     665            COPY_OUT_SEG(iReg, HvX64RegisterGs,   pCtx->gs);
     666            iReg++;
     667        }
     668    }
     669
     670    /* Descriptor tables & task segment. */
     671    if (fWhat & CPUMCTX_EXTRN_TABLE_MASK)
     672    {
     673        if (fWhat & CPUMCTX_EXTRN_LDTR)
     674        {
     675            COPY_OUT_SEG(iReg, HvX64RegisterLdtr, pCtx->ldtr);
     676            iReg++;
     677        }
     678        if (fWhat & CPUMCTX_EXTRN_TR)
     679        {
     680            COPY_OUT_SEG(iReg, HvX64RegisterTr,   pCtx->tr);
     681            iReg++;
     682        }
     683
     684        if (fWhat & CPUMCTX_EXTRN_IDTR)
     685        {
     686            HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     687            pInput->Elements[iReg].Value.Table.Pad[0]   = 0;
     688            pInput->Elements[iReg].Value.Table.Pad[1]   = 0;
     689            pInput->Elements[iReg].Value.Table.Pad[2]   = 0;
     690            pInput->Elements[iReg].Name                 = HvX64RegisterIdtr;
     691            pInput->Elements[iReg].Value.Table.Limit    = pCtx->idtr.cbIdt;
     692            pInput->Elements[iReg].Value.Table.Base     = pCtx->idtr.pIdt;
     693            iReg++;
     694        }
     695        if (fWhat & CPUMCTX_EXTRN_GDTR)
     696        {
     697            HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     698            pInput->Elements[iReg].Value.Table.Pad[0]   = 0;
     699            pInput->Elements[iReg].Value.Table.Pad[1]   = 0;
     700            pInput->Elements[iReg].Value.Table.Pad[2]   = 0;
     701            pInput->Elements[iReg].Name                 = HvX64RegisterGdtr;
     702            pInput->Elements[iReg].Value.Table.Limit    = pCtx->gdtr.cbGdt;
     703            pInput->Elements[iReg].Value.Table.Base     = pCtx->gdtr.pGdt;
     704            iReg++;
     705        }
     706    }
    606707
    607708    /* Control registers. */
    608     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
    609     pInput->Elements[iReg].Name                 = HvX64RegisterCr0;
    610     pInput->Elements[iReg].Value.Reg64          = pCtx->cr0;
    611     iReg++;
    612     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
    613     pInput->Elements[iReg].Name                 = HvX64RegisterCr2;
    614     pInput->Elements[iReg].Value.Reg64          = pCtx->cr2;
    615     iReg++;
    616     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
    617     pInput->Elements[iReg].Name                 = HvX64RegisterCr3;
    618     pInput->Elements[iReg].Value.Reg64          = pCtx->cr3;
    619     iReg++;
    620     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
    621     pInput->Elements[iReg].Name                 = HvX64RegisterCr4;
    622     pInput->Elements[iReg].Value.Reg64          = pCtx->cr4;
    623     iReg++;
     709    if (fWhat & CPUMCTX_EXTRN_CR_MASK)
     710    {
     711        if (fWhat & CPUMCTX_EXTRN_CR0)
     712        {
     713            HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     714            pInput->Elements[iReg].Name                 = HvX64RegisterCr0;
     715            pInput->Elements[iReg].Value.Reg64          = pCtx->cr0;
     716            iReg++;
     717        }
     718        if (fWhat & CPUMCTX_EXTRN_CR2)
     719        {
     720            HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     721            pInput->Elements[iReg].Name                 = HvX64RegisterCr2;
     722            pInput->Elements[iReg].Value.Reg64          = pCtx->cr2;
     723            iReg++;
     724        }
     725        if (fWhat & CPUMCTX_EXTRN_CR3)
     726        {
     727            HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     728            pInput->Elements[iReg].Name                 = HvX64RegisterCr3;
     729            pInput->Elements[iReg].Value.Reg64          = pCtx->cr3;
     730            iReg++;
     731        }
     732        if (fWhat & CPUMCTX_EXTRN_CR4)
     733        {
     734            HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     735            pInput->Elements[iReg].Name                 = HvX64RegisterCr4;
     736            pInput->Elements[iReg].Value.Reg64          = pCtx->cr4;
     737            iReg++;
     738        }
     739    }
     740    /** @todo CR8/TPR */
    624741    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
    625742    pInput->Elements[iReg].Name                 = HvX64RegisterCr8;
     
    627744    iReg++;
    628745
     746    /** @todo does HvX64RegisterXfem mean XCR0? What about the related MSR. */
     747
    629748    /* Debug registers. */
    630749/** @todo fixme. Figure out what the hyper-v version of KVM_SET_GUEST_DEBUG would be. */
    631     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
    632     pInput->Elements[iReg].Name                 = HvX64RegisterDr0;
    633     //pInput->Elements[iReg].Value.Reg64        = CPUMGetHyperDR0(pVCpu);
    634     pInput->Elements[iReg].Value.Reg64          = pCtx->dr[0];
    635     iReg++;
    636     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
    637     pInput->Elements[iReg].Name                 = HvX64RegisterDr1;
    638     //pInput->Elements[iReg].Value.Reg64        = CPUMGetHyperDR1(pVCpu);
    639     pInput->Elements[iReg].Value.Reg64          = pCtx->dr[1];
    640     iReg++;
    641     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
    642     pInput->Elements[iReg].Name                 = HvX64RegisterDr2;
    643     //pInput->Elements[iReg].Value.Reg64        = CPUMGetHyperDR2(pVCpu);
    644     pInput->Elements[iReg].Value.Reg64          = pCtx->dr[2];
    645     iReg++;
    646     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
    647     pInput->Elements[iReg].Name                 = HvX64RegisterDr3;
    648     //pInput->Elements[iReg].Value.Reg64        = CPUMGetHyperDR3(pVCpu);
    649     pInput->Elements[iReg].Value.Reg64          = pCtx->dr[3];
    650     iReg++;
    651     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
    652     pInput->Elements[iReg].Name                 = HvX64RegisterDr6;
    653     //pInput->Elements[iReg].Value.Reg64        = CPUMGetHyperDR6(pVCpu);
    654     pInput->Elements[iReg].Value.Reg64          = pCtx->dr[6];
    655     iReg++;
    656     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
    657     pInput->Elements[iReg].Name                 = HvX64RegisterDr7;
    658     //pInput->Elements[iReg].Value.Reg64        = CPUMGetHyperDR7(pVCpu);
    659     pInput->Elements[iReg].Value.Reg64          = pCtx->dr[7];
    660     iReg++;
     750    if (fWhat & CPUMCTX_EXTRN_DR0_DR3)
     751    {
     752        HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     753        pInput->Elements[iReg].Name                 = HvX64RegisterDr0;
     754        //pInput->Elements[iReg].Value.Reg64        = CPUMGetHyperDR0(pVCpu);
     755        pInput->Elements[iReg].Value.Reg64          = pCtx->dr[0];
     756        iReg++;
     757        HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     758        pInput->Elements[iReg].Name                 = HvX64RegisterDr1;
     759        //pInput->Elements[iReg].Value.Reg64        = CPUMGetHyperDR1(pVCpu);
     760        pInput->Elements[iReg].Value.Reg64          = pCtx->dr[1];
     761        iReg++;
     762        HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     763        pInput->Elements[iReg].Name                 = HvX64RegisterDr2;
     764        //pInput->Elements[iReg].Value.Reg64        = CPUMGetHyperDR2(pVCpu);
     765        pInput->Elements[iReg].Value.Reg64          = pCtx->dr[2];
     766        iReg++;
     767        HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     768        pInput->Elements[iReg].Name                 = HvX64RegisterDr3;
     769        //pInput->Elements[iReg].Value.Reg64        = CPUMGetHyperDR3(pVCpu);
     770        pInput->Elements[iReg].Value.Reg64          = pCtx->dr[3];
     771        iReg++;
     772    }
     773    if (fWhat & CPUMCTX_EXTRN_DR6)
     774    {
     775        HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     776        pInput->Elements[iReg].Name                 = HvX64RegisterDr6;
     777        //pInput->Elements[iReg].Value.Reg64        = CPUMGetHyperDR6(pVCpu);
     778        pInput->Elements[iReg].Value.Reg64          = pCtx->dr[6];
     779        iReg++;
     780    }
     781    if (fWhat & CPUMCTX_EXTRN_DR7)
     782    {
     783        HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     784        pInput->Elements[iReg].Name                 = HvX64RegisterDr7;
     785        //pInput->Elements[iReg].Value.Reg64        = CPUMGetHyperDR7(pVCpu);
     786        pInput->Elements[iReg].Value.Reg64          = pCtx->dr[7];
     787        iReg++;
     788    }
     789
     790    /* Floating point state. */
     791    if (fWhat & CPUMCTX_EXTRN_X87)
     792    {
     793        HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     794        pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx0;
     795        pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[0].au64[0];
     796        pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[0].au64[1];
     797        iReg++;
     798        HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     799        pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx1;
     800        pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[1].au64[0];
     801        pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[1].au64[1];
     802        iReg++;
     803        HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     804        pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx2;
     805        pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[2].au64[0];
     806        pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[2].au64[1];
     807        iReg++;
     808        HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     809        pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx3;
     810        pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[3].au64[0];
     811        pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[3].au64[1];
     812        iReg++;
     813        HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     814        pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx4;
     815        pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[4].au64[0];
     816        pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[4].au64[1];
     817        iReg++;
     818        HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     819        pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx5;
     820        pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[5].au64[0];
     821        pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[5].au64[1];
     822        iReg++;
     823        HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     824        pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx6;
     825        pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[6].au64[0];
     826        pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[6].au64[1];
     827        iReg++;
     828        HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     829        pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx7;
     830        pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[7].au64[0];
     831        pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[7].au64[1];
     832        iReg++;
     833
     834        HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     835        pInput->Elements[iReg].Name                            = HvX64RegisterFpControlStatus;
     836        pInput->Elements[iReg].Value.FpControlStatus.FpControl = pCtx->pXStateR0->x87.FCW;
     837        pInput->Elements[iReg].Value.FpControlStatus.FpStatus  = pCtx->pXStateR0->x87.FSW;
     838        pInput->Elements[iReg].Value.FpControlStatus.FpTag     = pCtx->pXStateR0->x87.FTW;
     839        pInput->Elements[iReg].Value.FpControlStatus.Reserved  = pCtx->pXStateR0->x87.FTW >> 8;
     840        pInput->Elements[iReg].Value.FpControlStatus.LastFpOp  = pCtx->pXStateR0->x87.FOP;
     841        pInput->Elements[iReg].Value.FpControlStatus.LastFpRip = (pCtx->pXStateR0->x87.FPUIP)
     842                                                               | ((uint64_t)pCtx->pXStateR0->x87.CS << 32)
     843                                                               | ((uint64_t)pCtx->pXStateR0->x87.Rsrvd1 << 48);
     844        iReg++;
     845/** @todo we've got trouble if if we try write just SSE w/o X87.  */
     846        HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     847        pInput->Elements[iReg].Name                                        = HvX64RegisterXmmControlStatus;
     848        pInput->Elements[iReg].Value.XmmControlStatus.LastFpRdp            = (pCtx->pXStateR0->x87.FPUDP)
     849                                                                           | ((uint64_t)pCtx->pXStateR0->x87.DS << 32)
     850                                                                           | ((uint64_t)pCtx->pXStateR0->x87.Rsrvd2 << 48);
     851        pInput->Elements[iReg].Value.XmmControlStatus.XmmStatusControl     = pCtx->pXStateR0->x87.MXCSR;
     852        pInput->Elements[iReg].Value.XmmControlStatus.XmmStatusControlMask = pCtx->pXStateR0->x87.MXCSR_MASK; /** @todo ??? (Isn't this an output field?) */
     853        iReg++;
     854    }
    661855
    662856    /* Vector state. */
    663     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    664     pInput->Elements[iReg].Name                 = HvX64RegisterXmm0;
    665     pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Lo;
    666     pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Hi;
    667     iReg++;
    668     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    669     pInput->Elements[iReg].Name                 = HvX64RegisterXmm1;
    670     pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Lo;
    671     pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Hi;
    672     iReg++;
    673     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    674     pInput->Elements[iReg].Name                 = HvX64RegisterXmm2;
    675     pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Lo;
    676     pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Hi;
    677     iReg++;
    678     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    679     pInput->Elements[iReg].Name                 = HvX64RegisterXmm3;
    680     pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Lo;
    681     pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Hi;
    682     iReg++;
    683     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    684     pInput->Elements[iReg].Name                 = HvX64RegisterXmm4;
    685     pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Lo;
    686     pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Hi;
    687     iReg++;
    688     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    689     pInput->Elements[iReg].Name                 = HvX64RegisterXmm5;
    690     pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Lo;
    691     pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Hi;
    692     iReg++;
    693     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    694     pInput->Elements[iReg].Name                 = HvX64RegisterXmm6;
    695     pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Lo;
    696     pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Hi;
    697     iReg++;
    698     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    699     pInput->Elements[iReg].Name                 = HvX64RegisterXmm7;
    700     pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Lo;
    701     pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Hi;
    702     iReg++;
    703     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    704     pInput->Elements[iReg].Name                 = HvX64RegisterXmm8;
    705     pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Lo;
    706     pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Hi;
    707     iReg++;
    708     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    709     pInput->Elements[iReg].Name                 = HvX64RegisterXmm9;
    710     pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Lo;
    711     pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Hi;
    712     iReg++;
    713     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    714     pInput->Elements[iReg].Name                 = HvX64RegisterXmm10;
    715     pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Lo;
    716     pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Hi;
    717     iReg++;
    718     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    719     pInput->Elements[iReg].Name                 = HvX64RegisterXmm11;
    720     pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Lo;
    721     pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Hi;
    722     iReg++;
    723     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    724     pInput->Elements[iReg].Name                 = HvX64RegisterXmm12;
    725     pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Lo;
    726     pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Hi;
    727     iReg++;
    728     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    729     pInput->Elements[iReg].Name                 = HvX64RegisterXmm13;
    730     pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Lo;
    731     pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Hi;
    732     iReg++;
    733     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    734     pInput->Elements[iReg].Name                 = HvX64RegisterXmm14;
    735     pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Lo;
    736     pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Hi;
    737     iReg++;
    738     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    739     pInput->Elements[iReg].Name                 = HvX64RegisterXmm15;
    740     pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Lo;
    741     pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Hi;
    742     iReg++;
    743 
    744     /* Floating point state. */
    745     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    746     pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx0;
    747     pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[0].au64[0];
    748     pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[0].au64[1];
    749     iReg++;
    750     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    751     pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx1;
    752     pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[1].au64[0];
    753     pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[1].au64[1];
    754     iReg++;
    755     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    756     pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx2;
    757     pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[2].au64[0];
    758     pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[2].au64[1];
    759     iReg++;
    760     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    761     pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx3;
    762     pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[3].au64[0];
    763     pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[3].au64[1];
    764     iReg++;
    765     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    766     pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx4;
    767     pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[4].au64[0];
    768     pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[4].au64[1];
    769     iReg++;
    770     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    771     pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx5;
    772     pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[5].au64[0];
    773     pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[5].au64[1];
    774     iReg++;
    775     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    776     pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx6;
    777     pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[6].au64[0];
    778     pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[6].au64[1];
    779     iReg++;
    780     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    781     pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx7;
    782     pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[7].au64[0];
    783     pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[7].au64[1];
    784     iReg++;
    785 
    786     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    787     pInput->Elements[iReg].Name                            = HvX64RegisterFpControlStatus;
    788     pInput->Elements[iReg].Value.FpControlStatus.FpControl = pCtx->pXStateR0->x87.FCW;
    789     pInput->Elements[iReg].Value.FpControlStatus.FpStatus  = pCtx->pXStateR0->x87.FSW;
    790     pInput->Elements[iReg].Value.FpControlStatus.FpTag     = pCtx->pXStateR0->x87.FTW;
    791     pInput->Elements[iReg].Value.FpControlStatus.Reserved  = pCtx->pXStateR0->x87.FTW >> 8;
    792     pInput->Elements[iReg].Value.FpControlStatus.LastFpOp  = pCtx->pXStateR0->x87.FOP;
    793     pInput->Elements[iReg].Value.FpControlStatus.LastFpRip = (pCtx->pXStateR0->x87.FPUIP)
    794                                                            | ((uint64_t)pCtx->pXStateR0->x87.CS << 32)
    795                                                            | ((uint64_t)pCtx->pXStateR0->x87.Rsrvd1 << 48);
    796     iReg++;
    797 
    798     HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
    799     pInput->Elements[iReg].Name                                        = HvX64RegisterXmmControlStatus;
    800     pInput->Elements[iReg].Value.XmmControlStatus.LastFpRdp            = (pCtx->pXStateR0->x87.FPUDP)
    801                                                                        | ((uint64_t)pCtx->pXStateR0->x87.DS << 32)
    802                                                                        | ((uint64_t)pCtx->pXStateR0->x87.Rsrvd2 << 48);
    803     pInput->Elements[iReg].Value.XmmControlStatus.XmmStatusControl     = pCtx->pXStateR0->x87.MXCSR;
    804     pInput->Elements[iReg].Value.XmmControlStatus.XmmStatusControlMask = pCtx->pXStateR0->x87.MXCSR_MASK; /** @todo ??? (Isn't this an output field?) */
    805     iReg++;
     857    if (fWhat & CPUMCTX_EXTRN_SSE_AVX)
     858    {
     859        HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     860        pInput->Elements[iReg].Name                 = HvX64RegisterXmm0;
     861        pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Lo;
     862        pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Hi;
     863        iReg++;
     864        HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     865        pInput->Elements[iReg].Name                 = HvX64RegisterXmm1;
     866        pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Lo;
     867        pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Hi;
     868        iReg++;
     869        HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     870        pInput->Elements[iReg].Name                 = HvX64RegisterXmm2;
     871        pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Lo;
     872        pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Hi;
     873        iReg++;
     874        HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     875        pInput->Elements[iReg].Name                 = HvX64RegisterXmm3;
     876        pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Lo;
     877        pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Hi;
     878        iReg++;
     879        HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     880        pInput->Elements[iReg].Name                 = HvX64RegisterXmm4;
     881        pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Lo;
     882        pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Hi;
     883        iReg++;
     884        HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     885        pInput->Elements[iReg].Name                 = HvX64RegisterXmm5;
     886        pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Lo;
     887        pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Hi;
     888        iReg++;
     889        HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     890        pInput->Elements[iReg].Name                 = HvX64RegisterXmm6;
     891        pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Lo;
     892        pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Hi;
     893        iReg++;
     894        HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     895        pInput->Elements[iReg].Name                 = HvX64RegisterXmm7;
     896        pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Lo;
     897        pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Hi;
     898        iReg++;
     899        HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     900        pInput->Elements[iReg].Name                 = HvX64RegisterXmm8;
     901        pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Lo;
     902        pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Hi;
     903        iReg++;
     904        HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     905        pInput->Elements[iReg].Name                 = HvX64RegisterXmm9;
     906        pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Lo;
     907        pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Hi;
     908        iReg++;
     909        HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     910        pInput->Elements[iReg].Name                 = HvX64RegisterXmm10;
     911        pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Lo;
     912        pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Hi;
     913        iReg++;
     914        HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     915        pInput->Elements[iReg].Name                 = HvX64RegisterXmm11;
     916        pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Lo;
     917        pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Hi;
     918        iReg++;
     919        HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     920        pInput->Elements[iReg].Name                 = HvX64RegisterXmm12;
     921        pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Lo;
     922        pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Hi;
     923        iReg++;
     924        HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     925        pInput->Elements[iReg].Name                 = HvX64RegisterXmm13;
     926        pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Lo;
     927        pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Hi;
     928        iReg++;
     929        HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     930        pInput->Elements[iReg].Name                 = HvX64RegisterXmm14;
     931        pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Lo;
     932        pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Hi;
     933        iReg++;
     934        HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     935        pInput->Elements[iReg].Name                 = HvX64RegisterXmm15;
     936        pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Lo;
     937        pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Hi;
     938        iReg++;
     939    }
    806940
    807941    /* MSRs */
    808942    // HvX64RegisterTsc - don't touch
    809     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
    810     pInput->Elements[iReg].Name                 = HvX64RegisterEfer;
    811     pInput->Elements[iReg].Value.Reg64          = pCtx->msrEFER;
    812     iReg++;
    813     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
    814     pInput->Elements[iReg].Name                 = HvX64RegisterKernelGsBase;
    815     pInput->Elements[iReg].Value.Reg64          = pCtx->msrKERNELGSBASE;
    816     iReg++;
    817     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
    818     pInput->Elements[iReg].Name                 = HvX64RegisterApicBase;
    819     pInput->Elements[iReg].Value.Reg64          = APICGetBaseMsrNoCheck(pVCpu);
    820     iReg++;
    821     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
    822     pInput->Elements[iReg].Name                 = HvX64RegisterPat;
    823     pInput->Elements[iReg].Value.Reg64          = pCtx->msrPAT;
    824     iReg++;
    825     /// @todo HvX64RegisterSysenterCs
    826     /// @todo HvX64RegisterSysenterEip
    827     /// @todo HvX64RegisterSysenterEsp
    828     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
    829     pInput->Elements[iReg].Name                 = HvX64RegisterStar;
    830     pInput->Elements[iReg].Value.Reg64          = pCtx->msrSTAR;
    831     iReg++;
    832     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
    833     pInput->Elements[iReg].Name                 = HvX64RegisterLstar;
    834     pInput->Elements[iReg].Value.Reg64          = pCtx->msrLSTAR;
    835     iReg++;
    836     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
    837     pInput->Elements[iReg].Name                 = HvX64RegisterCstar;
    838     pInput->Elements[iReg].Value.Reg64          = pCtx->msrCSTAR;
    839     iReg++;
    840     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
    841     pInput->Elements[iReg].Name                 = HvX64RegisterSfmask;
    842     pInput->Elements[iReg].Value.Reg64          = pCtx->msrSFMASK;
    843     iReg++;
     943    /** @todo does HvX64RegisterTsc include TSC_AUX?  Is it TSC_AUX? */
     944    if (fWhat & CPUMCTX_EXTRN_EFER)
     945    {
     946        HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     947        pInput->Elements[iReg].Name                 = HvX64RegisterEfer;
     948        pInput->Elements[iReg].Value.Reg64          = pCtx->msrEFER;
     949        iReg++;
     950    }
     951    if (fWhat & CPUMCTX_EXTRN_KERNEL_GS_BASE)
     952    {
     953        HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     954        pInput->Elements[iReg].Name                 = HvX64RegisterKernelGsBase;
     955        pInput->Elements[iReg].Value.Reg64          = pCtx->msrKERNELGSBASE;
     956        iReg++;
     957    }
     958    if (fWhat & CPUMCTX_EXTRN_SYSENTER_MSRS)
     959    {
     960        HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     961        pInput->Elements[iReg].Name                 = HvX64RegisterSysenterCs;
     962        pInput->Elements[iReg].Value.Reg64          = pCtx->SysEnter.cs;
     963        iReg++;
     964        HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     965        pInput->Elements[iReg].Name                 = HvX64RegisterSysenterEip;
     966        pInput->Elements[iReg].Value.Reg64          = pCtx->SysEnter.eip;
     967        iReg++;
     968        HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     969        pInput->Elements[iReg].Name                 = HvX64RegisterSysenterEsp;
     970        pInput->Elements[iReg].Value.Reg64          = pCtx->SysEnter.esp;
     971        iReg++;
     972    }
     973    if (fWhat & CPUMCTX_EXTRN_SYSCALL_MSRS)
     974    {
     975        HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     976        pInput->Elements[iReg].Name                 = HvX64RegisterStar;
     977        pInput->Elements[iReg].Value.Reg64          = pCtx->msrSTAR;
     978        iReg++;
     979        HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     980        pInput->Elements[iReg].Name                 = HvX64RegisterLstar;
     981        pInput->Elements[iReg].Value.Reg64          = pCtx->msrLSTAR;
     982        iReg++;
     983        HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     984        pInput->Elements[iReg].Name                 = HvX64RegisterCstar;
     985        pInput->Elements[iReg].Value.Reg64          = pCtx->msrCSTAR;
     986        iReg++;
     987        HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     988        pInput->Elements[iReg].Name                 = HvX64RegisterSfmask;
     989        pInput->Elements[iReg].Value.Reg64          = pCtx->msrSFMASK;
     990        iReg++;
     991    }
     992    if (fWhat & CPUMCTX_EXTRN_OTHER_MSRS)
     993    {
     994        HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     995        pInput->Elements[iReg].Name                 = HvX64RegisterApicBase;
     996        pInput->Elements[iReg].Value.Reg64          = APICGetBaseMsrNoCheck(pVCpu);
     997        iReg++;
     998        HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     999        pInput->Elements[iReg].Name                 = HvX64RegisterPat;
     1000        pInput->Elements[iReg].Value.Reg64          = pCtx->msrPAT;
     1001        iReg++;
     1002    }
    8441003
    8451004    /* event injection (always clear it). */
    846     HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
    847     pInput->Elements[iReg].Name                 = HvRegisterPendingInterruption;
    848     pInput->Elements[iReg].Value.Reg64          = 0;
    849     iReg++;
     1005    if (fWhat & CPUMCTX_EXTRN_NEM_WIN_EVENT_INJECT)
     1006    {
     1007        HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     1008        pInput->Elements[iReg].Name                 = HvRegisterPendingInterruption;
     1009        pInput->Elements[iReg].Value.Reg64          = 0;
     1010        iReg++;
     1011    }
    8501012    /// @todo HvRegisterInterruptState
    8511013    /// @todo HvRegisterPendingEvent0
     
    8651027                          ("uResult=%RX64 iRegs=%#x\n", uResult, iReg),
    8661028                          VERR_NEM_SET_REGISTERS_FAILED);
     1029    //LogFlow(("nemR0WinExportState: uResult=%#RX64 iReg=%zu fWhat=%#018RX64 fExtrn=%#018RX64 -> %#018RX64\n", uResult, iReg, fWhat, pCtx->fExtrn,
     1030    //         pCtx->fExtrn | CPUMCTX_EXTRN_ALL | CPUMCTX_EXTRN_NEM_WIN_MASK | CPUMCTX_EXTRN_KEEPER_NEM ));
     1031    pCtx->fExtrn |= CPUMCTX_EXTRN_ALL | CPUMCTX_EXTRN_NEM_WIN_MASK | CPUMCTX_EXTRN_KEEPER_NEM;
    8671032    return VINF_SUCCESS;
    8681033}
     
    8771042 * @param   idCpu       The calling EMT.  Necessary for getting the
    8781043 *                      hypercall page and arguments.
    879  * @param   fWhat       What to export. To be defined, UINT64_MAX for now.
    8801044 */
    881 VMMR0_INT_DECL(int)  NEMR0ExportState(PGVM pGVM, PVM pVM, VMCPUID idCpu, uint64_t fWhat)
     1045VMMR0_INT_DECL(int)  NEMR0ExportState(PGVM pGVM, PVM pVM, VMCPUID idCpu)
    8821046{
    8831047    /*
     
    8941058         * Call worker.
    8951059         */
    896         rc = nemR0WinExportState(pGVM, pGVCpu, CPUMQueryGuestCtxPtr(pVCpu), fWhat);
     1060        rc = nemR0WinExportState(pGVM, pGVCpu, CPUMQueryGuestCtxPtr(pVCpu));
    8971061    }
    8981062    return rc;
     
    9091073 * @param   pGVCpu      The irng-0 VCPU handle.
    9101074 * @param   pCtx        The CPU context structure to import into.
    911  * @param   fWhat       What to import. To be defined, UINT64_MAX for now.
     1075 * @param   fWhat       What to import, CPUMCTX_EXTRN_XXX.
    9121076 */
    9131077static int nemR0WinImportState(PGVM pGVM, PGVMCPU pGVCpu, PCPUMCTX pCtx, uint64_t fWhat)
     
    9161080    AssertPtrReturn(pInput, VERR_INTERNAL_ERROR_3);
    9171081
     1082    fWhat &= pCtx->fExtrn;
     1083
    9181084    pInput->PartitionId = pGVM->nem.s.idHvPartition;
    9191085    pInput->VpIndex     = pGVCpu->idCpu;
    9201086    pInput->fFlags      = 0;
    9211087
    922     RT_NOREF_PV(fWhat); /** @todo group selection. */
    923 
    9241088    /* GPRs */
    925     pInput->Names[0]  = HvX64RegisterRax;
    926     pInput->Names[1]  = HvX64RegisterRcx;
    927     pInput->Names[2]  = HvX64RegisterRdx;
    928     pInput->Names[3]  = HvX64RegisterRbx;
    929     pInput->Names[4]  = HvX64RegisterRsp;
    930     pInput->Names[5]  = HvX64RegisterRbp;
    931     pInput->Names[6]  = HvX64RegisterRsi;
    932     pInput->Names[7]  = HvX64RegisterRdi;
    933     pInput->Names[8]  = HvX64RegisterR8;
    934     pInput->Names[9]  = HvX64RegisterR9;
    935     pInput->Names[10] = HvX64RegisterR10;
    936     pInput->Names[11] = HvX64RegisterR11;
    937     pInput->Names[12] = HvX64RegisterR12;
    938     pInput->Names[13] = HvX64RegisterR13;
    939     pInput->Names[14] = HvX64RegisterR14;
    940     pInput->Names[15] = HvX64RegisterR15;
     1089    uintptr_t iReg = 0;
     1090    if (fWhat & CPUMCTX_EXTRN_GPRS_MASK)
     1091    {
     1092        if (fWhat & CPUMCTX_EXTRN_RAX)
     1093            pInput->Names[iReg++] = HvX64RegisterRax;
     1094        if (fWhat & CPUMCTX_EXTRN_RCX)
     1095            pInput->Names[iReg++] = HvX64RegisterRcx;
     1096        if (fWhat & CPUMCTX_EXTRN_RDX)
     1097            pInput->Names[iReg++] = HvX64RegisterRdx;
     1098        if (fWhat & CPUMCTX_EXTRN_RBX)
     1099            pInput->Names[iReg++] = HvX64RegisterRbx;
     1100        if (fWhat & CPUMCTX_EXTRN_RSP)
     1101            pInput->Names[iReg++] = HvX64RegisterRsp;
     1102        if (fWhat & CPUMCTX_EXTRN_RBP)
     1103            pInput->Names[iReg++] = HvX64RegisterRbp;
     1104        if (fWhat & CPUMCTX_EXTRN_RSI)
     1105            pInput->Names[iReg++] = HvX64RegisterRsi;
     1106        if (fWhat & CPUMCTX_EXTRN_RDI)
     1107            pInput->Names[iReg++] = HvX64RegisterRdi;
     1108        if (fWhat & CPUMCTX_EXTRN_R8_R15)
     1109        {
     1110            pInput->Names[iReg++] = HvX64RegisterR8;
     1111            pInput->Names[iReg++] = HvX64RegisterR9;
     1112            pInput->Names[iReg++] = HvX64RegisterR10;
     1113            pInput->Names[iReg++] = HvX64RegisterR11;
     1114            pInput->Names[iReg++] = HvX64RegisterR12;
     1115            pInput->Names[iReg++] = HvX64RegisterR13;
     1116            pInput->Names[iReg++] = HvX64RegisterR14;
     1117            pInput->Names[iReg++] = HvX64RegisterR15;
     1118        }
     1119    }
    9411120
    9421121    /* RIP & Flags */
    943     pInput->Names[16] = HvX64RegisterRip;
    944     pInput->Names[17] = HvX64RegisterRflags;
     1122    if (fWhat & CPUMCTX_EXTRN_RIP)
     1123        pInput->Names[iReg++]  = HvX64RegisterRip;
     1124    if (fWhat & CPUMCTX_EXTRN_RFLAGS)
     1125        pInput->Names[iReg++] = HvX64RegisterRflags;
    9451126
    9461127    /* Segments */
    947     pInput->Names[18] = HvX64RegisterEs;
    948     pInput->Names[19] = HvX64RegisterCs;
    949     pInput->Names[20] = HvX64RegisterSs;
    950     pInput->Names[21] = HvX64RegisterDs;
    951     pInput->Names[22] = HvX64RegisterFs;
    952     pInput->Names[23] = HvX64RegisterGs;
    953     pInput->Names[24] = HvX64RegisterLdtr;
    954     pInput->Names[25] = HvX64RegisterTr;
    955 
    956     /* Descriptor tables. */
    957     pInput->Names[26] = HvX64RegisterIdtr;
    958     pInput->Names[27] = HvX64RegisterGdtr;
     1128    if (fWhat & CPUMCTX_EXTRN_SREG_MASK)
     1129    {
     1130        if (fWhat & CPUMCTX_EXTRN_CS)
     1131            pInput->Names[iReg++] = HvX64RegisterCs;
     1132        if (fWhat & CPUMCTX_EXTRN_ES)
     1133            pInput->Names[iReg++] = HvX64RegisterEs;
     1134        if (fWhat & CPUMCTX_EXTRN_SS)
     1135            pInput->Names[iReg++] = HvX64RegisterSs;
     1136        if (fWhat & CPUMCTX_EXTRN_DS)
     1137            pInput->Names[iReg++] = HvX64RegisterDs;
     1138        if (fWhat & CPUMCTX_EXTRN_FS)
     1139            pInput->Names[iReg++] = HvX64RegisterFs;
     1140        if (fWhat & CPUMCTX_EXTRN_GS)
     1141            pInput->Names[iReg++] = HvX64RegisterGs;
     1142    }
     1143
     1144    /* Descriptor tables and the task segment. */
     1145    if (fWhat & CPUMCTX_EXTRN_TABLE_MASK)
     1146    {
     1147        if (fWhat & CPUMCTX_EXTRN_LDTR)
     1148            pInput->Names[iReg++] = HvX64RegisterLdtr;
     1149        if (fWhat & CPUMCTX_EXTRN_TR)
     1150            pInput->Names[iReg++] = HvX64RegisterTr;
     1151        if (fWhat & CPUMCTX_EXTRN_IDTR)
     1152            pInput->Names[iReg++] = HvX64RegisterIdtr;
     1153        if (fWhat & CPUMCTX_EXTRN_GDTR)
     1154            pInput->Names[iReg++] = HvX64RegisterGdtr;
     1155    }
    9591156
    9601157    /* Control registers. */
    961     pInput->Names[28] = HvX64RegisterCr0;
    962     pInput->Names[29] = HvX64RegisterCr2;
    963     pInput->Names[30] = HvX64RegisterCr3;
    964     pInput->Names[31] = HvX64RegisterCr4;
    965     pInput->Names[32] = HvX64RegisterCr8;
     1158    if (fWhat & CPUMCTX_EXTRN_CR_MASK)
     1159    {
     1160        if (fWhat & CPUMCTX_EXTRN_CR0)
     1161            pInput->Names[iReg++] = HvX64RegisterCr0;
     1162        if (fWhat & CPUMCTX_EXTRN_CR2)
     1163            pInput->Names[iReg++] = HvX64RegisterCr2;
     1164        if (fWhat & CPUMCTX_EXTRN_CR3)
     1165            pInput->Names[iReg++] = HvX64RegisterCr3;
     1166        if (fWhat & CPUMCTX_EXTRN_CR4)
     1167            pInput->Names[iReg++] = HvX64RegisterCr4;
     1168    }
     1169    pInput->Names[iReg++] = HvX64RegisterCr8; /// @todo CR8/TPR
    9661170
    9671171    /* Debug registers. */
    968     pInput->Names[33] = HvX64RegisterDr0;
    969     pInput->Names[34] = HvX64RegisterDr1;
    970     pInput->Names[35] = HvX64RegisterDr2;
    971     pInput->Names[36] = HvX64RegisterDr3;
    972     pInput->Names[37] = HvX64RegisterDr6;
    973     pInput->Names[38] = HvX64RegisterDr7;
     1172    if (fWhat & CPUMCTX_EXTRN_DR0_DR3)
     1173    {
     1174        pInput->Names[iReg++] = HvX64RegisterDr0;
     1175        pInput->Names[iReg++] = HvX64RegisterDr1;
     1176        pInput->Names[iReg++] = HvX64RegisterDr2;
     1177        pInput->Names[iReg++] = HvX64RegisterDr3;
     1178    }
     1179    if (fWhat & CPUMCTX_EXTRN_DR6)
     1180        pInput->Names[iReg++] = HvX64RegisterDr6;
     1181    if (fWhat & CPUMCTX_EXTRN_DR7)
     1182        pInput->Names[iReg++] = HvX64RegisterDr7;
     1183
     1184    /* Floating point state. */
     1185    if (fWhat & CPUMCTX_EXTRN_X87)
     1186    {
     1187        pInput->Names[iReg++] = HvX64RegisterFpMmx0;
     1188        pInput->Names[iReg++] = HvX64RegisterFpMmx1;
     1189        pInput->Names[iReg++] = HvX64RegisterFpMmx2;
     1190        pInput->Names[iReg++] = HvX64RegisterFpMmx3;
     1191        pInput->Names[iReg++] = HvX64RegisterFpMmx4;
     1192        pInput->Names[iReg++] = HvX64RegisterFpMmx5;
     1193        pInput->Names[iReg++] = HvX64RegisterFpMmx6;
     1194        pInput->Names[iReg++] = HvX64RegisterFpMmx7;
     1195        pInput->Names[iReg++] = HvX64RegisterFpControlStatus;
     1196    }
     1197    if (fWhat & (CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX))
     1198        pInput->Names[iReg++] = HvX64RegisterXmmControlStatus;
    9741199
    9751200    /* Vector state. */
    976     pInput->Names[39] = HvX64RegisterXmm0;
    977     pInput->Names[40] = HvX64RegisterXmm1;
    978     pInput->Names[41] = HvX64RegisterXmm2;
    979     pInput->Names[42] = HvX64RegisterXmm3;
    980     pInput->Names[43] = HvX64RegisterXmm4;
    981     pInput->Names[44] = HvX64RegisterXmm5;
    982     pInput->Names[45] = HvX64RegisterXmm6;
    983     pInput->Names[46] = HvX64RegisterXmm7;
    984     pInput->Names[47] = HvX64RegisterXmm8;
    985     pInput->Names[48] = HvX64RegisterXmm9;
    986     pInput->Names[49] = HvX64RegisterXmm10;
    987     pInput->Names[50] = HvX64RegisterXmm11;
    988     pInput->Names[51] = HvX64RegisterXmm12;
    989     pInput->Names[52] = HvX64RegisterXmm13;
    990     pInput->Names[53] = HvX64RegisterXmm14;
    991     pInput->Names[54] = HvX64RegisterXmm15;
    992 
    993     /* Floating point state. */
    994     pInput->Names[55] = HvX64RegisterFpMmx0;
    995     pInput->Names[56] = HvX64RegisterFpMmx1;
    996     pInput->Names[57] = HvX64RegisterFpMmx2;
    997     pInput->Names[58] = HvX64RegisterFpMmx3;
    998     pInput->Names[59] = HvX64RegisterFpMmx4;
    999     pInput->Names[60] = HvX64RegisterFpMmx5;
    1000     pInput->Names[61] = HvX64RegisterFpMmx6;
    1001     pInput->Names[62] = HvX64RegisterFpMmx7;
    1002     pInput->Names[63] = HvX64RegisterFpControlStatus;
    1003     pInput->Names[64] = HvX64RegisterXmmControlStatus;
     1201    if (fWhat & CPUMCTX_EXTRN_SSE_AVX)
     1202    {
     1203        pInput->Names[iReg++] = HvX64RegisterXmm0;
     1204        pInput->Names[iReg++] = HvX64RegisterXmm1;
     1205        pInput->Names[iReg++] = HvX64RegisterXmm2;
     1206        pInput->Names[iReg++] = HvX64RegisterXmm3;
     1207        pInput->Names[iReg++] = HvX64RegisterXmm4;
     1208        pInput->Names[iReg++] = HvX64RegisterXmm5;
     1209        pInput->Names[iReg++] = HvX64RegisterXmm6;
     1210        pInput->Names[iReg++] = HvX64RegisterXmm7;
     1211        pInput->Names[iReg++] = HvX64RegisterXmm8;
     1212        pInput->Names[iReg++] = HvX64RegisterXmm9;
     1213        pInput->Names[iReg++] = HvX64RegisterXmm10;
     1214        pInput->Names[iReg++] = HvX64RegisterXmm11;
     1215        pInput->Names[iReg++] = HvX64RegisterXmm12;
     1216        pInput->Names[iReg++] = HvX64RegisterXmm13;
     1217        pInput->Names[iReg++] = HvX64RegisterXmm14;
     1218        pInput->Names[iReg++] = HvX64RegisterXmm15;
     1219    }
    10041220
    10051221    /* MSRs */
    10061222    // HvX64RegisterTsc - don't touch
    1007     pInput->Names[65] = HvX64RegisterEfer;
    1008     pInput->Names[66] = HvX64RegisterKernelGsBase;
    1009     pInput->Names[67] = HvX64RegisterApicBase;
    1010     pInput->Names[68] = HvX64RegisterPat;
    1011     pInput->Names[69] = HvX64RegisterSysenterCs;
    1012     pInput->Names[70] = HvX64RegisterSysenterEip;
    1013     pInput->Names[71] = HvX64RegisterSysenterEsp;
    1014     pInput->Names[72] = HvX64RegisterStar;
    1015     pInput->Names[73] = HvX64RegisterLstar;
    1016     pInput->Names[74] = HvX64RegisterCstar;
    1017     pInput->Names[75] = HvX64RegisterSfmask;
     1223    if (fWhat & CPUMCTX_EXTRN_EFER)
     1224        pInput->Names[iReg++] = HvX64RegisterEfer;
     1225    if (fWhat & CPUMCTX_EXTRN_KERNEL_GS_BASE)
     1226        pInput->Names[iReg++] = HvX64RegisterKernelGsBase;
     1227    if (fWhat & CPUMCTX_EXTRN_SYSENTER_MSRS)
     1228    {
     1229        pInput->Names[iReg++] = HvX64RegisterSysenterCs;
     1230        pInput->Names[iReg++] = HvX64RegisterSysenterEip;
     1231        pInput->Names[iReg++] = HvX64RegisterSysenterEsp;
     1232    }
     1233    if (fWhat & CPUMCTX_EXTRN_SYSCALL_MSRS)
     1234    {
     1235        pInput->Names[iReg++] = HvX64RegisterStar;
     1236        pInput->Names[iReg++] = HvX64RegisterLstar;
     1237        pInput->Names[iReg++] = HvX64RegisterCstar;
     1238        pInput->Names[iReg++] = HvX64RegisterSfmask;
     1239    }
     1240
     1241    if (fWhat & CPUMCTX_EXTRN_OTHER_MSRS)
     1242    {
     1243        pInput->Names[iReg++] = HvX64RegisterApicBase; /// @todo APIC BASE
     1244        pInput->Names[iReg++] = HvX64RegisterPat;
     1245    }
    10181246
    10191247    /* event injection */
    1020     pInput->Names[76] = HvRegisterPendingInterruption;
    1021     pInput->Names[77] = HvRegisterInterruptState;
    1022     pInput->Names[78] = HvRegisterInterruptState;
    1023     pInput->Names[79] = HvRegisterPendingEvent0;
    1024     pInput->Names[80] = HvRegisterPendingEvent1;
    1025     unsigned const cRegs   = 81;
    1026     size_t const   cbInput = RT_ALIGN_Z(RT_OFFSETOF(HV_INPUT_GET_VP_REGISTERS, Names[cRegs]), 32);
     1248    pInput->Names[iReg++] = HvRegisterPendingInterruption;
     1249    pInput->Names[iReg++] = HvRegisterInterruptState;
     1250    pInput->Names[iReg++] = HvRegisterInterruptState;
     1251    pInput->Names[iReg++] = HvRegisterPendingEvent0;
     1252    pInput->Names[iReg++] = HvRegisterPendingEvent1;
     1253    size_t const cRegs   = iReg;
     1254    size_t const cbInput = RT_ALIGN_Z(RT_OFFSETOF(HV_INPUT_GET_VP_REGISTERS, Names[cRegs]), 32);
    10271255
    10281256    HV_REGISTER_VALUE *paValues = (HV_REGISTER_VALUE *)((uint8_t *)pInput + cbInput);
     
    10391267                          ("uResult=%RX64 cRegs=%#x\n", uResult, cRegs),
    10401268                          VERR_NEM_GET_REGISTERS_FAILED);
     1269    //LogFlow(("nemR0WinImportState: uResult=%#RX64 iReg=%zu fWhat=%#018RX64 fExtr=%#018RX64\n", uResult, cRegs, fWhat, pCtx->fExtrn));
    10411270
    10421271    /*
     
    10441273     */
    10451274    PVMCPU pVCpu = &pGVM->pVM->aCpus[pGVCpu->idCpu];
     1275    iReg = 0;
    10461276
    10471277    /* GPRs */
    1048     Assert(pInput->Names[0]  == HvX64RegisterRax);
    1049     Assert(pInput->Names[15] == HvX64RegisterR15);
    1050     pCtx->rax = paValues[0].Reg64;
    1051     pCtx->rcx = paValues[1].Reg64;
    1052     pCtx->rdx = paValues[2].Reg64;
    1053     pCtx->rbx = paValues[3].Reg64;
    1054     pCtx->rsp = paValues[4].Reg64;
    1055     pCtx->rbp = paValues[5].Reg64;
    1056     pCtx->rsi = paValues[6].Reg64;
    1057     pCtx->rdi = paValues[7].Reg64;
    1058     pCtx->r8  = paValues[8].Reg64;
    1059     pCtx->r9  = paValues[9].Reg64;
    1060     pCtx->r10 = paValues[10].Reg64;
    1061     pCtx->r11 = paValues[11].Reg64;
    1062     pCtx->r12 = paValues[12].Reg64;
    1063     pCtx->r13 = paValues[13].Reg64;
    1064     pCtx->r14 = paValues[14].Reg64;
    1065     pCtx->r15 = paValues[15].Reg64;
     1278    if (fWhat & CPUMCTX_EXTRN_GPRS_MASK)
     1279    {
     1280        if (fWhat & CPUMCTX_EXTRN_RAX)
     1281        {
     1282            Assert(pInput->Names[iReg] == HvX64RegisterRax);
     1283            pCtx->rax = paValues[iReg++].Reg64;
     1284        }
     1285        if (fWhat & CPUMCTX_EXTRN_RCX)
     1286        {
     1287            Assert(pInput->Names[iReg] == HvX64RegisterRcx);
     1288            pCtx->rcx = paValues[iReg++].Reg64;
     1289        }
     1290        if (fWhat & CPUMCTX_EXTRN_RDX)
     1291        {
     1292            Assert(pInput->Names[iReg] == HvX64RegisterRdx);
     1293            pCtx->rdx = paValues[iReg++].Reg64;
     1294        }
     1295        if (fWhat & CPUMCTX_EXTRN_RBX)
     1296        {
     1297            Assert(pInput->Names[iReg] == HvX64RegisterRbx);
     1298            pCtx->rbx = paValues[iReg++].Reg64;
     1299        }
     1300        if (fWhat & CPUMCTX_EXTRN_RSP)
     1301        {
     1302            Assert(pInput->Names[iReg] == HvX64RegisterRsp);
     1303            pCtx->rsp = paValues[iReg++].Reg64;
     1304        }
     1305        if (fWhat & CPUMCTX_EXTRN_RBP)
     1306        {
     1307            Assert(pInput->Names[iReg] == HvX64RegisterRbp);
     1308            pCtx->rbp = paValues[iReg++].Reg64;
     1309        }
     1310        if (fWhat & CPUMCTX_EXTRN_RSI)
     1311        {
     1312            Assert(pInput->Names[iReg] == HvX64RegisterRsi);
     1313            pCtx->rsi = paValues[iReg++].Reg64;
     1314        }
     1315        if (fWhat & CPUMCTX_EXTRN_RDI)
     1316        {
     1317            Assert(pInput->Names[iReg] == HvX64RegisterRdi);
     1318            pCtx->rdi = paValues[iReg++].Reg64;
     1319        }
     1320        if (fWhat & CPUMCTX_EXTRN_R8_R15)
     1321        {
     1322            Assert(pInput->Names[iReg] == HvX64RegisterR8);
     1323            Assert(pInput->Names[iReg + 7] == HvX64RegisterR15);
     1324            pCtx->r8  = paValues[iReg++].Reg64;
     1325            pCtx->r9  = paValues[iReg++].Reg64;
     1326            pCtx->r10 = paValues[iReg++].Reg64;
     1327            pCtx->r11 = paValues[iReg++].Reg64;
     1328            pCtx->r12 = paValues[iReg++].Reg64;
     1329            pCtx->r13 = paValues[iReg++].Reg64;
     1330            pCtx->r14 = paValues[iReg++].Reg64;
     1331            pCtx->r15 = paValues[iReg++].Reg64;
     1332        }
     1333    }
    10661334
    10671335    /* RIP & Flags */
    1068     Assert(pInput->Names[16] == HvX64RegisterRip);
    1069     pCtx->rip      = paValues[16].Reg64;
    1070     pCtx->rflags.u = paValues[17].Reg64;
     1336    if (fWhat & CPUMCTX_EXTRN_RIP)
     1337    {
     1338        Assert(pInput->Names[iReg] == HvX64RegisterRip);
     1339        pCtx->rip      = paValues[iReg++].Reg64;
     1340    }
     1341    if (fWhat & CPUMCTX_EXTRN_RFLAGS)
     1342    {
     1343        Assert(pInput->Names[iReg] == HvX64RegisterRflags);
     1344        pCtx->rflags.u = paValues[iReg++].Reg64;
     1345    }
    10711346
    10721347    /* Segments */
     
    10801355            (a_SReg).fFlags   = CPUMSELREG_FLAGS_VALID; \
    10811356        } while (0)
    1082     COPY_BACK_SEG(18, HvX64RegisterEs,   pCtx->es);
    1083     COPY_BACK_SEG(19, HvX64RegisterCs,   pCtx->cs);
    1084     COPY_BACK_SEG(20, HvX64RegisterSs,   pCtx->ss);
    1085     COPY_BACK_SEG(21, HvX64RegisterDs,   pCtx->ds);
    1086     COPY_BACK_SEG(22, HvX64RegisterFs,   pCtx->fs);
    1087     COPY_BACK_SEG(23, HvX64RegisterGs,   pCtx->gs);
    1088     COPY_BACK_SEG(24, HvX64RegisterLdtr, pCtx->ldtr);
    1089     COPY_BACK_SEG(25, HvX64RegisterTr,   pCtx->tr);
    1090 
    1091     /* Descriptor tables. */
    1092     Assert(pInput->Names[26] == HvX64RegisterIdtr);
    1093     pCtx->idtr.cbIdt = paValues[26].Table.Limit;
    1094     pCtx->idtr.pIdt  = paValues[26].Table.Base;
    1095     Assert(pInput->Names[27] == HvX64RegisterGdtr);
    1096     pCtx->gdtr.cbGdt = paValues[27].Table.Limit;
    1097     pCtx->gdtr.pGdt  = paValues[27].Table.Base;
     1357    if (fWhat & CPUMCTX_EXTRN_SREG_MASK)
     1358    {
     1359        if (fWhat & CPUMCTX_EXTRN_CS)
     1360        {
     1361            COPY_BACK_SEG(iReg, HvX64RegisterCs,   pCtx->cs);
     1362            iReg++;
     1363        }
     1364        if (fWhat & CPUMCTX_EXTRN_ES)
     1365        {
     1366            COPY_BACK_SEG(iReg, HvX64RegisterEs,   pCtx->es);
     1367            iReg++;
     1368        }
     1369        if (fWhat & CPUMCTX_EXTRN_SS)
     1370        {
     1371            COPY_BACK_SEG(iReg, HvX64RegisterSs,   pCtx->ss);
     1372            iReg++;
     1373        }
     1374        if (fWhat & CPUMCTX_EXTRN_DS)
     1375        {
     1376            COPY_BACK_SEG(iReg, HvX64RegisterDs,   pCtx->ds);
     1377            iReg++;
     1378        }
     1379        if (fWhat & CPUMCTX_EXTRN_FS)
     1380        {
     1381            COPY_BACK_SEG(iReg, HvX64RegisterFs,   pCtx->fs);
     1382            iReg++;
     1383        }
     1384        if (fWhat & CPUMCTX_EXTRN_GS)
     1385        {
     1386            COPY_BACK_SEG(iReg, HvX64RegisterGs,   pCtx->gs);
     1387            iReg++;
     1388        }
     1389    }
     1390    /* Descriptor tables and the task segment. */
     1391    if (fWhat & CPUMCTX_EXTRN_TABLE_MASK)
     1392    {
     1393        if (fWhat & CPUMCTX_EXTRN_LDTR)
     1394        {
     1395            COPY_BACK_SEG(iReg, HvX64RegisterLdtr, pCtx->ldtr);
     1396            iReg++;
     1397        }
     1398        if (fWhat & CPUMCTX_EXTRN_TR)
     1399        {
     1400            COPY_BACK_SEG(iReg, HvX64RegisterTr,   pCtx->tr);
     1401            iReg++;
     1402        }
     1403        if (fWhat & CPUMCTX_EXTRN_IDTR)
     1404        {
     1405            Assert(pInput->Names[iReg] == HvX64RegisterIdtr);
     1406            pCtx->idtr.cbIdt = paValues[iReg].Table.Limit;
     1407            pCtx->idtr.pIdt  = paValues[iReg].Table.Base;
     1408            iReg++;
     1409        }
     1410        if (fWhat & CPUMCTX_EXTRN_GDTR)
     1411        {
     1412            Assert(pInput->Names[iReg] == HvX64RegisterGdtr);
     1413            pCtx->gdtr.cbGdt = paValues[iReg].Table.Limit;
     1414            pCtx->gdtr.pGdt  = paValues[iReg].Table.Base;
     1415            iReg++;
     1416        }
     1417    }
    10981418
    10991419    /* Control registers. */
    1100     Assert(pInput->Names[28] == HvX64RegisterCr0);
    11011420    bool fMaybeChangedMode = false;
    11021421    bool fFlushTlb         = false;
    11031422    bool fFlushGlobalTlb   = false;
    1104     if (pCtx->cr0 != paValues[28].Reg64)
    1105     {
    1106         CPUMSetGuestCR0(pVCpu, paValues[28].Reg64);
    1107         fMaybeChangedMode = true;
    1108         fFlushTlb = fFlushGlobalTlb = true; /// @todo fix this
    1109     }
    1110     Assert(pInput->Names[29] == HvX64RegisterCr2);
    1111     pCtx->cr2 = paValues[29].Reg64;
    1112     if (pCtx->cr3 != paValues[30].Reg64)
    1113     {
    1114         CPUMSetGuestCR3(pVCpu, paValues[30].Reg64);
    1115         fFlushTlb = true;
    1116     }
    1117     if (pCtx->cr4 != paValues[31].Reg64)
    1118     {
    1119         CPUMSetGuestCR4(pVCpu, paValues[31].Reg64);
    1120         fMaybeChangedMode = true;
    1121         fFlushTlb = fFlushGlobalTlb = true; /// @todo fix this
    1122     }
    1123     APICSetTpr(pVCpu, (uint8_t)paValues[32].Reg64 << 4);
     1423    if (fWhat & CPUMCTX_EXTRN_CR_MASK)
     1424    {
     1425        if (fWhat & CPUMCTX_EXTRN_CR0)
     1426        {
     1427            Assert(pInput->Names[iReg] == HvX64RegisterCr0);
     1428            if (pCtx->cr0 != paValues[iReg].Reg64)
     1429            {
     1430                CPUMSetGuestCR0(pVCpu, paValues[iReg].Reg64);
     1431                fMaybeChangedMode = true;
     1432                fFlushTlb = fFlushGlobalTlb = true; /// @todo fix this
     1433            }
     1434            iReg++;
     1435        }
     1436        if (fWhat & CPUMCTX_EXTRN_CR2)
     1437        {
     1438            Assert(pInput->Names[iReg] == HvX64RegisterCr2);
     1439            pCtx->cr2 = paValues[iReg].Reg64;
     1440            iReg++;
     1441        }
     1442        if (fWhat & CPUMCTX_EXTRN_CR3)
     1443        {
     1444            Assert(pInput->Names[iReg] == HvX64RegisterCr3);
     1445            if (pCtx->cr3 != paValues[iReg].Reg64)
     1446            {
     1447                CPUMSetGuestCR3(pVCpu, paValues[iReg].Reg64);
     1448                fFlushTlb = true;
     1449            }
     1450            iReg++;
     1451        }
     1452        if (fWhat & CPUMCTX_EXTRN_CR4)
     1453        {
     1454            Assert(pInput->Names[iReg] == HvX64RegisterCr4);
     1455            if (pCtx->cr4 != paValues[iReg].Reg64)
     1456            {
     1457                CPUMSetGuestCR4(pVCpu, paValues[iReg].Reg64);
     1458                fMaybeChangedMode = true;
     1459                fFlushTlb = fFlushGlobalTlb = true; /// @todo fix this
     1460            }
     1461            iReg++;
     1462        }
     1463    }
     1464
     1465    /// @todo CR8/TPR
     1466    Assert(pInput->Names[iReg] == HvX64RegisterCr8);
     1467    APICSetTpr(pVCpu, (uint8_t)paValues[iReg].Reg64 << 4);
     1468    iReg++;
    11241469
    11251470    /* Debug registers. */
    1126     Assert(pInput->Names[33] == HvX64RegisterDr0);
    11271471/** @todo fixme */
    1128     if (pCtx->dr[0] != paValues[33].Reg64)
    1129         CPUMSetGuestDR0(pVCpu, paValues[33].Reg64);
    1130     if (pCtx->dr[1] != paValues[34].Reg64)
    1131         CPUMSetGuestDR1(pVCpu, paValues[34].Reg64);
    1132     if (pCtx->dr[2] != paValues[35].Reg64)
    1133         CPUMSetGuestDR2(pVCpu, paValues[35].Reg64);
    1134     if (pCtx->dr[3] != paValues[36].Reg64)
    1135         CPUMSetGuestDR3(pVCpu, paValues[36].Reg64);
    1136     Assert(pInput->Names[37] == HvX64RegisterDr6);
    1137     Assert(pInput->Names[38] == HvX64RegisterDr7);
    1138     if (pCtx->dr[6] != paValues[37].Reg64)
    1139         CPUMSetGuestDR6(pVCpu, paValues[37].Reg64);
    1140     if (pCtx->dr[7] != paValues[38].Reg64)
    1141         CPUMSetGuestDR6(pVCpu, paValues[38].Reg64);
     1472    if (fWhat & CPUMCTX_EXTRN_DR0_DR3)
     1473    {
     1474        Assert(pInput->Names[iReg] == HvX64RegisterDr0);
     1475        Assert(pInput->Names[iReg+3] == HvX64RegisterDr3);
     1476        if (pCtx->dr[0] != paValues[iReg].Reg64)
     1477            CPUMSetGuestDR0(pVCpu, paValues[iReg].Reg64);
     1478        iReg++;
     1479        if (pCtx->dr[1] != paValues[iReg].Reg64)
     1480            CPUMSetGuestDR1(pVCpu, paValues[iReg].Reg64);
     1481        iReg++;
     1482        if (pCtx->dr[2] != paValues[iReg].Reg64)
     1483            CPUMSetGuestDR2(pVCpu, paValues[iReg].Reg64);
     1484        iReg++;
     1485        if (pCtx->dr[3] != paValues[iReg].Reg64)
     1486            CPUMSetGuestDR3(pVCpu, paValues[iReg].Reg64);
     1487        iReg++;
     1488    }
     1489    if (fWhat & CPUMCTX_EXTRN_DR6)
     1490    {
     1491        Assert(pInput->Names[iReg] == HvX64RegisterDr6);
     1492        if (pCtx->dr[6] != paValues[iReg].Reg64)
     1493            CPUMSetGuestDR6(pVCpu, paValues[iReg].Reg64);
     1494        iReg++;
     1495    }
     1496    if (fWhat & CPUMCTX_EXTRN_DR7)
     1497    {
     1498        Assert(pInput->Names[iReg] == HvX64RegisterDr7);
     1499        if (pCtx->dr[7] != paValues[iReg].Reg64)
     1500            CPUMSetGuestDR6(pVCpu, paValues[iReg].Reg64);
     1501        iReg++;
     1502    }
     1503
     1504    /* Floating point state. */
     1505    if (fWhat & CPUMCTX_EXTRN_X87)
     1506    {
     1507        Assert(pInput->Names[iReg] == HvX64RegisterFpMmx0);
     1508        Assert(pInput->Names[iReg + 7] == HvX64RegisterFpMmx7);
     1509        pCtx->pXStateR0->x87.aRegs[0].au64[0] = paValues[iReg].Fp.AsUINT128.Low64;
     1510        pCtx->pXStateR0->x87.aRegs[0].au64[1] = paValues[iReg].Fp.AsUINT128.High64;
     1511        iReg++;
     1512        pCtx->pXStateR0->x87.aRegs[1].au64[0] = paValues[iReg].Fp.AsUINT128.Low64;
     1513        pCtx->pXStateR0->x87.aRegs[1].au64[1] = paValues[iReg].Fp.AsUINT128.High64;
     1514        iReg++;
     1515        pCtx->pXStateR0->x87.aRegs[2].au64[0] = paValues[iReg].Fp.AsUINT128.Low64;
     1516        pCtx->pXStateR0->x87.aRegs[2].au64[1] = paValues[iReg].Fp.AsUINT128.High64;
     1517        iReg++;
     1518        pCtx->pXStateR0->x87.aRegs[3].au64[0] = paValues[iReg].Fp.AsUINT128.Low64;
     1519        pCtx->pXStateR0->x87.aRegs[3].au64[1] = paValues[iReg].Fp.AsUINT128.High64;
     1520        iReg++;
     1521        pCtx->pXStateR0->x87.aRegs[4].au64[0] = paValues[iReg].Fp.AsUINT128.Low64;
     1522        pCtx->pXStateR0->x87.aRegs[4].au64[1] = paValues[iReg].Fp.AsUINT128.High64;
     1523        iReg++;
     1524        pCtx->pXStateR0->x87.aRegs[5].au64[0] = paValues[iReg].Fp.AsUINT128.Low64;
     1525        pCtx->pXStateR0->x87.aRegs[5].au64[1] = paValues[iReg].Fp.AsUINT128.High64;
     1526        iReg++;
     1527        pCtx->pXStateR0->x87.aRegs[6].au64[0] = paValues[iReg].Fp.AsUINT128.Low64;
     1528        pCtx->pXStateR0->x87.aRegs[6].au64[1] = paValues[iReg].Fp.AsUINT128.High64;
     1529        iReg++;
     1530        pCtx->pXStateR0->x87.aRegs[7].au64[0] = paValues[iReg].Fp.AsUINT128.Low64;
     1531        pCtx->pXStateR0->x87.aRegs[7].au64[1] = paValues[iReg].Fp.AsUINT128.High64;
     1532        iReg++;
     1533
     1534        Assert(pInput->Names[iReg] == HvX64RegisterFpControlStatus);
     1535        pCtx->pXStateR0->x87.FCW        = paValues[iReg].FpControlStatus.FpControl;
     1536        pCtx->pXStateR0->x87.FSW        = paValues[iReg].FpControlStatus.FpStatus;
     1537        pCtx->pXStateR0->x87.FTW        = paValues[iReg].FpControlStatus.FpTag
     1538                                        /*| (paValues[iReg].FpControlStatus.Reserved << 8)*/;
     1539        pCtx->pXStateR0->x87.FOP        = paValues[iReg].FpControlStatus.LastFpOp;
     1540        pCtx->pXStateR0->x87.FPUIP      = (uint32_t)paValues[iReg].FpControlStatus.LastFpRip;
     1541        pCtx->pXStateR0->x87.CS         = (uint16_t)(paValues[iReg].FpControlStatus.LastFpRip >> 32);
     1542        pCtx->pXStateR0->x87.Rsrvd1     = (uint16_t)(paValues[iReg].FpControlStatus.LastFpRip >> 48);
     1543        iReg++;
     1544    }
     1545
     1546    if (fWhat & (CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX))
     1547    {
     1548        Assert(pInput->Names[iReg] == HvX64RegisterXmmControlStatus);
     1549        if (fWhat & CPUMCTX_EXTRN_X87)
     1550        {
     1551            pCtx->pXStateR0->x87.FPUDP  = (uint32_t)paValues[iReg].XmmControlStatus.LastFpRdp;
     1552            pCtx->pXStateR0->x87.DS     = (uint16_t)(paValues[iReg].XmmControlStatus.LastFpRdp >> 32);
     1553            pCtx->pXStateR0->x87.Rsrvd2 = (uint16_t)(paValues[iReg].XmmControlStatus.LastFpRdp >> 48);
     1554        }
     1555        pCtx->pXStateR0->x87.MXCSR      = paValues[iReg].XmmControlStatus.XmmStatusControl;
     1556        pCtx->pXStateR0->x87.MXCSR_MASK = paValues[iReg].XmmControlStatus.XmmStatusControlMask; /** @todo ??? (Isn't this an output field?) */
     1557        iReg++;
     1558    }
    11421559
    11431560    /* Vector state. */
    1144     Assert(pInput->Names[39] == HvX64RegisterXmm0);
    1145     Assert(pInput->Names[54] == HvX64RegisterXmm15);
    1146     pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Lo  = paValues[39].Reg128.Low64;
    1147     pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Hi  = paValues[39].Reg128.High64;
    1148     pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Lo  = paValues[40].Reg128.Low64;
    1149     pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Hi  = paValues[40].Reg128.High64;
    1150     pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Lo  = paValues[41].Reg128.Low64;
    1151     pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Hi  = paValues[41].Reg128.High64;
    1152     pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Lo  = paValues[42].Reg128.Low64;
    1153     pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Hi  = paValues[42].Reg128.High64;
    1154     pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Lo  = paValues[43].Reg128.Low64;
    1155     pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Hi  = paValues[43].Reg128.High64;
    1156     pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Lo  = paValues[44].Reg128.Low64;
    1157     pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Hi  = paValues[44].Reg128.High64;
    1158     pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Lo  = paValues[45].Reg128.Low64;
    1159     pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Hi  = paValues[45].Reg128.High64;
    1160     pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Lo  = paValues[46].Reg128.Low64;
    1161     pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Hi  = paValues[46].Reg128.High64;
    1162     pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Lo  = paValues[47].Reg128.Low64;
    1163     pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Hi  = paValues[47].Reg128.High64;
    1164     pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Lo  = paValues[48].Reg128.Low64;
    1165     pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Hi  = paValues[48].Reg128.High64;
    1166     pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Lo = paValues[49].Reg128.Low64;
    1167     pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Hi = paValues[49].Reg128.High64;
    1168     pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Lo = paValues[50].Reg128.Low64;
    1169     pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Hi = paValues[50].Reg128.High64;
    1170     pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Lo = paValues[51].Reg128.Low64;
    1171     pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Hi = paValues[51].Reg128.High64;
    1172     pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Lo = paValues[52].Reg128.Low64;
    1173     pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Hi = paValues[52].Reg128.High64;
    1174     pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Lo = paValues[53].Reg128.Low64;
    1175     pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Hi = paValues[53].Reg128.High64;
    1176     pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Lo = paValues[54].Reg128.Low64;
    1177     pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Hi = paValues[54].Reg128.High64;
    1178 
    1179     /* Floating point state. */
    1180     Assert(pInput->Names[55] == HvX64RegisterFpMmx0);
    1181     Assert(pInput->Names[62] == HvX64RegisterFpMmx7);
    1182     pCtx->pXStateR0->x87.aRegs[0].au64[0] = paValues[55].Fp.AsUINT128.Low64;
    1183     pCtx->pXStateR0->x87.aRegs[0].au64[1] = paValues[55].Fp.AsUINT128.High64;
    1184     pCtx->pXStateR0->x87.aRegs[1].au64[0] = paValues[56].Fp.AsUINT128.Low64;
    1185     pCtx->pXStateR0->x87.aRegs[1].au64[1] = paValues[56].Fp.AsUINT128.High64;
    1186     pCtx->pXStateR0->x87.aRegs[2].au64[0] = paValues[57].Fp.AsUINT128.Low64;
    1187     pCtx->pXStateR0->x87.aRegs[2].au64[1] = paValues[57].Fp.AsUINT128.High64;
    1188     pCtx->pXStateR0->x87.aRegs[3].au64[0] = paValues[58].Fp.AsUINT128.Low64;
    1189     pCtx->pXStateR0->x87.aRegs[3].au64[1] = paValues[58].Fp.AsUINT128.High64;
    1190     pCtx->pXStateR0->x87.aRegs[4].au64[0] = paValues[59].Fp.AsUINT128.Low64;
    1191     pCtx->pXStateR0->x87.aRegs[4].au64[1] = paValues[59].Fp.AsUINT128.High64;
    1192     pCtx->pXStateR0->x87.aRegs[5].au64[0] = paValues[60].Fp.AsUINT128.Low64;
    1193     pCtx->pXStateR0->x87.aRegs[5].au64[1] = paValues[60].Fp.AsUINT128.High64;
    1194     pCtx->pXStateR0->x87.aRegs[6].au64[0] = paValues[61].Fp.AsUINT128.Low64;
    1195     pCtx->pXStateR0->x87.aRegs[6].au64[1] = paValues[61].Fp.AsUINT128.High64;
    1196     pCtx->pXStateR0->x87.aRegs[7].au64[0] = paValues[62].Fp.AsUINT128.Low64;
    1197     pCtx->pXStateR0->x87.aRegs[7].au64[1] = paValues[62].Fp.AsUINT128.High64;
    1198 
    1199     Assert(pInput->Names[63] == HvX64RegisterFpControlStatus);
    1200     pCtx->pXStateR0->x87.FCW        = paValues[63].FpControlStatus.FpControl;
    1201     pCtx->pXStateR0->x87.FSW        = paValues[63].FpControlStatus.FpStatus;
    1202     pCtx->pXStateR0->x87.FTW        = paValues[63].FpControlStatus.FpTag
    1203                                     /*| (paValues[63].FpControlStatus.Reserved << 8)*/;
    1204     pCtx->pXStateR0->x87.FOP        = paValues[63].FpControlStatus.LastFpOp;
    1205     pCtx->pXStateR0->x87.FPUIP      = (uint32_t)paValues[63].FpControlStatus.LastFpRip;
    1206     pCtx->pXStateR0->x87.CS         = (uint16_t)(paValues[63].FpControlStatus.LastFpRip >> 32);
    1207     pCtx->pXStateR0->x87.Rsrvd1     = (uint16_t)(paValues[63].FpControlStatus.LastFpRip >> 48);
    1208 
    1209     Assert(pInput->Names[64] == HvX64RegisterXmmControlStatus);
    1210     pCtx->pXStateR0->x87.FPUDP      = (uint32_t)paValues[64].XmmControlStatus.LastFpRdp;
    1211     pCtx->pXStateR0->x87.DS         = (uint16_t)(paValues[64].XmmControlStatus.LastFpRdp >> 32);
    1212     pCtx->pXStateR0->x87.Rsrvd2     = (uint16_t)(paValues[64].XmmControlStatus.LastFpRdp >> 48);
    1213     pCtx->pXStateR0->x87.MXCSR      = paValues[64].XmmControlStatus.XmmStatusControl;
    1214     pCtx->pXStateR0->x87.MXCSR_MASK = paValues[64].XmmControlStatus.XmmStatusControlMask; /** @todo ??? (Isn't this an output field?) */
     1561    if (fWhat & CPUMCTX_EXTRN_SSE_AVX)
     1562    {
     1563        Assert(pInput->Names[iReg] == HvX64RegisterXmm0);
     1564        Assert(pInput->Names[iReg+15] == HvX64RegisterXmm15);
     1565        pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Lo  = paValues[iReg].Reg128.Low64;
     1566        pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Hi  = paValues[iReg].Reg128.High64;
     1567        iReg++;
     1568        pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Lo  = paValues[iReg].Reg128.Low64;
     1569        pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Hi  = paValues[iReg].Reg128.High64;
     1570        iReg++;
     1571        pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Lo  = paValues[iReg].Reg128.Low64;
     1572        pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Hi  = paValues[iReg].Reg128.High64;
     1573        iReg++;
     1574        pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Lo  = paValues[iReg].Reg128.Low64;
     1575        pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Hi  = paValues[iReg].Reg128.High64;
     1576        iReg++;
     1577        pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Lo  = paValues[iReg].Reg128.Low64;
     1578        pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Hi  = paValues[iReg].Reg128.High64;
     1579        iReg++;
     1580        pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Lo  = paValues[iReg].Reg128.Low64;
     1581        pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Hi  = paValues[iReg].Reg128.High64;
     1582        iReg++;
     1583        pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Lo  = paValues[iReg].Reg128.Low64;
     1584        pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Hi  = paValues[iReg].Reg128.High64;
     1585        iReg++;
     1586        pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Lo  = paValues[iReg].Reg128.Low64;
     1587        pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Hi  = paValues[iReg].Reg128.High64;
     1588        iReg++;
     1589        pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Lo  = paValues[iReg].Reg128.Low64;
     1590        pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Hi  = paValues[iReg].Reg128.High64;
     1591        iReg++;
     1592        pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Lo  = paValues[iReg].Reg128.Low64;
     1593        pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Hi  = paValues[iReg].Reg128.High64;
     1594        iReg++;
     1595        pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Lo = paValues[iReg].Reg128.Low64;
     1596        pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Hi = paValues[iReg].Reg128.High64;
     1597        iReg++;
     1598        pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Lo = paValues[iReg].Reg128.Low64;
     1599        pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Hi = paValues[iReg].Reg128.High64;
     1600        iReg++;
     1601        pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Lo = paValues[iReg].Reg128.Low64;
     1602        pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Hi = paValues[iReg].Reg128.High64;
     1603        iReg++;
     1604        pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Lo = paValues[iReg].Reg128.Low64;
     1605        pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Hi = paValues[iReg].Reg128.High64;
     1606        iReg++;
     1607        pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Lo = paValues[iReg].Reg128.Low64;
     1608        pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Hi = paValues[iReg].Reg128.High64;
     1609        iReg++;
     1610        pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Lo = paValues[iReg].Reg128.Low64;
     1611        pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Hi = paValues[iReg].Reg128.High64;
     1612        iReg++;
     1613    }
     1614
    12151615
    12161616    /* MSRs */
    12171617    // HvX64RegisterTsc - don't touch
    1218     Assert(pInput->Names[65] == HvX64RegisterEfer);
    1219     if (paValues[65].Reg64 != pCtx->msrEFER)
    1220     {
    1221         pCtx->msrEFER = paValues[65].Reg64;
    1222         fMaybeChangedMode = true;
    1223     }
    1224 
    1225     Assert(pInput->Names[66] == HvX64RegisterKernelGsBase);
    1226     pCtx->msrKERNELGSBASE = paValues[66].Reg64;
    1227 
    1228     Assert(pInput->Names[67] == HvX64RegisterApicBase);
    1229     if (paValues[67].Reg64 != APICGetBaseMsrNoCheck(pVCpu))
    1230     {
    1231         VBOXSTRICTRC rc2 = APICSetBaseMsr(pVCpu, paValues[67].Reg64);
    1232         Assert(rc2 == VINF_SUCCESS); NOREF(rc2);
    1233     }
    1234 
    1235     Assert(pInput->Names[68] == HvX64RegisterPat);
    1236     pCtx->msrPAT    = paValues[68].Reg64;
    1237     /// @todo HvX64RegisterSysenterCs
    1238     /// @todo HvX64RegisterSysenterEip
    1239     /// @todo HvX64RegisterSysenterEsp
    1240     Assert(pInput->Names[72] == HvX64RegisterStar);
    1241     pCtx->msrSTAR   = paValues[72].Reg64;
    1242     Assert(pInput->Names[73] == HvX64RegisterLstar);
    1243     pCtx->msrLSTAR  = paValues[73].Reg64;
    1244     Assert(pInput->Names[74] == HvX64RegisterCstar);
    1245     pCtx->msrCSTAR  = paValues[74].Reg64;
    1246     Assert(pInput->Names[75] == HvX64RegisterSfmask);
    1247     pCtx->msrSFMASK = paValues[75].Reg64;
    1248 
     1618    if (fWhat & CPUMCTX_EXTRN_EFER)
     1619    {
     1620        Assert(pInput->Names[iReg] == HvX64RegisterEfer);
     1621        if (paValues[iReg].Reg64 != pCtx->msrEFER)
     1622        {
     1623            pCtx->msrEFER = paValues[iReg].Reg64;
     1624            fMaybeChangedMode = true;
     1625        }
     1626        iReg++;
     1627    }
     1628    if (fWhat & CPUMCTX_EXTRN_KERNEL_GS_BASE)
     1629    {
     1630        Assert(pInput->Names[iReg] == HvX64RegisterKernelGsBase);
     1631        pCtx->msrKERNELGSBASE = paValues[iReg].Reg64;
     1632        iReg++;
     1633    }
     1634    if (fWhat & CPUMCTX_EXTRN_SYSENTER_MSRS)
     1635    {
     1636        Assert(pInput->Names[iReg] == HvX64RegisterSysenterCs);
     1637        pCtx->SysEnter.cs = paValues[iReg].Reg64;
     1638        iReg++;
     1639        Assert(pInput->Names[iReg] == HvX64RegisterSysenterEip);
     1640        pCtx->SysEnter.eip = paValues[iReg].Reg64;
     1641        iReg++;
     1642        Assert(pInput->Names[iReg] == HvX64RegisterSysenterEsp);
     1643        pCtx->SysEnter.esp = paValues[iReg].Reg64;
     1644        iReg++;
     1645    }
     1646    if (fWhat & CPUMCTX_EXTRN_SYSCALL_MSRS)
     1647    {
     1648        Assert(pInput->Names[iReg] == HvX64RegisterStar);
     1649        pCtx->msrSTAR   = paValues[iReg].Reg64;
     1650        iReg++;
     1651        Assert(pInput->Names[iReg] == HvX64RegisterLstar);
     1652        pCtx->msrLSTAR  = paValues[iReg].Reg64;
     1653        iReg++;
     1654        Assert(pInput->Names[iReg] == HvX64RegisterCstar);
     1655        pCtx->msrCSTAR  = paValues[iReg].Reg64;
     1656        iReg++;
     1657        Assert(pInput->Names[iReg] == HvX64RegisterSfmask);
     1658        pCtx->msrSFMASK = paValues[iReg].Reg64;
     1659        iReg++;
     1660    }
     1661    if (fWhat & CPUMCTX_EXTRN_OTHER_MSRS)
     1662    {
     1663        Assert(pInput->Names[iReg] == HvX64RegisterApicBase);
     1664        if (paValues[iReg].Reg64 != APICGetBaseMsrNoCheck(pVCpu))
     1665        {
     1666            VBOXSTRICTRC rc2 = APICSetBaseMsr(pVCpu, paValues[iReg].Reg64);
     1667            Assert(rc2 == VINF_SUCCESS); NOREF(rc2);
     1668        }
     1669        iReg++;
     1670
     1671        Assert(pInput->Names[iReg] == HvX64RegisterPat);
     1672        pCtx->msrPAT    = paValues[iReg].Reg64;
     1673        iReg++;
     1674    }
     1675
     1676    /* Event injection. */
    12491677    /// @todo HvRegisterPendingInterruption
    1250     Assert(pInput->Names[76] == HvRegisterPendingInterruption);
    1251     if (paValues[76].PendingInterruption.InterruptionPending)
     1678    Assert(pInput->Names[iReg] == HvRegisterPendingInterruption);
     1679    if (paValues[iReg].PendingInterruption.InterruptionPending)
    12521680    {
    12531681        Log7(("PendingInterruption: type=%u vector=%#x errcd=%RTbool/%#x instr-len=%u nested=%u\n",
    1254               paValues[76].PendingInterruption.InterruptionType, paValues[76].PendingInterruption.InterruptionVector,
    1255               paValues[76].PendingInterruption.DeliverErrorCode, paValues[76].PendingInterruption.ErrorCode,
    1256               paValues[76].PendingInterruption.InstructionLength, paValues[76].PendingInterruption.NestedEvent));
    1257         AssertMsg((paValues[76].PendingInterruption.AsUINT64 & UINT64_C(0xfc00)) == 0,
    1258                   ("%#RX64\n", paValues[76].PendingInterruption.AsUINT64));
     1682              paValues[iReg].PendingInterruption.InterruptionType, paValues[iReg].PendingInterruption.InterruptionVector,
     1683              paValues[iReg].PendingInterruption.DeliverErrorCode, paValues[iReg].PendingInterruption.ErrorCode,
     1684              paValues[iReg].PendingInterruption.InstructionLength, paValues[iReg].PendingInterruption.NestedEvent));
     1685        AssertMsg((paValues[iReg].PendingInterruption.AsUINT64 & UINT64_C(0xfc00)) == 0,
     1686                  ("%#RX64\n", paValues[iReg].PendingInterruption.AsUINT64));
    12591687    }
    12601688
     
    12621690    /// @todo HvRegisterPendingEvent0
    12631691    /// @todo HvRegisterPendingEvent1
     1692
     1693    /* Almost done, just update extrn flags and maybe change PGM mode. */
     1694    pCtx->fExtrn &= ~fWhat;
    12641695
    12651696    int rc = VINF_SUCCESS;
     
    12871718 * @param   idCpu       The calling EMT.  Necessary for getting the
    12881719 *                      hypercall page and arguments.
    1289  * @param   fWhat       What to import. To be defined, UINT64_MAX for now.
     1720 * @param   fWhat       What to import, CPUMCTX_EXTRN_XXX. Set
     1721 *                      CPUMCTX_EXTERN_ALL for everything.
    12901722 */
    1291 VMMR0_INT_DECL(int)  NEMR0ImportState(PGVM pGVM, PVM pVM, VMCPUID idCpu, uint64_t fWhat)
     1723VMMR0_INT_DECL(int) NEMR0ImportState(PGVM pGVM, PVM pVM, VMCPUID idCpu, uint64_t fWhat)
    12921724{
    12931725    /*
  • trunk/src/VBox/VMM/VMMR0/VMMR0.cpp

    r71136 r71184  
    19971997
    19981998        case VMMR0_DO_NEM_EXPORT_STATE:
    1999             if (pReqHdr || idCpu == NIL_VMCPUID)
    2000                 return VERR_INVALID_PARAMETER;
    2001             rc = NEMR0ExportState(pGVM, pVM, idCpu, u64Arg);
     1999            if (u64Arg || pReqHdr || idCpu == NIL_VMCPUID)
     2000                return VERR_INVALID_PARAMETER;
     2001            rc = NEMR0ExportState(pGVM, pVM, idCpu);
    20022002            VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
    20032003            break;
  • trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp

    r71152 r71184  
    210210# define WHvGetVirtualProcessorRegisters            g_pfnWHvGetVirtualProcessorRegisters
    211211# define WHvSetVirtualProcessorRegisters            g_pfnWHvSetVirtualProcessorRegisters
     212
     213# define VidMessageSlotHandleAndGetNext             g_pfnVidMessageSlotHandleAndGetNext
     214# define VidStartVirtualProcessor                    g_pfnVidStartVirtualProcessor
     215# define VidStopVirtualProcessor                    g_pfnVidStopVirtualProcessor
     216
    212217#endif
    213218
     
    13371342}
    13381343
    1339 
    1340 #ifdef LOG_ENABLED
    1341 
     1344#ifndef NEM_WIN_USE_OUR_OWN_RUN_API
     1345
     1346# ifdef LOG_ENABLED
    13421347/**
    13431348 * Log the full details of an exit reason.
     
    13921397            break;
    13931398
    1394 # if 0
     1399#  if 0
    13951400        case WHvRunVpExitReasonUnrecoverableException:
    13961401        case WHvRunVpExitReasonInvalidVpRegisterValue:
     
    14101415            WHV_X64_UNSUPPORTED_FEATURE_CONTEXT UnsupportedFeature;
    14111416            WHV_RUN_VP_CANCELED_CONTEXT CancelReason;
    1412 #endif
     1417#  endif
    14131418
    14141419        case WHvRunVpExitReasonNone:
     
    14551460    }
    14561461}
    1457 
    1458 #endif /* LOG_ENABLED */
     1462# endif /* LOG_ENABLED */
     1463
     1464
     1465/**
     1466 * Advances the guest RIP and clear EFLAGS.RF.
     1467 *
     1468 * This may clear VMCPU_FF_INHIBIT_INTERRUPTS.
     1469 *
     1470 * @param   pVCpu           The cross context virtual CPU structure.
     1471 * @param   pCtx            The CPU context to update.
     1472 * @param   pExitCtx        The exit context.
     1473 */
     1474DECLINLINE(void) nemR3WinAdvanceGuestRipAndClearRF(PVMCPU pVCpu, PCPUMCTX pCtx, WHV_VP_EXIT_CONTEXT const *pExitCtx)
     1475{
     1476    /* Advance the RIP. */
     1477    Assert(pExitCtx->InstructionLength > 0 && pExitCtx->InstructionLength < 16);
     1478    pCtx->rip += pExitCtx->InstructionLength;
     1479    pCtx->rflags.Bits.u1RF = 0;
     1480
     1481    /* Update interrupt inhibition. */
     1482    if (!VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))
     1483    { /* likely */ }
     1484    else if (pCtx->rip != EMGetInhibitInterruptsPC(pVCpu))
     1485        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS);
     1486}
    14591487
    14601488
     
    14671495
    14681496
    1469 #ifndef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
     1497# ifndef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
    14701498/**
    14711499 * @callback_method_impl{FNPGMPHYSNEMENUMCALLBACK,
     
    14931521    return VINF_SUCCESS;
    14941522}
    1495 #endif /* !NEM_WIN_USE_HYPERCALLS_FOR_PAGES */
     1523# endif /* !NEM_WIN_USE_HYPERCALLS_FOR_PAGES */
    14961524
    14971525
     
    15871615                                      pIoPortCtx->AccessInfo.AccessSize);
    15881616            if (IOM_SUCCESS(rcStrict))
    1589                 nemHCWinAdvanceGuestRipAndClearRF(pVCpu, pCtx, &pIoPortCtx->VpContext);
     1617                nemR3WinAdvanceGuestRipAndClearRF(pVCpu, pCtx, &pIoPortCtx->VpContext);
    15901618        }
    15911619        else
     
    15971625            {
    15981626                pCtx->eax = (pCtx->eax & ~fAndMask) | (uValue & fAndMask);
    1599                 nemHCWinAdvanceGuestRipAndClearRF(pVCpu, pCtx, &pIoPortCtx->VpContext);
     1627                nemR3WinAdvanceGuestRipAndClearRF(pVCpu, pCtx, &pIoPortCtx->VpContext);
    16001628            }
    16011629        }
     
    16921720VBOXSTRICTRC nemR3WinWHvRunGC(PVM pVM, PVMCPU pVCpu)
    16931721{
    1694 #ifdef LOG_ENABLED
     1722# ifdef LOG_ENABLED
    16951723    if (LogIs3Enabled())
    16961724    {
     
    16981726        nemHCWinLogState(pVM, pVCpu);
    16991727    }
    1700 #endif
     1728# endif
    17011729
    17021730    /*
     
    17251753            && !VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_TO_R3_MASK))
    17261754        {
    1727 #ifdef NEM_WIN_USE_OUR_OWN_RUN_API
    1728             int rc2 = nemHCWinRunVirtualProcessor(pVM, pVCpu, &ExitReason, sizeof(ExitReason));
    1729             AssertRCBreakStmt(rc2, rcStrict = rc2);
    1730 #else
    17311755            Log8(("Calling WHvRunVirtualProcessor\n"));
    17321756            VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED);
     
    17391763            Log2(("WHvRunVirtualProcessor -> %#x; exit code %#x (%d) (cpu status %u)\n",
    17401764                  hrc, ExitReason.ExitReason, ExitReason.ExitReason, nemR3WinCpuGetRunningStatus(pVCpu) ));
    1741 #endif
    17421765        }
    17431766        else
     
    17531776        AssertRCBreakStmt(rc2, rcStrict = rc2);
    17541777
    1755 #ifdef LOG_ENABLED
     1778# ifdef LOG_ENABLED
    17561779        /*
    17571780         * Do some logging.
     
    17611784        if (LogIs3Enabled())
    17621785            nemHCWinLogState(pVM, pVCpu);
    1763 #endif
    1764 
    1765 #ifdef VBOX_STRICT
     1786# endif
     1787
     1788# ifdef VBOX_STRICT
    17661789        /* Assert that the VpContext field makes sense. */
    17671790        switch (ExitReason.ExitReason)
     
    17921815            default: break; /* shut up compiler. */
    17931816        }
    1794 #endif
     1817# endif
    17951818
    17961819        /*
     
    18591882        }
    18601883
    1861 #ifndef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
     1884# ifndef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
    18621885        /* Hack alert! */
    18631886        uint32_t const cMappedPages = pVM->nem.s.cMappedPages;
     
    18691892            Log(("nemR3NativeRunGC: Unmapped all; cMappedPages=%u -> %u\n", cMappedPages, pVM->nem.s.cMappedPages));
    18701893        }
    1871 #endif
     1894# endif
    18721895
    18731896        /* If any FF is pending, return to the EM loops.  That's okay for the
     
    18841907}
    18851908
     1909#endif /* !NEM_WIN_USE_OUR_OWN_RUN_API */
     1910
    18861911
    18871912VBOXSTRICTRC nemR3NativeRunGC(PVM pVM, PVMCPU pVCpu)
    18881913{
    1889 #if 1
     1914#ifndef NEM_WIN_USE_OUR_OWN_RUN_API
    18901915    return nemR3WinWHvRunGC(pVM, pVCpu);
    18911916#elif 1
  • trunk/src/VBox/VMM/include/CPUMInternal.mac

    r70732 r71184  
    230230    .Guest.aoffXState         resw    64
    231231    .Guest.fWorldSwitcher     resd    1
     232    .Guest.fExtrn             resq    1
    232233    alignb 8
    233234    .Guest.hwvirt.svm.uMsrHSavePa            resq         1
    234235    .Guest.hwvirt.svm.GCPhysVmcb             resq         1
    235236    .Guest.hwvirt.svm.pVmcbR0                RTR0PTR_RES  1
     237    alignb 8
    236238    .Guest.hwvirt.svm.pVmcbR3                RTR3PTR_RES  1
    237 %if HC_ARCH_BITS == 32
    238     .Guest.hwvirt.svm.abPadding0             resb         8
    239 %endif
     239    alignb 8
    240240    .Guest.hwvirt.svm.HostState              resb         184
    241241    .Guest.hwvirt.svm.u16Padding0            resw         1
     
    245245    .Guest.hwvirt.svm.fHMCachedVmcb          resb         1
    246246    .Guest.hwvirt.svm.pvMsrBitmapR0          RTR0PTR_RES  1
     247    alignb 8
    247248    .Guest.hwvirt.svm.pvMsrBitmapR3          RTR3PTR_RES  1
     249    alignb 8
    248250    .Guest.hwvirt.svm.pvIoBitmapR0           RTR0PTR_RES  1
     251    alignb 8
    249252    .Guest.hwvirt.svm.pvIoBitmapR3           RTR3PTR_RES  1
     253    alignb 8
    250254    .Guest.hwvirt.svm.HCPhysVmcb             RTHCPHYS_RES 1
    251 %if HC_ARCH_BITS == 32
    252     .Guest.hwvirt.svm.abPadding2             resb         16
    253 %endif
    254255    .Guest.hwvirt.fLocalForcedActions        resd         1
    255256    .Guest.hwvirt.fGif                       resb         1
     
    516517    .Hyper.aoffXState         resw    64
    517518    .Hyper.fWorldSwitcher     resd    1
     519    .Hyper.fExtrn             resq    1
    518520    alignb 8
    519521    .Hyper.hwvirt.svm.uMsrHSavePa            resq         1
    520522    .Hyper.hwvirt.svm.GCPhysVmcb             resq         1
    521523    .Hyper.hwvirt.svm.pVmcbR0                RTR0PTR_RES  1
     524    alignb 8
    522525    .Hyper.hwvirt.svm.pVmcbR3                RTR3PTR_RES  1
    523 %if HC_ARCH_BITS == 32
    524     .Hyper.hwvirt.svm.abPadding0             resb         8
    525 %endif
     526    alignb 8
    526527    .Hyper.hwvirt.svm.HostState              resb         184
    527528    .Hyper.hwvirt.svm.u16Padding0            resw         1
     
    531532    .Hyper.hwvirt.svm.fHMCachedVmcb          resb         1
    532533    .Hyper.hwvirt.svm.pvMsrBitmapR0          RTR0PTR_RES  1
     534    alignb 8
    533535    .Hyper.hwvirt.svm.pvMsrBitmapR3          RTR3PTR_RES  1
     536    alignb 8
    534537    .Hyper.hwvirt.svm.pvIoBitmapR0           RTR0PTR_RES  1
     538    alignb 8
    535539    .Hyper.hwvirt.svm.pvIoBitmapR3           RTR3PTR_RES  1
     540    alignb 8
    536541    .Hyper.hwvirt.svm.HCPhysVmcb             RTHCPHYS_RES 1
    537 %if HC_ARCH_BITS == 32
    538     .Hyper.hwvirt.svm.abPadding2             resb         16
    539 %endif
    540542    .Hyper.hwvirt.fLocalForcedActions        resd         1
    541543    .Hyper.hwvirt.fGif                       resb         1
  • trunk/src/VBox/VMM/include/NEMInternal.h

    r71152 r71184  
    169169#ifdef RT_OS_WINDOWS
    170170# ifdef NEM_WIN_USE_OUR_OWN_RUN_API
    171     /** We've got a message pending (NEM_WIN_MSG_STATE_XXX). */
    172     uint8_t                     bMsgState;
     171    /** The VID_MSHAGN_F_XXX flags.
     172     * Either VID_MSHAGN_F_HANDLE_MESSAGE | VID_MSHAGN_F_GET_NEXT_MESSAGE or zero. */
     173    uint32_t                    fHandleAndGetFlags;
    173174    /** What VidMessageSlotMap returns and is used for passing exit info. */
    174175    RTR3PTR                     pvMsgSlotMapping;
     
    212213
    213214
    214 #if defined(RT_OS_WINDOWS) && defined(NEM_WIN_USE_OUR_OWN_RUN_API)
    215 /** @name NEM_WIN_MSG_STATE_XXX - Windows message handling state.
    216  * @{ */
    217 /** The CPU has not been started. */
    218 # define NEM_WIN_MSG_STATE_STOPPED              UINT8_C(0x00)
    219 /** The CPU has been started, no messages are pending. */
    220 # define NEM_WIN_MSG_STATE_STARTED              UINT8_C(0x01)
    221 /** Message is pending and needs to be ACKed. */
    222 # define NEM_WIN_MSG_STATE_PENDING_MSG          UINT8_C(0x02)
    223 /** Both a message and execution stopping is pending.  We need to ACK the
    224  * current message and get the stop message, then ACK the stop message before
    225  *  the CPU can be started again.  */
    226 # define NEM_WIN_MSG_STATE_PENDING_STOP_AND_MSG UINT8_C(0x03)
    227 /** @} */
    228 #endif
    229 
    230 
    231 
    232215#ifdef IN_RING0
    233216
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