- Timestamp:
- Mar 3, 2018 3:01:59 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/cpum.mac
r70732 r71184 257 257 .aoffXState resw 64 258 258 .fWorldSwitcher resd 1 259 .fExtrn resq 1 259 260 alignb 8 260 261 .hwvirt.svm.uMsrHSavePa resq 1 261 262 .hwvirt.svm.GCPhysVmcb resq 1 262 263 .hwvirt.svm.pVmcbR0 RTR0PTR_RES 1 264 alignb 8 263 265 .hwvirt.svm.pVmcbR3 RTR3PTR_RES 1 264 %if HC_ARCH_BITS == 32 265 .hwvirt.svm.abPadding0 resb 8 266 %endif 266 alignb 8 267 267 .hwvirt.svm.HostState resb 184 268 268 .hwvirt.svm.u16Padding0 resw 1 … … 271 271 .hwvirt.svm.fInterceptEvents resb 1 272 272 .hwvirt.svm.fHMCachedVmcb resb 1 273 alignb 8 273 274 .hwvirt.svm.pvMsrBitmapR0 RTR0PTR_RES 1 275 alignb 8 274 276 .hwvirt.svm.pvMsrBitmapR3 RTR3PTR_RES 1 277 alignb 8 275 278 .hwvirt.svm.pvIoBitmapR0 RTR0PTR_RES 1 279 alignb 8 276 280 .hwvirt.svm.pvIoBitmapR3 RTR3PTR_RES 1 281 alignb 8 277 282 .hwvirt.svm.HCPhysVmcb RTHCPHYS_RES 1 278 %if HC_ARCH_BITS == 32279 .hwvirt.svm.abPadding2 resb 16280 %endif281 283 .hwvirt.fLocalForcedActions resd 1 282 284 .hwvirt.fGif resb 1 -
trunk/include/VBox/vmm/cpumctx.h
r70913 r71184 473 473 /** 0x2d4 - World switcher flags, CPUMCTX_WSF_XXX. */ 474 474 uint32_t fWorldSwitcher; 475 476 /** 728 - Hardware virtualization state. */ 475 /** 0x2d8 - Externalized state tracker, CPUMCTX_EXTRN_XXX. 476 * Currently only used internally in NEM/win. */ 477 uint64_t fExtrn; 478 479 /** 0x2e0 - Hardware virtualization state. */ 477 480 struct 478 481 { … … 481 484 struct 482 485 { 483 /** 728- MSR holding physical address of the Guest's Host-state. */486 /** 0x2e0 - MSR holding physical address of the Guest's Host-state. */ 484 487 uint64_t uMsrHSavePa; 485 /** 736- Guest physical address of the nested-guest VMCB. */488 /** 0x2e8 - Guest physical address of the nested-guest VMCB. */ 486 489 RTGCPHYS GCPhysVmcb; 487 /** 744- Cache of the nested-guest VMCB - R0 ptr. */490 /** 0x2f0 - Cache of the nested-guest VMCB - R0 ptr. */ 488 491 R0PTRTYPE(PSVMVMCB) pVmcbR0; 489 /** 752 / 748 - Cache of the nested-guest VMCB - R3 ptr. */ 492 #if HC_ARCH_BITS == 32 493 uint32_t uVmcbR0Padding; 494 #endif 495 /** 0x2f8 - Cache of the nested-guest VMCB - R3 ptr. */ 490 496 R3PTRTYPE(PSVMVMCB) pVmcbR3; 491 497 #if HC_ARCH_BITS == 32 492 /** NA / 752 - Padding. */ 493 uint8_t abPadding0[8]; 494 #endif 495 /** 760 - Guest's host-state save area. */ 498 uint32_t uVmcbR3Padding; 499 #endif 500 /** 0x300 - Guest's host-state save area. */ 496 501 SVMHOSTSTATE HostState; 497 /** 944- Padding. */502 /** 0x3b8 - Padding. */ 498 503 uint16_t u16Padding0; 499 /** 946- Pause filter count. */504 /** 0x3ba - Pause filter count. */ 500 505 uint16_t cPauseFilter; 501 /** 948- Pause filter count. */506 /** 0x3bc - Pause filter count. */ 502 507 uint16_t cPauseFilterThreshold; 503 /** 950- Whether the injected event is subject to event intercepts. */508 /** 0x3be - Whether the injected event is subject to event intercepts. */ 504 509 bool fInterceptEvents; 505 /** 951- Whether parts of the VMCB are cached (and potentially modified) by HM. */510 /** 0x3bf - Whether parts of the VMCB are cached (and potentially modified) by HM. */ 506 511 bool fHMCachedVmcb; 507 /** 952- MSR permission bitmap - R0 ptr. */512 /** 0x3c0 - MSR permission bitmap - R0 ptr. */ 508 513 R0PTRTYPE(void *) pvMsrBitmapR0; 509 /** 960 / 956 - MSR permission bitmap - R3 ptr. */ 514 #if HC_ARCH_BITS == 32 515 uint32_t uvMsrBitmapR0Padding; 516 #endif 517 /** 0x3c8 - MSR permission bitmap - R3 ptr. */ 510 518 R3PTRTYPE(void *) pvMsrBitmapR3; 511 /** 968 / 960 - IO permission bitmap - R0 ptr. */ 519 #if HC_ARCH_BITS == 32 520 uint32_t uvMsrBitmapR3Padding; 521 #endif 522 /** 0x3d0 - IO permission bitmap - R0 ptr. */ 512 523 R0PTRTYPE(void *) pvIoBitmapR0; 513 /** 976 / 964 - IO permission bitmap - R3 ptr. */ 524 #if HC_ARCH_BITS == 32 525 uint32_t uIoBitmapR0Padding; 526 #endif 527 /** 0x3d8 - IO permission bitmap - R3 ptr. */ 514 528 R3PTRTYPE(void *) pvIoBitmapR3; 515 /** 984 / 968 - Host physical address of the nested-guest VMCB. */ 529 #if HC_ARCH_BITS == 32 530 uint32_t uIoBitmapR3Padding; 531 #endif 532 /** 0x3e0 - Host physical address of the nested-guest VMCB. */ 516 533 RTHCPHYS HCPhysVmcb; 517 #if HC_ARCH_BITS == 32518 /** NA / 976 - Padding. */519 uint8_t abPadding2[16];520 #endif521 534 } svm; 522 535 #if 0 … … 527 540 } CPUM_UNION_NM(s); 528 541 529 /** 992 - A subset of force flags that are preserved while running 530 * the nested-guest. */ 542 /** 0x3e8 - A subset of force flags that are preserved while running the nested-guest. */ 531 543 uint32_t fLocalForcedActions; 532 /** 996- Global interrupt flag (always true on nested VMX). */544 /** 0x3f0 - Global interrupt flag (always true on nested VMX). */ 533 545 bool fGif; 534 /** 997- Padding. */535 uint8_t abPadding1[ 27];546 /** 0x3f1 - Padding. */ 547 uint8_t abPadding1[19]; 536 548 } hwvirt; 537 549 /** @} */ … … 588 600 AssertCompileMemberOffset(CPUMCTX, pXStateRC, 592); 589 601 AssertCompileMemberOffset(CPUMCTX, aoffXState, 596); 590 AssertCompileMemberOffset(CPUMCTX, hwvirt, 728); 591 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.uMsrHSavePa, 728); 592 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.GCPhysVmcb, 736); 593 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pVmcbR0, 744); 594 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pVmcbR3, HC_ARCH_BITS == 64 ? 752 : 748); 595 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.HostState, 760); 596 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.cPauseFilter, 946); 597 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.cPauseFilterThreshold, 948); 598 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.fInterceptEvents, 950); 599 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pvMsrBitmapR0, 952); 600 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pvMsrBitmapR3, HC_ARCH_BITS == 64 ? 960 : 956); 601 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pvIoBitmapR0, HC_ARCH_BITS == 64 ? 968 : 960); 602 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pvIoBitmapR3, HC_ARCH_BITS == 64 ? 976 : 964); 603 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.HCPhysVmcb, HC_ARCH_BITS == 64 ? 984 : 968); 604 AssertCompileMemberOffset(CPUMCTX, hwvirt.fLocalForcedActions, 992); 605 AssertCompileMemberOffset(CPUMCTX, hwvirt.fGif, 996); 602 AssertCompileMemberOffset(CPUMCTX, hwvirt, 0x2e0); 603 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.uMsrHSavePa, 0x2e0); 604 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pVmcbR0, 0x2f0); 605 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pVmcbR3, 0x2f8); 606 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.HostState, 0x300); 607 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.cPauseFilter, 0x3ba); 608 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pvMsrBitmapR0, 0x3c0); 609 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pvIoBitmapR3, 0x3d8); 610 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.HCPhysVmcb, 0x3e0); 611 AssertCompileMemberOffset(CPUMCTX, hwvirt.fLocalForcedActions, 0x3e8); 606 612 AssertCompileMemberAlignment(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pVmcbR0, 8); 607 613 AssertCompileMemberAlignment(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pvMsrBitmapR0, 8); … … 752 758 /** @} */ 753 759 760 /** @name CPUMCTX_EXTRN_XXX 761 * Used to parts of the CPUM state that is externalized and needs fetching 762 * before use. 763 * 764 * @{ */ 765 /** External state keeper: Invalid. */ 766 #define CPUMCTX_EXTRN_KEEPER_INVALID UINT64_C(0x0000000000000000) 767 /** External state keeper: HM. */ 768 #define CPUMCTX_EXTRN_KEEPER_HM UINT64_C(0x0000000000000001) 769 /** External state keeper: NEM. */ 770 #define CPUMCTX_EXTRN_KEEPER_NEM UINT64_C(0x0000000000000002) 771 /** External state keeper: REM. */ 772 #define CPUMCTX_EXTRN_KEEPER_REM UINT64_C(0x0000000000000003) 773 /** External state keeper mask. */ 774 #define CPUMCTX_EXTRN_KEEPER_MASK UINT64_C(0x0000000000000003) 775 776 /** The RIP register value is kept externally. */ 777 #define CPUMCTX_EXTRN_RIP UINT64_C(0x0000000000000004) 778 /** The CS register values are kept externally. */ 779 #define CPUMCTX_EXTRN_CS UINT64_C(0x0000000000000008) 780 /** The RFLAGS register values are kept externally. */ 781 #define CPUMCTX_EXTRN_RFLAGS UINT64_C(0x0000000000000010) 782 783 /** The RAX register value is kept externally. */ 784 #define CPUMCTX_EXTRN_RAX UINT64_C(0x0000000000000020) 785 /** The RCX register value is kept externally. */ 786 #define CPUMCTX_EXTRN_RCX UINT64_C(0x0000000000000040) 787 /** The RDX register value is kept externally. */ 788 #define CPUMCTX_EXTRN_RDX UINT64_C(0x0000000000000080) 789 /** The RBX register value is kept externally. */ 790 #define CPUMCTX_EXTRN_RBX UINT64_C(0x0000000000000100) 791 /** The RSP register value is kept externally. */ 792 #define CPUMCTX_EXTRN_RSP UINT64_C(0x0000000000000200) 793 /** The RBP register value is kept externally. */ 794 #define CPUMCTX_EXTRN_RBP UINT64_C(0x0000000000000400) 795 /** The RSI register value is kept externally. */ 796 #define CPUMCTX_EXTRN_RSI UINT64_C(0x0000000000000800) 797 /** The RDI register value is kept externally. */ 798 #define CPUMCTX_EXTRN_RDI UINT64_C(0x0000000000001000) 799 /** The R8 thru R15 register values are kept externally. */ 800 #define CPUMCTX_EXTRN_R8_R15 UINT64_C(0x0000000000002000) 801 /** General purpose registers mask. */ 802 #define CPUMCTX_EXTRN_GPRS_MASK UINT64_C(0x0000000000003fe0) 803 804 /** The SS register values are kept externally. */ 805 #define CPUMCTX_EXTRN_SS UINT64_C(0x0000000000004000) 806 /** The DS register values are kept externally. */ 807 #define CPUMCTX_EXTRN_DS UINT64_C(0x0000000000008000) 808 /** The ES register values are kept externally. */ 809 #define CPUMCTX_EXTRN_ES UINT64_C(0x0000000000010000) 810 /** The FS register values are kept externally. */ 811 #define CPUMCTX_EXTRN_FS UINT64_C(0x0000000000020000) 812 /** The GS register values are kept externally. */ 813 #define CPUMCTX_EXTRN_GS UINT64_C(0x0000000000040000) 814 /** Segment registers (includes CS). */ 815 #define CPUMCTX_EXTRN_SREG_MASK UINT64_C(0x000000000007c008) 816 817 /** The GDTR register values are kept externally. */ 818 #define CPUMCTX_EXTRN_GDTR UINT64_C(0x0000000000080000) 819 /** The IDTR register values are kept externally. */ 820 #define CPUMCTX_EXTRN_IDTR UINT64_C(0x0000000000100000) 821 /** The LDTR register values are kept externally. */ 822 #define CPUMCTX_EXTRN_LDTR UINT64_C(0x0000000000200000) 823 /** The TR register values are kept externally. */ 824 #define CPUMCTX_EXTRN_TR UINT64_C(0x0000000000400000) 825 /** Table register mask. */ 826 #define CPUMCTX_EXTRN_TABLE_MASK UINT64_C(0x0000000000780000) 827 828 /** The CR0 register value is kept externally. */ 829 #define CPUMCTX_EXTRN_CR0 UINT64_C(0x0000000000800000) 830 /** The CR2 register value is kept externally. */ 831 #define CPUMCTX_EXTRN_CR2 UINT64_C(0x0000000001000000) 832 /** The CR3 register value is kept externally. */ 833 #define CPUMCTX_EXTRN_CR3 UINT64_C(0x0000000002000000) 834 /** The CR4 register value is kept externally. */ 835 #define CPUMCTX_EXTRN_CR4 UINT64_C(0x0000000004000000) 836 /** Control register mask. */ 837 #define CPUMCTX_EXTRN_CR_MASK UINT64_C(0x0000000007800000) 838 /** The EFER register value is kept externally. */ 839 #define CPUMCTX_EXTRN_EFER UINT64_C(0x0000000008000000) 840 841 /** The DR0, DR1, DR2 and DR3 register values are kept externally. */ 842 #define CPUMCTX_EXTRN_DR0_DR3 UINT64_C(0x0000000010000000) 843 /** The DR6 register value is kept externally. */ 844 #define CPUMCTX_EXTRN_DR6 UINT64_C(0x0000000020000000) 845 /** The DR7 register value is kept externally. */ 846 #define CPUMCTX_EXTRN_DR7 UINT64_C(0x0000000040000000) 847 /** Debug register mask. */ 848 #define CPUMCTX_EXTRN_DR_MASK UINT64_C(0x0000000070000000) 849 850 /** The XSAVE_C_X87 state is kept externally. */ 851 #define CPUMCTX_EXTRN_X87 UINT64_C(0x0000000080000000) 852 /** The XSAVE_C_SSE, XSAVE_C_YMM, XSAVE_C_ZMM_HI256, XSAVE_C_ZMM_16HI and 853 * XSAVE_C_OPMASK state is kept externally. */ 854 #define CPUMCTX_EXTRN_SSE_AVX UINT64_C(0x0000000100000000) 855 /** The state of XSAVE components not covered by CPUMCTX_EXTRN_X87 and 856 * CPUMCTX_EXTRN_SEE_AVX is kept externally. */ 857 #define CPUMCTX_EXTRN_OTHER_XSAVE UINT64_C(0x0000000200000000) 858 /** The state of XCR0 and XCR1 register values are kept externally. */ 859 #define CPUMCTX_EXTRN_XCRx UINT64_C(0x0000000400000000) 860 861 /** The KERNEL GS BASE MSR value is kept externally. */ 862 #define CPUMCTX_EXTRN_KERNEL_GS_BASE UINT64_C(0x0000000800000000) 863 /** The STAR, LSTAR, CSTAR and SFMASK MSR values are kept externally. */ 864 #define CPUMCTX_EXTRN_SYSCALL_MSRS UINT64_C(0x0000001000000000) 865 /** The SYSENTER_CS, SYSENTER_EIP and SYSENTER_ESP MSR values are kept externally. */ 866 #define CPUMCTX_EXTRN_SYSENTER_MSRS UINT64_C(0x0000002000000000) 867 /** The SYSENTER_CS, SYSENTER_EIP and SYSENTER_ESP MSR values are kept externally. */ 868 #define CPUMCTX_EXTRN_TSC_AUX UINT64_C(0x0000004000000000) 869 /** All other stateful MSRs not covered by CPUMCTX_EXTRN_EFER, 870 * CPUMCTX_EXTRN_KERNEL_GS_BASE, CPUMCTX_EXTRN_SYSCALL_MSRS, 871 * CPUMCTX_EXTRN_SYSENTER_MSRS, and CPUMCTX_EXTRN_TSC_AUX. */ 872 #define CPUMCTX_EXTRN_OTHER_MSRS UINT64_C(0x0000008000000000) 873 874 /** Mask of bits the keepers can use for state tracking. */ 875 #define CPUMCTX_EXTRN_KEEPER_STATE_MASK UINT64_C(0xffff000000000000) 876 877 /** NEM/Win: Event injection (known was interruption) pending state. */ 878 #define CPUMCTX_EXTRN_NEM_WIN_EVENT_INJECT UINT64_C(0x0001000000000000) 879 /** NEM/Win: Mask. */ 880 #define CPUMCTX_EXTRN_NEM_WIN_MASK UINT64_C(0x0001000000000000) 881 882 /** All CPUM state bits, not including keeper specific ones. */ 883 #define CPUMCTX_EXTRN_ALL UINT64_C(0x000000fffffffffc) 884 /** @} */ 885 754 886 755 887 /** -
trunk/include/VBox/vmm/nem.h
r71136 r71184 88 88 VMMR0_INT_DECL(int) NEMR0MapPages(PGVM pGVM, PVM pVM, VMCPUID idCpu); 89 89 VMMR0_INT_DECL(int) NEMR0UnmapPages(PGVM pGVM, PVM pVM, VMCPUID idCpu); 90 VMMR0_INT_DECL(int) NEMR0ExportState(PGVM pGVM, PVM pVM, VMCPUID idCpu , uint64_t fWhat);90 VMMR0_INT_DECL(int) NEMR0ExportState(PGVM pGVM, PVM pVM, VMCPUID idCpu); 91 91 VMMR0_INT_DECL(int) NEMR0ImportState(PGVM pGVM, PVM pVM, VMCPUID idCpu, uint64_t fWhat); 92 92 /** @} */ -
trunk/include/iprt/nt/hyperv.h
r71129 r71184 1440 1440 HV_X64_INTERCEPT_MESSAGE_HEADER X64InterceptHeader; 1441 1441 /** HvMessageTypeGpaIntercept, HvMessageTypeUnmappedGpa. */ 1442 HV_X64_MEMORY_INTERCEPT_MESSAGE X 86MemoryIntercept;1442 HV_X64_MEMORY_INTERCEPT_MESSAGE X64MemoryIntercept; 1443 1443 /** HvMessageTypeX64IoPortIntercept */ 1444 1444 HV_X64_IO_PORT_INTERCEPT_MESSAGE X64IoPortIntercept; -
trunk/src/VBox/VMM/VMMAll/NEMAllNativeTemplate-win.cpp.h
r71152 r71184 15 15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. 16 16 */ 17 18 19 /********************************************************************************************************************************* 20 * Defined Constants And Macros * 21 *********************************************************************************************************************************/ 22 /** Copy back a segment from hyper-V. */ 23 #define NEM_WIN_COPY_BACK_SEG(a_Dst, a_Src) \ 24 do { \ 25 (a_Dst).u64Base = (a_Src).Base; \ 26 (a_Dst).u32Limit = (a_Src).Limit; \ 27 (a_Dst).ValidSel = (a_Dst).Sel = (a_Src).Selector; \ 28 (a_Dst).Attr.u = (a_Src).Attributes; \ 29 (a_Dst).fFlags = CPUMSELREG_FLAGS_VALID; \ 30 } while (0) 31 32 /** The CPUMCTX_EXTRN_XXX mask for IEM. */ 33 #define NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM CPUMCTX_EXTRN_ALL 17 34 18 35 … … 91 108 #ifdef NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS 92 109 NOREF(pCtx); 93 int rc = VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_NEM_EXPORT_STATE, UINT64_MAX, NULL);110 int rc = VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_NEM_EXPORT_STATE, 0, NULL); 94 111 AssertLogRelRCReturn(rc, rc); 95 112 return rc; … … 389 406 390 407 391 NEM_TMPL_STATIC int nemHCWinCopyStateFromHyperV(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx )408 NEM_TMPL_STATIC int nemHCWinCopyStateFromHyperV(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, uint64_t fWhat) 392 409 { 393 410 #ifdef NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS 411 /* See NEMR0ImportState */ 394 412 NOREF(pCtx); 395 int rc = VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_NEM_IMPORT_STATE, UINT64_MAX, NULL);413 int rc = VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_NEM_IMPORT_STATE, fWhat, NULL); 396 414 if (RT_SUCCESS(rc)) 397 415 return rc; … … 552 570 do { \ 553 571 Assert(aenmNames[a_idx] == a_enmName); \ 554 (a_SReg).u64Base = aValues[a_idx].Segment.Base; \ 555 (a_SReg).u32Limit = aValues[a_idx].Segment.Limit; \ 556 (a_SReg).ValidSel = (a_SReg).Sel = aValues[a_idx].Segment.Selector; \ 557 (a_SReg).Attr.u = aValues[a_idx].Segment.Attributes; \ 558 (a_SReg).fFlags = CPUMSELREG_FLAGS_VALID; \ 572 NEM_WIN_COPY_BACK_SEG(a_SReg, aValues[a_idx]); \ 559 573 } while (0) 560 574 COPY_BACK_SEG(18, WHvX64RegisterEs, pCtx->es); … … 740 754 /// @todo WHvRegisterPendingEvent1 741 755 756 pCtx->fExtrn = 0; 742 757 743 758 if (fMaybeChangedMode) … … 792 807 793 808 #ifdef NEM_WIN_USE_OUR_OWN_RUN_API 794 795 809 # ifdef IN_RING3 /* hopefully not needed in ring-0, as we'd need KTHREADs and KeAlertThread. */ 796 810 /** … … 851 865 } 852 866 # endif /* IN_RING3 */ 853 854 855 /**856 * Fills in WHV_VP_EXIT_CONTEXT from HV_X64_INTERCEPT_MESSAGE_HEADER.857 */858 DECLINLINE(void) nemHCWinConvertX64MsgHdrToVpExitCtx(HV_X64_INTERCEPT_MESSAGE_HEADER const *pHdr, WHV_VP_EXIT_CONTEXT *pCtx)859 {860 pCtx->ExecutionState.AsUINT16 = pHdr->ExecutionState.AsUINT16;861 pCtx->InstructionLength = pHdr->InstructionLength;862 pCtx->Cs.Base = pHdr->CsSegment.Base;863 pCtx->Cs.Limit = pHdr->CsSegment.Limit;864 pCtx->Cs.Selector = pHdr->CsSegment.Selector;865 pCtx->Cs.Attributes = pHdr->CsSegment.Attributes;866 pCtx->Rip = pHdr->Rip;867 pCtx->Rflags = pHdr->Rflags;868 }869 870 871 /**872 * Convert hyper-V exit message to the WinHvPlatform structures.873 *874 * @returns VBox status code875 * @param pMsgHdr The message to convert.876 * @param pExitCtx The output structure. Assumes zeroed.877 */878 NEM_TMPL_STATIC int nemHCWinRunVirtualProcessorConvertPending(HV_MESSAGE_HEADER const *pMsgHdr, WHV_RUN_VP_EXIT_CONTEXT *pExitCtx)879 {880 switch (pMsgHdr->MessageType)881 {882 case HvMessageTypeUnmappedGpa:883 case HvMessageTypeGpaIntercept:884 {885 PCHV_X64_MEMORY_INTERCEPT_MESSAGE pMemMsg = (PCHV_X64_MEMORY_INTERCEPT_MESSAGE)(pMsgHdr + 1);886 Assert(pMsgHdr->PayloadSize == RT_UOFFSETOF(HV_X64_MEMORY_INTERCEPT_MESSAGE, DsSegment));887 888 pExitCtx->ExitReason = WHvRunVpExitReasonMemoryAccess;889 nemHCWinConvertX64MsgHdrToVpExitCtx(&pMemMsg->Header, &pExitCtx->MemoryAccess.VpContext);890 pExitCtx->MemoryAccess.InstructionByteCount = pMemMsg->InstructionByteCount;891 ((uint64_t *)pExitCtx->MemoryAccess.InstructionBytes)[0] = ((uint64_t const *)pMemMsg->InstructionBytes)[0];892 ((uint64_t *)pExitCtx->MemoryAccess.InstructionBytes)[1] = ((uint64_t const *)pMemMsg->InstructionBytes)[1];893 894 pExitCtx->MemoryAccess.AccessInfo.AccessType = pMemMsg->Header.InterceptAccessType;895 pExitCtx->MemoryAccess.AccessInfo.GpaUnmapped = pMsgHdr->MessageType == HvMessageTypeUnmappedGpa;896 pExitCtx->MemoryAccess.AccessInfo.GvaValid = pMemMsg->MemoryAccessInfo.GvaValid;897 pExitCtx->MemoryAccess.AccessInfo.Reserved = pMemMsg->MemoryAccessInfo.Reserved;898 pExitCtx->MemoryAccess.Gpa = pMemMsg->GuestPhysicalAddress;899 pExitCtx->MemoryAccess.Gva = pMemMsg->GuestVirtualAddress;900 return VINF_SUCCESS;901 }902 903 case HvMessageTypeX64IoPortIntercept:904 {905 PCHV_X64_IO_PORT_INTERCEPT_MESSAGE pPioMsg= (PCHV_X64_IO_PORT_INTERCEPT_MESSAGE)(pMsgHdr + 1);906 Assert(pMsgHdr->PayloadSize == sizeof(*pPioMsg));907 908 pExitCtx->ExitReason = WHvRunVpExitReasonX64IoPortAccess;909 nemHCWinConvertX64MsgHdrToVpExitCtx(&pPioMsg->Header, &pExitCtx->IoPortAccess.VpContext);910 pExitCtx->IoPortAccess.InstructionByteCount = pPioMsg->InstructionByteCount;911 ((uint64_t *)pExitCtx->IoPortAccess.InstructionBytes)[0] = ((uint64_t const *)pPioMsg->InstructionBytes)[0];912 ((uint64_t *)pExitCtx->IoPortAccess.InstructionBytes)[1] = ((uint64_t const *)pPioMsg->InstructionBytes)[1];913 914 pExitCtx->IoPortAccess.AccessInfo.IsWrite = pPioMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_WRITE;915 pExitCtx->IoPortAccess.AccessInfo.AccessSize = pPioMsg->AccessInfo.AccessSize;916 pExitCtx->IoPortAccess.AccessInfo.StringOp = pPioMsg->AccessInfo.StringOp;917 pExitCtx->IoPortAccess.AccessInfo.RepPrefix = pPioMsg->AccessInfo.RepPrefix;918 pExitCtx->IoPortAccess.AccessInfo.Reserved = pPioMsg->AccessInfo.Reserved;919 pExitCtx->IoPortAccess.PortNumber = pPioMsg->PortNumber;920 pExitCtx->IoPortAccess.Rax = pPioMsg->Rax;921 pExitCtx->IoPortAccess.Rcx = pPioMsg->Rcx;922 pExitCtx->IoPortAccess.Rsi = pPioMsg->Rsi;923 pExitCtx->IoPortAccess.Rdi = pPioMsg->Rdi;924 pExitCtx->IoPortAccess.Ds.Base = pPioMsg->DsSegment.Base;925 pExitCtx->IoPortAccess.Ds.Limit = pPioMsg->DsSegment.Limit;926 pExitCtx->IoPortAccess.Ds.Selector = pPioMsg->DsSegment.Selector;927 pExitCtx->IoPortAccess.Ds.Attributes = pPioMsg->DsSegment.Attributes;928 pExitCtx->IoPortAccess.Es.Base = pPioMsg->EsSegment.Base;929 pExitCtx->IoPortAccess.Es.Limit = pPioMsg->EsSegment.Limit;930 pExitCtx->IoPortAccess.Es.Selector = pPioMsg->EsSegment.Selector;931 pExitCtx->IoPortAccess.Es.Attributes = pPioMsg->EsSegment.Attributes;932 return VINF_SUCCESS;933 }934 935 case HvMessageTypeX64Halt:936 {937 PCHV_X64_HALT_MESSAGE pHaltMsg = (PCHV_X64_HALT_MESSAGE)(pMsgHdr + 1);938 AssertMsg(pHaltMsg->u64Reserved == 0, ("HALT reserved: %#RX64\n", pHaltMsg->u64Reserved));939 pExitCtx->ExitReason = WHvRunVpExitReasonX64Halt;940 return VINF_SUCCESS;941 }942 943 case HvMessageTypeX64InterruptWindow:944 AssertLogRelMsgFailedReturn(("Message type %#x not implemented!\n", pMsgHdr->MessageType), VERR_INTERNAL_ERROR_2);945 946 case HvMessageTypeInvalidVpRegisterValue:947 case HvMessageTypeUnrecoverableException:948 case HvMessageTypeUnsupportedFeature:949 case HvMessageTypeTlbPageSizeMismatch:950 AssertLogRelMsgFailedReturn(("Message type %#x not implemented!\n", pMsgHdr->MessageType), VERR_INTERNAL_ERROR_2);951 952 case HvMessageTypeX64MsrIntercept:953 case HvMessageTypeX64CpuidIntercept:954 case HvMessageTypeX64ExceptionIntercept:955 case HvMessageTypeX64ApicEoi:956 case HvMessageTypeX64LegacyFpError:957 case HvMessageTypeX64RegisterIntercept:958 case HvMessageTypeApicEoi:959 case HvMessageTypeFerrAsserted:960 case HvMessageTypeEventLogBufferComplete:961 case HvMessageTimerExpired:962 AssertLogRelMsgFailedReturn(("Unexpected message type #x!\n", pMsgHdr->MessageType), VERR_INTERNAL_ERROR_2);963 964 default:965 AssertLogRelMsgFailedReturn(("Unknown message type #x!\n", pMsgHdr->MessageType), VERR_INTERNAL_ERROR_2);966 }967 }968 969 970 /**971 * Our own WHvRunVirtualProcessor that can later be moved to ring-0.972 *973 * This is an experiment only.974 *975 * @returns VBox status code.976 * @param pVM The cross context VM structure.977 * @param pVCpu The cross context virtual CPU structure of the978 * calling EMT.979 * @param pExitCtx Where to return exit information.980 * @param cbExitCtx Size of the exit information area.981 */982 NEM_TMPL_STATIC int nemHCWinRunVirtualProcessor(PVM pVM, PVMCPU pVCpu, WHV_RUN_VP_EXIT_CONTEXT *pExitCtx, size_t cbExitCtx)983 {984 RT_BZERO(pExitCtx, cbExitCtx);985 986 /*987 * Tell the CPU to execute stuff if we haven't got a pending message.988 */989 VID_MESSAGE_MAPPING_HEADER volatile *pMappingHeader = (VID_MESSAGE_MAPPING_HEADER volatile *)pVCpu->nem.s.pvMsgSlotMapping;990 uint32_t fHandleAndGetFlags;991 if (VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED))992 {993 uint8_t const bMsgState = pVCpu->nem.s.bMsgState;994 if (bMsgState == NEM_WIN_MSG_STATE_PENDING_MSG)995 {996 Assert(pMappingHeader->enmVidMsgType == VidMessageHypervisorMessage);997 fHandleAndGetFlags = VID_MSHAGN_F_GET_NEXT_MESSAGE | VID_MSHAGN_F_HANDLE_MESSAGE;998 Log8(("nemHCWinRunVirtualProcessor: #1: msg pending, no need to start CPU (cpu state %u)\n", nemHCWinCpuGetRunningStatus(pVCpu) ));999 }1000 else if (bMsgState != NEM_WIN_MSG_STATE_STARTED)1001 {1002 if (bMsgState == NEM_WIN_MSG_STATE_PENDING_STOP_AND_MSG)1003 {1004 Log8(("nemHCWinRunVirtualProcessor: #0: pending stop+message (cpu status %u)\n", nemHCWinCpuGetRunningStatus(pVCpu) ));1005 /* ACK the pending message and get the stop message. */1006 BOOL fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu,1007 VID_MSHAGN_F_HANDLE_MESSAGE | VID_MSHAGN_F_GET_NEXT_MESSAGE, 5000);1008 AssertLogRelMsg(fWait, ("dwErr=%u (%#x) rcNt=%#x\n", RTNtLastErrorValue(), RTNtLastErrorValue(), RTNtLastStatusValue()));1009 1010 /* ACK the stop message. */1011 fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu,1012 VID_MSHAGN_F_HANDLE_MESSAGE, 5000);1013 AssertLogRelMsg(fWait, ("dwErr=%u (%#x) rcNt=%#x\n", RTNtLastErrorValue(), RTNtLastErrorValue(), RTNtLastStatusValue()));1014 1015 pVCpu->nem.s.bMsgState = NEM_WIN_MSG_STATE_STOPPED;1016 }1017 1018 Log8(("nemHCWinRunVirtualProcessor: #1: starting CPU (cpu status %u)\n", nemHCWinCpuGetRunningStatus(pVCpu) ));1019 if (g_pfnVidStartVirtualProcessor(pVM->nem.s.hPartitionDevice, pVCpu->idCpu))1020 pVCpu->nem.s.bMsgState = NEM_WIN_MSG_STATE_STARTED;1021 else1022 {1023 VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM);1024 AssertLogRelMsgFailedReturn(("VidStartVirtualProcessor failed for CPU #%u: rcNt=%#x dwErr=%u\n",1025 pVCpu->idCpu, RTNtLastStatusValue(), RTNtLastErrorValue()),1026 VERR_INTERNAL_ERROR_3);1027 }1028 fHandleAndGetFlags = VID_MSHAGN_F_GET_NEXT_MESSAGE;1029 }1030 else1031 {1032 /* This shouldn't happen. */1033 fHandleAndGetFlags = VID_MSHAGN_F_GET_NEXT_MESSAGE;1034 Log8(("nemHCWinRunVirtualProcessor: #1: NO MSG PENDING! No need to start CPU (cpu state %u)\n", nemHCWinCpuGetRunningStatus(pVCpu) ));1035 }1036 }1037 else1038 {1039 Log8(("nemHCWinRunVirtualProcessor: #1: state=%u -> canceled (cpu status %u)\n",1040 VMCPU_GET_STATE(pVCpu), nemHCWinCpuGetRunningStatus(pVCpu)));1041 pExitCtx->ExitReason = WHvRunVpExitReasonCanceled;1042 return VINF_SUCCESS;1043 }1044 1045 /*1046 * Wait for it to stop and give us a reason to work with.1047 */1048 uint32_t cMillies = 5000; // Starting low so we can experiment without getting stuck.1049 for (;;)1050 {1051 if (VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM_WAIT, VMCPUSTATE_STARTED_EXEC_NEM))1052 {1053 Log8(("nemHCWinRunVirtualProcessor: #2: Waiting %#x (cpu status %u)...\n",1054 fHandleAndGetFlags, nemHCWinCpuGetRunningStatus(pVCpu)));1055 BOOL fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu,1056 fHandleAndGetFlags, cMillies);1057 if (fWait)1058 {1059 /* Not sure yet, but we have to check whether there is anything pending1060 and retry if there isn't. */1061 VID_MESSAGE_TYPE const enmVidMsgType = pMappingHeader->enmVidMsgType;1062 if (enmVidMsgType == VidMessageHypervisorMessage)1063 {1064 if (!VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM_WAIT))1065 VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM_CANCELED);1066 Log8(("nemHCWinRunVirtualProcessor: #3: wait succeeded: %#x / %#x (cpu status %u)\n",1067 enmVidMsgType, ((HV_MESSAGE_HEADER const *)(pMappingHeader + 1))->MessageType,1068 nemHCWinCpuGetRunningStatus(pVCpu) ));1069 pVCpu->nem.s.bMsgState = NEM_WIN_MSG_STATE_PENDING_MSG;1070 return nemHCWinRunVirtualProcessorConvertPending((HV_MESSAGE_HEADER const *)(pMappingHeader + 1), pExitCtx);1071 }1072 1073 /* This shouldn't happen, and I think its wrong. */1074 VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED_EXEC_NEM_WAIT);1075 #ifdef DEBUG_bird1076 __debugbreak();1077 #endif1078 Log8(("nemHCWinRunVirtualProcessor: #3: wait succeeded, but nothing pending: %#x / %#x (cpu status %u)\n",1079 enmVidMsgType, ((HV_MESSAGE_HEADER const *)(pMappingHeader + 1))->MessageType, nemHCWinCpuGetRunningStatus(pVCpu) ));1080 pVCpu->nem.s.bMsgState = NEM_WIN_MSG_STATE_STARTED;1081 AssertLogRelMsgReturnStmt(enmVidMsgType == VidMessageStopRequestComplete,1082 ("enmVidMsgType=%#x\n", enmVidMsgType),1083 g_pfnVidStopVirtualProcessor(pVM->nem.s.hPartitionDevice, pVCpu->idCpu),1084 VERR_INTERNAL_ERROR_3);1085 fHandleAndGetFlags &= ~VID_MSHAGN_F_HANDLE_MESSAGE;1086 }1087 else1088 {1089 VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED_EXEC_NEM_WAIT);1090 1091 /* Note! VID.SYS merges STATUS_ALERTED and STATUS_USER_APC into STATUS_TIMEOUT. */1092 DWORD const dwErr = RTNtLastErrorValue();1093 AssertLogRelMsgReturnStmt( dwErr == STATUS_TIMEOUT1094 || dwErr == STATUS_ALERTED || dwErr == STATUS_USER_APC, /* just in case */1095 ("dwErr=%u (%#x) (cpu status %u)\n", dwErr, dwErr, nemHCWinCpuGetRunningStatus(pVCpu)),1096 g_pfnVidStopVirtualProcessor(pVM->nem.s.hPartitionDevice, pVCpu->idCpu),1097 VERR_INTERNAL_ERROR_3);1098 Log8(("nemHCWinRunVirtualProcessor: #3: wait timed out (cpu status %u)\n", nemHCWinCpuGetRunningStatus(pVCpu) ));1099 pVCpu->nem.s.bMsgState = NEM_WIN_MSG_STATE_STARTED;1100 fHandleAndGetFlags &= ~VID_MSHAGN_F_HANDLE_MESSAGE;1101 }1102 }1103 else1104 {1105 /*1106 * State changed and we need to return.1107 *1108 * We must ensure that the processor is not running while we1109 * return, and that can be a bit complicated.1110 */1111 Log8(("nemHCWinRunVirtualProcessor: #4: state changed to %u (cpu status %u)\n",1112 VMCPU_GET_STATE(pVCpu), nemHCWinCpuGetRunningStatus(pVCpu) ));1113 VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM_CANCELED);1114 1115 /* If we haven't marked the pervious message as handled, simply return1116 without doing anything special. */1117 if (fHandleAndGetFlags & VID_MSHAGN_F_HANDLE_MESSAGE)1118 {1119 Log8(("nemHCWinRunVirtualProcessor: #5: Didn't resume previous message.\n"));1120 pVCpu->nem.s.bMsgState = NEM_WIN_MSG_STATE_PENDING_MSG;1121 pExitCtx->ExitReason = WHvRunVpExitReasonCanceled;1122 return VINF_SUCCESS;1123 }1124 1125 /* The processor is running, so try stop it. */1126 BOOL fStop = g_pfnVidStopVirtualProcessor(pVM->nem.s.hPartitionDevice, pVCpu->idCpu);1127 if (fStop)1128 {1129 Log8(("nemHCWinRunVirtualProcessor: #5: Stopping CPU succeeded (cpu status %u)\n", nemHCWinCpuGetRunningStatus(pVCpu) ));1130 pVCpu->nem.s.bMsgState = NEM_WIN_MSG_STATE_STOPPED;1131 pExitCtx->ExitReason = WHvRunVpExitReasonCanceled;1132 return VINF_SUCCESS;1133 }1134 1135 /* Dang, the CPU stopped by itself with a message pending. */1136 DWORD dwErr = RTNtLastErrorValue();1137 Log8(("nemHCWinRunVirtualProcessor: #5: Stopping CPU failed (%u/%#x) - cpu status %u\n",1138 dwErr, dwErr, nemHCWinCpuGetRunningStatus(pVCpu) ));1139 pExitCtx->ExitReason = WHvRunVpExitReasonCanceled;1140 AssertLogRelMsgReturn(dwErr == ERROR_VID_STOP_PENDING, ("dwErr=%#u\n", dwErr), VERR_INTERNAL_ERROR_3);1141 1142 /* Get the pending message. */1143 BOOL fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu,1144 VID_MSHAGN_F_GET_NEXT_MESSAGE, 5000);1145 AssertLogRelMsgReturn(fWait, ("error=%#u\n", RTNtLastErrorValue()), VERR_INTERNAL_ERROR_3);1146 1147 VID_MESSAGE_TYPE const enmVidMsgType = pMappingHeader->enmVidMsgType;1148 if (enmVidMsgType == VidMessageHypervisorMessage)1149 {1150 Log8(("nemHCWinRunVirtualProcessor: #6: wait succeeded: %#x / %#x (cpu status %u)\n", enmVidMsgType,1151 ((HV_MESSAGE_HEADER const *)(pMappingHeader + 1))->MessageType, nemHCWinCpuGetRunningStatus(pVCpu) ));1152 pVCpu->nem.s.bMsgState = NEM_WIN_MSG_STATE_PENDING_STOP_AND_MSG;1153 return nemHCWinRunVirtualProcessorConvertPending((HV_MESSAGE_HEADER const *)(pMappingHeader + 1), pExitCtx);1154 }1155 1156 /* ACK the stop message, if that's what it is. Don't think we'll ever get here. */1157 Log8(("nemHCWinRunVirtualProcessor: #6b: wait succeeded: %#x / %#x (cpu status %u)\n", enmVidMsgType,1158 ((HV_MESSAGE_HEADER const *)(pMappingHeader + 1))->MessageType, nemHCWinCpuGetRunningStatus(pVCpu) ));1159 AssertLogRelMsgReturn(enmVidMsgType == VidMessageStopRequestComplete, ("enmVidMsgType=%#x\n", enmVidMsgType),1160 VERR_INTERNAL_ERROR_3);1161 fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu,1162 VID_MSHAGN_F_HANDLE_MESSAGE, 5000);1163 AssertLogRelMsgReturn(fWait, ("dwErr=%#u\n", RTNtLastErrorValue()), VERR_INTERNAL_ERROR_3);1164 1165 pVCpu->nem.s.bMsgState = NEM_WIN_MSG_STATE_STOPPED;1166 pExitCtx->ExitReason = WHvRunVpExitReasonCanceled;1167 return VINF_SUCCESS;1168 }1169 1170 /** @todo check flags and stuff? */1171 }1172 }1173 1174 867 #endif /* NEM_WIN_USE_OUR_OWN_RUN_API */ 868 1175 869 1176 870 #ifdef LOG_ENABLED … … 1234 928 * @param pExitCtx The exit context. 1235 929 */ 1236 DECLINLINE(void) nemHCWinAdvanceGuestRipAndClearRF(PVMCPU pVCpu, PCPUMCTX pCtx, WHV_VP_EXIT_CONTEXT const *pExitCtx) 1237 { 930 DECLINLINE(void) nemHCWinAdvanceGuestRipAndClearRF(PVMCPU pVCpu, PCPUMCTX pCtx, HV_X64_INTERCEPT_MESSAGE_HEADER const *pMsgHdr) 931 { 932 Assert(!(pCtx->fExtrn & (CPUMCTX_EXTRN_RIP | CPUMCTX_EXTRN_RFLAGS))); 933 1238 934 /* Advance the RIP. */ 1239 Assert(p ExitCtx->InstructionLength > 0 && pExitCtx->InstructionLength < 16);1240 pCtx->rip += p ExitCtx->InstructionLength;935 Assert(pMsgHdr->InstructionLength > 0 && pMsgHdr->InstructionLength < 16); 936 pCtx->rip += pMsgHdr->InstructionLength; 1241 937 pCtx->rflags.Bits.u1RF = 0; 1242 938 … … 1476 1172 } 1477 1173 1478 1479 #if 0 /* later */ 1480 NEM_TMPL_STATIC nemHCWinRunGC(PVM pVM, PVMCPU pVCpu) 1481 { 1174 #ifdef IN_RING3 1175 1176 /** 1177 * Copies register state from the X64 intercept message header. 1178 * 1179 * ASSUMES no state copied yet. 1180 * 1181 * @param pCtx The registe rcontext. 1182 * @param pHdr The X64 intercept message header. 1183 */ 1184 DECLINLINE(void) nemHCWinCopyStateFromX64Header(PCPUMCTX pCtx, HV_X64_INTERCEPT_MESSAGE_HEADER const *pHdr) 1185 { 1186 Assert( (pCtx->fExtrn & (CPUMCTX_EXTRN_RIP | CPUMCTX_EXTRN_RFLAGS | CPUMCTX_EXTRN_CS)) 1187 == (CPUMCTX_EXTRN_RIP | CPUMCTX_EXTRN_RFLAGS | CPUMCTX_EXTRN_CS)); 1188 NEM_WIN_COPY_BACK_SEG(pCtx->cs, pHdr->CsSegment); 1189 pCtx->rip = pHdr->Rip; 1190 pCtx->rflags.u = pHdr->Rflags; 1191 pCtx->fExtrn &= ~(CPUMCTX_EXTRN_RIP | CPUMCTX_EXTRN_RFLAGS | CPUMCTX_EXTRN_CS); 1192 } 1193 1194 1195 /** 1196 * Deals with memory intercept message. 1197 * 1198 * @returns Strict VBox status code. 1199 * @param pVM The cross context VM structure. 1200 * @param pVCpu The cross context per CPU structure. 1201 * @param pMsg The message. 1202 * @param pCtx The register context. 1203 */ 1204 NEM_TMPL_STATIC VBOXSTRICTRC nemHCWinHandleMessageMemory(PVM pVM, PVMCPU pVCpu, HV_X64_MEMORY_INTERCEPT_MESSAGE const *pMsg, 1205 PCPUMCTX pCtx) 1206 { 1207 /* 1208 * Whatever we do, we must clear pending event ejection upon resume. 1209 */ 1210 if (pMsg->Header.ExecutionState.InterruptionPending) 1211 pCtx->fExtrn &= ~CPUMCTX_EXTRN_NEM_WIN_MASK; 1212 1213 /* 1214 * Ask PGM for information about the given GCPhys. We need to check if we're 1215 * out of sync first. 1216 */ 1217 NEMHCWINHMACPCCSTATE State = { pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_WRITE, false, false }; 1218 PGMPHYSNEMPAGEINFO Info; 1219 int rc = PGMPhysNemPageInfoChecker(pVM, pVCpu, pMsg->GuestPhysicalAddress, State.fWriteAccess, &Info, 1220 nemHCWinHandleMemoryAccessPageCheckerCallback, &State); 1221 if (RT_SUCCESS(rc)) 1222 { 1223 if (Info.fNemProt & ( pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_WRITE 1224 ? NEM_PAGE_PROT_WRITE : NEM_PAGE_PROT_READ)) 1225 { 1226 if (State.fCanResume) 1227 { 1228 Log4(("MemExit: %RGp (=>%RHp) %s fProt=%u%s%s%s; restarting (%s)\n", 1229 pMsg->GuestPhysicalAddress, Info.HCPhys, g_apszPageStates[Info.u2NemState], Info.fNemProt, 1230 Info.fHasHandlers ? " handlers" : "", Info.fZeroPage ? " zero-pg" : "", 1231 State.fDidSomething ? "" : " no-change", g_apszWHvMemAccesstypes[pMsg->Header.InterceptAccessType])); 1232 return VINF_SUCCESS; 1233 } 1234 } 1235 Log4(("MemExit: %RGp (=>%RHp) %s fProt=%u%s%s%s; emulating (%s)\n", 1236 pMsg->GuestPhysicalAddress, Info.HCPhys, g_apszPageStates[Info.u2NemState], Info.fNemProt, 1237 Info.fHasHandlers ? " handlers" : "", Info.fZeroPage ? " zero-pg" : "", 1238 State.fDidSomething ? "" : " no-change", g_apszWHvMemAccesstypes[pMsg->Header.InterceptAccessType])); 1239 } 1240 else 1241 Log4(("MemExit: %RGp rc=%Rrc%s; emulating (%s)\n", pMsg->GuestPhysicalAddress, rc, 1242 State.fDidSomething ? " modified-backing" : "", g_apszWHvMemAccesstypes[pMsg->Header.InterceptAccessType])); 1243 1244 /* 1245 * Emulate the memory access, either access handler or special memory. 1246 */ 1247 nemHCWinCopyStateFromX64Header(pCtx, &pMsg->Header); 1248 rc = nemHCWinCopyStateFromHyperV(pVM, pVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM); 1249 AssertRCReturn(rc, rc); 1250 1251 VBOXSTRICTRC rcStrict; 1252 if (pMsg->InstructionByteCount > 0) 1253 rcStrict = IEMExecOneWithPrefetchedByPC(pVCpu, CPUMCTX2CORE(pCtx), pMsg->Header.Rip, 1254 pMsg->InstructionBytes, pMsg->InstructionByteCount); 1255 else 1256 rcStrict = IEMExecOne(pVCpu); 1257 /** @todo do we need to do anything wrt debugging here? */ 1258 return rcStrict; 1259 1260 } 1261 1262 1263 /** 1264 * Deals with I/O port intercept message. 1265 * 1266 * @returns Strict VBox status code. 1267 * @param pVM The cross context VM structure. 1268 * @param pVCpu The cross context per CPU structure. 1269 * @param pMsg The message. 1270 */ 1271 NEM_TMPL_STATIC VBOXSTRICTRC nemHCWinHandleMessageIoPort(PVM pVM, PVMCPU pVCpu, HV_X64_IO_PORT_INTERCEPT_MESSAGE const *pMsg, 1272 PCPUMCTX pCtx) 1273 { 1274 Assert( pMsg->AccessInfo.AccessSize == 1 1275 || pMsg->AccessInfo.AccessSize == 2 1276 || pMsg->AccessInfo.AccessSize == 4); 1277 1278 /* 1279 * Whatever we do, we must clear pending event ejection upon resume. 1280 */ 1281 if (pMsg->Header.ExecutionState.InterruptionPending) 1282 pCtx->fExtrn &= ~CPUMCTX_EXTRN_NEM_WIN_MASK; 1283 1284 VBOXSTRICTRC rcStrict; 1285 if (!pMsg->AccessInfo.StringOp) 1286 { 1287 /* 1288 * Simple port I/O. 1289 */ 1290 static uint32_t const s_fAndMask[8] = 1291 { UINT32_MAX, UINT32_C(0xff), UINT32_C(0xffff), UINT32_MAX, UINT32_MAX, UINT32_MAX, UINT32_MAX, UINT32_MAX }; 1292 uint32_t const fAndMask = s_fAndMask[pMsg->AccessInfo.AccessSize]; 1293 if (pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_WRITE) 1294 { 1295 rcStrict = IOMIOPortWrite(pVM, pVCpu, pMsg->PortNumber, (uint32_t)pMsg->Rax & fAndMask, pMsg->AccessInfo.AccessSize); 1296 Log4(("IOExit: %04x:%08RX64: OUT %#x, %#x LB %u rcStrict=%Rrc\n", pMsg->Header.CsSegment.Selector, pMsg->Header.Rip, 1297 pMsg->PortNumber, (uint32_t)pMsg->Rax & fAndMask, pMsg->AccessInfo.AccessSize, VBOXSTRICTRC_VAL(rcStrict) )); 1298 if (IOM_SUCCESS(rcStrict)) 1299 { 1300 nemHCWinCopyStateFromX64Header(pCtx, &pMsg->Header); 1301 nemHCWinAdvanceGuestRipAndClearRF(pVCpu, pCtx, &pMsg->Header); 1302 } 1303 } 1304 else 1305 { 1306 uint32_t uValue = 0; 1307 rcStrict = IOMIOPortRead(pVM, pVCpu, pMsg->PortNumber, &uValue, pMsg->AccessInfo.AccessSize); 1308 Log4(("IOExit: %04x:%08RX64: IN %#x LB %u -> %#x, rcStrict=%Rrc\n", pMsg->Header.CsSegment.Selector, pMsg->Header.Rip, 1309 pMsg->PortNumber, pMsg->AccessInfo.AccessSize, uValue, VBOXSTRICTRC_VAL(rcStrict) )); 1310 if (IOM_SUCCESS(rcStrict)) 1311 { 1312 if (pMsg->AccessInfo.AccessSize != 4) 1313 pCtx->rax = (pMsg->Rax & ~(uint64_t)fAndMask) | (uValue & fAndMask); 1314 else 1315 pCtx->rax = uValue; 1316 pCtx->fExtrn &= ~CPUMCTX_EXTRN_RAX; 1317 Log4(("IOExit: RAX %#RX64 -> %#RX64\n", pMsg->Rax, pCtx->rax)); 1318 nemHCWinCopyStateFromX64Header(pCtx, &pMsg->Header); 1319 nemHCWinAdvanceGuestRipAndClearRF(pVCpu, pCtx, &pMsg->Header); 1320 } 1321 } 1322 } 1323 else 1324 { 1325 /* 1326 * String port I/O. 1327 */ 1328 /** @todo Someone at Microsoft please explain how we can get the address mode 1329 * from the IoPortAccess.VpContext. CS.Attributes is only sufficient for 1330 * getting the default mode, it can always be overridden by a prefix. This 1331 * forces us to interpret the instruction from opcodes, which is suboptimal. 1332 * Both AMD-V and VT-x includes the address size in the exit info, at least on 1333 * CPUs that are reasonably new. 1334 * 1335 * Of course, it's possible this is an undocumented and we just need to do some 1336 * experiments to figure out how it's communicated. Alternatively, we can scan 1337 * the opcode bytes for possible evil prefixes. 1338 */ 1339 nemHCWinCopyStateFromX64Header(pCtx, &pMsg->Header); 1340 pCtx->fExtrn &= ~( CPUMCTX_EXTRN_RAX | CPUMCTX_EXTRN_RCX | CPUMCTX_EXTRN_RDI | CPUMCTX_EXTRN_RSI 1341 | CPUMCTX_EXTRN_DS | CPUMCTX_EXTRN_ES); 1342 NEM_WIN_COPY_BACK_SEG(pCtx->ds, pMsg->DsSegment); 1343 NEM_WIN_COPY_BACK_SEG(pCtx->es, pMsg->EsSegment); 1344 pCtx->rax = pMsg->Rax; 1345 pCtx->rcx = pMsg->Rcx; 1346 pCtx->rdi = pMsg->Rdi; 1347 pCtx->rsi = pMsg->Rsi; 1348 int rc = nemHCWinCopyStateFromHyperV(pVM, pVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM); 1349 AssertRCReturn(rc, rc); 1350 1351 Log4(("IOExit: %04x:%08RX64: %s%s %#x LB %u (emulating)\n", pMsg->Header.CsSegment.Selector, pMsg->Header.Rip, 1352 pMsg->AccessInfo.RepPrefix ? "REP " : "", 1353 pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_WRITE ? "OUTS" : "INS", 1354 pMsg->PortNumber, pMsg->AccessInfo.AccessSize )); 1355 rcStrict = IEMExecOne(pVCpu); 1356 } 1357 if (IOM_SUCCESS(rcStrict)) 1358 { 1359 /* 1360 * Do debug checks. 1361 */ 1362 if ( pMsg->Header.ExecutionState.DebugActive /** @todo Microsoft: Does DebugActive this only reflext DR7? */ 1363 || (pMsg->Header.Rflags & X86_EFL_TF) 1364 || DBGFBpIsHwIoArmed(pVM) ) 1365 { 1366 /** @todo Debugging. */ 1367 } 1368 } 1369 return rcStrict; 1370 } 1371 1372 1373 /** 1374 * Handles messages (VM exits). 1375 * 1376 * @returns Strict VBox status code. 1377 * @param pVM The cross context VM structure. 1378 * @param pVCpu The cross context per CPU structure. 1379 * @param pMappingHeader The message slot mapping. 1380 * @param pCtx The register context. 1381 */ 1382 NEM_TMPL_STATIC VBOXSTRICTRC nemHCWinHandleMessage(PVM pVM, PVMCPU pVCpu, VID_MESSAGE_MAPPING_HEADER volatile *pMappingHeader, 1383 PCPUMCTX pCtx) 1384 { 1385 if (pMappingHeader->enmVidMsgType == VidMessageHypervisorMessage) 1386 { 1387 AssertMsg(pMappingHeader->cbMessage == HV_MESSAGE_SIZE, ("%#x\n", pMappingHeader->cbMessage)); 1388 HV_MESSAGE const *pMsg = (HV_MESSAGE const *)(pMappingHeader + 1); 1389 switch (pMsg->Header.MessageType) 1390 { 1391 case HvMessageTypeUnmappedGpa: 1392 Assert(pMsg->Header.PayloadSize == RT_UOFFSETOF(HV_X64_MEMORY_INTERCEPT_MESSAGE, DsSegment)); 1393 return nemHCWinHandleMessageMemory(pVM, pVCpu, &pMsg->X64MemoryIntercept, pCtx); 1394 1395 case HvMessageTypeGpaIntercept: 1396 Assert(pMsg->Header.PayloadSize == RT_UOFFSETOF(HV_X64_MEMORY_INTERCEPT_MESSAGE, DsSegment)); 1397 return nemHCWinHandleMessageMemory(pVM, pVCpu, &pMsg->X64MemoryIntercept, pCtx); 1398 1399 case HvMessageTypeX64IoPortIntercept: 1400 Assert(pMsg->Header.PayloadSize == sizeof(pMsg->X64IoPortIntercept)); 1401 return nemHCWinHandleMessageIoPort(pVM, pVCpu, &pMsg->X64IoPortIntercept, pCtx); 1402 1403 case HvMessageTypeX64Halt: 1404 return VINF_EM_HALT; 1405 1406 case HvMessageTypeX64InterruptWindow: 1407 AssertLogRelMsgFailedReturn(("Message type %#x not implemented!\n", pMsg->Header.MessageType), 1408 VERR_INTERNAL_ERROR_2); 1409 1410 case HvMessageTypeInvalidVpRegisterValue: 1411 case HvMessageTypeUnrecoverableException: 1412 case HvMessageTypeUnsupportedFeature: 1413 case HvMessageTypeTlbPageSizeMismatch: 1414 AssertLogRelMsgFailedReturn(("Message type %#x not implemented!\n", pMsg->Header.MessageType), 1415 VERR_INTERNAL_ERROR_2); 1416 1417 case HvMessageTypeX64MsrIntercept: 1418 case HvMessageTypeX64CpuidIntercept: 1419 case HvMessageTypeX64ExceptionIntercept: 1420 case HvMessageTypeX64ApicEoi: 1421 case HvMessageTypeX64LegacyFpError: 1422 case HvMessageTypeX64RegisterIntercept: 1423 case HvMessageTypeApicEoi: 1424 case HvMessageTypeFerrAsserted: 1425 case HvMessageTypeEventLogBufferComplete: 1426 case HvMessageTimerExpired: 1427 AssertLogRelMsgFailedReturn(("Unexpected message on CPU #%u: #x\n", pVCpu->idCpu, pMsg->Header.MessageType), 1428 VERR_INTERNAL_ERROR_2); 1429 1430 default: 1431 AssertLogRelMsgFailedReturn(("Unknown message on CPU #%u: #x\n", pVCpu->idCpu, pMsg->Header.MessageType), 1432 VERR_INTERNAL_ERROR_2); 1433 } 1434 } 1435 else 1436 AssertLogRelMsgFailedReturn(("Unexpected VID message type on CPU #%u: %#x LB %u\n", 1437 pVCpu->idCpu, pMappingHeader->enmVidMsgType, pMappingHeader->cbMessage), 1438 VERR_INTERNAL_ERROR_3); 1439 } 1440 1441 1442 /** 1443 * Worker for nemHCWinRunGC that stops the execution on the way out. 1444 * 1445 * The CPU was running the last time we checked, no there are no messages that 1446 * needs being marked handled/whatever. Caller checks this. 1447 * 1448 * @returns rcStrict on success, error status on failure. 1449 * @param pVM The cross context VM structure. 1450 * @param pVCpu The cross context per CPU structure. 1451 * @param rcStrict The nemHCWinRunGC return status. This is a little 1452 * bit unnecessary, except in internal error cases, 1453 * since we won't need to stop the CPU if we took an 1454 * exit. 1455 * @param pMappingHeader The message slot mapping. 1456 */ 1457 NEM_TMPL_STATIC VBOXSTRICTRC nemHCWinStopCpu(PVM pVM, PVMCPU pVCpu, VBOXSTRICTRC rcStrict, 1458 VID_MESSAGE_MAPPING_HEADER volatile *pMappingHeader) 1459 { 1460 /* 1461 * Try stopping the processor. If we're lucky we manage to do this before it 1462 * does another VM exit. 1463 */ 1464 BOOL fRet = VidStopVirtualProcessor(pVM->nem.s.hPartitionDevice, pVCpu->idCpu); 1465 if (fRet) 1466 { 1467 Log8(("nemHCWinStopCpu: Stopping CPU succeeded (cpu status %u)\n", nemHCWinCpuGetRunningStatus(pVCpu) )); 1468 return rcStrict; 1469 } 1470 1471 /* 1472 * Dang. The CPU stopped by itself and we got a couple of message to deal with. 1473 */ 1474 DWORD dwErr = RTNtLastErrorValue(); 1475 AssertLogRelMsgReturn(dwErr == ERROR_VID_STOP_PENDING, ("dwErr=%#u\n", dwErr), 1476 RT_SUCCESS(rcStrict) ? VERR_INTERNAL_ERROR_3 : rcStrict); 1477 Log8(("nemHCWinStopCpu: Stopping CPU pending...\n")); 1478 1479 /* 1480 * First message: Exit or similar. 1481 * Note! We can safely ASSUME that rcStrict isn't an important information one. 1482 */ 1483 BOOL fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu, 1484 VID_MSHAGN_F_GET_NEXT_MESSAGE, 30000 /*ms*/); 1485 AssertLogRelMsgReturn(fWait, 1486 ("1st VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %u\n", RTNtLastErrorValue()), 1487 RT_SUCCESS(rcStrict) ? VERR_INTERNAL_ERROR_3 : rcStrict); 1488 1489 /* It should be a hypervisor message and definitely not a stop request completed message. */ 1490 VID_MESSAGE_TYPE enmVidMsgType = pMappingHeader->enmVidMsgType; 1491 AssertLogRelMsgReturn(enmVidMsgType != VidMessageStopRequestComplete, 1492 ("Unexpected 1st message following ERROR_VID_STOP_PENDING: %#x LB %#x\n", 1493 enmVidMsgType, pMappingHeader->cbMessage), 1494 RT_SUCCESS(rcStrict) ? VERR_INTERNAL_ERROR_3 : rcStrict); 1495 1496 VBOXSTRICTRC rcStrict2 = nemHCWinHandleMessage(pVM, pVCpu, pMappingHeader, CPUMQueryGuestCtxPtr(pVCpu)); 1497 if (rcStrict2 != VINF_SUCCESS && RT_SUCCESS(rcStrict)) 1498 rcStrict = rcStrict2; 1499 1500 /* 1501 * Mark it as handled and get the stop request completed message, then mark 1502 * that as handled too. CPU is back into fully stopped stated then. 1503 */ 1504 fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu, 1505 VID_MSHAGN_F_HANDLE_MESSAGE | VID_MSHAGN_F_GET_NEXT_MESSAGE, 30000 /*ms*/); 1506 AssertLogRelMsgReturn(fWait, 1507 ("2nd VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %u\n", RTNtLastErrorValue()), 1508 RT_SUCCESS(rcStrict) ? VERR_INTERNAL_ERROR_3 : rcStrict); 1509 1510 /* It should be a stop request completed message. */ 1511 enmVidMsgType = pMappingHeader->enmVidMsgType; 1512 AssertLogRelMsgReturn(enmVidMsgType == VidMessageStopRequestComplete, 1513 ("Unexpected 2nd message following ERROR_VID_STOP_PENDING: %#x LB %#x\n", 1514 enmVidMsgType, pMappingHeader->cbMessage), 1515 RT_SUCCESS(rcStrict) ? VERR_INTERNAL_ERROR_3 : rcStrict); 1516 1517 /* Mark this as handled. */ 1518 fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu, 1519 VID_MSHAGN_F_HANDLE_MESSAGE, 30000 /*ms*/); 1520 AssertLogRelMsgReturn(fWait, 1521 ("3rd VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %u\n", RTNtLastErrorValue()), 1522 RT_SUCCESS(rcStrict) ? VERR_INTERNAL_ERROR_3 : rcStrict); 1523 Log8(("nemHCWinStopCpu: Stopped the CPU (rcStrict=%Rrc)\n", VBOXSTRICTRC_VAL(rcStrict) )); 1524 return rcStrict; 1525 } 1526 1527 1528 NEM_TMPL_STATIC VBOXSTRICTRC nemHCWinRunGC(PVM pVM, PVMCPU pVCpu) 1529 { 1530 PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu); 1531 LogFlow(("nemHCWinRunGC: Entering #%u cs:rip=%04x:%08RX64 efl=%#08RX64\n", pVCpu->idCpu, pCtx->cs.Sel, pCtx->rip, pCtx->rflags)); 1482 1532 #ifdef LOG_ENABLED 1483 1533 if (LogIs3Enabled()) 1484 { 1485 Log3(("nemR3NativeRunGC: Entering #%u\n", pVCpu->idCpu)); 1486 nemR3WinLogState(pVM, pVCpu); 1487 } 1534 nemHCWinLogState(pVM, pVCpu); 1488 1535 #endif 1489 1536 … … 1494 1541 * everything every time. This will be optimized later. 1495 1542 */ 1496 const bool fSingleStepping = false; /** @todo get this from somewhere. */ 1497 VBOXSTRICTRC rcStrict = VINF_SUCCESS; 1543 VID_MESSAGE_MAPPING_HEADER volatile *pMappingHeader = (VID_MESSAGE_MAPPING_HEADER volatile *)pVCpu->nem.s.pvMsgSlotMapping; 1544 uint32_t cMillies = 5000; /** @todo lower this later... */ 1545 const bool fSingleStepping = false; /** @todo get this from somewhere. */ 1546 VBOXSTRICTRC rcStrict = VINF_SUCCESS; 1498 1547 for (unsigned iLoop = 0;;iLoop++) 1499 1548 { 1500 1549 /* 1501 * Copy the state.1550 * Ensure that hyper-V has the whole state. 1502 1551 */ 1503 PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu); 1504 int rc2 = nemHCWinCopyStateToHyperV(pVM, pVCpu, pCtx); 1505 AssertRCBreakStmt(rc2, rcStrict = rc2); 1552 if ((pCtx->fExtrn & (CPUMCTX_EXTRN_ALL | CPUMCTX_EXTRN_NEM_WIN_MASK)) != (CPUMCTX_EXTRN_ALL | CPUMCTX_EXTRN_NEM_WIN_MASK)) 1553 { 1554 int rc2 = nemHCWinCopyStateToHyperV(pVM, pVCpu, pCtx); 1555 AssertRCReturn(rc2, rc2); 1556 } 1506 1557 1507 1558 /* 1508 1559 * Run a bit. 1509 1560 */ 1510 WHV_RUN_VP_EXIT_CONTEXT ExitReason;1511 RT_ZERO(ExitReason);1512 1561 if ( !VM_FF_IS_PENDING(pVM, VM_FF_EMT_RENDEZVOUS | VM_FF_TM_VIRTUAL_SYNC) 1513 1562 && !VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_TO_R3_MASK)) 1514 1563 { 1515 #ifdef NEM_WIN_USE_OUR_OWN_RUN_API 1516 int rc2 = nemR3WinRunVirtualProcessor(pVM, pVCpu, &ExitReason, sizeof(ExitReason)); 1517 AssertRCBreakStmt(rc2, rcStrict = rc2); 1518 #else 1519 Log8(("Calling WHvRunVirtualProcessor\n")); 1520 VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED); 1521 HRESULT hrc = WHvRunVirtualProcessor(pVM->nem.s.hPartition, pVCpu->idCpu, &ExitReason, sizeof(ExitReason)); 1522 VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM); 1523 AssertLogRelMsgBreakStmt(SUCCEEDED(hrc), 1524 ("WHvRunVirtualProcessor(%p, %u,,) -> %Rhrc (Last=%#x/%u)\n", pVM->nem.s.hPartition, pVCpu->idCpu, 1525 hrc, RTNtLastStatusValue(), RTNtLastErrorValue()), 1526 rcStrict = VERR_INTERNAL_ERROR); 1527 Log2(("WHvRunVirtualProcessor -> %#x; exit code %#x (%d) (cpu status %u)\n", 1528 hrc, ExitReason.ExitReason, ExitReason.ExitReason, nemR3WinCpuGetRunningStatus(pVCpu) )); 1564 if (pVCpu->nem.s.fHandleAndGetFlags) 1565 { /* Very likely that the CPU does NOT need starting (pending msg, running). */ } 1566 else 1567 { 1568 if (g_pfnVidStartVirtualProcessor(pVM->nem.s.hPartitionDevice, pVCpu->idCpu)) 1569 pVCpu->nem.s.fHandleAndGetFlags = VID_MSHAGN_F_GET_NEXT_MESSAGE; 1570 else 1571 AssertLogRelMsgFailedReturn(("VidStartVirtualProcessor failed for CPU #%u: %u (%#x, rcNt=%#x)\n", 1572 pVCpu->idCpu, RTNtLastErrorValue(), RTNtLastErrorValue(), RTNtLastStatusValue()), 1573 VERR_INTERNAL_ERROR_3); 1574 } 1575 1576 if (VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED)) 1577 { 1578 BOOL fRet = VidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu, 1579 pVCpu->nem.s.fHandleAndGetFlags, cMillies); 1580 VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM); 1581 if (fRet) 1582 { 1583 /* 1584 * Deal with the message. 1585 */ 1586 rcStrict = nemHCWinHandleMessage(pVM, pVCpu, pMappingHeader, pCtx); 1587 pVCpu->nem.s.fHandleAndGetFlags |= VID_MSHAGN_F_HANDLE_MESSAGE; 1588 } 1589 else 1590 { 1591 /* VID.SYS merges STATUS_ALERTED and STATUS_USER_APC into STATUS_TIMEOUT, 1592 so after NtAlertThread we end up here with a STATUS_TIMEOUT. And yeah, 1593 the error code conversion is into WAIT_XXX, i.e. NT status codes. */ 1594 DWORD dwErr = GetLastError(); 1595 if ( dwErr == STATUS_TIMEOUT 1596 || dwErr == STATUS_ALERTED /* just in case */ 1597 || dwErr == STATUS_USER_APC /* ditto */ ) 1598 pVCpu->nem.s.fHandleAndGetFlags = VID_MSHAGN_F_GET_NEXT_MESSAGE; /* exits are likely */ 1599 else 1600 AssertLogRelMsgFailedReturn(("VidMessageSlotHandleAndGetNext failed for CPU #%u: %u (%#x, rcNt=%#x)\n", 1601 pVCpu->idCpu, dwErr, dwErr, RTNtLastStatusValue()), 1602 VERR_INTERNAL_ERROR_3); 1603 } 1604 1605 /* 1606 * If no relevant FFs are pending, loop. 1607 */ 1608 if ( !VM_FF_IS_PENDING( pVM, !fSingleStepping ? VM_FF_HP_R0_PRE_HM_MASK : VM_FF_HP_R0_PRE_HM_STEP_MASK) 1609 && !VMCPU_FF_IS_PENDING(pVCpu, !fSingleStepping ? VMCPU_FF_HP_R0_PRE_HM_MASK : VMCPU_FF_HP_R0_PRE_HM_STEP_MASK) ) 1610 continue; 1611 1612 /** @todo Try handle pending flags, not just return to EM loops. Take care 1613 * not to set important RCs here unless we've handled a message. */ 1614 LogFlow(("nemHCWinRunGC: returning: pending FF (%#x / %#x)\n", pVM->fGlobalForcedActions, pVCpu->fLocalForcedActions)); 1615 } 1616 else 1617 LogFlow(("nemHCWinRunGC: returning: canceled %d (pre exec)\n", VMCPU_GET_STATE(pVCpu) )); 1618 } 1619 else 1620 LogFlow(("nemHCWinRunGC: returning: pending FF (pre exec)\n")); 1621 break; 1622 } /* the run loop */ 1623 1624 1625 /* 1626 * If the CPU is running, make sure to stop it before we try sync back the 1627 * state and return to EM. 1628 */ 1629 if (pVCpu->nem.s.fHandleAndGetFlags == VID_MSHAGN_F_GET_NEXT_MESSAGE) 1630 { 1631 pVCpu->nem.s.fHandleAndGetFlags = 0; 1632 rcStrict = nemHCWinStopCpu(pVM, pVCpu, rcStrict, pMappingHeader); 1633 } 1634 1635 VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM_CANCELED); 1636 1637 if (pCtx->fExtrn & (CPUMCTX_EXTRN_ALL | (CPUMCTX_EXTRN_NEM_WIN_MASK & ~CPUMCTX_EXTRN_NEM_WIN_EVENT_INJECT))) 1638 { 1639 int rc2 = nemHCWinCopyStateFromHyperV(pVM, pVCpu, pCtx, CPUMCTX_EXTRN_ALL | CPUMCTX_EXTRN_NEM_WIN_MASK); 1640 if (RT_SUCCESS(rc2)) 1641 pCtx->fExtrn = 0; 1642 else if (RT_SUCCESS(rcStrict)) 1643 rcStrict = rc2; 1644 } 1645 else 1646 pCtx->fExtrn = 0; 1647 1648 LogFlow(("nemHCWinRunGC: Leaving #%u cs:rip=%04x:%08RX64 efl=%#08RX64\n", pVCpu->idCpu, pCtx->cs.Sel, pCtx->rip, pCtx->rflags)); 1649 return rcStrict; 1650 } 1529 1651 #endif 1530 }1531 else1532 {1533 LogFlow(("nemR3NativeRunGC: returning: pending FF (pre exec)\n"));1534 break;1535 }1536 1537 /*1538 * Copy back the state.1539 */1540 rc2 = nemR3WinCopyStateFromHyperV(pVM, pVCpu, pCtx);1541 AssertRCBreakStmt(rc2, rcStrict = rc2);1542 1543 #ifdef LOG_ENABLED1544 /*1545 * Do some logging.1546 */1547 if (LogIs2Enabled())1548 nemR3WinLogExitReason(&ExitReason);1549 if (LogIs3Enabled())1550 nemR3WinLogState(pVM, pVCpu);1551 #endif1552 1553 #ifdef VBOX_STRICT1554 /* Assert that the VpContext field makes sense. */1555 switch (ExitReason.ExitReason)1556 {1557 case WHvRunVpExitReasonMemoryAccess:1558 case WHvRunVpExitReasonX64IoPortAccess:1559 case WHvRunVpExitReasonX64MsrAccess:1560 case WHvRunVpExitReasonX64Cpuid:1561 case WHvRunVpExitReasonException:1562 case WHvRunVpExitReasonUnrecoverableException:1563 Assert( ExitReason.IoPortAccess.VpContext.InstructionLength > 01564 || ( ExitReason.ExitReason == WHvRunVpExitReasonMemoryAccess1565 && ExitReason.MemoryAccess.AccessInfo.AccessType == WHvMemoryAccessExecute));1566 Assert(ExitReason.IoPortAccess.VpContext.InstructionLength < 16);1567 Assert(ExitReason.IoPortAccess.VpContext.ExecutionState.Cpl == CPUMGetGuestCPL(pVCpu));1568 Assert(ExitReason.IoPortAccess.VpContext.ExecutionState.Cr0Pe == RT_BOOL(pCtx->cr0 & X86_CR0_PE));1569 Assert(ExitReason.IoPortAccess.VpContext.ExecutionState.Cr0Am == RT_BOOL(pCtx->cr0 & X86_CR0_AM));1570 Assert(ExitReason.IoPortAccess.VpContext.ExecutionState.EferLma == RT_BOOL(pCtx->msrEFER & MSR_K6_EFER_LMA));1571 Assert(ExitReason.IoPortAccess.VpContext.ExecutionState.DebugActive == RT_BOOL(pCtx->dr[7] & X86_DR7_ENABLED_MASK));1572 Assert(ExitReason.IoPortAccess.VpContext.ExecutionState.Reserved0 == 0);1573 Assert(ExitReason.IoPortAccess.VpContext.ExecutionState.Reserved1 == 0);1574 Assert(ExitReason.IoPortAccess.VpContext.Rip == pCtx->rip);1575 Assert(ExitReason.IoPortAccess.VpContext.Rflags == pCtx->rflags.u);1576 Assert( ExitReason.IoPortAccess.VpContext.Cs.Base == pCtx->cs.u64Base1577 && ExitReason.IoPortAccess.VpContext.Cs.Limit == pCtx->cs.u32Limit1578 && ExitReason.IoPortAccess.VpContext.Cs.Selector == pCtx->cs.Sel);1579 break;1580 default: break; /* shut up compiler. */1581 }1582 #endif1583 1584 /*1585 * Deal with the exit.1586 */1587 switch (ExitReason.ExitReason)1588 {1589 /* Frequent exits: */1590 case WHvRunVpExitReasonCanceled:1591 case WHvRunVpExitReasonAlerted:1592 rcStrict = VINF_SUCCESS;1593 break;1594 1595 case WHvRunVpExitReasonX64Halt:1596 rcStrict = nemR3WinHandleHalt(pVM, pVCpu, pCtx);1597 break;1598 1599 case WHvRunVpExitReasonMemoryAccess:1600 rcStrict = nemR3WinHandleMemoryAccess(pVM, pVCpu, pCtx, &ExitReason.MemoryAccess);1601 break;1602 1603 case WHvRunVpExitReasonX64IoPortAccess:1604 rcStrict = nemR3WinHandleIoPortAccess(pVM, pVCpu, pCtx, &ExitReason.IoPortAccess);1605 break;1606 1607 case WHvRunVpExitReasonX64InterruptWindow:1608 rcStrict = nemR3WinHandleInterruptWindow(pVM, pVCpu, pCtx, &ExitReason);1609 break;1610 1611 case WHvRunVpExitReasonX64MsrAccess: /* needs configuring */1612 rcStrict = nemR3WinHandleMsrAccess(pVM, pVCpu, pCtx, &ExitReason);1613 break;1614 1615 case WHvRunVpExitReasonX64Cpuid: /* needs configuring */1616 rcStrict = nemR3WinHandleCpuId(pVM, pVCpu, pCtx, &ExitReason);1617 break;1618 1619 case WHvRunVpExitReasonException: /* needs configuring */1620 rcStrict = nemR3WinHandleException(pVM, pVCpu, pCtx, &ExitReason);1621 break;1622 1623 /* Unlikely exits: */1624 case WHvRunVpExitReasonUnsupportedFeature:1625 rcStrict = nemR3WinHandleUD(pVM, pVCpu, pCtx, &ExitReason);1626 break;1627 1628 case WHvRunVpExitReasonUnrecoverableException:1629 rcStrict = nemR3WinHandleTripleFault(pVM, pVCpu, pCtx, &ExitReason);1630 break;1631 1632 case WHvRunVpExitReasonInvalidVpRegisterValue:1633 rcStrict = nemR3WinHandleInvalidState(pVM, pVCpu, pCtx, &ExitReason);1634 break;1635 1636 /* Undesired exits: */1637 case WHvRunVpExitReasonNone:1638 default:1639 AssertLogRelMsgFailed(("Unknown ExitReason: %#x\n", ExitReason.ExitReason));1640 rcStrict = VERR_INTERNAL_ERROR_3;1641 break;1642 }1643 if (rcStrict != VINF_SUCCESS)1644 {1645 LogFlow(("nemR3NativeRunGC: returning: %Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));1646 break;1647 }1648 1649 #ifndef NEM_WIN_USE_HYPERCALLS_FOR_PAGES1650 /* Hack alert! */1651 uint32_t const cMappedPages = pVM->nem.s.cMappedPages;1652 if (cMappedPages < 4000)1653 { /* likely */ }1654 else1655 {1656 PGMPhysNemEnumPagesByState(pVM, pVCpu, NEM_WIN_PAGE_STATE_READABLE, nemR3WinUnmapOnePageCallback, NULL);1657 Log(("nemR3NativeRunGC: Unmapped all; cMappedPages=%u -> %u\n", cMappedPages, pVM->nem.s.cMappedPages));1658 }1659 #endif1660 1661 /* If any FF is pending, return to the EM loops. That's okay for the1662 current sledgehammer approach. */1663 if ( VM_FF_IS_PENDING( pVM, !fSingleStepping ? VM_FF_HP_R0_PRE_HM_MASK : VM_FF_HP_R0_PRE_HM_STEP_MASK)1664 || VMCPU_FF_IS_PENDING(pVCpu, !fSingleStepping ? VMCPU_FF_HP_R0_PRE_HM_MASK : VMCPU_FF_HP_R0_PRE_HM_STEP_MASK) )1665 {1666 LogFlow(("nemR3NativeRunGC: returning: pending FF (%#x / %#x)\n", pVM->fGlobalForcedActions, pVCpu->fLocalForcedActions));1667 break;1668 }1669 }1670 1671 return rcStrict;1672 }1673 #endif /* later */1674 1675 1652 1676 1653 #endif /* IN_RING0 */ -
trunk/src/VBox/VMM/VMMR0/NEMR0Native-win.cpp
r71152 r71184 497 497 * @param fWhat What to export. To be defined, UINT64_MAX for now. 498 498 */ 499 static int nemR0WinExportState(PGVM pGVM, PGVMCPU pGVCpu, PCPUMCTX pCtx , uint64_t fWhat)499 static int nemR0WinExportState(PGVM pGVM, PGVMCPU pGVCpu, PCPUMCTX pCtx) 500 500 { 501 501 PVMCPU pVCpu = &pGVM->pVM->aCpus[pGVCpu->idCpu]; … … 507 507 pInput->RsvdZ = 0; 508 508 509 RT_NOREF_PV(fWhat); /** @todo group selection. */ 509 uint64_t const fWhat = ~pCtx->fExtrn & (CPUMCTX_EXTRN_ALL | CPUMCTX_EXTRN_NEM_WIN_MASK); 510 if (!fWhat) 511 return VINF_SUCCESS; 512 uintptr_t iReg = 0; 510 513 511 514 /* GPRs */ 512 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[0]); 513 pInput->Elements[0].Name = HvX64RegisterRax; 514 pInput->Elements[0].Value.Reg64 = pCtx->rax; 515 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[1]); 516 pInput->Elements[1].Name = HvX64RegisterRcx; 517 pInput->Elements[1].Value.Reg64 = pCtx->rcx; 518 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[2]); 519 pInput->Elements[2].Name = HvX64RegisterRdx; 520 pInput->Elements[2].Value.Reg64 = pCtx->rdx; 521 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[3]); 522 pInput->Elements[3].Name = HvX64RegisterRbx; 523 pInput->Elements[3].Value.Reg64 = pCtx->rbx; 524 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[4]); 525 pInput->Elements[4].Name = HvX64RegisterRsp; 526 pInput->Elements[4].Value.Reg64 = pCtx->rsp; 527 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[5]); 528 pInput->Elements[5].Name = HvX64RegisterRbp; 529 pInput->Elements[5].Value.Reg64 = pCtx->rbp; 530 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[6]); 531 pInput->Elements[6].Name = HvX64RegisterRsi; 532 pInput->Elements[6].Value.Reg64 = pCtx->rsi; 533 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[7]); 534 pInput->Elements[7].Name = HvX64RegisterRdi; 535 pInput->Elements[7].Value.Reg64 = pCtx->rdi; 536 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[8]); 537 pInput->Elements[8].Name = HvX64RegisterR8; 538 pInput->Elements[8].Value.Reg64 = pCtx->r8; 539 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[9]); 540 pInput->Elements[9].Name = HvX64RegisterR9; 541 pInput->Elements[9].Value.Reg64 = pCtx->r9; 542 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[10]); 543 pInput->Elements[10].Name = HvX64RegisterR10; 544 pInput->Elements[10].Value.Reg64 = pCtx->r10; 545 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[11]); 546 pInput->Elements[11].Name = HvX64RegisterR11; 547 pInput->Elements[11].Value.Reg64 = pCtx->r11; 548 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[12]); 549 pInput->Elements[12].Name = HvX64RegisterR12; 550 pInput->Elements[12].Value.Reg64 = pCtx->r12; 551 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[13]); 552 pInput->Elements[13].Name = HvX64RegisterR13; 553 pInput->Elements[13].Value.Reg64 = pCtx->r13; 554 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[14]); 555 pInput->Elements[14].Name = HvX64RegisterR14; 556 pInput->Elements[14].Value.Reg64 = pCtx->r14; 557 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[15]); 558 pInput->Elements[15].Name = HvX64RegisterR15; 559 pInput->Elements[15].Value.Reg64 = pCtx->r15; 515 if (fWhat & CPUMCTX_EXTRN_GPRS_MASK) 516 { 517 if (fWhat & CPUMCTX_EXTRN_RAX) 518 { 519 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 520 pInput->Elements[iReg].Name = HvX64RegisterRax; 521 pInput->Elements[iReg].Value.Reg64 = pCtx->rax; 522 iReg++; 523 } 524 if (fWhat & CPUMCTX_EXTRN_RCX) 525 { 526 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 527 pInput->Elements[iReg].Name = HvX64RegisterRcx; 528 pInput->Elements[iReg].Value.Reg64 = pCtx->rcx; 529 iReg++; 530 } 531 if (fWhat & CPUMCTX_EXTRN_RDX) 532 { 533 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 534 pInput->Elements[iReg].Name = HvX64RegisterRdx; 535 pInput->Elements[iReg].Value.Reg64 = pCtx->rdx; 536 iReg++; 537 } 538 if (fWhat & CPUMCTX_EXTRN_RBX) 539 { 540 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 541 pInput->Elements[iReg].Name = HvX64RegisterRbx; 542 pInput->Elements[iReg].Value.Reg64 = pCtx->rbx; 543 iReg++; 544 } 545 if (fWhat & CPUMCTX_EXTRN_RSP) 546 { 547 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 548 pInput->Elements[iReg].Name = HvX64RegisterRsp; 549 pInput->Elements[iReg].Value.Reg64 = pCtx->rsp; 550 iReg++; 551 } 552 if (fWhat & CPUMCTX_EXTRN_RBP) 553 { 554 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 555 pInput->Elements[iReg].Name = HvX64RegisterRbp; 556 pInput->Elements[iReg].Value.Reg64 = pCtx->rbp; 557 iReg++; 558 } 559 if (fWhat & CPUMCTX_EXTRN_RSI) 560 { 561 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 562 pInput->Elements[iReg].Name = HvX64RegisterRsi; 563 pInput->Elements[iReg].Value.Reg64 = pCtx->rsi; 564 iReg++; 565 } 566 if (fWhat & CPUMCTX_EXTRN_RDI) 567 { 568 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 569 pInput->Elements[iReg].Name = HvX64RegisterRdi; 570 pInput->Elements[iReg].Value.Reg64 = pCtx->rdi; 571 iReg++; 572 } 573 if (fWhat & CPUMCTX_EXTRN_R8_R15) 574 { 575 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 576 pInput->Elements[iReg].Name = HvX64RegisterR8; 577 pInput->Elements[iReg].Value.Reg64 = pCtx->r8; 578 iReg++; 579 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 580 pInput->Elements[iReg].Name = HvX64RegisterR9; 581 pInput->Elements[iReg].Value.Reg64 = pCtx->r9; 582 iReg++; 583 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 584 pInput->Elements[iReg].Name = HvX64RegisterR10; 585 pInput->Elements[iReg].Value.Reg64 = pCtx->r10; 586 iReg++; 587 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 588 pInput->Elements[iReg].Name = HvX64RegisterR11; 589 pInput->Elements[iReg].Value.Reg64 = pCtx->r11; 590 iReg++; 591 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 592 pInput->Elements[iReg].Name = HvX64RegisterR12; 593 pInput->Elements[iReg].Value.Reg64 = pCtx->r12; 594 iReg++; 595 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 596 pInput->Elements[iReg].Name = HvX64RegisterR13; 597 pInput->Elements[iReg].Value.Reg64 = pCtx->r13; 598 iReg++; 599 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 600 pInput->Elements[iReg].Name = HvX64RegisterR14; 601 pInput->Elements[iReg].Value.Reg64 = pCtx->r14; 602 iReg++; 603 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 604 pInput->Elements[iReg].Name = HvX64RegisterR15; 605 pInput->Elements[iReg].Value.Reg64 = pCtx->r15; 606 iReg++; 607 } 608 } 560 609 561 610 /* RIP & Flags */ 562 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[16]); 563 pInput->Elements[16].Name = HvX64RegisterRip; 564 pInput->Elements[16].Value.Reg64 = pCtx->rip; 565 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[17]); 566 pInput->Elements[17].Name = HvX64RegisterRflags; 567 pInput->Elements[17].Value.Reg64 = pCtx->rflags.u; 611 if (fWhat & CPUMCTX_EXTRN_RIP) 612 { 613 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 614 pInput->Elements[iReg].Name = HvX64RegisterRip; 615 pInput->Elements[iReg].Value.Reg64 = pCtx->rip; 616 iReg++; 617 } 618 if (fWhat & CPUMCTX_EXTRN_RFLAGS) 619 { 620 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 621 pInput->Elements[iReg].Name = HvX64RegisterRflags; 622 pInput->Elements[iReg].Value.Reg64 = pCtx->rflags.u; 623 iReg++; 624 } 568 625 569 626 /* Segments */ … … 577 634 pInput->Elements[a_idx].Value.Segment.Attributes = (a_SReg).Attr.u; \ 578 635 } while (0) 579 COPY_OUT_SEG(18, HvX64RegisterEs, pCtx->es); 580 COPY_OUT_SEG(19, HvX64RegisterCs, pCtx->cs); 581 COPY_OUT_SEG(20, HvX64RegisterSs, pCtx->ss); 582 COPY_OUT_SEG(21, HvX64RegisterDs, pCtx->ds); 583 COPY_OUT_SEG(22, HvX64RegisterFs, pCtx->fs); 584 COPY_OUT_SEG(23, HvX64RegisterGs, pCtx->gs); 585 COPY_OUT_SEG(24, HvX64RegisterLdtr, pCtx->ldtr); 586 COPY_OUT_SEG(25, HvX64RegisterTr, pCtx->tr); 587 588 uintptr_t iReg = 26; 589 /* Descriptor tables. */ 590 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 591 pInput->Elements[iReg].Value.Table.Pad[0] = 0; 592 pInput->Elements[iReg].Value.Table.Pad[1] = 0; 593 pInput->Elements[iReg].Value.Table.Pad[2] = 0; 594 pInput->Elements[iReg].Name = HvX64RegisterIdtr; 595 pInput->Elements[iReg].Value.Table.Limit = pCtx->idtr.cbIdt; 596 pInput->Elements[iReg].Value.Table.Base = pCtx->idtr.pIdt; 597 iReg++; 598 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 599 pInput->Elements[iReg].Value.Table.Pad[0] = 0; 600 pInput->Elements[iReg].Value.Table.Pad[1] = 0; 601 pInput->Elements[iReg].Value.Table.Pad[2] = 0; 602 pInput->Elements[iReg].Name = HvX64RegisterGdtr; 603 pInput->Elements[iReg].Value.Table.Limit = pCtx->gdtr.cbGdt; 604 pInput->Elements[iReg].Value.Table.Base = pCtx->gdtr.pGdt; 605 iReg++; 636 if (fWhat & CPUMCTX_EXTRN_SREG_MASK) 637 { 638 if (fWhat & CPUMCTX_EXTRN_CS) 639 { 640 COPY_OUT_SEG(iReg, HvX64RegisterCs, pCtx->cs); 641 iReg++; 642 } 643 if (fWhat & CPUMCTX_EXTRN_ES) 644 { 645 COPY_OUT_SEG(iReg, HvX64RegisterEs, pCtx->es); 646 iReg++; 647 } 648 if (fWhat & CPUMCTX_EXTRN_SS) 649 { 650 COPY_OUT_SEG(iReg, HvX64RegisterSs, pCtx->ss); 651 iReg++; 652 } 653 if (fWhat & CPUMCTX_EXTRN_DS) 654 { 655 COPY_OUT_SEG(iReg, HvX64RegisterDs, pCtx->ds); 656 iReg++; 657 } 658 if (fWhat & CPUMCTX_EXTRN_FS) 659 { 660 COPY_OUT_SEG(iReg, HvX64RegisterFs, pCtx->fs); 661 iReg++; 662 } 663 if (fWhat & CPUMCTX_EXTRN_GS) 664 { 665 COPY_OUT_SEG(iReg, HvX64RegisterGs, pCtx->gs); 666 iReg++; 667 } 668 } 669 670 /* Descriptor tables & task segment. */ 671 if (fWhat & CPUMCTX_EXTRN_TABLE_MASK) 672 { 673 if (fWhat & CPUMCTX_EXTRN_LDTR) 674 { 675 COPY_OUT_SEG(iReg, HvX64RegisterLdtr, pCtx->ldtr); 676 iReg++; 677 } 678 if (fWhat & CPUMCTX_EXTRN_TR) 679 { 680 COPY_OUT_SEG(iReg, HvX64RegisterTr, pCtx->tr); 681 iReg++; 682 } 683 684 if (fWhat & CPUMCTX_EXTRN_IDTR) 685 { 686 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 687 pInput->Elements[iReg].Value.Table.Pad[0] = 0; 688 pInput->Elements[iReg].Value.Table.Pad[1] = 0; 689 pInput->Elements[iReg].Value.Table.Pad[2] = 0; 690 pInput->Elements[iReg].Name = HvX64RegisterIdtr; 691 pInput->Elements[iReg].Value.Table.Limit = pCtx->idtr.cbIdt; 692 pInput->Elements[iReg].Value.Table.Base = pCtx->idtr.pIdt; 693 iReg++; 694 } 695 if (fWhat & CPUMCTX_EXTRN_GDTR) 696 { 697 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 698 pInput->Elements[iReg].Value.Table.Pad[0] = 0; 699 pInput->Elements[iReg].Value.Table.Pad[1] = 0; 700 pInput->Elements[iReg].Value.Table.Pad[2] = 0; 701 pInput->Elements[iReg].Name = HvX64RegisterGdtr; 702 pInput->Elements[iReg].Value.Table.Limit = pCtx->gdtr.cbGdt; 703 pInput->Elements[iReg].Value.Table.Base = pCtx->gdtr.pGdt; 704 iReg++; 705 } 706 } 606 707 607 708 /* Control registers. */ 608 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 609 pInput->Elements[iReg].Name = HvX64RegisterCr0; 610 pInput->Elements[iReg].Value.Reg64 = pCtx->cr0; 611 iReg++; 612 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 613 pInput->Elements[iReg].Name = HvX64RegisterCr2; 614 pInput->Elements[iReg].Value.Reg64 = pCtx->cr2; 615 iReg++; 616 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 617 pInput->Elements[iReg].Name = HvX64RegisterCr3; 618 pInput->Elements[iReg].Value.Reg64 = pCtx->cr3; 619 iReg++; 620 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 621 pInput->Elements[iReg].Name = HvX64RegisterCr4; 622 pInput->Elements[iReg].Value.Reg64 = pCtx->cr4; 623 iReg++; 709 if (fWhat & CPUMCTX_EXTRN_CR_MASK) 710 { 711 if (fWhat & CPUMCTX_EXTRN_CR0) 712 { 713 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 714 pInput->Elements[iReg].Name = HvX64RegisterCr0; 715 pInput->Elements[iReg].Value.Reg64 = pCtx->cr0; 716 iReg++; 717 } 718 if (fWhat & CPUMCTX_EXTRN_CR2) 719 { 720 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 721 pInput->Elements[iReg].Name = HvX64RegisterCr2; 722 pInput->Elements[iReg].Value.Reg64 = pCtx->cr2; 723 iReg++; 724 } 725 if (fWhat & CPUMCTX_EXTRN_CR3) 726 { 727 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 728 pInput->Elements[iReg].Name = HvX64RegisterCr3; 729 pInput->Elements[iReg].Value.Reg64 = pCtx->cr3; 730 iReg++; 731 } 732 if (fWhat & CPUMCTX_EXTRN_CR4) 733 { 734 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 735 pInput->Elements[iReg].Name = HvX64RegisterCr4; 736 pInput->Elements[iReg].Value.Reg64 = pCtx->cr4; 737 iReg++; 738 } 739 } 740 /** @todo CR8/TPR */ 624 741 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 625 742 pInput->Elements[iReg].Name = HvX64RegisterCr8; … … 627 744 iReg++; 628 745 746 /** @todo does HvX64RegisterXfem mean XCR0? What about the related MSR. */ 747 629 748 /* Debug registers. */ 630 749 /** @todo fixme. Figure out what the hyper-v version of KVM_SET_GUEST_DEBUG would be. */ 631 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 632 pInput->Elements[iReg].Name = HvX64RegisterDr0; 633 //pInput->Elements[iReg].Value.Reg64 = CPUMGetHyperDR0(pVCpu); 634 pInput->Elements[iReg].Value.Reg64 = pCtx->dr[0]; 635 iReg++; 636 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 637 pInput->Elements[iReg].Name = HvX64RegisterDr1; 638 //pInput->Elements[iReg].Value.Reg64 = CPUMGetHyperDR1(pVCpu); 639 pInput->Elements[iReg].Value.Reg64 = pCtx->dr[1]; 640 iReg++; 641 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 642 pInput->Elements[iReg].Name = HvX64RegisterDr2; 643 //pInput->Elements[iReg].Value.Reg64 = CPUMGetHyperDR2(pVCpu); 644 pInput->Elements[iReg].Value.Reg64 = pCtx->dr[2]; 645 iReg++; 646 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 647 pInput->Elements[iReg].Name = HvX64RegisterDr3; 648 //pInput->Elements[iReg].Value.Reg64 = CPUMGetHyperDR3(pVCpu); 649 pInput->Elements[iReg].Value.Reg64 = pCtx->dr[3]; 650 iReg++; 651 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 652 pInput->Elements[iReg].Name = HvX64RegisterDr6; 653 //pInput->Elements[iReg].Value.Reg64 = CPUMGetHyperDR6(pVCpu); 654 pInput->Elements[iReg].Value.Reg64 = pCtx->dr[6]; 655 iReg++; 656 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 657 pInput->Elements[iReg].Name = HvX64RegisterDr7; 658 //pInput->Elements[iReg].Value.Reg64 = CPUMGetHyperDR7(pVCpu); 659 pInput->Elements[iReg].Value.Reg64 = pCtx->dr[7]; 660 iReg++; 750 if (fWhat & CPUMCTX_EXTRN_DR0_DR3) 751 { 752 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 753 pInput->Elements[iReg].Name = HvX64RegisterDr0; 754 //pInput->Elements[iReg].Value.Reg64 = CPUMGetHyperDR0(pVCpu); 755 pInput->Elements[iReg].Value.Reg64 = pCtx->dr[0]; 756 iReg++; 757 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 758 pInput->Elements[iReg].Name = HvX64RegisterDr1; 759 //pInput->Elements[iReg].Value.Reg64 = CPUMGetHyperDR1(pVCpu); 760 pInput->Elements[iReg].Value.Reg64 = pCtx->dr[1]; 761 iReg++; 762 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 763 pInput->Elements[iReg].Name = HvX64RegisterDr2; 764 //pInput->Elements[iReg].Value.Reg64 = CPUMGetHyperDR2(pVCpu); 765 pInput->Elements[iReg].Value.Reg64 = pCtx->dr[2]; 766 iReg++; 767 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 768 pInput->Elements[iReg].Name = HvX64RegisterDr3; 769 //pInput->Elements[iReg].Value.Reg64 = CPUMGetHyperDR3(pVCpu); 770 pInput->Elements[iReg].Value.Reg64 = pCtx->dr[3]; 771 iReg++; 772 } 773 if (fWhat & CPUMCTX_EXTRN_DR6) 774 { 775 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 776 pInput->Elements[iReg].Name = HvX64RegisterDr6; 777 //pInput->Elements[iReg].Value.Reg64 = CPUMGetHyperDR6(pVCpu); 778 pInput->Elements[iReg].Value.Reg64 = pCtx->dr[6]; 779 iReg++; 780 } 781 if (fWhat & CPUMCTX_EXTRN_DR7) 782 { 783 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 784 pInput->Elements[iReg].Name = HvX64RegisterDr7; 785 //pInput->Elements[iReg].Value.Reg64 = CPUMGetHyperDR7(pVCpu); 786 pInput->Elements[iReg].Value.Reg64 = pCtx->dr[7]; 787 iReg++; 788 } 789 790 /* Floating point state. */ 791 if (fWhat & CPUMCTX_EXTRN_X87) 792 { 793 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 794 pInput->Elements[iReg].Name = HvX64RegisterFpMmx0; 795 pInput->Elements[iReg].Value.Fp.AsUINT128.Low64 = pCtx->pXStateR0->x87.aRegs[0].au64[0]; 796 pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[0].au64[1]; 797 iReg++; 798 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 799 pInput->Elements[iReg].Name = HvX64RegisterFpMmx1; 800 pInput->Elements[iReg].Value.Fp.AsUINT128.Low64 = pCtx->pXStateR0->x87.aRegs[1].au64[0]; 801 pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[1].au64[1]; 802 iReg++; 803 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 804 pInput->Elements[iReg].Name = HvX64RegisterFpMmx2; 805 pInput->Elements[iReg].Value.Fp.AsUINT128.Low64 = pCtx->pXStateR0->x87.aRegs[2].au64[0]; 806 pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[2].au64[1]; 807 iReg++; 808 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 809 pInput->Elements[iReg].Name = HvX64RegisterFpMmx3; 810 pInput->Elements[iReg].Value.Fp.AsUINT128.Low64 = pCtx->pXStateR0->x87.aRegs[3].au64[0]; 811 pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[3].au64[1]; 812 iReg++; 813 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 814 pInput->Elements[iReg].Name = HvX64RegisterFpMmx4; 815 pInput->Elements[iReg].Value.Fp.AsUINT128.Low64 = pCtx->pXStateR0->x87.aRegs[4].au64[0]; 816 pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[4].au64[1]; 817 iReg++; 818 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 819 pInput->Elements[iReg].Name = HvX64RegisterFpMmx5; 820 pInput->Elements[iReg].Value.Fp.AsUINT128.Low64 = pCtx->pXStateR0->x87.aRegs[5].au64[0]; 821 pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[5].au64[1]; 822 iReg++; 823 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 824 pInput->Elements[iReg].Name = HvX64RegisterFpMmx6; 825 pInput->Elements[iReg].Value.Fp.AsUINT128.Low64 = pCtx->pXStateR0->x87.aRegs[6].au64[0]; 826 pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[6].au64[1]; 827 iReg++; 828 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 829 pInput->Elements[iReg].Name = HvX64RegisterFpMmx7; 830 pInput->Elements[iReg].Value.Fp.AsUINT128.Low64 = pCtx->pXStateR0->x87.aRegs[7].au64[0]; 831 pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[7].au64[1]; 832 iReg++; 833 834 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 835 pInput->Elements[iReg].Name = HvX64RegisterFpControlStatus; 836 pInput->Elements[iReg].Value.FpControlStatus.FpControl = pCtx->pXStateR0->x87.FCW; 837 pInput->Elements[iReg].Value.FpControlStatus.FpStatus = pCtx->pXStateR0->x87.FSW; 838 pInput->Elements[iReg].Value.FpControlStatus.FpTag = pCtx->pXStateR0->x87.FTW; 839 pInput->Elements[iReg].Value.FpControlStatus.Reserved = pCtx->pXStateR0->x87.FTW >> 8; 840 pInput->Elements[iReg].Value.FpControlStatus.LastFpOp = pCtx->pXStateR0->x87.FOP; 841 pInput->Elements[iReg].Value.FpControlStatus.LastFpRip = (pCtx->pXStateR0->x87.FPUIP) 842 | ((uint64_t)pCtx->pXStateR0->x87.CS << 32) 843 | ((uint64_t)pCtx->pXStateR0->x87.Rsrvd1 << 48); 844 iReg++; 845 /** @todo we've got trouble if if we try write just SSE w/o X87. */ 846 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 847 pInput->Elements[iReg].Name = HvX64RegisterXmmControlStatus; 848 pInput->Elements[iReg].Value.XmmControlStatus.LastFpRdp = (pCtx->pXStateR0->x87.FPUDP) 849 | ((uint64_t)pCtx->pXStateR0->x87.DS << 32) 850 | ((uint64_t)pCtx->pXStateR0->x87.Rsrvd2 << 48); 851 pInput->Elements[iReg].Value.XmmControlStatus.XmmStatusControl = pCtx->pXStateR0->x87.MXCSR; 852 pInput->Elements[iReg].Value.XmmControlStatus.XmmStatusControlMask = pCtx->pXStateR0->x87.MXCSR_MASK; /** @todo ??? (Isn't this an output field?) */ 853 iReg++; 854 } 661 855 662 856 /* Vector state. */ 663 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 664 pInput->Elements[iReg].Name = HvX64RegisterXmm0; 665 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Lo; 666 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Hi; 667 iReg++; 668 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 669 pInput->Elements[iReg].Name = HvX64RegisterXmm1; 670 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Lo; 671 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Hi; 672 iReg++; 673 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 674 pInput->Elements[iReg].Name = HvX64RegisterXmm2; 675 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Lo; 676 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Hi; 677 iReg++; 678 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 679 pInput->Elements[iReg].Name = HvX64RegisterXmm3; 680 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Lo; 681 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Hi; 682 iReg++; 683 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 684 pInput->Elements[iReg].Name = HvX64RegisterXmm4; 685 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Lo; 686 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Hi; 687 iReg++; 688 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 689 pInput->Elements[iReg].Name = HvX64RegisterXmm5; 690 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Lo; 691 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Hi; 692 iReg++; 693 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 694 pInput->Elements[iReg].Name = HvX64RegisterXmm6; 695 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Lo; 696 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Hi; 697 iReg++; 698 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 699 pInput->Elements[iReg].Name = HvX64RegisterXmm7; 700 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Lo; 701 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Hi; 702 iReg++; 703 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 704 pInput->Elements[iReg].Name = HvX64RegisterXmm8; 705 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Lo; 706 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Hi; 707 iReg++; 708 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 709 pInput->Elements[iReg].Name = HvX64RegisterXmm9; 710 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Lo; 711 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Hi; 712 iReg++; 713 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 714 pInput->Elements[iReg].Name = HvX64RegisterXmm10; 715 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Lo; 716 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Hi; 717 iReg++; 718 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 719 pInput->Elements[iReg].Name = HvX64RegisterXmm11; 720 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Lo; 721 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Hi; 722 iReg++; 723 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 724 pInput->Elements[iReg].Name = HvX64RegisterXmm12; 725 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Lo; 726 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Hi; 727 iReg++; 728 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 729 pInput->Elements[iReg].Name = HvX64RegisterXmm13; 730 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Lo; 731 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Hi; 732 iReg++; 733 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 734 pInput->Elements[iReg].Name = HvX64RegisterXmm14; 735 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Lo; 736 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Hi; 737 iReg++; 738 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 739 pInput->Elements[iReg].Name = HvX64RegisterXmm15; 740 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Lo; 741 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Hi; 742 iReg++; 743 744 /* Floating point state. */ 745 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 746 pInput->Elements[iReg].Name = HvX64RegisterFpMmx0; 747 pInput->Elements[iReg].Value.Fp.AsUINT128.Low64 = pCtx->pXStateR0->x87.aRegs[0].au64[0]; 748 pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[0].au64[1]; 749 iReg++; 750 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 751 pInput->Elements[iReg].Name = HvX64RegisterFpMmx1; 752 pInput->Elements[iReg].Value.Fp.AsUINT128.Low64 = pCtx->pXStateR0->x87.aRegs[1].au64[0]; 753 pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[1].au64[1]; 754 iReg++; 755 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 756 pInput->Elements[iReg].Name = HvX64RegisterFpMmx2; 757 pInput->Elements[iReg].Value.Fp.AsUINT128.Low64 = pCtx->pXStateR0->x87.aRegs[2].au64[0]; 758 pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[2].au64[1]; 759 iReg++; 760 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 761 pInput->Elements[iReg].Name = HvX64RegisterFpMmx3; 762 pInput->Elements[iReg].Value.Fp.AsUINT128.Low64 = pCtx->pXStateR0->x87.aRegs[3].au64[0]; 763 pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[3].au64[1]; 764 iReg++; 765 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 766 pInput->Elements[iReg].Name = HvX64RegisterFpMmx4; 767 pInput->Elements[iReg].Value.Fp.AsUINT128.Low64 = pCtx->pXStateR0->x87.aRegs[4].au64[0]; 768 pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[4].au64[1]; 769 iReg++; 770 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 771 pInput->Elements[iReg].Name = HvX64RegisterFpMmx5; 772 pInput->Elements[iReg].Value.Fp.AsUINT128.Low64 = pCtx->pXStateR0->x87.aRegs[5].au64[0]; 773 pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[5].au64[1]; 774 iReg++; 775 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 776 pInput->Elements[iReg].Name = HvX64RegisterFpMmx6; 777 pInput->Elements[iReg].Value.Fp.AsUINT128.Low64 = pCtx->pXStateR0->x87.aRegs[6].au64[0]; 778 pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[6].au64[1]; 779 iReg++; 780 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 781 pInput->Elements[iReg].Name = HvX64RegisterFpMmx7; 782 pInput->Elements[iReg].Value.Fp.AsUINT128.Low64 = pCtx->pXStateR0->x87.aRegs[7].au64[0]; 783 pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[7].au64[1]; 784 iReg++; 785 786 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 787 pInput->Elements[iReg].Name = HvX64RegisterFpControlStatus; 788 pInput->Elements[iReg].Value.FpControlStatus.FpControl = pCtx->pXStateR0->x87.FCW; 789 pInput->Elements[iReg].Value.FpControlStatus.FpStatus = pCtx->pXStateR0->x87.FSW; 790 pInput->Elements[iReg].Value.FpControlStatus.FpTag = pCtx->pXStateR0->x87.FTW; 791 pInput->Elements[iReg].Value.FpControlStatus.Reserved = pCtx->pXStateR0->x87.FTW >> 8; 792 pInput->Elements[iReg].Value.FpControlStatus.LastFpOp = pCtx->pXStateR0->x87.FOP; 793 pInput->Elements[iReg].Value.FpControlStatus.LastFpRip = (pCtx->pXStateR0->x87.FPUIP) 794 | ((uint64_t)pCtx->pXStateR0->x87.CS << 32) 795 | ((uint64_t)pCtx->pXStateR0->x87.Rsrvd1 << 48); 796 iReg++; 797 798 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 799 pInput->Elements[iReg].Name = HvX64RegisterXmmControlStatus; 800 pInput->Elements[iReg].Value.XmmControlStatus.LastFpRdp = (pCtx->pXStateR0->x87.FPUDP) 801 | ((uint64_t)pCtx->pXStateR0->x87.DS << 32) 802 | ((uint64_t)pCtx->pXStateR0->x87.Rsrvd2 << 48); 803 pInput->Elements[iReg].Value.XmmControlStatus.XmmStatusControl = pCtx->pXStateR0->x87.MXCSR; 804 pInput->Elements[iReg].Value.XmmControlStatus.XmmStatusControlMask = pCtx->pXStateR0->x87.MXCSR_MASK; /** @todo ??? (Isn't this an output field?) */ 805 iReg++; 857 if (fWhat & CPUMCTX_EXTRN_SSE_AVX) 858 { 859 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 860 pInput->Elements[iReg].Name = HvX64RegisterXmm0; 861 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Lo; 862 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Hi; 863 iReg++; 864 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 865 pInput->Elements[iReg].Name = HvX64RegisterXmm1; 866 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Lo; 867 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Hi; 868 iReg++; 869 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 870 pInput->Elements[iReg].Name = HvX64RegisterXmm2; 871 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Lo; 872 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Hi; 873 iReg++; 874 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 875 pInput->Elements[iReg].Name = HvX64RegisterXmm3; 876 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Lo; 877 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Hi; 878 iReg++; 879 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 880 pInput->Elements[iReg].Name = HvX64RegisterXmm4; 881 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Lo; 882 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Hi; 883 iReg++; 884 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 885 pInput->Elements[iReg].Name = HvX64RegisterXmm5; 886 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Lo; 887 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Hi; 888 iReg++; 889 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 890 pInput->Elements[iReg].Name = HvX64RegisterXmm6; 891 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Lo; 892 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Hi; 893 iReg++; 894 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 895 pInput->Elements[iReg].Name = HvX64RegisterXmm7; 896 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Lo; 897 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Hi; 898 iReg++; 899 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 900 pInput->Elements[iReg].Name = HvX64RegisterXmm8; 901 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Lo; 902 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Hi; 903 iReg++; 904 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 905 pInput->Elements[iReg].Name = HvX64RegisterXmm9; 906 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Lo; 907 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Hi; 908 iReg++; 909 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 910 pInput->Elements[iReg].Name = HvX64RegisterXmm10; 911 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Lo; 912 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Hi; 913 iReg++; 914 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 915 pInput->Elements[iReg].Name = HvX64RegisterXmm11; 916 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Lo; 917 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Hi; 918 iReg++; 919 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 920 pInput->Elements[iReg].Name = HvX64RegisterXmm12; 921 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Lo; 922 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Hi; 923 iReg++; 924 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 925 pInput->Elements[iReg].Name = HvX64RegisterXmm13; 926 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Lo; 927 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Hi; 928 iReg++; 929 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 930 pInput->Elements[iReg].Name = HvX64RegisterXmm14; 931 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Lo; 932 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Hi; 933 iReg++; 934 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 935 pInput->Elements[iReg].Name = HvX64RegisterXmm15; 936 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Lo; 937 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Hi; 938 iReg++; 939 } 806 940 807 941 /* MSRs */ 808 942 // HvX64RegisterTsc - don't touch 809 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 810 pInput->Elements[iReg].Name = HvX64RegisterEfer; 811 pInput->Elements[iReg].Value.Reg64 = pCtx->msrEFER; 812 iReg++; 813 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 814 pInput->Elements[iReg].Name = HvX64RegisterKernelGsBase; 815 pInput->Elements[iReg].Value.Reg64 = pCtx->msrKERNELGSBASE; 816 iReg++; 817 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 818 pInput->Elements[iReg].Name = HvX64RegisterApicBase; 819 pInput->Elements[iReg].Value.Reg64 = APICGetBaseMsrNoCheck(pVCpu); 820 iReg++; 821 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 822 pInput->Elements[iReg].Name = HvX64RegisterPat; 823 pInput->Elements[iReg].Value.Reg64 = pCtx->msrPAT; 824 iReg++; 825 /// @todo HvX64RegisterSysenterCs 826 /// @todo HvX64RegisterSysenterEip 827 /// @todo HvX64RegisterSysenterEsp 828 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 829 pInput->Elements[iReg].Name = HvX64RegisterStar; 830 pInput->Elements[iReg].Value.Reg64 = pCtx->msrSTAR; 831 iReg++; 832 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 833 pInput->Elements[iReg].Name = HvX64RegisterLstar; 834 pInput->Elements[iReg].Value.Reg64 = pCtx->msrLSTAR; 835 iReg++; 836 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 837 pInput->Elements[iReg].Name = HvX64RegisterCstar; 838 pInput->Elements[iReg].Value.Reg64 = pCtx->msrCSTAR; 839 iReg++; 840 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 841 pInput->Elements[iReg].Name = HvX64RegisterSfmask; 842 pInput->Elements[iReg].Value.Reg64 = pCtx->msrSFMASK; 843 iReg++; 943 /** @todo does HvX64RegisterTsc include TSC_AUX? Is it TSC_AUX? */ 944 if (fWhat & CPUMCTX_EXTRN_EFER) 945 { 946 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 947 pInput->Elements[iReg].Name = HvX64RegisterEfer; 948 pInput->Elements[iReg].Value.Reg64 = pCtx->msrEFER; 949 iReg++; 950 } 951 if (fWhat & CPUMCTX_EXTRN_KERNEL_GS_BASE) 952 { 953 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 954 pInput->Elements[iReg].Name = HvX64RegisterKernelGsBase; 955 pInput->Elements[iReg].Value.Reg64 = pCtx->msrKERNELGSBASE; 956 iReg++; 957 } 958 if (fWhat & CPUMCTX_EXTRN_SYSENTER_MSRS) 959 { 960 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 961 pInput->Elements[iReg].Name = HvX64RegisterSysenterCs; 962 pInput->Elements[iReg].Value.Reg64 = pCtx->SysEnter.cs; 963 iReg++; 964 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 965 pInput->Elements[iReg].Name = HvX64RegisterSysenterEip; 966 pInput->Elements[iReg].Value.Reg64 = pCtx->SysEnter.eip; 967 iReg++; 968 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 969 pInput->Elements[iReg].Name = HvX64RegisterSysenterEsp; 970 pInput->Elements[iReg].Value.Reg64 = pCtx->SysEnter.esp; 971 iReg++; 972 } 973 if (fWhat & CPUMCTX_EXTRN_SYSCALL_MSRS) 974 { 975 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 976 pInput->Elements[iReg].Name = HvX64RegisterStar; 977 pInput->Elements[iReg].Value.Reg64 = pCtx->msrSTAR; 978 iReg++; 979 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 980 pInput->Elements[iReg].Name = HvX64RegisterLstar; 981 pInput->Elements[iReg].Value.Reg64 = pCtx->msrLSTAR; 982 iReg++; 983 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 984 pInput->Elements[iReg].Name = HvX64RegisterCstar; 985 pInput->Elements[iReg].Value.Reg64 = pCtx->msrCSTAR; 986 iReg++; 987 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 988 pInput->Elements[iReg].Name = HvX64RegisterSfmask; 989 pInput->Elements[iReg].Value.Reg64 = pCtx->msrSFMASK; 990 iReg++; 991 } 992 if (fWhat & CPUMCTX_EXTRN_OTHER_MSRS) 993 { 994 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 995 pInput->Elements[iReg].Name = HvX64RegisterApicBase; 996 pInput->Elements[iReg].Value.Reg64 = APICGetBaseMsrNoCheck(pVCpu); 997 iReg++; 998 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 999 pInput->Elements[iReg].Name = HvX64RegisterPat; 1000 pInput->Elements[iReg].Value.Reg64 = pCtx->msrPAT; 1001 iReg++; 1002 } 844 1003 845 1004 /* event injection (always clear it). */ 846 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 847 pInput->Elements[iReg].Name = HvRegisterPendingInterruption; 848 pInput->Elements[iReg].Value.Reg64 = 0; 849 iReg++; 1005 if (fWhat & CPUMCTX_EXTRN_NEM_WIN_EVENT_INJECT) 1006 { 1007 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 1008 pInput->Elements[iReg].Name = HvRegisterPendingInterruption; 1009 pInput->Elements[iReg].Value.Reg64 = 0; 1010 iReg++; 1011 } 850 1012 /// @todo HvRegisterInterruptState 851 1013 /// @todo HvRegisterPendingEvent0 … … 865 1027 ("uResult=%RX64 iRegs=%#x\n", uResult, iReg), 866 1028 VERR_NEM_SET_REGISTERS_FAILED); 1029 //LogFlow(("nemR0WinExportState: uResult=%#RX64 iReg=%zu fWhat=%#018RX64 fExtrn=%#018RX64 -> %#018RX64\n", uResult, iReg, fWhat, pCtx->fExtrn, 1030 // pCtx->fExtrn | CPUMCTX_EXTRN_ALL | CPUMCTX_EXTRN_NEM_WIN_MASK | CPUMCTX_EXTRN_KEEPER_NEM )); 1031 pCtx->fExtrn |= CPUMCTX_EXTRN_ALL | CPUMCTX_EXTRN_NEM_WIN_MASK | CPUMCTX_EXTRN_KEEPER_NEM; 867 1032 return VINF_SUCCESS; 868 1033 } … … 877 1042 * @param idCpu The calling EMT. Necessary for getting the 878 1043 * hypercall page and arguments. 879 * @param fWhat What to export. To be defined, UINT64_MAX for now.880 1044 */ 881 VMMR0_INT_DECL(int) NEMR0ExportState(PGVM pGVM, PVM pVM, VMCPUID idCpu , uint64_t fWhat)1045 VMMR0_INT_DECL(int) NEMR0ExportState(PGVM pGVM, PVM pVM, VMCPUID idCpu) 882 1046 { 883 1047 /* … … 894 1058 * Call worker. 895 1059 */ 896 rc = nemR0WinExportState(pGVM, pGVCpu, CPUMQueryGuestCtxPtr(pVCpu) , fWhat);1060 rc = nemR0WinExportState(pGVM, pGVCpu, CPUMQueryGuestCtxPtr(pVCpu)); 897 1061 } 898 1062 return rc; … … 909 1073 * @param pGVCpu The irng-0 VCPU handle. 910 1074 * @param pCtx The CPU context structure to import into. 911 * @param fWhat What to import . To be defined, UINT64_MAX for now.1075 * @param fWhat What to import, CPUMCTX_EXTRN_XXX. 912 1076 */ 913 1077 static int nemR0WinImportState(PGVM pGVM, PGVMCPU pGVCpu, PCPUMCTX pCtx, uint64_t fWhat) … … 916 1080 AssertPtrReturn(pInput, VERR_INTERNAL_ERROR_3); 917 1081 1082 fWhat &= pCtx->fExtrn; 1083 918 1084 pInput->PartitionId = pGVM->nem.s.idHvPartition; 919 1085 pInput->VpIndex = pGVCpu->idCpu; 920 1086 pInput->fFlags = 0; 921 1087 922 RT_NOREF_PV(fWhat); /** @todo group selection. */923 924 1088 /* GPRs */ 925 pInput->Names[0] = HvX64RegisterRax; 926 pInput->Names[1] = HvX64RegisterRcx; 927 pInput->Names[2] = HvX64RegisterRdx; 928 pInput->Names[3] = HvX64RegisterRbx; 929 pInput->Names[4] = HvX64RegisterRsp; 930 pInput->Names[5] = HvX64RegisterRbp; 931 pInput->Names[6] = HvX64RegisterRsi; 932 pInput->Names[7] = HvX64RegisterRdi; 933 pInput->Names[8] = HvX64RegisterR8; 934 pInput->Names[9] = HvX64RegisterR9; 935 pInput->Names[10] = HvX64RegisterR10; 936 pInput->Names[11] = HvX64RegisterR11; 937 pInput->Names[12] = HvX64RegisterR12; 938 pInput->Names[13] = HvX64RegisterR13; 939 pInput->Names[14] = HvX64RegisterR14; 940 pInput->Names[15] = HvX64RegisterR15; 1089 uintptr_t iReg = 0; 1090 if (fWhat & CPUMCTX_EXTRN_GPRS_MASK) 1091 { 1092 if (fWhat & CPUMCTX_EXTRN_RAX) 1093 pInput->Names[iReg++] = HvX64RegisterRax; 1094 if (fWhat & CPUMCTX_EXTRN_RCX) 1095 pInput->Names[iReg++] = HvX64RegisterRcx; 1096 if (fWhat & CPUMCTX_EXTRN_RDX) 1097 pInput->Names[iReg++] = HvX64RegisterRdx; 1098 if (fWhat & CPUMCTX_EXTRN_RBX) 1099 pInput->Names[iReg++] = HvX64RegisterRbx; 1100 if (fWhat & CPUMCTX_EXTRN_RSP) 1101 pInput->Names[iReg++] = HvX64RegisterRsp; 1102 if (fWhat & CPUMCTX_EXTRN_RBP) 1103 pInput->Names[iReg++] = HvX64RegisterRbp; 1104 if (fWhat & CPUMCTX_EXTRN_RSI) 1105 pInput->Names[iReg++] = HvX64RegisterRsi; 1106 if (fWhat & CPUMCTX_EXTRN_RDI) 1107 pInput->Names[iReg++] = HvX64RegisterRdi; 1108 if (fWhat & CPUMCTX_EXTRN_R8_R15) 1109 { 1110 pInput->Names[iReg++] = HvX64RegisterR8; 1111 pInput->Names[iReg++] = HvX64RegisterR9; 1112 pInput->Names[iReg++] = HvX64RegisterR10; 1113 pInput->Names[iReg++] = HvX64RegisterR11; 1114 pInput->Names[iReg++] = HvX64RegisterR12; 1115 pInput->Names[iReg++] = HvX64RegisterR13; 1116 pInput->Names[iReg++] = HvX64RegisterR14; 1117 pInput->Names[iReg++] = HvX64RegisterR15; 1118 } 1119 } 941 1120 942 1121 /* RIP & Flags */ 943 pInput->Names[16] = HvX64RegisterRip; 944 pInput->Names[17] = HvX64RegisterRflags; 1122 if (fWhat & CPUMCTX_EXTRN_RIP) 1123 pInput->Names[iReg++] = HvX64RegisterRip; 1124 if (fWhat & CPUMCTX_EXTRN_RFLAGS) 1125 pInput->Names[iReg++] = HvX64RegisterRflags; 945 1126 946 1127 /* Segments */ 947 pInput->Names[18] = HvX64RegisterEs; 948 pInput->Names[19] = HvX64RegisterCs; 949 pInput->Names[20] = HvX64RegisterSs; 950 pInput->Names[21] = HvX64RegisterDs; 951 pInput->Names[22] = HvX64RegisterFs; 952 pInput->Names[23] = HvX64RegisterGs; 953 pInput->Names[24] = HvX64RegisterLdtr; 954 pInput->Names[25] = HvX64RegisterTr; 955 956 /* Descriptor tables. */ 957 pInput->Names[26] = HvX64RegisterIdtr; 958 pInput->Names[27] = HvX64RegisterGdtr; 1128 if (fWhat & CPUMCTX_EXTRN_SREG_MASK) 1129 { 1130 if (fWhat & CPUMCTX_EXTRN_CS) 1131 pInput->Names[iReg++] = HvX64RegisterCs; 1132 if (fWhat & CPUMCTX_EXTRN_ES) 1133 pInput->Names[iReg++] = HvX64RegisterEs; 1134 if (fWhat & CPUMCTX_EXTRN_SS) 1135 pInput->Names[iReg++] = HvX64RegisterSs; 1136 if (fWhat & CPUMCTX_EXTRN_DS) 1137 pInput->Names[iReg++] = HvX64RegisterDs; 1138 if (fWhat & CPUMCTX_EXTRN_FS) 1139 pInput->Names[iReg++] = HvX64RegisterFs; 1140 if (fWhat & CPUMCTX_EXTRN_GS) 1141 pInput->Names[iReg++] = HvX64RegisterGs; 1142 } 1143 1144 /* Descriptor tables and the task segment. */ 1145 if (fWhat & CPUMCTX_EXTRN_TABLE_MASK) 1146 { 1147 if (fWhat & CPUMCTX_EXTRN_LDTR) 1148 pInput->Names[iReg++] = HvX64RegisterLdtr; 1149 if (fWhat & CPUMCTX_EXTRN_TR) 1150 pInput->Names[iReg++] = HvX64RegisterTr; 1151 if (fWhat & CPUMCTX_EXTRN_IDTR) 1152 pInput->Names[iReg++] = HvX64RegisterIdtr; 1153 if (fWhat & CPUMCTX_EXTRN_GDTR) 1154 pInput->Names[iReg++] = HvX64RegisterGdtr; 1155 } 959 1156 960 1157 /* Control registers. */ 961 pInput->Names[28] = HvX64RegisterCr0; 962 pInput->Names[29] = HvX64RegisterCr2; 963 pInput->Names[30] = HvX64RegisterCr3; 964 pInput->Names[31] = HvX64RegisterCr4; 965 pInput->Names[32] = HvX64RegisterCr8; 1158 if (fWhat & CPUMCTX_EXTRN_CR_MASK) 1159 { 1160 if (fWhat & CPUMCTX_EXTRN_CR0) 1161 pInput->Names[iReg++] = HvX64RegisterCr0; 1162 if (fWhat & CPUMCTX_EXTRN_CR2) 1163 pInput->Names[iReg++] = HvX64RegisterCr2; 1164 if (fWhat & CPUMCTX_EXTRN_CR3) 1165 pInput->Names[iReg++] = HvX64RegisterCr3; 1166 if (fWhat & CPUMCTX_EXTRN_CR4) 1167 pInput->Names[iReg++] = HvX64RegisterCr4; 1168 } 1169 pInput->Names[iReg++] = HvX64RegisterCr8; /// @todo CR8/TPR 966 1170 967 1171 /* Debug registers. */ 968 pInput->Names[33] = HvX64RegisterDr0; 969 pInput->Names[34] = HvX64RegisterDr1; 970 pInput->Names[35] = HvX64RegisterDr2; 971 pInput->Names[36] = HvX64RegisterDr3; 972 pInput->Names[37] = HvX64RegisterDr6; 973 pInput->Names[38] = HvX64RegisterDr7; 1172 if (fWhat & CPUMCTX_EXTRN_DR0_DR3) 1173 { 1174 pInput->Names[iReg++] = HvX64RegisterDr0; 1175 pInput->Names[iReg++] = HvX64RegisterDr1; 1176 pInput->Names[iReg++] = HvX64RegisterDr2; 1177 pInput->Names[iReg++] = HvX64RegisterDr3; 1178 } 1179 if (fWhat & CPUMCTX_EXTRN_DR6) 1180 pInput->Names[iReg++] = HvX64RegisterDr6; 1181 if (fWhat & CPUMCTX_EXTRN_DR7) 1182 pInput->Names[iReg++] = HvX64RegisterDr7; 1183 1184 /* Floating point state. */ 1185 if (fWhat & CPUMCTX_EXTRN_X87) 1186 { 1187 pInput->Names[iReg++] = HvX64RegisterFpMmx0; 1188 pInput->Names[iReg++] = HvX64RegisterFpMmx1; 1189 pInput->Names[iReg++] = HvX64RegisterFpMmx2; 1190 pInput->Names[iReg++] = HvX64RegisterFpMmx3; 1191 pInput->Names[iReg++] = HvX64RegisterFpMmx4; 1192 pInput->Names[iReg++] = HvX64RegisterFpMmx5; 1193 pInput->Names[iReg++] = HvX64RegisterFpMmx6; 1194 pInput->Names[iReg++] = HvX64RegisterFpMmx7; 1195 pInput->Names[iReg++] = HvX64RegisterFpControlStatus; 1196 } 1197 if (fWhat & (CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX)) 1198 pInput->Names[iReg++] = HvX64RegisterXmmControlStatus; 974 1199 975 1200 /* Vector state. */ 976 pInput->Names[39] = HvX64RegisterXmm0; 977 pInput->Names[40] = HvX64RegisterXmm1; 978 pInput->Names[41] = HvX64RegisterXmm2; 979 pInput->Names[42] = HvX64RegisterXmm3; 980 pInput->Names[43] = HvX64RegisterXmm4; 981 pInput->Names[44] = HvX64RegisterXmm5; 982 pInput->Names[45] = HvX64RegisterXmm6; 983 pInput->Names[46] = HvX64RegisterXmm7; 984 pInput->Names[47] = HvX64RegisterXmm8; 985 pInput->Names[48] = HvX64RegisterXmm9; 986 pInput->Names[49] = HvX64RegisterXmm10; 987 pInput->Names[50] = HvX64RegisterXmm11; 988 pInput->Names[51] = HvX64RegisterXmm12; 989 pInput->Names[52] = HvX64RegisterXmm13; 990 pInput->Names[53] = HvX64RegisterXmm14; 991 pInput->Names[54] = HvX64RegisterXmm15; 992 993 /* Floating point state. */ 994 pInput->Names[55] = HvX64RegisterFpMmx0; 995 pInput->Names[56] = HvX64RegisterFpMmx1; 996 pInput->Names[57] = HvX64RegisterFpMmx2; 997 pInput->Names[58] = HvX64RegisterFpMmx3; 998 pInput->Names[59] = HvX64RegisterFpMmx4; 999 pInput->Names[60] = HvX64RegisterFpMmx5; 1000 pInput->Names[61] = HvX64RegisterFpMmx6; 1001 pInput->Names[62] = HvX64RegisterFpMmx7; 1002 pInput->Names[63] = HvX64RegisterFpControlStatus; 1003 pInput->Names[64] = HvX64RegisterXmmControlStatus; 1201 if (fWhat & CPUMCTX_EXTRN_SSE_AVX) 1202 { 1203 pInput->Names[iReg++] = HvX64RegisterXmm0; 1204 pInput->Names[iReg++] = HvX64RegisterXmm1; 1205 pInput->Names[iReg++] = HvX64RegisterXmm2; 1206 pInput->Names[iReg++] = HvX64RegisterXmm3; 1207 pInput->Names[iReg++] = HvX64RegisterXmm4; 1208 pInput->Names[iReg++] = HvX64RegisterXmm5; 1209 pInput->Names[iReg++] = HvX64RegisterXmm6; 1210 pInput->Names[iReg++] = HvX64RegisterXmm7; 1211 pInput->Names[iReg++] = HvX64RegisterXmm8; 1212 pInput->Names[iReg++] = HvX64RegisterXmm9; 1213 pInput->Names[iReg++] = HvX64RegisterXmm10; 1214 pInput->Names[iReg++] = HvX64RegisterXmm11; 1215 pInput->Names[iReg++] = HvX64RegisterXmm12; 1216 pInput->Names[iReg++] = HvX64RegisterXmm13; 1217 pInput->Names[iReg++] = HvX64RegisterXmm14; 1218 pInput->Names[iReg++] = HvX64RegisterXmm15; 1219 } 1004 1220 1005 1221 /* MSRs */ 1006 1222 // HvX64RegisterTsc - don't touch 1007 pInput->Names[65] = HvX64RegisterEfer; 1008 pInput->Names[66] = HvX64RegisterKernelGsBase; 1009 pInput->Names[67] = HvX64RegisterApicBase; 1010 pInput->Names[68] = HvX64RegisterPat; 1011 pInput->Names[69] = HvX64RegisterSysenterCs; 1012 pInput->Names[70] = HvX64RegisterSysenterEip; 1013 pInput->Names[71] = HvX64RegisterSysenterEsp; 1014 pInput->Names[72] = HvX64RegisterStar; 1015 pInput->Names[73] = HvX64RegisterLstar; 1016 pInput->Names[74] = HvX64RegisterCstar; 1017 pInput->Names[75] = HvX64RegisterSfmask; 1223 if (fWhat & CPUMCTX_EXTRN_EFER) 1224 pInput->Names[iReg++] = HvX64RegisterEfer; 1225 if (fWhat & CPUMCTX_EXTRN_KERNEL_GS_BASE) 1226 pInput->Names[iReg++] = HvX64RegisterKernelGsBase; 1227 if (fWhat & CPUMCTX_EXTRN_SYSENTER_MSRS) 1228 { 1229 pInput->Names[iReg++] = HvX64RegisterSysenterCs; 1230 pInput->Names[iReg++] = HvX64RegisterSysenterEip; 1231 pInput->Names[iReg++] = HvX64RegisterSysenterEsp; 1232 } 1233 if (fWhat & CPUMCTX_EXTRN_SYSCALL_MSRS) 1234 { 1235 pInput->Names[iReg++] = HvX64RegisterStar; 1236 pInput->Names[iReg++] = HvX64RegisterLstar; 1237 pInput->Names[iReg++] = HvX64RegisterCstar; 1238 pInput->Names[iReg++] = HvX64RegisterSfmask; 1239 } 1240 1241 if (fWhat & CPUMCTX_EXTRN_OTHER_MSRS) 1242 { 1243 pInput->Names[iReg++] = HvX64RegisterApicBase; /// @todo APIC BASE 1244 pInput->Names[iReg++] = HvX64RegisterPat; 1245 } 1018 1246 1019 1247 /* event injection */ 1020 pInput->Names[ 76] = HvRegisterPendingInterruption;1021 pInput->Names[ 77] = HvRegisterInterruptState;1022 pInput->Names[ 78] = HvRegisterInterruptState;1023 pInput->Names[ 79] = HvRegisterPendingEvent0;1024 pInput->Names[ 80] = HvRegisterPendingEvent1;1025 unsigned const cRegs = 81;1026 size_t const 1248 pInput->Names[iReg++] = HvRegisterPendingInterruption; 1249 pInput->Names[iReg++] = HvRegisterInterruptState; 1250 pInput->Names[iReg++] = HvRegisterInterruptState; 1251 pInput->Names[iReg++] = HvRegisterPendingEvent0; 1252 pInput->Names[iReg++] = HvRegisterPendingEvent1; 1253 size_t const cRegs = iReg; 1254 size_t const cbInput = RT_ALIGN_Z(RT_OFFSETOF(HV_INPUT_GET_VP_REGISTERS, Names[cRegs]), 32); 1027 1255 1028 1256 HV_REGISTER_VALUE *paValues = (HV_REGISTER_VALUE *)((uint8_t *)pInput + cbInput); … … 1039 1267 ("uResult=%RX64 cRegs=%#x\n", uResult, cRegs), 1040 1268 VERR_NEM_GET_REGISTERS_FAILED); 1269 //LogFlow(("nemR0WinImportState: uResult=%#RX64 iReg=%zu fWhat=%#018RX64 fExtr=%#018RX64\n", uResult, cRegs, fWhat, pCtx->fExtrn)); 1041 1270 1042 1271 /* … … 1044 1273 */ 1045 1274 PVMCPU pVCpu = &pGVM->pVM->aCpus[pGVCpu->idCpu]; 1275 iReg = 0; 1046 1276 1047 1277 /* GPRs */ 1048 Assert(pInput->Names[0] == HvX64RegisterRax); 1049 Assert(pInput->Names[15] == HvX64RegisterR15); 1050 pCtx->rax = paValues[0].Reg64; 1051 pCtx->rcx = paValues[1].Reg64; 1052 pCtx->rdx = paValues[2].Reg64; 1053 pCtx->rbx = paValues[3].Reg64; 1054 pCtx->rsp = paValues[4].Reg64; 1055 pCtx->rbp = paValues[5].Reg64; 1056 pCtx->rsi = paValues[6].Reg64; 1057 pCtx->rdi = paValues[7].Reg64; 1058 pCtx->r8 = paValues[8].Reg64; 1059 pCtx->r9 = paValues[9].Reg64; 1060 pCtx->r10 = paValues[10].Reg64; 1061 pCtx->r11 = paValues[11].Reg64; 1062 pCtx->r12 = paValues[12].Reg64; 1063 pCtx->r13 = paValues[13].Reg64; 1064 pCtx->r14 = paValues[14].Reg64; 1065 pCtx->r15 = paValues[15].Reg64; 1278 if (fWhat & CPUMCTX_EXTRN_GPRS_MASK) 1279 { 1280 if (fWhat & CPUMCTX_EXTRN_RAX) 1281 { 1282 Assert(pInput->Names[iReg] == HvX64RegisterRax); 1283 pCtx->rax = paValues[iReg++].Reg64; 1284 } 1285 if (fWhat & CPUMCTX_EXTRN_RCX) 1286 { 1287 Assert(pInput->Names[iReg] == HvX64RegisterRcx); 1288 pCtx->rcx = paValues[iReg++].Reg64; 1289 } 1290 if (fWhat & CPUMCTX_EXTRN_RDX) 1291 { 1292 Assert(pInput->Names[iReg] == HvX64RegisterRdx); 1293 pCtx->rdx = paValues[iReg++].Reg64; 1294 } 1295 if (fWhat & CPUMCTX_EXTRN_RBX) 1296 { 1297 Assert(pInput->Names[iReg] == HvX64RegisterRbx); 1298 pCtx->rbx = paValues[iReg++].Reg64; 1299 } 1300 if (fWhat & CPUMCTX_EXTRN_RSP) 1301 { 1302 Assert(pInput->Names[iReg] == HvX64RegisterRsp); 1303 pCtx->rsp = paValues[iReg++].Reg64; 1304 } 1305 if (fWhat & CPUMCTX_EXTRN_RBP) 1306 { 1307 Assert(pInput->Names[iReg] == HvX64RegisterRbp); 1308 pCtx->rbp = paValues[iReg++].Reg64; 1309 } 1310 if (fWhat & CPUMCTX_EXTRN_RSI) 1311 { 1312 Assert(pInput->Names[iReg] == HvX64RegisterRsi); 1313 pCtx->rsi = paValues[iReg++].Reg64; 1314 } 1315 if (fWhat & CPUMCTX_EXTRN_RDI) 1316 { 1317 Assert(pInput->Names[iReg] == HvX64RegisterRdi); 1318 pCtx->rdi = paValues[iReg++].Reg64; 1319 } 1320 if (fWhat & CPUMCTX_EXTRN_R8_R15) 1321 { 1322 Assert(pInput->Names[iReg] == HvX64RegisterR8); 1323 Assert(pInput->Names[iReg + 7] == HvX64RegisterR15); 1324 pCtx->r8 = paValues[iReg++].Reg64; 1325 pCtx->r9 = paValues[iReg++].Reg64; 1326 pCtx->r10 = paValues[iReg++].Reg64; 1327 pCtx->r11 = paValues[iReg++].Reg64; 1328 pCtx->r12 = paValues[iReg++].Reg64; 1329 pCtx->r13 = paValues[iReg++].Reg64; 1330 pCtx->r14 = paValues[iReg++].Reg64; 1331 pCtx->r15 = paValues[iReg++].Reg64; 1332 } 1333 } 1066 1334 1067 1335 /* RIP & Flags */ 1068 Assert(pInput->Names[16] == HvX64RegisterRip); 1069 pCtx->rip = paValues[16].Reg64; 1070 pCtx->rflags.u = paValues[17].Reg64; 1336 if (fWhat & CPUMCTX_EXTRN_RIP) 1337 { 1338 Assert(pInput->Names[iReg] == HvX64RegisterRip); 1339 pCtx->rip = paValues[iReg++].Reg64; 1340 } 1341 if (fWhat & CPUMCTX_EXTRN_RFLAGS) 1342 { 1343 Assert(pInput->Names[iReg] == HvX64RegisterRflags); 1344 pCtx->rflags.u = paValues[iReg++].Reg64; 1345 } 1071 1346 1072 1347 /* Segments */ … … 1080 1355 (a_SReg).fFlags = CPUMSELREG_FLAGS_VALID; \ 1081 1356 } while (0) 1082 COPY_BACK_SEG(18, HvX64RegisterEs, pCtx->es); 1083 COPY_BACK_SEG(19, HvX64RegisterCs, pCtx->cs); 1084 COPY_BACK_SEG(20, HvX64RegisterSs, pCtx->ss); 1085 COPY_BACK_SEG(21, HvX64RegisterDs, pCtx->ds); 1086 COPY_BACK_SEG(22, HvX64RegisterFs, pCtx->fs); 1087 COPY_BACK_SEG(23, HvX64RegisterGs, pCtx->gs); 1088 COPY_BACK_SEG(24, HvX64RegisterLdtr, pCtx->ldtr); 1089 COPY_BACK_SEG(25, HvX64RegisterTr, pCtx->tr); 1090 1091 /* Descriptor tables. */ 1092 Assert(pInput->Names[26] == HvX64RegisterIdtr); 1093 pCtx->idtr.cbIdt = paValues[26].Table.Limit; 1094 pCtx->idtr.pIdt = paValues[26].Table.Base; 1095 Assert(pInput->Names[27] == HvX64RegisterGdtr); 1096 pCtx->gdtr.cbGdt = paValues[27].Table.Limit; 1097 pCtx->gdtr.pGdt = paValues[27].Table.Base; 1357 if (fWhat & CPUMCTX_EXTRN_SREG_MASK) 1358 { 1359 if (fWhat & CPUMCTX_EXTRN_CS) 1360 { 1361 COPY_BACK_SEG(iReg, HvX64RegisterCs, pCtx->cs); 1362 iReg++; 1363 } 1364 if (fWhat & CPUMCTX_EXTRN_ES) 1365 { 1366 COPY_BACK_SEG(iReg, HvX64RegisterEs, pCtx->es); 1367 iReg++; 1368 } 1369 if (fWhat & CPUMCTX_EXTRN_SS) 1370 { 1371 COPY_BACK_SEG(iReg, HvX64RegisterSs, pCtx->ss); 1372 iReg++; 1373 } 1374 if (fWhat & CPUMCTX_EXTRN_DS) 1375 { 1376 COPY_BACK_SEG(iReg, HvX64RegisterDs, pCtx->ds); 1377 iReg++; 1378 } 1379 if (fWhat & CPUMCTX_EXTRN_FS) 1380 { 1381 COPY_BACK_SEG(iReg, HvX64RegisterFs, pCtx->fs); 1382 iReg++; 1383 } 1384 if (fWhat & CPUMCTX_EXTRN_GS) 1385 { 1386 COPY_BACK_SEG(iReg, HvX64RegisterGs, pCtx->gs); 1387 iReg++; 1388 } 1389 } 1390 /* Descriptor tables and the task segment. */ 1391 if (fWhat & CPUMCTX_EXTRN_TABLE_MASK) 1392 { 1393 if (fWhat & CPUMCTX_EXTRN_LDTR) 1394 { 1395 COPY_BACK_SEG(iReg, HvX64RegisterLdtr, pCtx->ldtr); 1396 iReg++; 1397 } 1398 if (fWhat & CPUMCTX_EXTRN_TR) 1399 { 1400 COPY_BACK_SEG(iReg, HvX64RegisterTr, pCtx->tr); 1401 iReg++; 1402 } 1403 if (fWhat & CPUMCTX_EXTRN_IDTR) 1404 { 1405 Assert(pInput->Names[iReg] == HvX64RegisterIdtr); 1406 pCtx->idtr.cbIdt = paValues[iReg].Table.Limit; 1407 pCtx->idtr.pIdt = paValues[iReg].Table.Base; 1408 iReg++; 1409 } 1410 if (fWhat & CPUMCTX_EXTRN_GDTR) 1411 { 1412 Assert(pInput->Names[iReg] == HvX64RegisterGdtr); 1413 pCtx->gdtr.cbGdt = paValues[iReg].Table.Limit; 1414 pCtx->gdtr.pGdt = paValues[iReg].Table.Base; 1415 iReg++; 1416 } 1417 } 1098 1418 1099 1419 /* Control registers. */ 1100 Assert(pInput->Names[28] == HvX64RegisterCr0);1101 1420 bool fMaybeChangedMode = false; 1102 1421 bool fFlushTlb = false; 1103 1422 bool fFlushGlobalTlb = false; 1104 if (pCtx->cr0 != paValues[28].Reg64) 1105 { 1106 CPUMSetGuestCR0(pVCpu, paValues[28].Reg64); 1107 fMaybeChangedMode = true; 1108 fFlushTlb = fFlushGlobalTlb = true; /// @todo fix this 1109 } 1110 Assert(pInput->Names[29] == HvX64RegisterCr2); 1111 pCtx->cr2 = paValues[29].Reg64; 1112 if (pCtx->cr3 != paValues[30].Reg64) 1113 { 1114 CPUMSetGuestCR3(pVCpu, paValues[30].Reg64); 1115 fFlushTlb = true; 1116 } 1117 if (pCtx->cr4 != paValues[31].Reg64) 1118 { 1119 CPUMSetGuestCR4(pVCpu, paValues[31].Reg64); 1120 fMaybeChangedMode = true; 1121 fFlushTlb = fFlushGlobalTlb = true; /// @todo fix this 1122 } 1123 APICSetTpr(pVCpu, (uint8_t)paValues[32].Reg64 << 4); 1423 if (fWhat & CPUMCTX_EXTRN_CR_MASK) 1424 { 1425 if (fWhat & CPUMCTX_EXTRN_CR0) 1426 { 1427 Assert(pInput->Names[iReg] == HvX64RegisterCr0); 1428 if (pCtx->cr0 != paValues[iReg].Reg64) 1429 { 1430 CPUMSetGuestCR0(pVCpu, paValues[iReg].Reg64); 1431 fMaybeChangedMode = true; 1432 fFlushTlb = fFlushGlobalTlb = true; /// @todo fix this 1433 } 1434 iReg++; 1435 } 1436 if (fWhat & CPUMCTX_EXTRN_CR2) 1437 { 1438 Assert(pInput->Names[iReg] == HvX64RegisterCr2); 1439 pCtx->cr2 = paValues[iReg].Reg64; 1440 iReg++; 1441 } 1442 if (fWhat & CPUMCTX_EXTRN_CR3) 1443 { 1444 Assert(pInput->Names[iReg] == HvX64RegisterCr3); 1445 if (pCtx->cr3 != paValues[iReg].Reg64) 1446 { 1447 CPUMSetGuestCR3(pVCpu, paValues[iReg].Reg64); 1448 fFlushTlb = true; 1449 } 1450 iReg++; 1451 } 1452 if (fWhat & CPUMCTX_EXTRN_CR4) 1453 { 1454 Assert(pInput->Names[iReg] == HvX64RegisterCr4); 1455 if (pCtx->cr4 != paValues[iReg].Reg64) 1456 { 1457 CPUMSetGuestCR4(pVCpu, paValues[iReg].Reg64); 1458 fMaybeChangedMode = true; 1459 fFlushTlb = fFlushGlobalTlb = true; /// @todo fix this 1460 } 1461 iReg++; 1462 } 1463 } 1464 1465 /// @todo CR8/TPR 1466 Assert(pInput->Names[iReg] == HvX64RegisterCr8); 1467 APICSetTpr(pVCpu, (uint8_t)paValues[iReg].Reg64 << 4); 1468 iReg++; 1124 1469 1125 1470 /* Debug registers. */ 1126 Assert(pInput->Names[33] == HvX64RegisterDr0);1127 1471 /** @todo fixme */ 1128 if (pCtx->dr[0] != paValues[33].Reg64) 1129 CPUMSetGuestDR0(pVCpu, paValues[33].Reg64); 1130 if (pCtx->dr[1] != paValues[34].Reg64) 1131 CPUMSetGuestDR1(pVCpu, paValues[34].Reg64); 1132 if (pCtx->dr[2] != paValues[35].Reg64) 1133 CPUMSetGuestDR2(pVCpu, paValues[35].Reg64); 1134 if (pCtx->dr[3] != paValues[36].Reg64) 1135 CPUMSetGuestDR3(pVCpu, paValues[36].Reg64); 1136 Assert(pInput->Names[37] == HvX64RegisterDr6); 1137 Assert(pInput->Names[38] == HvX64RegisterDr7); 1138 if (pCtx->dr[6] != paValues[37].Reg64) 1139 CPUMSetGuestDR6(pVCpu, paValues[37].Reg64); 1140 if (pCtx->dr[7] != paValues[38].Reg64) 1141 CPUMSetGuestDR6(pVCpu, paValues[38].Reg64); 1472 if (fWhat & CPUMCTX_EXTRN_DR0_DR3) 1473 { 1474 Assert(pInput->Names[iReg] == HvX64RegisterDr0); 1475 Assert(pInput->Names[iReg+3] == HvX64RegisterDr3); 1476 if (pCtx->dr[0] != paValues[iReg].Reg64) 1477 CPUMSetGuestDR0(pVCpu, paValues[iReg].Reg64); 1478 iReg++; 1479 if (pCtx->dr[1] != paValues[iReg].Reg64) 1480 CPUMSetGuestDR1(pVCpu, paValues[iReg].Reg64); 1481 iReg++; 1482 if (pCtx->dr[2] != paValues[iReg].Reg64) 1483 CPUMSetGuestDR2(pVCpu, paValues[iReg].Reg64); 1484 iReg++; 1485 if (pCtx->dr[3] != paValues[iReg].Reg64) 1486 CPUMSetGuestDR3(pVCpu, paValues[iReg].Reg64); 1487 iReg++; 1488 } 1489 if (fWhat & CPUMCTX_EXTRN_DR6) 1490 { 1491 Assert(pInput->Names[iReg] == HvX64RegisterDr6); 1492 if (pCtx->dr[6] != paValues[iReg].Reg64) 1493 CPUMSetGuestDR6(pVCpu, paValues[iReg].Reg64); 1494 iReg++; 1495 } 1496 if (fWhat & CPUMCTX_EXTRN_DR7) 1497 { 1498 Assert(pInput->Names[iReg] == HvX64RegisterDr7); 1499 if (pCtx->dr[7] != paValues[iReg].Reg64) 1500 CPUMSetGuestDR6(pVCpu, paValues[iReg].Reg64); 1501 iReg++; 1502 } 1503 1504 /* Floating point state. */ 1505 if (fWhat & CPUMCTX_EXTRN_X87) 1506 { 1507 Assert(pInput->Names[iReg] == HvX64RegisterFpMmx0); 1508 Assert(pInput->Names[iReg + 7] == HvX64RegisterFpMmx7); 1509 pCtx->pXStateR0->x87.aRegs[0].au64[0] = paValues[iReg].Fp.AsUINT128.Low64; 1510 pCtx->pXStateR0->x87.aRegs[0].au64[1] = paValues[iReg].Fp.AsUINT128.High64; 1511 iReg++; 1512 pCtx->pXStateR0->x87.aRegs[1].au64[0] = paValues[iReg].Fp.AsUINT128.Low64; 1513 pCtx->pXStateR0->x87.aRegs[1].au64[1] = paValues[iReg].Fp.AsUINT128.High64; 1514 iReg++; 1515 pCtx->pXStateR0->x87.aRegs[2].au64[0] = paValues[iReg].Fp.AsUINT128.Low64; 1516 pCtx->pXStateR0->x87.aRegs[2].au64[1] = paValues[iReg].Fp.AsUINT128.High64; 1517 iReg++; 1518 pCtx->pXStateR0->x87.aRegs[3].au64[0] = paValues[iReg].Fp.AsUINT128.Low64; 1519 pCtx->pXStateR0->x87.aRegs[3].au64[1] = paValues[iReg].Fp.AsUINT128.High64; 1520 iReg++; 1521 pCtx->pXStateR0->x87.aRegs[4].au64[0] = paValues[iReg].Fp.AsUINT128.Low64; 1522 pCtx->pXStateR0->x87.aRegs[4].au64[1] = paValues[iReg].Fp.AsUINT128.High64; 1523 iReg++; 1524 pCtx->pXStateR0->x87.aRegs[5].au64[0] = paValues[iReg].Fp.AsUINT128.Low64; 1525 pCtx->pXStateR0->x87.aRegs[5].au64[1] = paValues[iReg].Fp.AsUINT128.High64; 1526 iReg++; 1527 pCtx->pXStateR0->x87.aRegs[6].au64[0] = paValues[iReg].Fp.AsUINT128.Low64; 1528 pCtx->pXStateR0->x87.aRegs[6].au64[1] = paValues[iReg].Fp.AsUINT128.High64; 1529 iReg++; 1530 pCtx->pXStateR0->x87.aRegs[7].au64[0] = paValues[iReg].Fp.AsUINT128.Low64; 1531 pCtx->pXStateR0->x87.aRegs[7].au64[1] = paValues[iReg].Fp.AsUINT128.High64; 1532 iReg++; 1533 1534 Assert(pInput->Names[iReg] == HvX64RegisterFpControlStatus); 1535 pCtx->pXStateR0->x87.FCW = paValues[iReg].FpControlStatus.FpControl; 1536 pCtx->pXStateR0->x87.FSW = paValues[iReg].FpControlStatus.FpStatus; 1537 pCtx->pXStateR0->x87.FTW = paValues[iReg].FpControlStatus.FpTag 1538 /*| (paValues[iReg].FpControlStatus.Reserved << 8)*/; 1539 pCtx->pXStateR0->x87.FOP = paValues[iReg].FpControlStatus.LastFpOp; 1540 pCtx->pXStateR0->x87.FPUIP = (uint32_t)paValues[iReg].FpControlStatus.LastFpRip; 1541 pCtx->pXStateR0->x87.CS = (uint16_t)(paValues[iReg].FpControlStatus.LastFpRip >> 32); 1542 pCtx->pXStateR0->x87.Rsrvd1 = (uint16_t)(paValues[iReg].FpControlStatus.LastFpRip >> 48); 1543 iReg++; 1544 } 1545 1546 if (fWhat & (CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX)) 1547 { 1548 Assert(pInput->Names[iReg] == HvX64RegisterXmmControlStatus); 1549 if (fWhat & CPUMCTX_EXTRN_X87) 1550 { 1551 pCtx->pXStateR0->x87.FPUDP = (uint32_t)paValues[iReg].XmmControlStatus.LastFpRdp; 1552 pCtx->pXStateR0->x87.DS = (uint16_t)(paValues[iReg].XmmControlStatus.LastFpRdp >> 32); 1553 pCtx->pXStateR0->x87.Rsrvd2 = (uint16_t)(paValues[iReg].XmmControlStatus.LastFpRdp >> 48); 1554 } 1555 pCtx->pXStateR0->x87.MXCSR = paValues[iReg].XmmControlStatus.XmmStatusControl; 1556 pCtx->pXStateR0->x87.MXCSR_MASK = paValues[iReg].XmmControlStatus.XmmStatusControlMask; /** @todo ??? (Isn't this an output field?) */ 1557 iReg++; 1558 } 1142 1559 1143 1560 /* Vector state. */ 1144 Assert(pInput->Names[39] == HvX64RegisterXmm0); 1145 Assert(pInput->Names[54] == HvX64RegisterXmm15); 1146 pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Lo = paValues[39].Reg128.Low64; 1147 pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Hi = paValues[39].Reg128.High64; 1148 pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Lo = paValues[40].Reg128.Low64; 1149 pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Hi = paValues[40].Reg128.High64; 1150 pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Lo = paValues[41].Reg128.Low64; 1151 pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Hi = paValues[41].Reg128.High64; 1152 pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Lo = paValues[42].Reg128.Low64; 1153 pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Hi = paValues[42].Reg128.High64; 1154 pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Lo = paValues[43].Reg128.Low64; 1155 pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Hi = paValues[43].Reg128.High64; 1156 pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Lo = paValues[44].Reg128.Low64; 1157 pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Hi = paValues[44].Reg128.High64; 1158 pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Lo = paValues[45].Reg128.Low64; 1159 pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Hi = paValues[45].Reg128.High64; 1160 pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Lo = paValues[46].Reg128.Low64; 1161 pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Hi = paValues[46].Reg128.High64; 1162 pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Lo = paValues[47].Reg128.Low64; 1163 pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Hi = paValues[47].Reg128.High64; 1164 pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Lo = paValues[48].Reg128.Low64; 1165 pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Hi = paValues[48].Reg128.High64; 1166 pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Lo = paValues[49].Reg128.Low64; 1167 pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Hi = paValues[49].Reg128.High64; 1168 pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Lo = paValues[50].Reg128.Low64; 1169 pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Hi = paValues[50].Reg128.High64; 1170 pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Lo = paValues[51].Reg128.Low64; 1171 pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Hi = paValues[51].Reg128.High64; 1172 pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Lo = paValues[52].Reg128.Low64; 1173 pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Hi = paValues[52].Reg128.High64; 1174 pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Lo = paValues[53].Reg128.Low64; 1175 pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Hi = paValues[53].Reg128.High64; 1176 pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Lo = paValues[54].Reg128.Low64; 1177 pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Hi = paValues[54].Reg128.High64; 1178 1179 /* Floating point state. */ 1180 Assert(pInput->Names[55] == HvX64RegisterFpMmx0); 1181 Assert(pInput->Names[62] == HvX64RegisterFpMmx7); 1182 pCtx->pXStateR0->x87.aRegs[0].au64[0] = paValues[55].Fp.AsUINT128.Low64; 1183 pCtx->pXStateR0->x87.aRegs[0].au64[1] = paValues[55].Fp.AsUINT128.High64; 1184 pCtx->pXStateR0->x87.aRegs[1].au64[0] = paValues[56].Fp.AsUINT128.Low64; 1185 pCtx->pXStateR0->x87.aRegs[1].au64[1] = paValues[56].Fp.AsUINT128.High64; 1186 pCtx->pXStateR0->x87.aRegs[2].au64[0] = paValues[57].Fp.AsUINT128.Low64; 1187 pCtx->pXStateR0->x87.aRegs[2].au64[1] = paValues[57].Fp.AsUINT128.High64; 1188 pCtx->pXStateR0->x87.aRegs[3].au64[0] = paValues[58].Fp.AsUINT128.Low64; 1189 pCtx->pXStateR0->x87.aRegs[3].au64[1] = paValues[58].Fp.AsUINT128.High64; 1190 pCtx->pXStateR0->x87.aRegs[4].au64[0] = paValues[59].Fp.AsUINT128.Low64; 1191 pCtx->pXStateR0->x87.aRegs[4].au64[1] = paValues[59].Fp.AsUINT128.High64; 1192 pCtx->pXStateR0->x87.aRegs[5].au64[0] = paValues[60].Fp.AsUINT128.Low64; 1193 pCtx->pXStateR0->x87.aRegs[5].au64[1] = paValues[60].Fp.AsUINT128.High64; 1194 pCtx->pXStateR0->x87.aRegs[6].au64[0] = paValues[61].Fp.AsUINT128.Low64; 1195 pCtx->pXStateR0->x87.aRegs[6].au64[1] = paValues[61].Fp.AsUINT128.High64; 1196 pCtx->pXStateR0->x87.aRegs[7].au64[0] = paValues[62].Fp.AsUINT128.Low64; 1197 pCtx->pXStateR0->x87.aRegs[7].au64[1] = paValues[62].Fp.AsUINT128.High64; 1198 1199 Assert(pInput->Names[63] == HvX64RegisterFpControlStatus); 1200 pCtx->pXStateR0->x87.FCW = paValues[63].FpControlStatus.FpControl; 1201 pCtx->pXStateR0->x87.FSW = paValues[63].FpControlStatus.FpStatus; 1202 pCtx->pXStateR0->x87.FTW = paValues[63].FpControlStatus.FpTag 1203 /*| (paValues[63].FpControlStatus.Reserved << 8)*/; 1204 pCtx->pXStateR0->x87.FOP = paValues[63].FpControlStatus.LastFpOp; 1205 pCtx->pXStateR0->x87.FPUIP = (uint32_t)paValues[63].FpControlStatus.LastFpRip; 1206 pCtx->pXStateR0->x87.CS = (uint16_t)(paValues[63].FpControlStatus.LastFpRip >> 32); 1207 pCtx->pXStateR0->x87.Rsrvd1 = (uint16_t)(paValues[63].FpControlStatus.LastFpRip >> 48); 1208 1209 Assert(pInput->Names[64] == HvX64RegisterXmmControlStatus); 1210 pCtx->pXStateR0->x87.FPUDP = (uint32_t)paValues[64].XmmControlStatus.LastFpRdp; 1211 pCtx->pXStateR0->x87.DS = (uint16_t)(paValues[64].XmmControlStatus.LastFpRdp >> 32); 1212 pCtx->pXStateR0->x87.Rsrvd2 = (uint16_t)(paValues[64].XmmControlStatus.LastFpRdp >> 48); 1213 pCtx->pXStateR0->x87.MXCSR = paValues[64].XmmControlStatus.XmmStatusControl; 1214 pCtx->pXStateR0->x87.MXCSR_MASK = paValues[64].XmmControlStatus.XmmStatusControlMask; /** @todo ??? (Isn't this an output field?) */ 1561 if (fWhat & CPUMCTX_EXTRN_SSE_AVX) 1562 { 1563 Assert(pInput->Names[iReg] == HvX64RegisterXmm0); 1564 Assert(pInput->Names[iReg+15] == HvX64RegisterXmm15); 1565 pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Lo = paValues[iReg].Reg128.Low64; 1566 pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Hi = paValues[iReg].Reg128.High64; 1567 iReg++; 1568 pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Lo = paValues[iReg].Reg128.Low64; 1569 pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Hi = paValues[iReg].Reg128.High64; 1570 iReg++; 1571 pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Lo = paValues[iReg].Reg128.Low64; 1572 pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Hi = paValues[iReg].Reg128.High64; 1573 iReg++; 1574 pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Lo = paValues[iReg].Reg128.Low64; 1575 pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Hi = paValues[iReg].Reg128.High64; 1576 iReg++; 1577 pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Lo = paValues[iReg].Reg128.Low64; 1578 pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Hi = paValues[iReg].Reg128.High64; 1579 iReg++; 1580 pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Lo = paValues[iReg].Reg128.Low64; 1581 pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Hi = paValues[iReg].Reg128.High64; 1582 iReg++; 1583 pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Lo = paValues[iReg].Reg128.Low64; 1584 pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Hi = paValues[iReg].Reg128.High64; 1585 iReg++; 1586 pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Lo = paValues[iReg].Reg128.Low64; 1587 pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Hi = paValues[iReg].Reg128.High64; 1588 iReg++; 1589 pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Lo = paValues[iReg].Reg128.Low64; 1590 pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Hi = paValues[iReg].Reg128.High64; 1591 iReg++; 1592 pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Lo = paValues[iReg].Reg128.Low64; 1593 pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Hi = paValues[iReg].Reg128.High64; 1594 iReg++; 1595 pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Lo = paValues[iReg].Reg128.Low64; 1596 pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Hi = paValues[iReg].Reg128.High64; 1597 iReg++; 1598 pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Lo = paValues[iReg].Reg128.Low64; 1599 pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Hi = paValues[iReg].Reg128.High64; 1600 iReg++; 1601 pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Lo = paValues[iReg].Reg128.Low64; 1602 pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Hi = paValues[iReg].Reg128.High64; 1603 iReg++; 1604 pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Lo = paValues[iReg].Reg128.Low64; 1605 pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Hi = paValues[iReg].Reg128.High64; 1606 iReg++; 1607 pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Lo = paValues[iReg].Reg128.Low64; 1608 pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Hi = paValues[iReg].Reg128.High64; 1609 iReg++; 1610 pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Lo = paValues[iReg].Reg128.Low64; 1611 pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Hi = paValues[iReg].Reg128.High64; 1612 iReg++; 1613 } 1614 1215 1615 1216 1616 /* MSRs */ 1217 1617 // HvX64RegisterTsc - don't touch 1218 Assert(pInput->Names[65] == HvX64RegisterEfer); 1219 if (paValues[65].Reg64 != pCtx->msrEFER) 1220 { 1221 pCtx->msrEFER = paValues[65].Reg64; 1222 fMaybeChangedMode = true; 1223 } 1224 1225 Assert(pInput->Names[66] == HvX64RegisterKernelGsBase); 1226 pCtx->msrKERNELGSBASE = paValues[66].Reg64; 1227 1228 Assert(pInput->Names[67] == HvX64RegisterApicBase); 1229 if (paValues[67].Reg64 != APICGetBaseMsrNoCheck(pVCpu)) 1230 { 1231 VBOXSTRICTRC rc2 = APICSetBaseMsr(pVCpu, paValues[67].Reg64); 1232 Assert(rc2 == VINF_SUCCESS); NOREF(rc2); 1233 } 1234 1235 Assert(pInput->Names[68] == HvX64RegisterPat); 1236 pCtx->msrPAT = paValues[68].Reg64; 1237 /// @todo HvX64RegisterSysenterCs 1238 /// @todo HvX64RegisterSysenterEip 1239 /// @todo HvX64RegisterSysenterEsp 1240 Assert(pInput->Names[72] == HvX64RegisterStar); 1241 pCtx->msrSTAR = paValues[72].Reg64; 1242 Assert(pInput->Names[73] == HvX64RegisterLstar); 1243 pCtx->msrLSTAR = paValues[73].Reg64; 1244 Assert(pInput->Names[74] == HvX64RegisterCstar); 1245 pCtx->msrCSTAR = paValues[74].Reg64; 1246 Assert(pInput->Names[75] == HvX64RegisterSfmask); 1247 pCtx->msrSFMASK = paValues[75].Reg64; 1248 1618 if (fWhat & CPUMCTX_EXTRN_EFER) 1619 { 1620 Assert(pInput->Names[iReg] == HvX64RegisterEfer); 1621 if (paValues[iReg].Reg64 != pCtx->msrEFER) 1622 { 1623 pCtx->msrEFER = paValues[iReg].Reg64; 1624 fMaybeChangedMode = true; 1625 } 1626 iReg++; 1627 } 1628 if (fWhat & CPUMCTX_EXTRN_KERNEL_GS_BASE) 1629 { 1630 Assert(pInput->Names[iReg] == HvX64RegisterKernelGsBase); 1631 pCtx->msrKERNELGSBASE = paValues[iReg].Reg64; 1632 iReg++; 1633 } 1634 if (fWhat & CPUMCTX_EXTRN_SYSENTER_MSRS) 1635 { 1636 Assert(pInput->Names[iReg] == HvX64RegisterSysenterCs); 1637 pCtx->SysEnter.cs = paValues[iReg].Reg64; 1638 iReg++; 1639 Assert(pInput->Names[iReg] == HvX64RegisterSysenterEip); 1640 pCtx->SysEnter.eip = paValues[iReg].Reg64; 1641 iReg++; 1642 Assert(pInput->Names[iReg] == HvX64RegisterSysenterEsp); 1643 pCtx->SysEnter.esp = paValues[iReg].Reg64; 1644 iReg++; 1645 } 1646 if (fWhat & CPUMCTX_EXTRN_SYSCALL_MSRS) 1647 { 1648 Assert(pInput->Names[iReg] == HvX64RegisterStar); 1649 pCtx->msrSTAR = paValues[iReg].Reg64; 1650 iReg++; 1651 Assert(pInput->Names[iReg] == HvX64RegisterLstar); 1652 pCtx->msrLSTAR = paValues[iReg].Reg64; 1653 iReg++; 1654 Assert(pInput->Names[iReg] == HvX64RegisterCstar); 1655 pCtx->msrCSTAR = paValues[iReg].Reg64; 1656 iReg++; 1657 Assert(pInput->Names[iReg] == HvX64RegisterSfmask); 1658 pCtx->msrSFMASK = paValues[iReg].Reg64; 1659 iReg++; 1660 } 1661 if (fWhat & CPUMCTX_EXTRN_OTHER_MSRS) 1662 { 1663 Assert(pInput->Names[iReg] == HvX64RegisterApicBase); 1664 if (paValues[iReg].Reg64 != APICGetBaseMsrNoCheck(pVCpu)) 1665 { 1666 VBOXSTRICTRC rc2 = APICSetBaseMsr(pVCpu, paValues[iReg].Reg64); 1667 Assert(rc2 == VINF_SUCCESS); NOREF(rc2); 1668 } 1669 iReg++; 1670 1671 Assert(pInput->Names[iReg] == HvX64RegisterPat); 1672 pCtx->msrPAT = paValues[iReg].Reg64; 1673 iReg++; 1674 } 1675 1676 /* Event injection. */ 1249 1677 /// @todo HvRegisterPendingInterruption 1250 Assert(pInput->Names[ 76] == HvRegisterPendingInterruption);1251 if (paValues[ 76].PendingInterruption.InterruptionPending)1678 Assert(pInput->Names[iReg] == HvRegisterPendingInterruption); 1679 if (paValues[iReg].PendingInterruption.InterruptionPending) 1252 1680 { 1253 1681 Log7(("PendingInterruption: type=%u vector=%#x errcd=%RTbool/%#x instr-len=%u nested=%u\n", 1254 paValues[ 76].PendingInterruption.InterruptionType, paValues[76].PendingInterruption.InterruptionVector,1255 paValues[ 76].PendingInterruption.DeliverErrorCode, paValues[76].PendingInterruption.ErrorCode,1256 paValues[ 76].PendingInterruption.InstructionLength, paValues[76].PendingInterruption.NestedEvent));1257 AssertMsg((paValues[ 76].PendingInterruption.AsUINT64 & UINT64_C(0xfc00)) == 0,1258 ("%#RX64\n", paValues[ 76].PendingInterruption.AsUINT64));1682 paValues[iReg].PendingInterruption.InterruptionType, paValues[iReg].PendingInterruption.InterruptionVector, 1683 paValues[iReg].PendingInterruption.DeliverErrorCode, paValues[iReg].PendingInterruption.ErrorCode, 1684 paValues[iReg].PendingInterruption.InstructionLength, paValues[iReg].PendingInterruption.NestedEvent)); 1685 AssertMsg((paValues[iReg].PendingInterruption.AsUINT64 & UINT64_C(0xfc00)) == 0, 1686 ("%#RX64\n", paValues[iReg].PendingInterruption.AsUINT64)); 1259 1687 } 1260 1688 … … 1262 1690 /// @todo HvRegisterPendingEvent0 1263 1691 /// @todo HvRegisterPendingEvent1 1692 1693 /* Almost done, just update extrn flags and maybe change PGM mode. */ 1694 pCtx->fExtrn &= ~fWhat; 1264 1695 1265 1696 int rc = VINF_SUCCESS; … … 1287 1718 * @param idCpu The calling EMT. Necessary for getting the 1288 1719 * hypercall page and arguments. 1289 * @param fWhat What to import. To be defined, UINT64_MAX for now. 1720 * @param fWhat What to import, CPUMCTX_EXTRN_XXX. Set 1721 * CPUMCTX_EXTERN_ALL for everything. 1290 1722 */ 1291 VMMR0_INT_DECL(int) 1723 VMMR0_INT_DECL(int) NEMR0ImportState(PGVM pGVM, PVM pVM, VMCPUID idCpu, uint64_t fWhat) 1292 1724 { 1293 1725 /* -
trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
r71136 r71184 1997 1997 1998 1998 case VMMR0_DO_NEM_EXPORT_STATE: 1999 if ( pReqHdr || idCpu == NIL_VMCPUID)2000 return VERR_INVALID_PARAMETER; 2001 rc = NEMR0ExportState(pGVM, pVM, idCpu , u64Arg);1999 if (u64Arg || pReqHdr || idCpu == NIL_VMCPUID) 2000 return VERR_INVALID_PARAMETER; 2001 rc = NEMR0ExportState(pGVM, pVM, idCpu); 2002 2002 VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING); 2003 2003 break; -
trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp
r71152 r71184 210 210 # define WHvGetVirtualProcessorRegisters g_pfnWHvGetVirtualProcessorRegisters 211 211 # define WHvSetVirtualProcessorRegisters g_pfnWHvSetVirtualProcessorRegisters 212 213 # define VidMessageSlotHandleAndGetNext g_pfnVidMessageSlotHandleAndGetNext 214 # define VidStartVirtualProcessor g_pfnVidStartVirtualProcessor 215 # define VidStopVirtualProcessor g_pfnVidStopVirtualProcessor 216 212 217 #endif 213 218 … … 1337 1342 } 1338 1343 1339 1340 #ifdef LOG_ENABLED 1341 1344 #ifndef NEM_WIN_USE_OUR_OWN_RUN_API 1345 1346 # ifdef LOG_ENABLED 1342 1347 /** 1343 1348 * Log the full details of an exit reason. … … 1392 1397 break; 1393 1398 1394 # if 01399 # if 0 1395 1400 case WHvRunVpExitReasonUnrecoverableException: 1396 1401 case WHvRunVpExitReasonInvalidVpRegisterValue: … … 1410 1415 WHV_X64_UNSUPPORTED_FEATURE_CONTEXT UnsupportedFeature; 1411 1416 WHV_RUN_VP_CANCELED_CONTEXT CancelReason; 1412 # endif1417 # endif 1413 1418 1414 1419 case WHvRunVpExitReasonNone: … … 1455 1460 } 1456 1461 } 1457 1458 #endif /* LOG_ENABLED */ 1462 # endif /* LOG_ENABLED */ 1463 1464 1465 /** 1466 * Advances the guest RIP and clear EFLAGS.RF. 1467 * 1468 * This may clear VMCPU_FF_INHIBIT_INTERRUPTS. 1469 * 1470 * @param pVCpu The cross context virtual CPU structure. 1471 * @param pCtx The CPU context to update. 1472 * @param pExitCtx The exit context. 1473 */ 1474 DECLINLINE(void) nemR3WinAdvanceGuestRipAndClearRF(PVMCPU pVCpu, PCPUMCTX pCtx, WHV_VP_EXIT_CONTEXT const *pExitCtx) 1475 { 1476 /* Advance the RIP. */ 1477 Assert(pExitCtx->InstructionLength > 0 && pExitCtx->InstructionLength < 16); 1478 pCtx->rip += pExitCtx->InstructionLength; 1479 pCtx->rflags.Bits.u1RF = 0; 1480 1481 /* Update interrupt inhibition. */ 1482 if (!VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)) 1483 { /* likely */ } 1484 else if (pCtx->rip != EMGetInhibitInterruptsPC(pVCpu)) 1485 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS); 1486 } 1459 1487 1460 1488 … … 1467 1495 1468 1496 1469 # ifndef NEM_WIN_USE_HYPERCALLS_FOR_PAGES1497 # ifndef NEM_WIN_USE_HYPERCALLS_FOR_PAGES 1470 1498 /** 1471 1499 * @callback_method_impl{FNPGMPHYSNEMENUMCALLBACK, … … 1493 1521 return VINF_SUCCESS; 1494 1522 } 1495 # endif /* !NEM_WIN_USE_HYPERCALLS_FOR_PAGES */1523 # endif /* !NEM_WIN_USE_HYPERCALLS_FOR_PAGES */ 1496 1524 1497 1525 … … 1587 1615 pIoPortCtx->AccessInfo.AccessSize); 1588 1616 if (IOM_SUCCESS(rcStrict)) 1589 nem HCWinAdvanceGuestRipAndClearRF(pVCpu, pCtx, &pIoPortCtx->VpContext);1617 nemR3WinAdvanceGuestRipAndClearRF(pVCpu, pCtx, &pIoPortCtx->VpContext); 1590 1618 } 1591 1619 else … … 1597 1625 { 1598 1626 pCtx->eax = (pCtx->eax & ~fAndMask) | (uValue & fAndMask); 1599 nem HCWinAdvanceGuestRipAndClearRF(pVCpu, pCtx, &pIoPortCtx->VpContext);1627 nemR3WinAdvanceGuestRipAndClearRF(pVCpu, pCtx, &pIoPortCtx->VpContext); 1600 1628 } 1601 1629 } … … 1692 1720 VBOXSTRICTRC nemR3WinWHvRunGC(PVM pVM, PVMCPU pVCpu) 1693 1721 { 1694 # ifdef LOG_ENABLED1722 # ifdef LOG_ENABLED 1695 1723 if (LogIs3Enabled()) 1696 1724 { … … 1698 1726 nemHCWinLogState(pVM, pVCpu); 1699 1727 } 1700 # endif1728 # endif 1701 1729 1702 1730 /* … … 1725 1753 && !VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_TO_R3_MASK)) 1726 1754 { 1727 #ifdef NEM_WIN_USE_OUR_OWN_RUN_API1728 int rc2 = nemHCWinRunVirtualProcessor(pVM, pVCpu, &ExitReason, sizeof(ExitReason));1729 AssertRCBreakStmt(rc2, rcStrict = rc2);1730 #else1731 1755 Log8(("Calling WHvRunVirtualProcessor\n")); 1732 1756 VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED); … … 1739 1763 Log2(("WHvRunVirtualProcessor -> %#x; exit code %#x (%d) (cpu status %u)\n", 1740 1764 hrc, ExitReason.ExitReason, ExitReason.ExitReason, nemR3WinCpuGetRunningStatus(pVCpu) )); 1741 #endif1742 1765 } 1743 1766 else … … 1753 1776 AssertRCBreakStmt(rc2, rcStrict = rc2); 1754 1777 1755 # ifdef LOG_ENABLED1778 # ifdef LOG_ENABLED 1756 1779 /* 1757 1780 * Do some logging. … … 1761 1784 if (LogIs3Enabled()) 1762 1785 nemHCWinLogState(pVM, pVCpu); 1763 # endif1764 1765 # ifdef VBOX_STRICT1786 # endif 1787 1788 # ifdef VBOX_STRICT 1766 1789 /* Assert that the VpContext field makes sense. */ 1767 1790 switch (ExitReason.ExitReason) … … 1792 1815 default: break; /* shut up compiler. */ 1793 1816 } 1794 # endif1817 # endif 1795 1818 1796 1819 /* … … 1859 1882 } 1860 1883 1861 # ifndef NEM_WIN_USE_HYPERCALLS_FOR_PAGES1884 # ifndef NEM_WIN_USE_HYPERCALLS_FOR_PAGES 1862 1885 /* Hack alert! */ 1863 1886 uint32_t const cMappedPages = pVM->nem.s.cMappedPages; … … 1869 1892 Log(("nemR3NativeRunGC: Unmapped all; cMappedPages=%u -> %u\n", cMappedPages, pVM->nem.s.cMappedPages)); 1870 1893 } 1871 # endif1894 # endif 1872 1895 1873 1896 /* If any FF is pending, return to the EM loops. That's okay for the … … 1884 1907 } 1885 1908 1909 #endif /* !NEM_WIN_USE_OUR_OWN_RUN_API */ 1910 1886 1911 1887 1912 VBOXSTRICTRC nemR3NativeRunGC(PVM pVM, PVMCPU pVCpu) 1888 1913 { 1889 #if 11914 #ifndef NEM_WIN_USE_OUR_OWN_RUN_API 1890 1915 return nemR3WinWHvRunGC(pVM, pVCpu); 1891 1916 #elif 1 -
trunk/src/VBox/VMM/include/CPUMInternal.mac
r70732 r71184 230 230 .Guest.aoffXState resw 64 231 231 .Guest.fWorldSwitcher resd 1 232 .Guest.fExtrn resq 1 232 233 alignb 8 233 234 .Guest.hwvirt.svm.uMsrHSavePa resq 1 234 235 .Guest.hwvirt.svm.GCPhysVmcb resq 1 235 236 .Guest.hwvirt.svm.pVmcbR0 RTR0PTR_RES 1 237 alignb 8 236 238 .Guest.hwvirt.svm.pVmcbR3 RTR3PTR_RES 1 237 %if HC_ARCH_BITS == 32 238 .Guest.hwvirt.svm.abPadding0 resb 8 239 %endif 239 alignb 8 240 240 .Guest.hwvirt.svm.HostState resb 184 241 241 .Guest.hwvirt.svm.u16Padding0 resw 1 … … 245 245 .Guest.hwvirt.svm.fHMCachedVmcb resb 1 246 246 .Guest.hwvirt.svm.pvMsrBitmapR0 RTR0PTR_RES 1 247 alignb 8 247 248 .Guest.hwvirt.svm.pvMsrBitmapR3 RTR3PTR_RES 1 249 alignb 8 248 250 .Guest.hwvirt.svm.pvIoBitmapR0 RTR0PTR_RES 1 251 alignb 8 249 252 .Guest.hwvirt.svm.pvIoBitmapR3 RTR3PTR_RES 1 253 alignb 8 250 254 .Guest.hwvirt.svm.HCPhysVmcb RTHCPHYS_RES 1 251 %if HC_ARCH_BITS == 32252 .Guest.hwvirt.svm.abPadding2 resb 16253 %endif254 255 .Guest.hwvirt.fLocalForcedActions resd 1 255 256 .Guest.hwvirt.fGif resb 1 … … 516 517 .Hyper.aoffXState resw 64 517 518 .Hyper.fWorldSwitcher resd 1 519 .Hyper.fExtrn resq 1 518 520 alignb 8 519 521 .Hyper.hwvirt.svm.uMsrHSavePa resq 1 520 522 .Hyper.hwvirt.svm.GCPhysVmcb resq 1 521 523 .Hyper.hwvirt.svm.pVmcbR0 RTR0PTR_RES 1 524 alignb 8 522 525 .Hyper.hwvirt.svm.pVmcbR3 RTR3PTR_RES 1 523 %if HC_ARCH_BITS == 32 524 .Hyper.hwvirt.svm.abPadding0 resb 8 525 %endif 526 alignb 8 526 527 .Hyper.hwvirt.svm.HostState resb 184 527 528 .Hyper.hwvirt.svm.u16Padding0 resw 1 … … 531 532 .Hyper.hwvirt.svm.fHMCachedVmcb resb 1 532 533 .Hyper.hwvirt.svm.pvMsrBitmapR0 RTR0PTR_RES 1 534 alignb 8 533 535 .Hyper.hwvirt.svm.pvMsrBitmapR3 RTR3PTR_RES 1 536 alignb 8 534 537 .Hyper.hwvirt.svm.pvIoBitmapR0 RTR0PTR_RES 1 538 alignb 8 535 539 .Hyper.hwvirt.svm.pvIoBitmapR3 RTR3PTR_RES 1 540 alignb 8 536 541 .Hyper.hwvirt.svm.HCPhysVmcb RTHCPHYS_RES 1 537 %if HC_ARCH_BITS == 32538 .Hyper.hwvirt.svm.abPadding2 resb 16539 %endif540 542 .Hyper.hwvirt.fLocalForcedActions resd 1 541 543 .Hyper.hwvirt.fGif resb 1 -
trunk/src/VBox/VMM/include/NEMInternal.h
r71152 r71184 169 169 #ifdef RT_OS_WINDOWS 170 170 # ifdef NEM_WIN_USE_OUR_OWN_RUN_API 171 /** We've got a message pending (NEM_WIN_MSG_STATE_XXX). */ 172 uint8_t bMsgState; 171 /** The VID_MSHAGN_F_XXX flags. 172 * Either VID_MSHAGN_F_HANDLE_MESSAGE | VID_MSHAGN_F_GET_NEXT_MESSAGE or zero. */ 173 uint32_t fHandleAndGetFlags; 173 174 /** What VidMessageSlotMap returns and is used for passing exit info. */ 174 175 RTR3PTR pvMsgSlotMapping; … … 212 213 213 214 214 #if defined(RT_OS_WINDOWS) && defined(NEM_WIN_USE_OUR_OWN_RUN_API)215 /** @name NEM_WIN_MSG_STATE_XXX - Windows message handling state.216 * @{ */217 /** The CPU has not been started. */218 # define NEM_WIN_MSG_STATE_STOPPED UINT8_C(0x00)219 /** The CPU has been started, no messages are pending. */220 # define NEM_WIN_MSG_STATE_STARTED UINT8_C(0x01)221 /** Message is pending and needs to be ACKed. */222 # define NEM_WIN_MSG_STATE_PENDING_MSG UINT8_C(0x02)223 /** Both a message and execution stopping is pending. We need to ACK the224 * current message and get the stop message, then ACK the stop message before225 * the CPU can be started again. */226 # define NEM_WIN_MSG_STATE_PENDING_STOP_AND_MSG UINT8_C(0x03)227 /** @} */228 #endif229 230 231 232 215 #ifdef IN_RING0 233 216
Note:
See TracChangeset
for help on using the changeset viewer.