VirtualBox

Changeset 71087 in vbox


Ignore:
Timestamp:
Feb 21, 2018 4:35:23 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
120951
Message:

VMM/NEM/win: Get registers via hypercalls. bugref:9044

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/err.h

    r71075 r71087  
    28232823/** NEM failed to unmap page(s) into the VM. */
    28242824#define VERR_NEM_UNMAP_PAGES_FAILED                 (-6806)
     2825/** NEM failed to get registers. */
     2826#define VERR_NEM_GET_REGISTERS_FAILED               (-6807)
     2827/** NEM failed to set registers. */
     2828#define VERR_NEM_SET_REGISTERS_FAILED               (-6808)
     2829/** Get register caller must flush the TLB (not an error). */
     2830#define VERR_NEM_FLUSH_TLB                          (-6809)
     2831/** Get register caller must change the CPU mode (not an error). */
     2832#define VERR_NEM_CHANGE_PGM_MODE                    (-6810)
    28252833/** @} */
    28262834
  • trunk/include/VBox/vmm/nem.h

    r71075 r71087  
    8787VMMR0_INT_DECL(int)  NEMR0MapPages(PGVM pGVM, PVM pVM, VMCPUID idCpu);
    8888VMMR0_INT_DECL(int)  NEMR0UnmapPages(PGVM pGVM, PVM pVM, VMCPUID idCpu);
     89VMMR0_INT_DECL(int)  NEMR0ExportState(PGVM pGVM, PVM pVM, VMCPUID idCpu, uint64_t fWhat);
     90VMMR0_INT_DECL(int)  NEMR0ImportState(PGVM pGVM, PVM pVM, VMCPUID idCpu, uint64_t fWhat);
    8991/** @} */
    9092
  • trunk/include/VBox/vmm/vmm.h

    r71081 r71087  
    436436    /** Call NEMR0UnmapPages() (host specific). */
    437437    VMMR0_DO_NEM_UNMAP_PAGES,
     438    /** Call NEMR0ExportState() (host specific). */
     439    VMMR0_DO_NEM_EXPORT_STATE,
     440    /** Call NEMR0ImportState() (host specific). */
     441    VMMR0_DO_NEM_IMPORT_STATE,
    438442
    439443    /** Official call we use for testing Ring-0 APIs. */
  • trunk/include/iprt/nt/hyperv.h

    r71075 r71087  
    2828#define ___iprt_nt_hyperv_h
    2929
    30 #include <iprt/types.h>
    31 #include <iprt/assertcompile.h>
     30#ifndef IN_IDA_PRO
     31# include <iprt/types.h>
     32# include <iprt/assertcompile.h>
     33#else
     34# define RT_FLEXIBLE_ARRAY
     35# define AssertCompile(expr)
     36# define AssertCompileSize(type, size)
     37# define AssertCompileMemberOffset(type, member, off)
     38#endif
    3239
    3340
     
    4451/** System(/parent) physical page number. */
    4552typedef uint64_t HV_SPA_PAGE_NUMBER;
    46 
    47 
    48 
    49 /** Hypercall IDs.   */
     53/** Hyper-V unsigned 128-bit integer type.   */
     54typedef struct { uint64_t Low64, High64; } HV_UINT128;
     55
     56
     57/**
     58 * Hypercall IDs.
     59 */
    5060typedef enum
    5161{
     
    160170    HvCallStartVirtualProcessor = 0x99,
    161171    HvCallGetVpIndexFromApicId,
    162     /* 0x9b.. are reserved/undocumented. */
     172    /* 0x9b..0xae are reserved/undocumented.
     173       0xad: New version of HvCallGetVpRegisters? Perhaps on logical CPU or smth. */
    163174    HvCallFlushGuestPhysicalAddressSpace = 0xaf,
    164175    HvCallFlushGuestPhysicalAddressList,
     
    197208AssertCompile(HvCallCount == 0xda);
    198209
     210/** Makes the first parameter to a hypercall (rcx).  */
     211#define HV_MAKE_CALL_INFO(a_enmCallCode, a_cReps) ( (uint64_t)(a_enmCallCode) | ((uint64_t)(a_cReps) << 32) )
     212/** Makes the return value (success) for a rep hypercall. */
     213#define HV_MAKE_CALL_REP_RET(a_cReps)    ((uint64_t)(a_cReps) << 32)
    199214
    200215/** Hypercall status code. */
     
    468483
    469484
     485/**
     486 * Register names used by HvCallGetVpRegisters and HvCallSetVpRegisters.
     487 */
     488typedef enum _HV_REGISTER_NAME
     489{
     490    HvRegisterExplicitSuspend = 0x00000000,
     491    HvRegisterInterceptSuspend,
     492
     493    HvRegisterHypervisorVersion = 0x00000100,           /**< @since v5 */
     494
     495    HvRegisterPrivilegesAndFeaturesInfo = 0x00000200,   /**< @since v5 */
     496    HvRegisterFeaturesInfo,                             /**< @since v5 */
     497    HvRegisterImplementationLimitsInfo,                 /**< @since v5 */
     498    HvRegisterHardwareFeaturesInfo,                     /**< @since v5 */
     499
     500    HvRegisterGuestCrashP0 = 0x00000210,                /**< @since v5 */
     501    HvRegisterGuestCrashP1,                             /**< @since v5 */
     502    HvRegisterGuestCrashP2,                             /**< @since v5 */
     503    HvRegisterGuestCrashP3,                             /**< @since v5 */
     504    HvRegisterGuestCrashP4,                             /**< @since v5 */
     505    HvRegisterGuestCrashCtl,                            /**< @since v5 */
     506
     507    HvRegisterPowerStateConfigC1 = 0x00000220,          /**< @since v5 */
     508    HvRegisterPowerStateTriggerC1,                      /**< @since v5 */
     509    HvRegisterPowerStateConfigC2,                       /**< @since v5 */
     510    HvRegisterPowerStateTriggerC2,                      /**< @since v5 */
     511    HvRegisterPowerStateConfigC3,                       /**< @since v5 */
     512    HvRegisterPowerStateTriggerC3,                      /**< @since v5 */
     513
     514    HvRegisterSystemReset = 0x00000230,                 /**< @since v5 */
     515
     516    HvRegisterProcessorClockFrequency = 0x00000240,     /**< @since v5 */
     517    HvRegisterInterruptClockFrequency,                  /**< @since v5 */
     518
     519    HvRegisterGuestIdle = 0x00000250,                   /**< @since v5 */
     520
     521    HvRegisterDebugDeviceOptions = 0x00000260,          /**< @since v5 */
     522
     523    HvRegisterPendingInterruption = 0x00010002,
     524    HvRegisterInterruptState,
     525    HvRegisterPendingEvent0,                            /**< @since v5 */
     526    HvRegisterPendingEvent1,                            /**< @since v5 */
     527
     528    HvX64RegisterRax = 0x00020000,
     529    HvX64RegisterRcx,
     530    HvX64RegisterRdx,
     531    HvX64RegisterRbx,
     532    HvX64RegisterRsp,
     533    HvX64RegisterRbp,
     534    HvX64RegisterRsi,
     535    HvX64RegisterRdi,
     536    HvX64RegisterR8,
     537    HvX64RegisterR9,
     538    HvX64RegisterR10,
     539    HvX64RegisterR11,
     540    HvX64RegisterR12,
     541    HvX64RegisterR13,
     542    HvX64RegisterR14,
     543    HvX64RegisterR15,
     544    HvX64RegisterRip,
     545    HvX64RegisterRflags,
     546
     547    HvX64RegisterXmm0 = 0x00030000,
     548    HvX64RegisterXmm1,
     549    HvX64RegisterXmm2,
     550    HvX64RegisterXmm3,
     551    HvX64RegisterXmm4,
     552    HvX64RegisterXmm5,
     553    HvX64RegisterXmm6,
     554    HvX64RegisterXmm7,
     555    HvX64RegisterXmm8,
     556    HvX64RegisterXmm9,
     557    HvX64RegisterXmm10,
     558    HvX64RegisterXmm11,
     559    HvX64RegisterXmm12,
     560    HvX64RegisterXmm13,
     561    HvX64RegisterXmm14,
     562    HvX64RegisterXmm15,
     563    HvX64RegisterFpMmx0,
     564    HvX64RegisterFpMmx1,
     565    HvX64RegisterFpMmx2,
     566    HvX64RegisterFpMmx3,
     567    HvX64RegisterFpMmx4,
     568    HvX64RegisterFpMmx5,
     569    HvX64RegisterFpMmx6,
     570    HvX64RegisterFpMmx7,
     571    HvX64RegisterFpControlStatus,
     572    HvX64RegisterXmmControlStatus,
     573
     574    HvX64RegisterCr0 = 0x00040000,
     575    HvX64RegisterCr2,
     576    HvX64RegisterCr3,
     577    HvX64RegisterCr4,
     578    HvX64RegisterCr8,
     579    HvX64RegisterXfem,
     580
     581    HvX64RegisterIntermediateCr0 = 0x00041000,          /**< @since v5 */
     582    HvX64RegisterIntermediateCr4 = 0x00041003,          /**< @since v5 */
     583    HvX64RegisterIntermediateCr8,                       /**< @since v5 */
     584
     585    HvX64RegisterDr0 = 0x00050000,
     586    HvX64RegisterDr1,
     587    HvX64RegisterDr2,
     588    HvX64RegisterDr3,
     589    HvX64RegisterDr6,
     590    HvX64RegisterDr7,
     591
     592    HvX64RegisterEs = 0x00060000,
     593    HvX64RegisterCs,
     594    HvX64RegisterSs,
     595    HvX64RegisterDs,
     596    HvX64RegisterFs,
     597    HvX64RegisterGs,
     598    HvX64RegisterLdtr,
     599    HvX64RegisterTr,
     600
     601    HvX64RegisterIdtr = 0x00070000,
     602    HvX64RegisterGdtr,
     603
     604    HvX64RegisterTsc = 0x00080000,
     605    HvX64RegisterEfer,
     606    HvX64RegisterKernelGsBase,
     607    HvX64RegisterApicBase,
     608    HvX64RegisterPat,
     609    HvX64RegisterSysenterCs,
     610    HvX64RegisterSysenterEip,
     611    HvX64RegisterSysenterEsp,
     612    HvX64RegisterStar,
     613    HvX64RegisterLstar,
     614    HvX64RegisterCstar,
     615    HvX64RegisterSfmask,
     616    HvX64RegisterInitialApicId,
     617
     618    HvX64RegisterMtrrCap,
     619    HvX64RegisterMtrrDefType,
     620
     621    HvX64RegisterMtrrPhysBase0 = 0x00080010,
     622    HvX64RegisterMtrrPhysBase1,
     623    HvX64RegisterMtrrPhysBase2,
     624    HvX64RegisterMtrrPhysBase3,
     625    HvX64RegisterMtrrPhysBase4,
     626    HvX64RegisterMtrrPhysBase5,
     627    HvX64RegisterMtrrPhysBase6,
     628    HvX64RegisterMtrrPhysBase7,
     629    HvX64RegisterMtrrPhysBase8,                     /**< @since v4 */
     630    HvX64RegisterMtrrPhysBase9,                     /**< @since v4 */
     631    HvX64RegisterMtrrPhysBaseA,                     /**< @since v4 */
     632    HvX64RegisterMtrrPhysBaseB,                     /**< @since v4 */
     633    HvX64RegisterMtrrPhysBaseC,                     /**< @since v4 */
     634    HvX64RegisterMtrrPhysBaseD,                     /**< @since v4 */
     635    HvX64RegisterMtrrPhysBaseE,                     /**< @since v4 */
     636    HvX64RegisterMtrrPhysBaseF,                     /**< @since v4 */
     637
     638    HvX64RegisterMtrrPhysMask0 = 0x00080040,
     639    HvX64RegisterMtrrPhysMask1,
     640    HvX64RegisterMtrrPhysMask2,
     641    HvX64RegisterMtrrPhysMask3,
     642    HvX64RegisterMtrrPhysMask4,
     643    HvX64RegisterMtrrPhysMask5,
     644    HvX64RegisterMtrrPhysMask6,
     645    HvX64RegisterMtrrPhysMask7,
     646    HvX64RegisterMtrrPhysMask8,                     /**< @since v4 */
     647    HvX64RegisterMtrrPhysMask9,                     /**< @since v4 */
     648    HvX64RegisterMtrrPhysMaskA,                     /**< @since v4 */
     649    HvX64RegisterMtrrPhysMaskB,                     /**< @since v4 */
     650    HvX64RegisterMtrrPhysMaskC,                     /**< @since v4 */
     651    HvX64RegisterMtrrPhysMaskD,                     /**< @since v4 */
     652    HvX64RegisterMtrrPhysMaskE,                     /**< @since v4 */
     653    HvX64RegisterMtrrPhysMaskF,                     /**< @since v4 */
     654
     655    HvX64RegisterMtrrFix64k00000 = 0x00080070,
     656    HvX64RegisterMtrrFix16k80000,
     657    HvX64RegisterMtrrFix16kA0000,
     658    HvX64RegisterMtrrFix4kC0000,
     659    HvX64RegisterMtrrFix4kC8000,
     660    HvX64RegisterMtrrFix4kD0000,
     661    HvX64RegisterMtrrFix4kD8000,
     662    HvX64RegisterMtrrFix4kE0000,
     663    HvX64RegisterMtrrFix4kE8000,
     664    HvX64RegisterMtrrFix4kF0000,
     665    HvX64RegisterMtrrFix4kF8000,
     666
     667    HvX64RegisterIa32MiscEnable = 0x000800a0,       /**< @since v5 */
     668    HvX64RegisterIa32FeatureControl,                /**< @since v5 */
     669
     670    HvX64RegisterVpRuntime = 0x00090000,
     671    HvX64RegisterHypercall,
     672    HvRegisterGuestOsId,
     673    HvRegisterVpIndex,
     674    HvRegisterTimeRefCount,
     675
     676    HvRegisterCpuManagementVersion = 0x00090007,    /**< @since v5 */
     677
     678    HvX64RegisterEoi = 0x00090010,
     679    HvX64RegisterIcr,
     680    HvX64RegisterTpr,
     681    HvRegisterVpAssistPage,
     682
     683    HvRegisterStatsPartitionRetail = 0x00090020,
     684    HvRegisterStatsPartitionInternal,
     685    HvRegisterStatsVpRetail,
     686    HvRegisterStatsVpInternal,
     687
     688    HvRegisterSint0 = 0x000a0000,
     689    HvRegisterSint1,
     690    HvRegisterSint2,
     691    HvRegisterSint3,
     692    HvRegisterSint4,
     693    HvRegisterSint5,
     694    HvRegisterSint6,
     695    HvRegisterSint7,
     696    HvRegisterSint8,
     697    HvRegisterSint9,
     698    HvRegisterSint10,
     699    HvRegisterSint11,
     700    HvRegisterSint12,
     701    HvRegisterSint13,
     702    HvRegisterSint14,
     703    HvRegisterSint15,
     704    HvRegisterScontrol,
     705    HvRegisterSversion,
     706    HvRegisterSifp,
     707    HvRegisterSipp,
     708    HvRegisterEom,
     709    HvRegisterSirbp,                                /**< @since v4 */
     710
     711    HvRegisterStimer0Config = 0x000b0000,
     712    HvRegisterStimer0Count,
     713    HvRegisterStimer1Config,
     714    HvRegisterStimer1Count,
     715    HvRegisterStimer2Config,
     716    HvRegisterStimer2Count,
     717    HvRegisterStimer3Config,
     718    HvRegisterStimer3Count,
     719
     720    HvX64RegisterYmm0Low = 0x000c0000,
     721    HvX64RegisterYmm1Low,
     722    HvX64RegisterYmm2Low,
     723    HvX64RegisterYmm3Low,
     724    HvX64RegisterYmm4Low,
     725    HvX64RegisterYmm5Low,
     726    HvX64RegisterYmm6Low,
     727    HvX64RegisterYmm7Low,
     728    HvX64RegisterYmm8Low,
     729    HvX64RegisterYmm9Low,
     730    HvX64RegisterYmm10Low,
     731    HvX64RegisterYmm11Low,
     732    HvX64RegisterYmm12Low,
     733    HvX64RegisterYmm13Low,
     734    HvX64RegisterYmm14Low,
     735    HvX64RegisterYmm15Low,
     736    HvX64RegisterYmm0High,
     737    HvX64RegisterYmm1High,
     738    HvX64RegisterYmm2High,
     739    HvX64RegisterYmm3High,
     740    HvX64RegisterYmm4High,
     741    HvX64RegisterYmm5High,
     742    HvX64RegisterYmm6High,
     743    HvX64RegisterYmm7High,
     744    HvX64RegisterYmm8High,
     745    HvX64RegisterYmm9High,
     746    HvX64RegisterYmm10High,
     747    HvX64RegisterYmm11High,
     748    HvX64RegisterYmm12High,
     749    HvX64RegisterYmm13High,
     750    HvX64RegisterYmm14High,
     751    HvX64RegisterYmm15High,
     752
     753    HvRegisterVsmVpVtlControl = 0x000d0000,
     754
     755    HvRegisterVsmCodePageOffsets = 0x000d0002,
     756    HvRegisterVsmVpStatus,
     757    HvRegisterVsmPartitionStatus,
     758    HvRegisterVsmVina,
     759    HvRegisterVsmCapabilities,
     760    HvRegisterVsmPartitionConfig,
     761
     762    HvRegisterVsmVpSecureConfigVtl0 = 0x000d0010,   /**< @since v5 */
     763    HvRegisterVsmVpSecureConfigVtl1,                /**< @since v5 */
     764    HvRegisterVsmVpSecureConfigVtl2,                /**< @since v5 */
     765    HvRegisterVsmVpSecureConfigVtl3,                /**< @since v5 */
     766    HvRegisterVsmVpSecureConfigVtl4,                /**< @since v5 */
     767    HvRegisterVsmVpSecureConfigVtl5,                /**< @since v5 */
     768    HvRegisterVsmVpSecureConfigVtl6,                /**< @since v5 */
     769    HvRegisterVsmVpSecureConfigVtl7,                /**< @since v5 */
     770    HvRegisterVsmVpSecureConfigVtl8,                /**< @since v5 */
     771    HvRegisterVsmVpSecureConfigVtl9,                /**< @since v5 */
     772    HvRegisterVsmVpSecureConfigVtl10,               /**< @since v5 */
     773    HvRegisterVsmVpSecureConfigVtl11,               /**< @since v5 */
     774    HvRegisterVsmVpSecureConfigVtl12,               /**< @since v5 */
     775    HvRegisterVsmVpSecureConfigVtl13,               /**< @since v5 */
     776    HvRegisterVsmVpSecureConfigVtl14                /**< @since v5 */
     777
     778} HV_REGISTER_NAME;
     779AssertCompile(HvRegisterInterceptSuspend == 0x00000001);
     780AssertCompile(HvRegisterPendingEvent1 == 0x00010005);
     781AssertCompile(HvX64RegisterRflags == 0x00020011);
     782AssertCompile(HvX64RegisterXmmControlStatus == 0x00030019);
     783AssertCompile(HvX64RegisterXfem == 0x00040005);
     784AssertCompile(HvX64RegisterIntermediateCr0 == 0x00041000);
     785AssertCompile(HvX64RegisterIntermediateCr4 == 0x00041003);
     786AssertCompile(HvX64RegisterDr7 == 0x00050005);
     787AssertCompile(HvX64RegisterTr == 0x00060007);
     788AssertCompile(HvX64RegisterGdtr == 0x00070001);
     789AssertCompile(HvX64RegisterInitialApicId == 0x0008000c);
     790AssertCompile(HvX64RegisterMtrrDefType == 0x0008000e);
     791AssertCompile(HvX64RegisterMtrrPhysBaseF == 0x0008001f);
     792AssertCompile(HvX64RegisterMtrrPhysMaskF == 0x0008004f);
     793AssertCompile(HvX64RegisterMtrrFix4kF8000 == 0x0008007a);
     794AssertCompile(HvRegisterTimeRefCount == 0x00090004);
     795AssertCompile(HvRegisterCpuManagementVersion == 0x00090007);
     796AssertCompile(HvRegisterVpAssistPage == 0x00090013);
     797AssertCompile(HvRegisterStatsVpInternal == 0x00090023);
     798AssertCompile(HvRegisterSirbp == 0x000a0015);
     799AssertCompile(HvRegisterStimer3Count == 0x000b0007);
     800AssertCompile(HvX64RegisterYmm15High == 0x000c001f);
     801AssertCompile(HvRegisterVsmVpSecureConfigVtl14 == 0x000d001e);
     802AssertCompileSize(HV_REGISTER_NAME, 4);
     803
     804
     805/** Value format for HvRegisterExplicitSuspend. */
     806typedef union
     807{
     808    uint64_t            AsUINT64;
     809    struct
     810    {
     811        uint64_t        Suspended : 1;
     812        uint64_t        Reserved  : 63;
     813    };
     814} HV_EXPLICIT_SUSPEND_REGISTER;
     815/** Pointer to a value of HvRegisterExplicitSuspend. */
     816typedef HV_EXPLICIT_SUSPEND_REGISTER *PHV_EXPLICIT_SUSPEND_REGISTER;
     817
     818/** Value format for HvRegisterInterceptSuspend. */
     819typedef union
     820{
     821    uint64_t            AsUINT64;
     822    struct
     823    {
     824        uint64_t        Suspended : 1;
     825        uint64_t        TlbLocked : 1;
     826        uint64_t        Reserved  : 62;
     827    };
     828} HV_INTERCEPT_SUSPEND_REGISTER;
     829/** Pointer to a value of HvRegisterInterceptSuspend. */
     830typedef HV_INTERCEPT_SUSPEND_REGISTER *PHV_INTERCEPT_SUSPEND_REGISTER;
     831
     832/** Value format for HvRegisterInterruptState.
     833 * @sa WHV_X64_INTERRUPT_STATE_REGISTER */
     834typedef union
     835{
     836    uint64_t            AsUINT64;
     837    struct
     838    {
     839        uint64_t        InterruptShadow : 1;
     840        uint64_t        NmiMasked       : 1;
     841        uint64_t        Reserved        : 62;
     842    };
     843} HV_X64_INTERRUPT_STATE_REGISTER;
     844/** Pointer to a value of HvRegisterInterruptState. */
     845typedef HV_X64_INTERRUPT_STATE_REGISTER *PHV_X64_INTERRUPT_STATE_REGISTER;
     846
     847/** Pending exception type for HvRegisterPendingInterruption.
     848 * @sa WHV_X64_PENDING_INTERRUPTION_TYPE */
     849typedef enum
     850{
     851    HvX64PendingInterrupt = 0,
     852    /* what is/was 1? */
     853    HvX64PendingNmi = 2,
     854    HvX64PendingException
     855    /* any more? */
     856} HV_X64_PENDING_INTERRUPTION_TYPE;
     857
     858/** Value format for HvRegisterPendingInterruption.
     859 * @sa WHV_X64_PENDING_INTERRUPTION_REGISTER  */
     860typedef union
     861{
     862    uint64_t            AsUINT64;
     863    struct
     864    {
     865        uint32_t        InterruptionPending : 1;
     866        uint32_t        InterruptionType    : 3;    /**< HV_X64_PENDING_INTERRUPTION_TYPE */
     867        uint32_t        DeliverErrorCode    : 1;
     868        uint32_t        InstructionLength   : 4;    /**< @since v5? Wasn't in 7600 WDK */
     869        uint32_t        NestedEvent         : 1;    /**< @since v5? Wasn't in 7600 WDK */
     870        uint32_t        Reserved            : 6;
     871        uint32_t        InterruptionVector  : 16;
     872        uint32_t        ErrorCode;
     873    };
     874} HV_X64_PENDING_INTERRUPTION_REGISTER;
     875/** Pointer to a value of HvRegisterPendingInterruption. */
     876typedef HV_X64_PENDING_INTERRUPTION_REGISTER *PHV_X64_PENDING_INTERRUPTION_REGISTER;
     877
     878/** Value format for HvRegisterPendingEvent0/1.
     879 * @sa WHV_X64_DELIVERABILITY_NOTIFICATIONS_REGISTER  */
     880typedef union
     881{
     882    uint64_t            AsUINT64;
     883    struct
     884    {
     885        uint64_t        NmiNotification         : 1;
     886        uint64_t        InterruptNotification   : 1;
     887        uint64_t        InterruptPriority       : 4;
     888        uint64_t        Reserved                : 58;
     889    };
     890} HV_X64_DELIVERABILITY_NOTIFICATIONS_REGISTER;
     891/** Pointer to a value of HvRegisterPendingEvent0/1. */
     892typedef HV_X64_DELIVERABILITY_NOTIFICATIONS_REGISTER *PHV_X64_DELIVERABILITY_NOTIFICATIONS_REGISTER;
     893
     894
     895/** Value format for HvX64RegisterEs..Tr.
     896 * @sa WHV_X64_SEGMENT_REGISTER  */
     897typedef struct _HV_X64_SEGMENT_REGISTER
     898{
     899    uint64_t            Base;
     900    uint32_t            Limit;
     901    uint16_t            Selector;
     902    union
     903    {
     904        struct
     905        {
     906            uint16_t    SegmentType              : 4;
     907            uint16_t    NonSystemSegment         : 1;
     908            uint16_t    DescriptorPrivilegeLevel : 2;
     909            uint16_t    Present                  : 1;
     910            uint16_t    Reserved                 : 4;
     911            uint16_t    Available                : 1;
     912            uint16_t    Long                     : 1;
     913            uint16_t    Default                  : 1;
     914            uint16_t    Granularity              : 1;
     915        };
     916        uint16_t        Attributes;
     917    };
     918} HV_X64_SEGMENT_REGISTER;
     919/** Pointer to a value of HvX64RegisterEs..Tr. */
     920typedef HV_X64_SEGMENT_REGISTER *PHV_X64_SEGMENT_REGISTER;
     921
     922/** Value format for HvX64RegisterIdtr/Gdtr.
     923 * @sa WHV_X64_TABLE_REGISTER */
     924typedef struct
     925{
     926    uint16_t            Pad[3];
     927    uint16_t            Limit;
     928    uint64_t            Base;
     929} HV_X64_TABLE_REGISTER;
     930/** Pointer to a value of HvX64RegisterIdtr/Gdtrr. */
     931typedef HV_X64_TABLE_REGISTER *PHV_X64_TABLE_REGISTER;
     932
     933/** Value format for HvX64RegisterFpMmx0..7 in floating pointer mode.
     934 * @sa WHV_X64_FP_REGISTER, RTFLOAT80U2 */
     935typedef union
     936{
     937    HV_UINT128          AsUINT128;
     938    struct
     939    {
     940        uint64_t        Mantissa;
     941        uint64_t        BiasedExponent  : 15;
     942        uint64_t        Sign            : 1;
     943        uint64_t        Reserved        : 48;
     944    };
     945} HV_X64_FP_REGISTER;
     946/** Pointer to a value of HvX64RegisterFpMmx0..7 in floating point mode. */
     947typedef HV_X64_FP_REGISTER *PHV_X64_FP_REGISTER;
     948
     949/** Value union for HvX64RegisterFpMmx0..7. */
     950typedef union
     951{
     952    HV_UINT128          AsUINT128;
     953    HV_X64_FP_REGISTER  Fp;
     954    uint64_t            Mmx;
     955} HV_X64_FP_MMX_REGISTER;
     956/** Pointer to a value of HvX64RegisterFpMmx0..7. */
     957typedef HV_X64_FP_MMX_REGISTER *PHV_X64_FP_MMX_REGISTER;
     958
     959/** Value format for HvX64RegisterFpControlStatus.
     960 * @sa WHV_X64_FP_CONTROL_STATUS_REGISTER  */
     961typedef union
     962{
     963    HV_UINT128              AsUINT128;
     964    struct
     965    {
     966        uint16_t            FpControl;
     967        uint16_t            FpStatus;
     968        uint8_t             FpTag;
     969        uint8_t             IgnNe    : 1;
     970        uint8_t             Reserved : 7;
     971        uint16_t            LastFpOp;
     972        union
     973        {
     974            uint64_t        LastFpRip;
     975            struct
     976            {
     977                uint32_t    LastFpEip;
     978                uint16_t    LastFpCs;
     979            };
     980        };
     981    };
     982} HV_X64_FP_CONTROL_STATUS_REGISTER;
     983/** Pointer to a value of HvX64RegisterFpControlStatus. */
     984typedef HV_X64_FP_CONTROL_STATUS_REGISTER *PHV_X64_FP_CONTROL_STATUS_REGISTER;
     985
     986/** Value format for HvX64RegisterXmmControlStatus.
     987 * @sa WHV_X64_XMM_CONTROL_STATUS_REGISTER  */
     988typedef union
     989{
     990    HV_UINT128 AsUINT128;
     991    struct
     992    {
     993        union
     994        {
     995            uint64_t        LastFpRdp;
     996            struct
     997            {
     998                uint32_t    LastFpDp;
     999                uint16_t    LastFpDs;
     1000            };
     1001        };
     1002        uint32_t            XmmStatusControl;
     1003        uint32_t            XmmStatusControlMask;
     1004    };
     1005} HV_X64_XMM_CONTROL_STATUS_REGISTER;
     1006/** Pointer to a value of HvX64RegisterXmmControlStatus. */
     1007typedef HV_X64_XMM_CONTROL_STATUS_REGISTER *PHV_X64_XMM_CONTROL_STATUS_REGISTER;
     1008
     1009/** Register value union.
     1010 * @sa WHV_REGISTER_VALUE  */
     1011typedef union
     1012{
     1013    HV_UINT128                                      Reg128;
     1014    uint64_t                                        Reg64;
     1015    uint32_t                                        Reg32;
     1016    uint16_t                                        Reg16;
     1017    uint8_t                                         Reg8;
     1018    HV_EXPLICIT_SUSPEND_REGISTER                    ExplicitSuspend;
     1019    HV_INTERCEPT_SUSPEND_REGISTER                   InterceptSuspend;
     1020    HV_X64_INTERRUPT_STATE_REGISTER                 InterruptState;
     1021    HV_X64_PENDING_INTERRUPTION_REGISTER            PendingInterruption;
     1022    HV_X64_DELIVERABILITY_NOTIFICATIONS_REGISTER    DeliverabilityNotifications;
     1023    HV_X64_TABLE_REGISTER                           Table;
     1024    HV_X64_SEGMENT_REGISTER                         Segment;
     1025    HV_X64_FP_REGISTER                              Fp;
     1026    HV_X64_FP_CONTROL_STATUS_REGISTER               FpControlStatus;
     1027    HV_X64_XMM_CONTROL_STATUS_REGISTER              XmmControlStatus;
     1028} HV_REGISTER_VALUE;
     1029AssertCompileSize(HV_REGISTER_VALUE, 16);
     1030/** Pointer to a Hyper-V register value union. */
     1031typedef HV_REGISTER_VALUE *PHV_REGISTER_VALUE;
     1032/** Pointer to a const Hyper-V register value union. */
     1033typedef HV_REGISTER_VALUE const *PCHV_REGISTER_VALUE;
     1034
     1035
     1036/** Input for HvCallGetVpRegister. */
     1037typedef struct
     1038{
     1039    HV_PARTITION_ID     PartitionId;
     1040    HV_VP_INDEX         VpIndex;
     1041    /** Was this introduced after v2? Dunno what it it really is. */
     1042    uint32_t            fFlags;
     1043    /* The repeating part: */
     1044    HV_REGISTER_NAME    Names[RT_FLEXIBLE_ARRAY];
     1045} HV_INPUT_GET_VP_REGISTERS;
     1046AssertCompileMemberOffset(HV_INPUT_GET_VP_REGISTERS, Names, 16);
     1047/** Pointer to input for HvCallGetVpRegister. */
     1048typedef HV_INPUT_GET_VP_REGISTERS *PHV_INPUT_GET_VP_REGISTERS;
     1049/* Output for HvCallGetVpRegister is an array of HV_REGISTER_VALUE parallel to HV_INPUT_GET_VP_REGISTERS::Names. */
     1050
     1051
     1052/** Register and value pair for HvCallSetVpRegister. */
     1053typedef struct
     1054{
     1055    HV_REGISTER_NAME    Name;
     1056    uint32_t            Pad0;
     1057    uint64_t            Pad1;
     1058    HV_REGISTER_VALUE   Value;
     1059} HV_REGISTER_ASSOC;
     1060AssertCompileSize(HV_REGISTER_ASSOC, 32);
     1061AssertCompileMemberOffset(HV_REGISTER_ASSOC, Value, 16);
     1062/** Pointer to a register and value pair for HvCallSetVpRegister. */
     1063typedef HV_REGISTER_ASSOC *PHV_REGISTER_ASSOC;
     1064/** Helper for clearing the alignment padding members. */
     1065#define HV_REGISTER_ASSOC_ZERO_PADDING(a_pRegAssoc) do { (a_pRegAssoc)->Pad0 = 0; (a_pRegAssoc)->Pad1 = 0; } while (0)
     1066/** Helper for clearing the alignment padding members and the high 64-bit
     1067 * part of the value. */
     1068#define HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(a_pRegAssoc) \
     1069    do { (a_pRegAssoc)->Pad0 = 0; (a_pRegAssoc)->Pad1 = 0; (a_pRegAssoc)->Value.Reg128.High64 = 0; } while (0)
     1070
     1071/** Input for HvCallSetVpRegister. */
     1072typedef struct
     1073{
     1074    HV_PARTITION_ID     PartitionId;
     1075    HV_VP_INDEX         VpIndex;
     1076    uint32_t            RsvdZ;
     1077    /* The repeating part: */
     1078    HV_REGISTER_ASSOC   Elements[RT_FLEXIBLE_ARRAY];
     1079} HV_INPUT_SET_VP_REGISTERS;
     1080AssertCompileMemberOffset(HV_INPUT_SET_VP_REGISTERS, Elements, 16);
     1081/** Pointer to input for HvCallSetVpRegister. */
     1082typedef HV_INPUT_SET_VP_REGISTERS *PHV_INPUT_SET_VP_REGISTERS;
     1083
     1084
    4701085#endif
    4711086
  • trunk/src/VBox/VMM/VMMR0/NEMR0Native-win.cpp

    r71075 r71087  
    5050*   Global Variables                                                                                                             *
    5151*********************************************************************************************************************************/
    52 static uint64_t (* g_pfnHvlInvokeHypercall)(uint64_t uCallInfo, uint64_t GCPhysInput, uint64_t GCPhysOutput);
     52static uint64_t (* g_pfnHvlInvokeHypercall)(uint64_t uCallInfo, uint64_t HCPhysInput, uint64_t HCPhysOutput);
    5353
    5454
     
    327327
    328328
     329/**
     330 * Worker for NEMR0ExportState.
     331 *
     332 * Intention is to use it internally later.
     333 *
     334 * @returns VBox status code.
     335 * @param   pGVM        The ring-0 VM handle.
     336 * @param   pGVCpu      The irng-0 VCPU handle.
     337 * @param   pCtx        The CPU context structure to import into.
     338 * @param   fWhat       What to export. To be defined, UINT64_MAX for now.
     339 */
     340static int nemR0WinExportState(PGVM pGVM, PGVMCPU pGVCpu, PCPUMCTX pCtx, uint64_t fWhat)
     341{
     342    PVMCPU                     pVCpu  = &pGVM->pVM->aCpus[pGVCpu->idCpu];
     343    HV_INPUT_SET_VP_REGISTERS *pInput = (HV_INPUT_SET_VP_REGISTERS *)pGVCpu->nem.s.pbHypercallData;
     344    AssertPtrReturn(pInput, VERR_INTERNAL_ERROR_3);
     345
     346    pInput->PartitionId = pGVM->nem.s.idHvPartition;
     347    pInput->VpIndex     = pGVCpu->idCpu;
     348    pInput->RsvdZ       = 0;
     349
     350    RT_NOREF_PV(fWhat); /** @todo group selection. */
     351
     352    /* GPRs */
     353    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[0]);
     354    pInput->Elements[0].Name                = HvX64RegisterRax;
     355    pInput->Elements[0].Value.Reg64         = pCtx->rax;
     356    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[1]);
     357    pInput->Elements[1].Name                = HvX64RegisterRcx;
     358    pInput->Elements[1].Value.Reg64         = pCtx->rcx;
     359    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[2]);
     360    pInput->Elements[2].Name                = HvX64RegisterRdx;
     361    pInput->Elements[2].Value.Reg64         = pCtx->rdx;
     362    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[3]);
     363    pInput->Elements[3].Name                = HvX64RegisterRbx;
     364    pInput->Elements[3].Value.Reg64         = pCtx->rbx;
     365    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[4]);
     366    pInput->Elements[4].Name                = HvX64RegisterRsp;
     367    pInput->Elements[4].Value.Reg64         = pCtx->rsp;
     368    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[5]);
     369    pInput->Elements[5].Name                = HvX64RegisterRbp;
     370    pInput->Elements[5].Value.Reg64         = pCtx->rbp;
     371    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[6]);
     372    pInput->Elements[6].Name                = HvX64RegisterRsi;
     373    pInput->Elements[6].Value.Reg64         = pCtx->rsi;
     374    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[7]);
     375    pInput->Elements[7].Name                = HvX64RegisterRdi;
     376    pInput->Elements[7].Value.Reg64         = pCtx->rdi;
     377    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[8]);
     378    pInput->Elements[8].Name                = HvX64RegisterR8;
     379    pInput->Elements[8].Value.Reg64         = pCtx->r8;
     380    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[9]);
     381    pInput->Elements[9].Name                = HvX64RegisterR9;
     382    pInput->Elements[9].Value.Reg64         = pCtx->r9;
     383    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[10]);
     384    pInput->Elements[10].Name                = HvX64RegisterR10;
     385    pInput->Elements[10].Value.Reg64         = pCtx->r10;
     386    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[11]);
     387    pInput->Elements[11].Name                = HvX64RegisterR11;
     388    pInput->Elements[11].Value.Reg64         = pCtx->r11;
     389    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[12]);
     390    pInput->Elements[12].Name                = HvX64RegisterR12;
     391    pInput->Elements[12].Value.Reg64         = pCtx->r12;
     392    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[13]);
     393    pInput->Elements[13].Name                = HvX64RegisterR13;
     394    pInput->Elements[13].Value.Reg64         = pCtx->r13;
     395    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[14]);
     396    pInput->Elements[14].Name                = HvX64RegisterR14;
     397    pInput->Elements[14].Value.Reg64         = pCtx->r14;
     398    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[15]);
     399    pInput->Elements[15].Name                = HvX64RegisterR15;
     400    pInput->Elements[15].Value.Reg64         = pCtx->r15;
     401
     402    /* RIP & Flags */
     403    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[16]);
     404    pInput->Elements[16].Name                = HvX64RegisterRip;
     405    pInput->Elements[16].Value.Reg64         = pCtx->rip;
     406    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[17]);
     407    pInput->Elements[17].Name                = HvX64RegisterRflags;
     408    pInput->Elements[17].Value.Reg64         = pCtx->rflags.u;
     409
     410    /* Segments */
     411#define COPY_OUT_SEG(a_idx, a_enmName, a_SReg) \
     412        do { \
     413            HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[a_idx]); \
     414            pInput->Elements[a_idx].Name                     = a_enmName; \
     415            pInput->Elements[a_idx].Value.Segment.Base       = (a_SReg).u64Base; \
     416            pInput->Elements[a_idx].Value.Segment.Limit      = (a_SReg).u32Limit; \
     417            pInput->Elements[a_idx].Value.Segment.Selector   = (a_SReg).Sel; \
     418            pInput->Elements[a_idx].Value.Segment.Attributes = (a_SReg).Attr.u; \
     419        } while (0)
     420    COPY_OUT_SEG(18, HvX64RegisterEs,   pCtx->es);
     421    COPY_OUT_SEG(19, HvX64RegisterCs,   pCtx->cs);
     422    COPY_OUT_SEG(20, HvX64RegisterSs,   pCtx->ss);
     423    COPY_OUT_SEG(21, HvX64RegisterDs,   pCtx->ds);
     424    COPY_OUT_SEG(22, HvX64RegisterFs,   pCtx->fs);
     425    COPY_OUT_SEG(23, HvX64RegisterGs,   pCtx->gs);
     426    COPY_OUT_SEG(24, HvX64RegisterLdtr, pCtx->ldtr);
     427    COPY_OUT_SEG(25, HvX64RegisterTr,   pCtx->tr);
     428
     429    uintptr_t iReg = 26;
     430    /* Descriptor tables. */
     431    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     432    pInput->Elements[iReg].Value.Table.Pad[0]   = 0;
     433    pInput->Elements[iReg].Value.Table.Pad[1]   = 0;
     434    pInput->Elements[iReg].Value.Table.Pad[2]   = 0;
     435    pInput->Elements[iReg].Name                 = HvX64RegisterIdtr;
     436    pInput->Elements[iReg].Value.Table.Limit    = pCtx->idtr.cbIdt;
     437    pInput->Elements[iReg].Value.Table.Base     = pCtx->idtr.pIdt;
     438    iReg++;
     439    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     440    pInput->Elements[iReg].Value.Table.Pad[0]   = 0;
     441    pInput->Elements[iReg].Value.Table.Pad[1]   = 0;
     442    pInput->Elements[iReg].Value.Table.Pad[2]   = 0;
     443    pInput->Elements[iReg].Name                 = HvX64RegisterGdtr;
     444    pInput->Elements[iReg].Value.Table.Limit    = pCtx->gdtr.cbGdt;
     445    pInput->Elements[iReg].Value.Table.Base     = pCtx->gdtr.pGdt;
     446    iReg++;
     447
     448    /* Control registers. */
     449    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     450    pInput->Elements[iReg].Name                 = HvX64RegisterCr0;
     451    pInput->Elements[iReg].Value.Reg64          = pCtx->cr0;
     452    iReg++;
     453    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     454    pInput->Elements[iReg].Name                 = HvX64RegisterCr2;
     455    pInput->Elements[iReg].Value.Reg64          = pCtx->cr2;
     456    iReg++;
     457    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     458    pInput->Elements[iReg].Name                 = HvX64RegisterCr3;
     459    pInput->Elements[iReg].Value.Reg64          = pCtx->cr3;
     460    iReg++;
     461    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     462    pInput->Elements[iReg].Name                 = HvX64RegisterCr4;
     463    pInput->Elements[iReg].Value.Reg64          = pCtx->cr4;
     464    iReg++;
     465    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     466    pInput->Elements[iReg].Name                 = HvX64RegisterCr8;
     467    pInput->Elements[iReg].Value.Reg64          = CPUMGetGuestCR8(pVCpu);
     468    iReg++;
     469
     470    /* Debug registers. */
     471/** @todo fixme. Figure out what the hyper-v version of KVM_SET_GUEST_DEBUG would be. */
     472    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     473    pInput->Elements[iReg].Name                 = HvX64RegisterDr0;
     474    //pInput->Elements[iReg].Value.Reg64        = CPUMGetHyperDR0(pVCpu);
     475    pInput->Elements[iReg].Value.Reg64          = pCtx->dr[0];
     476    iReg++;
     477    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     478    pInput->Elements[iReg].Name                 = HvX64RegisterDr1;
     479    //pInput->Elements[iReg].Value.Reg64        = CPUMGetHyperDR1(pVCpu);
     480    pInput->Elements[iReg].Value.Reg64          = pCtx->dr[1];
     481    iReg++;
     482    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     483    pInput->Elements[iReg].Name                 = HvX64RegisterDr2;
     484    //pInput->Elements[iReg].Value.Reg64        = CPUMGetHyperDR2(pVCpu);
     485    pInput->Elements[iReg].Value.Reg64          = pCtx->dr[2];
     486    iReg++;
     487    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     488    pInput->Elements[iReg].Name                 = HvX64RegisterDr3;
     489    //pInput->Elements[iReg].Value.Reg64        = CPUMGetHyperDR3(pVCpu);
     490    pInput->Elements[iReg].Value.Reg64          = pCtx->dr[3];
     491    iReg++;
     492    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     493    pInput->Elements[iReg].Name                 = HvX64RegisterDr6;
     494    //pInput->Elements[iReg].Value.Reg64        = CPUMGetHyperDR6(pVCpu);
     495    pInput->Elements[iReg].Value.Reg64          = pCtx->dr[6];
     496    iReg++;
     497    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     498    pInput->Elements[iReg].Name                 = HvX64RegisterDr7;
     499    //pInput->Elements[iReg].Value.Reg64        = CPUMGetHyperDR7(pVCpu);
     500    pInput->Elements[iReg].Value.Reg64          = pCtx->dr[7];
     501    iReg++;
     502
     503    /* Vector state. */
     504    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     505    pInput->Elements[iReg].Name                 = HvX64RegisterXmm0;
     506    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Lo;
     507    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Hi;
     508    iReg++;
     509    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     510    pInput->Elements[iReg].Name                 = HvX64RegisterXmm1;
     511    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Lo;
     512    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Hi;
     513    iReg++;
     514    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     515    pInput->Elements[iReg].Name                 = HvX64RegisterXmm2;
     516    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Lo;
     517    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Hi;
     518    iReg++;
     519    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     520    pInput->Elements[iReg].Name                 = HvX64RegisterXmm3;
     521    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Lo;
     522    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Hi;
     523    iReg++;
     524    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     525    pInput->Elements[iReg].Name                 = HvX64RegisterXmm4;
     526    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Lo;
     527    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Hi;
     528    iReg++;
     529    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     530    pInput->Elements[iReg].Name                 = HvX64RegisterXmm5;
     531    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Lo;
     532    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Hi;
     533    iReg++;
     534    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     535    pInput->Elements[iReg].Name                 = HvX64RegisterXmm6;
     536    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Lo;
     537    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Hi;
     538    iReg++;
     539    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     540    pInput->Elements[iReg].Name                 = HvX64RegisterXmm7;
     541    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Lo;
     542    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Hi;
     543    iReg++;
     544    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     545    pInput->Elements[iReg].Name                 = HvX64RegisterXmm8;
     546    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Lo;
     547    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Hi;
     548    iReg++;
     549    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     550    pInput->Elements[iReg].Name                 = HvX64RegisterXmm9;
     551    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Lo;
     552    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Hi;
     553    iReg++;
     554    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     555    pInput->Elements[iReg].Name                 = HvX64RegisterXmm10;
     556    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Lo;
     557    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Hi;
     558    iReg++;
     559    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     560    pInput->Elements[iReg].Name                 = HvX64RegisterXmm11;
     561    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Lo;
     562    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Hi;
     563    iReg++;
     564    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     565    pInput->Elements[iReg].Name                 = HvX64RegisterXmm12;
     566    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Lo;
     567    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Hi;
     568    iReg++;
     569    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     570    pInput->Elements[iReg].Name                 = HvX64RegisterXmm13;
     571    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Lo;
     572    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Hi;
     573    iReg++;
     574    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     575    pInput->Elements[iReg].Name                 = HvX64RegisterXmm14;
     576    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Lo;
     577    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Hi;
     578    iReg++;
     579    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     580    pInput->Elements[iReg].Name                 = HvX64RegisterXmm15;
     581    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Lo;
     582    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Hi;
     583    iReg++;
     584
     585    /* Floating point state. */
     586    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     587    pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx0;
     588    pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[0].au64[0];
     589    pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[0].au64[1];
     590    iReg++;
     591    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     592    pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx1;
     593    pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[1].au64[0];
     594    pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[1].au64[1];
     595    iReg++;
     596    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     597    pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx2;
     598    pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[2].au64[0];
     599    pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[2].au64[1];
     600    iReg++;
     601    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     602    pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx3;
     603    pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[3].au64[0];
     604    pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[3].au64[1];
     605    iReg++;
     606    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     607    pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx4;
     608    pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[4].au64[0];
     609    pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[4].au64[1];
     610    iReg++;
     611    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     612    pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx5;
     613    pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[5].au64[0];
     614    pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[5].au64[1];
     615    iReg++;
     616    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     617    pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx6;
     618    pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[6].au64[0];
     619    pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[6].au64[1];
     620    iReg++;
     621    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     622    pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx7;
     623    pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[7].au64[0];
     624    pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[7].au64[1];
     625    iReg++;
     626
     627    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     628    pInput->Elements[iReg].Name                            = HvX64RegisterFpControlStatus;
     629    pInput->Elements[iReg].Value.FpControlStatus.FpControl = pCtx->pXStateR0->x87.FCW;
     630    pInput->Elements[iReg].Value.FpControlStatus.FpStatus  = pCtx->pXStateR0->x87.FSW;
     631    pInput->Elements[iReg].Value.FpControlStatus.FpTag     = pCtx->pXStateR0->x87.FTW;
     632    pInput->Elements[iReg].Value.FpControlStatus.Reserved  = pCtx->pXStateR0->x87.FTW >> 8;
     633    pInput->Elements[iReg].Value.FpControlStatus.LastFpOp  = pCtx->pXStateR0->x87.FOP;
     634    pInput->Elements[iReg].Value.FpControlStatus.LastFpRip = (pCtx->pXStateR0->x87.FPUIP)
     635                                                           | ((uint64_t)pCtx->pXStateR0->x87.CS << 32)
     636                                                           | ((uint64_t)pCtx->pXStateR0->x87.Rsrvd1 << 48);
     637    iReg++;
     638
     639    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
     640    pInput->Elements[iReg].Name                                        = HvX64RegisterXmmControlStatus;
     641    pInput->Elements[iReg].Value.XmmControlStatus.LastFpRdp            = (pCtx->pXStateR0->x87.FPUDP)
     642                                                                       | ((uint64_t)pCtx->pXStateR0->x87.DS << 32)
     643                                                                       | ((uint64_t)pCtx->pXStateR0->x87.Rsrvd2 << 48);
     644    pInput->Elements[iReg].Value.XmmControlStatus.XmmStatusControl     = pCtx->pXStateR0->x87.MXCSR;
     645    pInput->Elements[iReg].Value.XmmControlStatus.XmmStatusControlMask = pCtx->pXStateR0->x87.MXCSR_MASK; /** @todo ??? (Isn't this an output field?) */
     646    iReg++;
     647
     648    /* MSRs */
     649    // HvX64RegisterTsc - don't touch
     650    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     651    pInput->Elements[iReg].Name                 = HvX64RegisterEfer;
     652    pInput->Elements[iReg].Value.Reg64          = pCtx->msrEFER;
     653    iReg++;
     654    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     655    pInput->Elements[iReg].Name                 = HvX64RegisterKernelGsBase;
     656    pInput->Elements[iReg].Value.Reg64          = pCtx->msrKERNELGSBASE;
     657    iReg++;
     658    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     659    pInput->Elements[iReg].Name                 = HvX64RegisterApicBase;
     660    pInput->Elements[iReg].Value.Reg64          = APICGetBaseMsrNoCheck(pVCpu);
     661    iReg++;
     662    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     663    pInput->Elements[iReg].Name                 = HvX64RegisterPat;
     664    pInput->Elements[iReg].Value.Reg64          = pCtx->msrPAT;
     665    iReg++;
     666    /// @todo HvX64RegisterSysenterCs
     667    /// @todo HvX64RegisterSysenterEip
     668    /// @todo HvX64RegisterSysenterEsp
     669    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     670    pInput->Elements[iReg].Name                 = HvX64RegisterStar;
     671    pInput->Elements[iReg].Value.Reg64          = pCtx->msrSTAR;
     672    iReg++;
     673    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     674    pInput->Elements[iReg].Name                 = HvX64RegisterLstar;
     675    pInput->Elements[iReg].Value.Reg64          = pCtx->msrLSTAR;
     676    iReg++;
     677    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     678    pInput->Elements[iReg].Name                 = HvX64RegisterCstar;
     679    pInput->Elements[iReg].Value.Reg64          = pCtx->msrCSTAR;
     680    iReg++;
     681    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     682    pInput->Elements[iReg].Name                 = HvX64RegisterSfmask;
     683    pInput->Elements[iReg].Value.Reg64          = pCtx->msrSFMASK;
     684    iReg++;
     685
     686    /* event injection (always clear it). */
     687    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
     688    pInput->Elements[iReg].Name                 = HvRegisterPendingInterruption;
     689    pInput->Elements[iReg].Value.Reg64          = 0;
     690    iReg++;
     691    /// @todo HvRegisterInterruptState
     692    /// @todo HvRegisterPendingEvent0
     693    /// @todo HvRegisterPendingEvent1
     694
     695    /*
     696     * Set the registers.
     697     */
     698    Assert((uintptr_t)&pInput->Elements[iReg] - (uintptr_t)pGVCpu->nem.s.pbHypercallData < PAGE_SIZE); /* max is 127 */
     699
     700    /*
     701     * Make the hypercall.
     702     */
     703    uint64_t uResult = g_pfnHvlInvokeHypercall(HV_MAKE_CALL_INFO(HvCallSetVpRegisters, iReg),
     704                                               pGVCpu->nem.s.HCPhysHypercallData, 0 /*GCPhysOutput*/);
     705    AssertLogRelMsgReturn(uResult == HV_MAKE_CALL_REP_RET(iReg),
     706                          ("uResult=%RX64 iRegs=%#x\n", uResult, iReg),
     707                          VERR_NEM_SET_REGISTERS_FAILED);
     708    return VINF_SUCCESS;
     709}
     710
     711
     712/**
     713 * Export the state to the native API (out of CPUMCTX).
     714 *
     715 * @returns VBox status code
     716 * @param   pGVM        The ring-0 VM handle.
     717 * @param   pVM         The cross context VM handle.
     718 * @param   idCpu       The calling EMT.  Necessary for getting the
     719 *                      hypercall page and arguments.
     720 * @param   fWhat       What to export. To be defined, UINT64_MAX for now.
     721 */
     722VMMR0_INT_DECL(int)  NEMR0ExportState(PGVM pGVM, PVM pVM, VMCPUID idCpu, uint64_t fWhat)
     723{
     724    /*
     725     * Validate the call.
     726     */
     727    int rc = GVMMR0ValidateGVMandVMandEMT(pGVM, pVM, idCpu);
     728    if (RT_SUCCESS(rc))
     729    {
     730        PVMCPU  pVCpu  = &pVM->aCpus[idCpu];
     731        PGVMCPU pGVCpu = &pGVM->aCpus[idCpu];
     732        AssertReturn(g_pfnHvlInvokeHypercall, VERR_NEM_MISSING_KERNEL_API);
     733
     734        /** @todo fix pGVM->nem.s.idHvPartition init. */
     735        if (pGVM->nem.s.idHvPartition == 0)
     736            pGVM->nem.s.idHvPartition = pVM->nem.s.idHvPartition;
     737
     738        /*
     739         * Call worker.
     740         */
     741        rc = nemR0WinExportState(pGVM, pGVCpu, CPUMQueryGuestCtxPtr(pVCpu), fWhat);
     742    }
     743    return rc;
     744}
     745
     746
     747/**
     748 * Worker for NEMR0ImportState.
     749 *
     750 * Intention is to use it internally later.
     751 *
     752 * @returns VBox status code.
     753 * @param   pGVM        The ring-0 VM handle.
     754 * @param   pGVCpu      The irng-0 VCPU handle.
     755 * @param   pCtx        The CPU context structure to import into.
     756 * @param   fWhat       What to import. To be defined, UINT64_MAX for now.
     757 */
     758static int nemR0WinImportState(PGVM pGVM, PGVMCPU pGVCpu, PCPUMCTX pCtx, uint64_t fWhat)
     759{
     760    HV_INPUT_GET_VP_REGISTERS *pInput = (HV_INPUT_GET_VP_REGISTERS *)pGVCpu->nem.s.pbHypercallData;
     761    AssertPtrReturn(pInput, VERR_INTERNAL_ERROR_3);
     762
     763    pInput->PartitionId = pGVM->nem.s.idHvPartition;
     764    pInput->VpIndex     = pGVCpu->idCpu;
     765    pInput->fFlags      = 0;
     766
     767    RT_NOREF_PV(fWhat); /** @todo group selection. */
     768
     769    /* GPRs */
     770    pInput->Names[0]  = HvX64RegisterRax;
     771    pInput->Names[1]  = HvX64RegisterRcx;
     772    pInput->Names[2]  = HvX64RegisterRdx;
     773    pInput->Names[3]  = HvX64RegisterRbx;
     774    pInput->Names[4]  = HvX64RegisterRsp;
     775    pInput->Names[5]  = HvX64RegisterRbp;
     776    pInput->Names[6]  = HvX64RegisterRsi;
     777    pInput->Names[7]  = HvX64RegisterRdi;
     778    pInput->Names[8]  = HvX64RegisterR8;
     779    pInput->Names[9]  = HvX64RegisterR9;
     780    pInput->Names[10] = HvX64RegisterR10;
     781    pInput->Names[11] = HvX64RegisterR11;
     782    pInput->Names[12] = HvX64RegisterR12;
     783    pInput->Names[13] = HvX64RegisterR13;
     784    pInput->Names[14] = HvX64RegisterR14;
     785    pInput->Names[15] = HvX64RegisterR15;
     786
     787    /* RIP & Flags */
     788    pInput->Names[16] = HvX64RegisterRip;
     789    pInput->Names[17] = HvX64RegisterRflags;
     790
     791    /* Segments */
     792    pInput->Names[18] = HvX64RegisterEs;
     793    pInput->Names[19] = HvX64RegisterCs;
     794    pInput->Names[20] = HvX64RegisterSs;
     795    pInput->Names[21] = HvX64RegisterDs;
     796    pInput->Names[22] = HvX64RegisterFs;
     797    pInput->Names[23] = HvX64RegisterGs;
     798    pInput->Names[24] = HvX64RegisterLdtr;
     799    pInput->Names[25] = HvX64RegisterTr;
     800
     801    /* Descriptor tables. */
     802    pInput->Names[26] = HvX64RegisterIdtr;
     803    pInput->Names[27] = HvX64RegisterGdtr;
     804
     805    /* Control registers. */
     806    pInput->Names[28] = HvX64RegisterCr0;
     807    pInput->Names[29] = HvX64RegisterCr2;
     808    pInput->Names[30] = HvX64RegisterCr3;
     809    pInput->Names[31] = HvX64RegisterCr4;
     810    pInput->Names[32] = HvX64RegisterCr8;
     811
     812    /* Debug registers. */
     813    pInput->Names[33] = HvX64RegisterDr0;
     814    pInput->Names[34] = HvX64RegisterDr1;
     815    pInput->Names[35] = HvX64RegisterDr2;
     816    pInput->Names[36] = HvX64RegisterDr3;
     817    pInput->Names[37] = HvX64RegisterDr6;
     818    pInput->Names[38] = HvX64RegisterDr7;
     819
     820    /* Vector state. */
     821    pInput->Names[39] = HvX64RegisterXmm0;
     822    pInput->Names[40] = HvX64RegisterXmm1;
     823    pInput->Names[41] = HvX64RegisterXmm2;
     824    pInput->Names[42] = HvX64RegisterXmm3;
     825    pInput->Names[43] = HvX64RegisterXmm4;
     826    pInput->Names[44] = HvX64RegisterXmm5;
     827    pInput->Names[45] = HvX64RegisterXmm6;
     828    pInput->Names[46] = HvX64RegisterXmm7;
     829    pInput->Names[47] = HvX64RegisterXmm8;
     830    pInput->Names[48] = HvX64RegisterXmm9;
     831    pInput->Names[49] = HvX64RegisterXmm10;
     832    pInput->Names[50] = HvX64RegisterXmm11;
     833    pInput->Names[51] = HvX64RegisterXmm12;
     834    pInput->Names[52] = HvX64RegisterXmm13;
     835    pInput->Names[53] = HvX64RegisterXmm14;
     836    pInput->Names[54] = HvX64RegisterXmm15;
     837
     838    /* Floating point state. */
     839    pInput->Names[55] = HvX64RegisterFpMmx0;
     840    pInput->Names[56] = HvX64RegisterFpMmx1;
     841    pInput->Names[57] = HvX64RegisterFpMmx2;
     842    pInput->Names[58] = HvX64RegisterFpMmx3;
     843    pInput->Names[59] = HvX64RegisterFpMmx4;
     844    pInput->Names[60] = HvX64RegisterFpMmx5;
     845    pInput->Names[61] = HvX64RegisterFpMmx6;
     846    pInput->Names[62] = HvX64RegisterFpMmx7;
     847    pInput->Names[63] = HvX64RegisterFpControlStatus;
     848    pInput->Names[64] = HvX64RegisterXmmControlStatus;
     849
     850    /* MSRs */
     851    // HvX64RegisterTsc - don't touch
     852    pInput->Names[65] = HvX64RegisterEfer;
     853    pInput->Names[66] = HvX64RegisterKernelGsBase;
     854    pInput->Names[67] = HvX64RegisterApicBase;
     855    pInput->Names[68] = HvX64RegisterPat;
     856    pInput->Names[69] = HvX64RegisterSysenterCs;
     857    pInput->Names[70] = HvX64RegisterSysenterEip;
     858    pInput->Names[71] = HvX64RegisterSysenterEsp;
     859    pInput->Names[72] = HvX64RegisterStar;
     860    pInput->Names[73] = HvX64RegisterLstar;
     861    pInput->Names[74] = HvX64RegisterCstar;
     862    pInput->Names[75] = HvX64RegisterSfmask;
     863
     864    /* event injection */
     865    pInput->Names[76] = HvRegisterPendingInterruption;
     866    pInput->Names[77] = HvRegisterInterruptState;
     867    pInput->Names[78] = HvRegisterInterruptState;
     868    pInput->Names[79] = HvRegisterPendingEvent0;
     869    pInput->Names[80] = HvRegisterPendingEvent1;
     870    unsigned const cRegs   = 81;
     871    size_t const   cbInput = RT_ALIGN_Z(RT_OFFSETOF(HV_INPUT_GET_VP_REGISTERS, Names[cRegs]), 32);
     872
     873    HV_REGISTER_VALUE *paValues = (HV_REGISTER_VALUE *)((uint8_t *)pInput + cbInput);
     874    Assert((uintptr_t)&paValues[cRegs] - (uintptr_t)pGVCpu->nem.s.pbHypercallData < PAGE_SIZE); /* (max is around 168 registers) */
     875    RT_BZERO(paValues, cRegs * sizeof(paValues[0]));
     876
     877    /*
     878     * Make the hypercall.
     879     */
     880    uint64_t uResult = g_pfnHvlInvokeHypercall(HV_MAKE_CALL_INFO(HvCallGetVpRegisters, cRegs),
     881                                               pGVCpu->nem.s.HCPhysHypercallData,
     882                                               pGVCpu->nem.s.HCPhysHypercallData + cbInput);
     883    AssertLogRelMsgReturn(uResult == HV_MAKE_CALL_REP_RET(cRegs),
     884                          ("uResult=%RX64 cRegs=%#x\n", uResult, cRegs),
     885                          VERR_NEM_GET_REGISTERS_FAILED);
     886
     887    /*
     888     * Copy information to the CPUM context.
     889     */
     890    PVMCPU pVCpu = &pGVM->pVM->aCpus[pGVCpu->idCpu];
     891
     892    /* GPRs */
     893    Assert(pInput->Names[0]  == HvX64RegisterRax);
     894    Assert(pInput->Names[15] == HvX64RegisterR15);
     895    pCtx->rax = paValues[0].Reg64;
     896    pCtx->rcx = paValues[1].Reg64;
     897    pCtx->rdx = paValues[2].Reg64;
     898    pCtx->rbx = paValues[3].Reg64;
     899    pCtx->rsp = paValues[4].Reg64;
     900    pCtx->rbp = paValues[5].Reg64;
     901    pCtx->rsi = paValues[6].Reg64;
     902    pCtx->rdi = paValues[7].Reg64;
     903    pCtx->r8  = paValues[8].Reg64;
     904    pCtx->r9  = paValues[9].Reg64;
     905    pCtx->r10 = paValues[10].Reg64;
     906    pCtx->r11 = paValues[11].Reg64;
     907    pCtx->r12 = paValues[12].Reg64;
     908    pCtx->r13 = paValues[13].Reg64;
     909    pCtx->r14 = paValues[14].Reg64;
     910    pCtx->r15 = paValues[15].Reg64;
     911
     912    /* RIP & Flags */
     913    Assert(pInput->Names[16] == HvX64RegisterRip);
     914    pCtx->rip      = paValues[16].Reg64;
     915    pCtx->rflags.u = paValues[17].Reg64;
     916
     917    /* Segments */
     918#define COPY_BACK_SEG(a_idx, a_enmName, a_SReg) \
     919        do { \
     920            Assert(pInput->Names[a_idx] == a_enmName); \
     921            (a_SReg).u64Base  = paValues[a_idx].Segment.Base; \
     922            (a_SReg).u32Limit = paValues[a_idx].Segment.Limit; \
     923            (a_SReg).ValidSel = (a_SReg).Sel = paValues[a_idx].Segment.Selector; \
     924            (a_SReg).Attr.u   = paValues[a_idx].Segment.Attributes; \
     925            (a_SReg).fFlags   = CPUMSELREG_FLAGS_VALID; \
     926        } while (0)
     927    COPY_BACK_SEG(18, HvX64RegisterEs,   pCtx->es);
     928    COPY_BACK_SEG(19, HvX64RegisterCs,   pCtx->cs);
     929    COPY_BACK_SEG(20, HvX64RegisterSs,   pCtx->ss);
     930    COPY_BACK_SEG(21, HvX64RegisterDs,   pCtx->ds);
     931    COPY_BACK_SEG(22, HvX64RegisterFs,   pCtx->fs);
     932    COPY_BACK_SEG(23, HvX64RegisterGs,   pCtx->gs);
     933    COPY_BACK_SEG(24, HvX64RegisterLdtr, pCtx->ldtr);
     934    COPY_BACK_SEG(25, HvX64RegisterTr,   pCtx->tr);
     935
     936    /* Descriptor tables. */
     937    Assert(pInput->Names[26] == HvX64RegisterIdtr);
     938    pCtx->idtr.cbIdt = paValues[26].Table.Limit;
     939    pCtx->idtr.pIdt  = paValues[26].Table.Base;
     940    Assert(pInput->Names[27] == HvX64RegisterGdtr);
     941    pCtx->gdtr.cbGdt = paValues[27].Table.Limit;
     942    pCtx->gdtr.pGdt  = paValues[27].Table.Base;
     943
     944    /* Control registers. */
     945    Assert(pInput->Names[28] == HvX64RegisterCr0);
     946    bool fMaybeChangedMode = false;
     947    bool fFlushTlb         = false;
     948    bool fFlushGlobalTlb   = false;
     949    if (pCtx->cr0 != paValues[28].Reg64)
     950    {
     951        CPUMSetGuestCR0(pVCpu, paValues[28].Reg64);
     952        fMaybeChangedMode = true;
     953        fFlushTlb = fFlushGlobalTlb = true; /// @todo fix this
     954    }
     955    Assert(pInput->Names[29] == HvX64RegisterCr2);
     956    pCtx->cr2 = paValues[29].Reg64;
     957    if (pCtx->cr3 != paValues[30].Reg64)
     958    {
     959        CPUMSetGuestCR3(pVCpu, paValues[30].Reg64);
     960        fFlushTlb = true;
     961    }
     962    if (pCtx->cr4 != paValues[31].Reg64)
     963    {
     964        CPUMSetGuestCR4(pVCpu, paValues[31].Reg64);
     965        fMaybeChangedMode = true;
     966        fFlushTlb = fFlushGlobalTlb = true; /// @todo fix this
     967    }
     968    APICSetTpr(pVCpu, (uint8_t)paValues[32].Reg64 << 4);
     969
     970    /* Debug registers. */
     971    Assert(pInput->Names[33] == HvX64RegisterDr0);
     972/** @todo fixme */
     973    if (pCtx->dr[0] != paValues[33].Reg64)
     974        CPUMSetGuestDR0(pVCpu, paValues[33].Reg64);
     975    if (pCtx->dr[1] != paValues[34].Reg64)
     976        CPUMSetGuestDR1(pVCpu, paValues[34].Reg64);
     977    if (pCtx->dr[2] != paValues[35].Reg64)
     978        CPUMSetGuestDR2(pVCpu, paValues[35].Reg64);
     979    if (pCtx->dr[3] != paValues[36].Reg64)
     980        CPUMSetGuestDR3(pVCpu, paValues[36].Reg64);
     981    Assert(pInput->Names[37] == HvX64RegisterDr6);
     982    Assert(pInput->Names[38] == HvX64RegisterDr7);
     983    if (pCtx->dr[6] != paValues[37].Reg64)
     984        CPUMSetGuestDR6(pVCpu, paValues[37].Reg64);
     985    if (pCtx->dr[7] != paValues[38].Reg64)
     986        CPUMSetGuestDR6(pVCpu, paValues[38].Reg64);
     987
     988    /* Vector state. */
     989    Assert(pInput->Names[39] == HvX64RegisterXmm0);
     990    Assert(pInput->Names[54] == HvX64RegisterXmm15);
     991    pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Lo  = paValues[39].Reg128.Low64;
     992    pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Hi  = paValues[39].Reg128.High64;
     993    pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Lo  = paValues[40].Reg128.Low64;
     994    pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Hi  = paValues[40].Reg128.High64;
     995    pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Lo  = paValues[41].Reg128.Low64;
     996    pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Hi  = paValues[41].Reg128.High64;
     997    pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Lo  = paValues[42].Reg128.Low64;
     998    pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Hi  = paValues[42].Reg128.High64;
     999    pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Lo  = paValues[43].Reg128.Low64;
     1000    pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Hi  = paValues[43].Reg128.High64;
     1001    pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Lo  = paValues[44].Reg128.Low64;
     1002    pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Hi  = paValues[44].Reg128.High64;
     1003    pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Lo  = paValues[45].Reg128.Low64;
     1004    pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Hi  = paValues[45].Reg128.High64;
     1005    pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Lo  = paValues[46].Reg128.Low64;
     1006    pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Hi  = paValues[46].Reg128.High64;
     1007    pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Lo  = paValues[47].Reg128.Low64;
     1008    pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Hi  = paValues[47].Reg128.High64;
     1009    pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Lo  = paValues[48].Reg128.Low64;
     1010    pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Hi  = paValues[48].Reg128.High64;
     1011    pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Lo = paValues[49].Reg128.Low64;
     1012    pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Hi = paValues[49].Reg128.High64;
     1013    pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Lo = paValues[50].Reg128.Low64;
     1014    pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Hi = paValues[50].Reg128.High64;
     1015    pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Lo = paValues[51].Reg128.Low64;
     1016    pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Hi = paValues[51].Reg128.High64;
     1017    pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Lo = paValues[52].Reg128.Low64;
     1018    pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Hi = paValues[52].Reg128.High64;
     1019    pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Lo = paValues[53].Reg128.Low64;
     1020    pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Hi = paValues[53].Reg128.High64;
     1021    pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Lo = paValues[54].Reg128.Low64;
     1022    pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Hi = paValues[54].Reg128.High64;
     1023
     1024    /* Floating point state. */
     1025    Assert(pInput->Names[55] == HvX64RegisterFpMmx0);
     1026    Assert(pInput->Names[62] == HvX64RegisterFpMmx7);
     1027    pCtx->pXStateR0->x87.aRegs[0].au64[0] = paValues[55].Fp.AsUINT128.Low64;
     1028    pCtx->pXStateR0->x87.aRegs[0].au64[1] = paValues[55].Fp.AsUINT128.High64;
     1029    pCtx->pXStateR0->x87.aRegs[1].au64[0] = paValues[56].Fp.AsUINT128.Low64;
     1030    pCtx->pXStateR0->x87.aRegs[1].au64[1] = paValues[56].Fp.AsUINT128.High64;
     1031    pCtx->pXStateR0->x87.aRegs[2].au64[0] = paValues[57].Fp.AsUINT128.Low64;
     1032    pCtx->pXStateR0->x87.aRegs[2].au64[1] = paValues[57].Fp.AsUINT128.High64;
     1033    pCtx->pXStateR0->x87.aRegs[3].au64[0] = paValues[58].Fp.AsUINT128.Low64;
     1034    pCtx->pXStateR0->x87.aRegs[3].au64[1] = paValues[58].Fp.AsUINT128.High64;
     1035    pCtx->pXStateR0->x87.aRegs[4].au64[0] = paValues[59].Fp.AsUINT128.Low64;
     1036    pCtx->pXStateR0->x87.aRegs[4].au64[1] = paValues[59].Fp.AsUINT128.High64;
     1037    pCtx->pXStateR0->x87.aRegs[5].au64[0] = paValues[60].Fp.AsUINT128.Low64;
     1038    pCtx->pXStateR0->x87.aRegs[5].au64[1] = paValues[60].Fp.AsUINT128.High64;
     1039    pCtx->pXStateR0->x87.aRegs[6].au64[0] = paValues[61].Fp.AsUINT128.Low64;
     1040    pCtx->pXStateR0->x87.aRegs[6].au64[1] = paValues[61].Fp.AsUINT128.High64;
     1041    pCtx->pXStateR0->x87.aRegs[7].au64[0] = paValues[62].Fp.AsUINT128.Low64;
     1042    pCtx->pXStateR0->x87.aRegs[7].au64[1] = paValues[62].Fp.AsUINT128.High64;
     1043
     1044    Assert(pInput->Names[63] == HvX64RegisterFpControlStatus);
     1045    pCtx->pXStateR0->x87.FCW        = paValues[63].FpControlStatus.FpControl;
     1046    pCtx->pXStateR0->x87.FSW        = paValues[63].FpControlStatus.FpStatus;
     1047    pCtx->pXStateR0->x87.FTW        = paValues[63].FpControlStatus.FpTag
     1048                                    /*| (paValues[63].FpControlStatus.Reserved << 8)*/;
     1049    pCtx->pXStateR0->x87.FOP        = paValues[63].FpControlStatus.LastFpOp;
     1050    pCtx->pXStateR0->x87.FPUIP      = (uint32_t)paValues[63].FpControlStatus.LastFpRip;
     1051    pCtx->pXStateR0->x87.CS         = (uint16_t)(paValues[63].FpControlStatus.LastFpRip >> 32);
     1052    pCtx->pXStateR0->x87.Rsrvd1     = (uint16_t)(paValues[63].FpControlStatus.LastFpRip >> 48);
     1053
     1054    Assert(pInput->Names[64] == HvX64RegisterXmmControlStatus);
     1055    pCtx->pXStateR0->x87.FPUDP      = (uint32_t)paValues[64].XmmControlStatus.LastFpRdp;
     1056    pCtx->pXStateR0->x87.DS         = (uint16_t)(paValues[64].XmmControlStatus.LastFpRdp >> 32);
     1057    pCtx->pXStateR0->x87.Rsrvd2     = (uint16_t)(paValues[64].XmmControlStatus.LastFpRdp >> 48);
     1058    pCtx->pXStateR0->x87.MXCSR      = paValues[64].XmmControlStatus.XmmStatusControl;
     1059    pCtx->pXStateR0->x87.MXCSR_MASK = paValues[64].XmmControlStatus.XmmStatusControlMask; /** @todo ??? (Isn't this an output field?) */
     1060
     1061    /* MSRs */
     1062    // HvX64RegisterTsc - don't touch
     1063    Assert(pInput->Names[65] == HvX64RegisterEfer);
     1064    if (paValues[65].Reg64 != pCtx->msrEFER)
     1065    {
     1066        pCtx->msrEFER = paValues[65].Reg64;
     1067        fMaybeChangedMode = true;
     1068    }
     1069
     1070    Assert(pInput->Names[66] == HvX64RegisterKernelGsBase);
     1071    pCtx->msrKERNELGSBASE = paValues[66].Reg64;
     1072
     1073    Assert(pInput->Names[67] == HvX64RegisterApicBase);
     1074    if (paValues[67].Reg64 != APICGetBaseMsrNoCheck(pVCpu))
     1075    {
     1076        VBOXSTRICTRC rc2 = APICSetBaseMsr(pVCpu, paValues[67].Reg64);
     1077        Assert(rc2 == VINF_SUCCESS); NOREF(rc2);
     1078    }
     1079
     1080    Assert(pInput->Names[68] == HvX64RegisterPat);
     1081    pCtx->msrPAT    = paValues[68].Reg64;
     1082    /// @todo HvX64RegisterSysenterCs
     1083    /// @todo HvX64RegisterSysenterEip
     1084    /// @todo HvX64RegisterSysenterEsp
     1085    Assert(pInput->Names[72] == HvX64RegisterStar);
     1086    pCtx->msrSTAR   = paValues[72].Reg64;
     1087    Assert(pInput->Names[73] == HvX64RegisterLstar);
     1088    pCtx->msrLSTAR  = paValues[73].Reg64;
     1089    Assert(pInput->Names[74] == HvX64RegisterCstar);
     1090    pCtx->msrCSTAR  = paValues[74].Reg64;
     1091    Assert(pInput->Names[75] == HvX64RegisterSfmask);
     1092    pCtx->msrSFMASK = paValues[75].Reg64;
     1093
     1094    /// @todo HvRegisterPendingInterruption
     1095    Assert(pInput->Names[76] == HvRegisterPendingInterruption);
     1096    if (paValues[76].PendingInterruption.InterruptionPending)
     1097    {
     1098        Log7(("PendingInterruption: type=%u vector=%#x errcd=%RTbool/%#x instr-len=%u nested=%u\n",
     1099              paValues[76].PendingInterruption.InterruptionType, paValues[76].PendingInterruption.InterruptionVector,
     1100              paValues[76].PendingInterruption.DeliverErrorCode, paValues[76].PendingInterruption.ErrorCode,
     1101              paValues[76].PendingInterruption.InstructionLength, paValues[76].PendingInterruption.NestedEvent));
     1102        AssertMsg((paValues[76].PendingInterruption.AsUINT64 & UINT64_C(0xfc00)) == 0,
     1103                  ("%#RX64\n", paValues[76].PendingInterruption.AsUINT64));
     1104    }
     1105
     1106    /// @todo HvRegisterInterruptState
     1107    /// @todo HvRegisterPendingEvent0
     1108    /// @todo HvRegisterPendingEvent1
     1109
     1110    int rc = VINF_SUCCESS;
     1111    if (fMaybeChangedMode)
     1112    {
     1113        rc = PGMChangeMode(pVCpu, pCtx->cr0, pCtx->cr4, pCtx->msrEFER);
     1114        if (rc == VINF_PGM_CHANGE_MODE)
     1115            rc = VERR_NEM_CHANGE_PGM_MODE;
     1116        else
     1117            AssertRC(rc);
     1118    }
     1119    if (fFlushTlb && rc == VINF_SUCCESS)
     1120        rc = VERR_NEM_FLUSH_TLB; /* Calling PGMFlushTLB w/o long jump setup doesn't work, ring-3 does it. */
     1121
     1122    return rc;
     1123}
     1124
     1125
     1126/**
     1127 * Import the state from the native API (back to CPUMCTX).
     1128 *
     1129 * @returns VBox status code
     1130 * @param   pGVM        The ring-0 VM handle.
     1131 * @param   pVM         The cross context VM handle.
     1132 * @param   idCpu       The calling EMT.  Necessary for getting the
     1133 *                      hypercall page and arguments.
     1134 * @param   fWhat       What to import. To be defined, UINT64_MAX for now.
     1135 */
     1136VMMR0_INT_DECL(int)  NEMR0ImportState(PGVM pGVM, PVM pVM, VMCPUID idCpu, uint64_t fWhat)
     1137{
     1138    /*
     1139     * Validate the call.
     1140     */
     1141    int rc = GVMMR0ValidateGVMandVMandEMT(pGVM, pVM, idCpu);
     1142    if (RT_SUCCESS(rc))
     1143    {
     1144        PVMCPU  pVCpu  = &pVM->aCpus[idCpu];
     1145        PGVMCPU pGVCpu = &pGVM->aCpus[idCpu];
     1146        AssertReturn(g_pfnHvlInvokeHypercall, VERR_NEM_MISSING_KERNEL_API);
     1147
     1148        /** @todo fix pGVM->nem.s.idHvPartition init. */
     1149        if (pGVM->nem.s.idHvPartition == 0)
     1150            pGVM->nem.s.idHvPartition = pVM->nem.s.idHvPartition;
     1151
     1152        /*
     1153         * Call worker.
     1154         */
     1155        rc = nemR0WinImportState(pGVM, pGVCpu, CPUMQueryGuestCtxPtr(pVCpu), fWhat);
     1156    }
     1157    return rc;
     1158}
     1159
  • trunk/src/VBox/VMM/VMMR0/VMMR0.cpp

    r71075 r71087  
    19881988            VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
    19891989            break;
     1990
     1991        case VMMR0_DO_NEM_EXPORT_STATE:
     1992            if (pReqHdr || idCpu == NIL_VMCPUID)
     1993                return VERR_INVALID_PARAMETER;
     1994            rc = NEMR0ExportState(pGVM, pVM, idCpu, u64Arg);
     1995            VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
     1996            break;
     1997
     1998        case VMMR0_DO_NEM_IMPORT_STATE:
     1999            if (pReqHdr || idCpu == NIL_VMCPUID)
     2000                return VERR_INVALID_PARAMETER;
     2001            rc = NEMR0ImportState(pGVM, pVM, idCpu, u64Arg);
     2002            VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
     2003            break;
    19902004# endif
    19912005#endif
  • trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp

    r71082 r71087  
    7878
    7979
    80 #define NEM_WIN_USE_HYPERCALLS
     80#define NEM_WIN_USE_HYPERCALLS_FOR_PAGES
     81#define NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS
    8182
    8283
     
    99100AssertCompileSize(MISSINGINTERUPTSTATEREG, 16);
    100101
    101 /** Used by MISSINGPENDINGINTERRUPTIONREG. */
    102 typedef enum MISSINGPENDINGINTERRUPTIONTYPE
    103 {
    104     kPendingIntType_Interrupt = 0,
    105     kPendingIntType_Nmi,
    106     kPendingIntType_Xcpt,
    107     kPendingIntType_Dunno,
    108     kPendingIntType_SoftwareInterrupt
    109 } MISSINGPENDINGINTERRUPTIONTYPE;
    110 
    111 /** WHvRegisterPendingInterruption layout, reconstructed from the v7.1 DDK. */
    112 typedef union MISSINGPENDINGINTERRUPTIONREG
    113 {
    114     /** 64-bit view. */
    115     uint64_t au64[2];
    116     struct /* unamed */
    117     {
    118         uint32_t fInterruptionPending : 1;
    119         uint32_t enmInterruptionType : 3; /**< MISSINGPENDINGINTERRUPTIONTYPE */
    120         uint32_t fDeliverErrCd : 1;
    121         uint32_t fUnknown0 : 1;
    122         uint32_t fUnknown1 : 1; /**< Observed set when software interrupt was issued. */
    123         uint32_t uReserved0 : 9;
    124         uint32_t InterruptionVector : 16;
    125         uint32_t uErrCd;
    126         uint64_t uReserved1;
    127     };
    128 } MISSINGPENDINGINTERRUPTIONREG;
    129 AssertCompileSize(MISSINGPENDINGINTERRUPTIONREG, 16);
    130102
    131103
     
    985957
    986958
    987 #ifdef NEM_WIN_USE_HYPERCALLS
     959#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
    988960
    989961/**
     
    1023995}
    1024996
    1025 #endif /* NEM_WIN_USE_HYPERCALLS */
     997#endif /* NEM_WIN_USE_HYPERCALLS_FOR_PAGES */
    1026998
    1027999static int nemR3WinCopyStateToHyperV(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
    10281000{
     1001#ifdef NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS
     1002    NOREF(pCtx);
     1003    int rc = VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_NEM_EXPORT_STATE, UINT64_MAX, NULL);
     1004    AssertLogRelRCReturn(rc, rc);
     1005    return rc;
     1006
     1007#else
    10291008    WHV_REGISTER_NAME  aenmNames[128];
    10301009    WHV_REGISTER_VALUE aValues[128];
     
    12931272
    12941273    /* event injection (always clear it). */
    1295     /** @todo Someone at microsoft please explain why HV_X64_PENDING_INTERRUPTION_REGISTER
    1296      * and HV_X64_INTERRUPT_STATE_REGISTER are missing from the headers.  Ditto for
    1297      * wathever structures WHvRegisterPendingEvent0/1 uses.   */
    12981274    aenmNames[iReg]     = WHvRegisterPendingInterruption;
    12991275    aValues[iReg].Reg64 = 0;
     
    13191295                           hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue));
    13201296    return VERR_INTERNAL_ERROR;
     1297#endif /* !NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS */
    13211298}
    13221299
    13231300static int nemR3WinCopyStateFromHyperV(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
    13241301{
     1302#ifdef NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS
     1303    NOREF(pCtx);
     1304    int rc = VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_NEM_IMPORT_STATE, UINT64_MAX, NULL);
     1305    if (RT_SUCCESS(rc))
     1306        return rc;
     1307    if (rc == VERR_NEM_FLUSH_TLB)
     1308        return PGMFlushTLB(pVCpu, pCtx->cr3, true /*fGlobal*/);
     1309    if (rc == VERR_NEM_CHANGE_PGM_MODE)
     1310        return PGMChangeMode(pVCpu, pCtx->cr0, pCtx->cr4, pCtx->msrEFER);
     1311    AssertLogRelRCReturn(rc, rc);
     1312    return rc;
     1313
     1314#else
    13251315    WHV_REGISTER_NAME  aenmNames[128];
    13261316
     
    16461636        /// @todo WHvRegisterPendingInterruption
    16471637        Assert(aenmNames[76] == WHvRegisterPendingInterruption);
    1648         /** @todo Someone at microsoft please explain why HV_X64_PENDING_INTERRUPTION_REGISTER
    1649          * and HV_X64_INTERRUPT_STATE_REGISTER are missing from the headers.  Ditto for
    1650          * wathever structures WHvRegisterPendingEvent0/1 uses.   */
    1651         MISSINGPENDINGINTERRUPTIONREG const * pPendingInt = (MISSINGPENDINGINTERRUPTIONREG const *)&aValues[76];
    1652         if (pPendingInt->fInterruptionPending)
    1653         {
    1654             Log7(("PendingInterruption: type=%u vector=%#x errcd=%RTbool/%#x unk0=%u unk1=%u\n",
    1655                   pPendingInt->enmInterruptionType, pPendingInt->InterruptionVector, pPendingInt->fDeliverErrCd,
    1656                   pPendingInt->uErrCd, pPendingInt->fUnknown0, pPendingInt->fUnknown1));
    1657             AssertMsg(pPendingInt->uReserved0 == 0 && pPendingInt->uReserved1 == 0,
    1658                       ("%#RX64 %#RX64\n", pPendingInt->au64[0], pPendingInt->au64[1]));
     1638        WHV_X64_PENDING_INTERRUPTION_REGISTER const * pPendingInt = (WHV_X64_PENDING_INTERRUPTION_REGISTER const *)&aValues[76];
     1639        if (pPendingInt->InterruptionPending)
     1640        {
     1641            Log7(("PendingInterruption: type=%u vector=%#x errcd=%RTbool/%#x instr-len=%u nested=%u\n",
     1642                  pPendingInt->InterruptionType, pPendingInt->InterruptionVector, pPendingInt->DeliverErrorCode,
     1643                  pPendingInt->ErrorCode, pPendingInt->InstructionLength, pPendingInt->NestedEvent));
     1644            AssertMsg((pPendingInt->AsUINT64 & UINT64_C(0xfc00)) == 0, ("%#RX64\n", pPendingInt->AsUINT64));
    16591645        }
    16601646
     
    16821668                           hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue));
    16831669    return VERR_INTERNAL_ERROR;
     1670#endif /* !NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS */
    16841671}
    16851672
     
    18841871{
    18851872    RT_NOREF_PV(pvUser);
    1886 #ifdef NEM_WIN_USE_HYPERCALLS
     1873#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
    18871874    int rc = nemR3WinHypercallUnmapPage(pVM, pVCpu, GCPhys);
    18881875    AssertRC(rc);
     
    18991886    else
    19001887    {
    1901 #ifdef NEM_WIN_USE_HYPERCALLS
     1888#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
    19021889        LogRel(("nemR3WinUnmapOnePageCallback: GCPhys=%RGp rc=%Rrc\n", GCPhys, rc));
    19031890#else
     
    19621949     * We don't really consider downgrades here, as they shouldn't happen.
    19631950     */
    1964 #ifndef NEM_WIN_USE_HYPERCALLS
     1951#ifndef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
    19651952    /** @todo Someone at microsoft please explain:
    19661953     * I'm not sure WTF was going on, but I ended up in a loop if I remapped a
     
    20142001            }
    20152002
    2016 #ifdef NEM_WIN_USE_HYPERCALLS
     2003#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
    20172004            /* Upgrade page to writable. */
    20182005/** @todo test this*/
     
    20502037                return VINF_SUCCESS;
    20512038            }
    2052 #ifdef NEM_WIN_USE_HYPERCALLS
     2039#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
    20532040            AssertFailed(); /* There should be no downgrades. */
    20542041#endif
     
    20632050     * If this fails, which it does every so often, just unmap everything for now.
    20642051     */
    2065 #ifdef NEM_WIN_USE_HYPERCALLS
     2052#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
    20662053    rc = nemR3WinHypercallUnmapPage(pVM, pVCpu, GCPhys);
    20672054    AssertRC(rc);
     
    20802067        return VINF_SUCCESS;
    20812068    }
    2082 #ifdef NEM_WIN_USE_HYPERCALLS
     2069#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
    20832070    LogRel(("nemR3WinHandleMemoryAccessPageCheckerCallback/unmap: GCPhysDst=%RGp rc=%Rrc\n", GCPhys, rc));
    20842071    return rc;
     
    24552442        }
    24562443
    2457 #ifndef NEM_WIN_USE_HYPERCALLS
     2444#ifndef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
    24582445        /* Hack alert! */
    24592446        uint32_t const cMappedPages = pVM->nem.s.cMappedPages;
     
    26372624    if (pInfo->u2NemState > NEM_WIN_PAGE_STATE_UNMAPPED)
    26382625    {
    2639 #ifdef NEM_WIN_USE_HYPERCALLS
     2626#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
    26402627        int rc = nemR3WinHypercallUnmapPage(pVM, pVCpu, GCPhys);
    26412628        AssertRC(rc);
     
    26522639        else
    26532640        {
    2654 #ifdef NEM_WIN_USE_HYPERCALLS
     2641#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
    26552642            LogRel(("nemR3WinUnsetForA20CheckerCallback/unmap: GCPhys=%RGp rc=%Rrc\n", GCPhys, rc));
    26562643            return rc;
     
    27522739                                  uint8_t *pu2State, bool fBackingChanged)
    27532740{
    2754 #ifdef NEM_WIN_USE_HYPERCALLS
     2741#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
    27552742    /*
    27562743     * When using the hypercalls instead of the ring-3 APIs, we don't need to
     
    28362823        if (u2OldState > NEM_WIN_PAGE_STATE_UNMAPPED)
    28372824        {
    2838 # ifdef NEM_WIN_USE_HYPERCALLS
     2825# ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
    28392826            int rc = nemR3WinHypercallUnmapPage(pVM, pVCpu, GCPhysDst);
    28402827            AssertRC(rc);
     
    28832870    if (fPageProt & NEM_PAGE_PROT_WRITE)
    28842871    {
    2885 # ifdef NEM_WIN_USE_HYPERCALLS
     2872# ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
    28862873        int rc = nemR3WinHypercallMapPage(pVM, pVCpu, GCPhysSrc, GCPhysDst,
    28872874                                            HV_MAP_GPA_READABLE   | HV_MAP_GPA_WRITABLE
     
    29242911    if (fPageProt & NEM_PAGE_PROT_READ)
    29252912    {
    2926 # ifdef NEM_WIN_USE_HYPERCALLS
     2913# ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
    29272914        int rc = nemR3WinHypercallMapPage(pVM, pVCpu, GCPhysSrc, GCPhysDst,
    29282915                                          HV_MAP_GPA_READABLE | HV_MAP_GPA_EXECUTABLE | HV_MAP_GPA_EXECUTABLE_AGAIN);
     
    29652952    *pu2State = NEM_WIN_PAGE_STATE_UNMAPPED;
    29662953    return VINF_SUCCESS;
    2967 #endif /* !NEM_WIN_USE_HYPERCALLS */
     2954#endif /* !NEM_WIN_USE_HYPERCALLS_FOR_PAGES */
    29682955}
    29692956
     
    29782965    }
    29792966
    2980 #ifdef NEM_WIN_USE_HYPERCALLS
     2967#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
    29812968    PVMCPU pVCpu = VMMGetCpu(pVM);
    29822969    int rc = nemR3WinHypercallUnmapPage(pVM, pVCpu, GCPhysDst);
     
    30153002
    30163003    int rc;
    3017 #ifdef NEM_WIN_USE_HYPERCALLS
     3004#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
    30183005    PVMCPU pVCpu = VMMGetCpu(pVM);
    30193006    if (   pVM->nem.s.fA20Enabled
     
    30493036    RT_NOREF_PV(HCPhys); RT_NOREF_PV(enmType);
    30503037
    3051 #ifdef NEM_WIN_USE_HYPERCALLS
     3038#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
    30523039    PVMCPU pVCpu = VMMGetCpu(pVM);
    30533040    if (   pVM->nem.s.fA20Enabled
     
    30803067    RT_NOREF_PV(HCPhysPrev); RT_NOREF_PV(HCPhysNew); RT_NOREF_PV(enmType);
    30813068
    3082 #ifdef NEM_WIN_USE_HYPERCALLS
     3069#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
    30833070    PVMCPU pVCpu = VMMGetCpu(pVM);
    30843071    if (   pVM->nem.s.fA20Enabled
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette