VirtualBox

Changeset 71087 in vbox for trunk/src/VBox/VMM/VMMR0


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/src/VBox/VMM/VMMR0
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • 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
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