Changeset 87344 in vbox
- Timestamp:
- Jan 21, 2021 11:36:03 AM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HMR0A.asm
r87337 r87344 447 447 448 448 %ifdef VBOX_WITH_KERNEL_USING_XMM 449 450 449 ;; 451 450 ; Wrapper around vmx.pfnStartVM that preserves host XMM registers and … … 628 627 jmp .restore_non_volatile_host_xmm_regs 629 628 ENDPROC hmR0VMXStartVMWrapXMM 630 631 ;;632 ; Wrapper around svm.pfnVMRun that preserves host XMM registers and633 ; load the guest ones when necessary.634 ;635 ; @cproto DECLASM(int) hmR0SVMRunWrapXMM(PVM pVM, PVMCPU pVCpu, RTHCPHYS HCPhysVmcb, PFNHMSVMVMRUN pfnVMRun);636 ;637 ; @returns eax638 ;639 ; @param pVM msc:rcx640 ; @param pVCpu msc:rdx The cross context virtual CPU structure of the calling EMT.641 ; @param HCPhysVmcb msc:r8642 ; @param pfnVMRun msc:r9643 ;644 ; @remarks This is essentially the same code as hmR0VMXStartVMWrapXMM, only the parameters differ a little bit.645 ;646 ; @remarks Drivers shouldn't use AVX registers without saving+loading:647 ; https://msdn.microsoft.com/en-us/library/windows/hardware/ff545910%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396648 ; However the compiler docs have different idea:649 ; https://msdn.microsoft.com/en-us/library/9z1stfyw.aspx650 ; We'll go with the former for now.651 ;652 ; ASSUMING 64-bit and windows for now.653 ALIGNCODE(64)654 BEGINPROC hmR0SVMRunWrapXMM655 SEH64_END_PROLOGUE656 push xBP657 mov xBP, xSP658 sub xSP, 0b0h + 040h ; don't bother optimizing the frame size659 660 %ifndef ASM_CALL64_MSC661 %error "MSC only"662 %endif663 ; Spill input parameters.664 mov [xBP + 010h], rcx ; pVM665 mov [xBP + 018h], rdx ; pVCpu666 mov [xBP + 020h], r8 ; HCPhysVmcb667 mov [xBP + 028h], r9 ; pfnVMRun668 669 ; Ask CPUM whether we've started using the FPU yet.670 ;; @todo implement this in assembly, it's just checking a couple of things. Or have the C code do it.671 mov rcx, rdx ; pVCpu672 call NAME(CPUMIsGuestFPUStateActive)673 test al, al674 675 mov rcx, [xBP + 010h] ; pVM676 mov rdx, [xBP + 018h] ; pVCpu677 mov r8, [xBP + 020h] ; HCPhysVmcb678 mov r9, [xBP + 028h] ; pfnVMRun679 680 jnz .guest_fpu_state_active681 682 ; No need to mess with XMM registers just call the start routine and return.683 call r9684 685 leave686 ret687 688 ALIGNCODE(8)689 .guest_fpu_state_active:690 ; Save the non-volatile host XMM registers.691 ;; @todo change to rbp relative addressing as that saves a byte per instruction!692 movdqa [rsp + 040h + 000h], xmm6693 movdqa [rsp + 040h + 010h], xmm7694 movdqa [rsp + 040h + 020h], xmm8695 movdqa [rsp + 040h + 030h], xmm9696 movdqa [rsp + 040h + 040h], xmm10697 movdqa [rsp + 040h + 050h], xmm11698 movdqa [rsp + 040h + 060h], xmm12699 movdqa [rsp + 040h + 070h], xmm13700 movdqa [rsp + 040h + 080h], xmm14701 movdqa [rsp + 040h + 090h], xmm15702 stmxcsr [rsp + 040h + 0a0h]703 704 mov r11, rdx ; r11 = pVCpu (rdx may get trashed)705 mov eax, [rdx + VMCPU.cpum.GstCtx + CPUMCTX.fXStateMask]706 test eax, eax707 jz .guest_fpu_state_manually708 709 ;710 ; Using XSAVE.711 ;712 and eax, CPUM_VOLATILE_XSAVE_GUEST_COMPONENTS713 xor edx, edx714 mov r10, [r11 + VMCPU.cpum.GstCtx + CPUMCTX.pXStateR0]715 xrstor [r10]716 717 ; Make the call (same as in the other case).718 mov rdx, r11 ; restore pVCpu to rdx719 call r9720 721 mov r10d, eax ; save return value (xsave below uses eax)722 723 ; Save the guest XMM registers.724 mov rcx, [xBP + 018h] ; pVCpu725 mov eax, [rcx + VMCPU.cpum.GstCtx + CPUMCTX.fXStateMask]726 and eax, CPUM_VOLATILE_XSAVE_GUEST_COMPONENTS727 mov rcx, [rcx + VMCPU.cpum.GstCtx + CPUMCTX.pXStateR0]728 xor edx, edx729 xsave [rcx]730 731 mov eax, r10d ; restore return value732 733 .restore_non_volatile_host_xmm_regs:734 ; Load the non-volatile host XMM registers.735 ;; @todo change to rbp relative addressing as that saves a byte per instruction!736 movdqa xmm6, [rsp + 040h + 000h]737 movdqa xmm7, [rsp + 040h + 010h]738 movdqa xmm8, [rsp + 040h + 020h]739 movdqa xmm9, [rsp + 040h + 030h]740 movdqa xmm10, [rsp + 040h + 040h]741 movdqa xmm11, [rsp + 040h + 050h]742 movdqa xmm12, [rsp + 040h + 060h]743 movdqa xmm13, [rsp + 040h + 070h]744 movdqa xmm14, [rsp + 040h + 080h]745 movdqa xmm15, [rsp + 040h + 090h]746 ldmxcsr [rsp + 040h + 0a0h]747 leave748 ret749 750 ;751 ; No XSAVE, load and save the guest XMM registers manually.752 ;753 ALIGNCODE(8)754 .guest_fpu_state_manually:755 ; Load the full guest XMM register state.756 mov rdx, [r11 + VMCPU.cpum.GstCtx + CPUMCTX.pXStateR0]757 movdqa xmm0, [rdx + XMM_OFF_IN_X86FXSTATE + 000h]758 movdqa xmm1, [rdx + XMM_OFF_IN_X86FXSTATE + 010h]759 movdqa xmm2, [rdx + XMM_OFF_IN_X86FXSTATE + 020h]760 movdqa xmm3, [rdx + XMM_OFF_IN_X86FXSTATE + 030h]761 movdqa xmm4, [rdx + XMM_OFF_IN_X86FXSTATE + 040h]762 movdqa xmm5, [rdx + XMM_OFF_IN_X86FXSTATE + 050h]763 movdqa xmm6, [rdx + XMM_OFF_IN_X86FXSTATE + 060h]764 movdqa xmm7, [rdx + XMM_OFF_IN_X86FXSTATE + 070h]765 movdqa xmm8, [rdx + XMM_OFF_IN_X86FXSTATE + 080h]766 movdqa xmm9, [rdx + XMM_OFF_IN_X86FXSTATE + 090h]767 movdqa xmm10, [rdx + XMM_OFF_IN_X86FXSTATE + 0a0h]768 movdqa xmm11, [rdx + XMM_OFF_IN_X86FXSTATE + 0b0h]769 movdqa xmm12, [rdx + XMM_OFF_IN_X86FXSTATE + 0c0h]770 movdqa xmm13, [rdx + XMM_OFF_IN_X86FXSTATE + 0d0h]771 movdqa xmm14, [rdx + XMM_OFF_IN_X86FXSTATE + 0e0h]772 movdqa xmm15, [rdx + XMM_OFF_IN_X86FXSTATE + 0f0h]773 ldmxcsr [rdx + X86FXSTATE.MXCSR]774 775 ; Make the call (same as in the other case).776 mov rdx, r11 ; restore pVCpu to rdx777 call r9778 779 ; Save the guest XMM registers.780 mov rdx, [xBP + 018h] ; pVCpu781 mov rdx, [rdx + VMCPU.cpum.GstCtx + CPUMCTX.pXStateR0]782 stmxcsr [rdx + X86FXSTATE.MXCSR]783 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 000h], xmm0784 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 010h], xmm1785 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 020h], xmm2786 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 030h], xmm3787 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 040h], xmm4788 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 050h], xmm5789 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 060h], xmm6790 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 070h], xmm7791 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 080h], xmm8792 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 090h], xmm9793 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 0a0h], xmm10794 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 0b0h], xmm11795 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 0c0h], xmm12796 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 0d0h], xmm13797 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 0e0h], xmm14798 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 0f0h], xmm15799 jmp .restore_non_volatile_host_xmm_regs800 ENDPROC hmR0SVMRunWrapXMM801 802 629 %endif ; VBOX_WITH_KERNEL_USING_XMM 803 630 … … 1089 916 1090 917 918 %ifdef VBOX_WITH_KERNEL_USING_XMM 919 ;; 920 ; Wrapper around svm.pfnVMRun that preserves host XMM registers and 921 ; load the guest ones when necessary. 922 ; 923 ; @cproto DECLASM(int) hmR0SVMRunWrapXMM(PVM pVM, PVMCPU pVCpu, RTHCPHYS HCPhysVmcb, PFNHMSVMVMRUN pfnVMRun); 924 ; 925 ; @returns eax 926 ; 927 ; @param pVM msc:rcx 928 ; @param pVCpu msc:rdx The cross context virtual CPU structure of the calling EMT. 929 ; @param HCPhysVmcb msc:r8 930 ; @param pfnVMRun msc:r9 931 ; 932 ; @remarks This is essentially the same code as hmR0VMXStartVMWrapXMM, only the parameters differ a little bit. 933 ; 934 ; @remarks Drivers shouldn't use AVX registers without saving+loading: 935 ; https://msdn.microsoft.com/en-us/library/windows/hardware/ff545910%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396 936 ; However the compiler docs have different idea: 937 ; https://msdn.microsoft.com/en-us/library/9z1stfyw.aspx 938 ; We'll go with the former for now. 939 ; 940 ; ASSUMING 64-bit and windows for now. 941 ALIGNCODE(64) 942 BEGINPROC hmR0SVMRunWrapXMM 943 SEH64_END_PROLOGUE 944 push xBP 945 mov xBP, xSP 946 sub xSP, 0b0h + 040h ; don't bother optimizing the frame size 947 948 %ifndef ASM_CALL64_MSC 949 %error "MSC only" 950 %endif 951 ; Spill input parameters. 952 mov [xBP + 010h], rcx ; pVM 953 mov [xBP + 018h], rdx ; pVCpu 954 mov [xBP + 020h], r8 ; HCPhysVmcb 955 mov [xBP + 028h], r9 ; pfnVMRun 956 957 ; Ask CPUM whether we've started using the FPU yet. 958 ;; @todo implement this in assembly, it's just checking a couple of things. Or have the C code do it. 959 mov rcx, rdx ; pVCpu 960 call NAME(CPUMIsGuestFPUStateActive) 961 test al, al 962 963 mov rcx, [xBP + 010h] ; pVM 964 mov rdx, [xBP + 018h] ; pVCpu 965 mov r8, [xBP + 020h] ; HCPhysVmcb 966 mov r9, [xBP + 028h] ; pfnVMRun 967 968 jnz .guest_fpu_state_active 969 970 ; No need to mess with XMM registers just call the start routine and return. 971 call r9 972 973 leave 974 ret 975 976 ALIGNCODE(8) 977 .guest_fpu_state_active: 978 ; Save the non-volatile host XMM registers. 979 ;; @todo change to rbp relative addressing as that saves a byte per instruction! 980 movdqa [rsp + 040h + 000h], xmm6 981 movdqa [rsp + 040h + 010h], xmm7 982 movdqa [rsp + 040h + 020h], xmm8 983 movdqa [rsp + 040h + 030h], xmm9 984 movdqa [rsp + 040h + 040h], xmm10 985 movdqa [rsp + 040h + 050h], xmm11 986 movdqa [rsp + 040h + 060h], xmm12 987 movdqa [rsp + 040h + 070h], xmm13 988 movdqa [rsp + 040h + 080h], xmm14 989 movdqa [rsp + 040h + 090h], xmm15 990 stmxcsr [rsp + 040h + 0a0h] 991 992 mov r11, rdx ; r11 = pVCpu (rdx may get trashed) 993 mov eax, [rdx + VMCPU.cpum.GstCtx + CPUMCTX.fXStateMask] 994 test eax, eax 995 jz .guest_fpu_state_manually 996 997 ; 998 ; Using XSAVE. 999 ; 1000 and eax, CPUM_VOLATILE_XSAVE_GUEST_COMPONENTS 1001 xor edx, edx 1002 mov r10, [r11 + VMCPU.cpum.GstCtx + CPUMCTX.pXStateR0] 1003 xrstor [r10] 1004 1005 ; Make the call (same as in the other case). 1006 mov rdx, r11 ; restore pVCpu to rdx 1007 call r9 1008 1009 mov r10d, eax ; save return value (xsave below uses eax) 1010 1011 ; Save the guest XMM registers. 1012 mov rcx, [xBP + 018h] ; pVCpu 1013 mov eax, [rcx + VMCPU.cpum.GstCtx + CPUMCTX.fXStateMask] 1014 and eax, CPUM_VOLATILE_XSAVE_GUEST_COMPONENTS 1015 mov rcx, [rcx + VMCPU.cpum.GstCtx + CPUMCTX.pXStateR0] 1016 xor edx, edx 1017 xsave [rcx] 1018 1019 mov eax, r10d ; restore return value 1020 1021 .restore_non_volatile_host_xmm_regs: 1022 ; Load the non-volatile host XMM registers. 1023 ;; @todo change to rbp relative addressing as that saves a byte per instruction! 1024 movdqa xmm6, [rsp + 040h + 000h] 1025 movdqa xmm7, [rsp + 040h + 010h] 1026 movdqa xmm8, [rsp + 040h + 020h] 1027 movdqa xmm9, [rsp + 040h + 030h] 1028 movdqa xmm10, [rsp + 040h + 040h] 1029 movdqa xmm11, [rsp + 040h + 050h] 1030 movdqa xmm12, [rsp + 040h + 060h] 1031 movdqa xmm13, [rsp + 040h + 070h] 1032 movdqa xmm14, [rsp + 040h + 080h] 1033 movdqa xmm15, [rsp + 040h + 090h] 1034 ldmxcsr [rsp + 040h + 0a0h] 1035 leave 1036 ret 1037 1038 ; 1039 ; No XSAVE, load and save the guest XMM registers manually. 1040 ; 1041 ALIGNCODE(8) 1042 .guest_fpu_state_manually: 1043 ; Load the full guest XMM register state. 1044 mov rdx, [r11 + VMCPU.cpum.GstCtx + CPUMCTX.pXStateR0] 1045 movdqa xmm0, [rdx + XMM_OFF_IN_X86FXSTATE + 000h] 1046 movdqa xmm1, [rdx + XMM_OFF_IN_X86FXSTATE + 010h] 1047 movdqa xmm2, [rdx + XMM_OFF_IN_X86FXSTATE + 020h] 1048 movdqa xmm3, [rdx + XMM_OFF_IN_X86FXSTATE + 030h] 1049 movdqa xmm4, [rdx + XMM_OFF_IN_X86FXSTATE + 040h] 1050 movdqa xmm5, [rdx + XMM_OFF_IN_X86FXSTATE + 050h] 1051 movdqa xmm6, [rdx + XMM_OFF_IN_X86FXSTATE + 060h] 1052 movdqa xmm7, [rdx + XMM_OFF_IN_X86FXSTATE + 070h] 1053 movdqa xmm8, [rdx + XMM_OFF_IN_X86FXSTATE + 080h] 1054 movdqa xmm9, [rdx + XMM_OFF_IN_X86FXSTATE + 090h] 1055 movdqa xmm10, [rdx + XMM_OFF_IN_X86FXSTATE + 0a0h] 1056 movdqa xmm11, [rdx + XMM_OFF_IN_X86FXSTATE + 0b0h] 1057 movdqa xmm12, [rdx + XMM_OFF_IN_X86FXSTATE + 0c0h] 1058 movdqa xmm13, [rdx + XMM_OFF_IN_X86FXSTATE + 0d0h] 1059 movdqa xmm14, [rdx + XMM_OFF_IN_X86FXSTATE + 0e0h] 1060 movdqa xmm15, [rdx + XMM_OFF_IN_X86FXSTATE + 0f0h] 1061 ldmxcsr [rdx + X86FXSTATE.MXCSR] 1062 1063 ; Make the call (same as in the other case). 1064 mov rdx, r11 ; restore pVCpu to rdx 1065 call r9 1066 1067 ; Save the guest XMM registers. 1068 mov rdx, [xBP + 018h] ; pVCpu 1069 mov rdx, [rdx + VMCPU.cpum.GstCtx + CPUMCTX.pXStateR0] 1070 stmxcsr [rdx + X86FXSTATE.MXCSR] 1071 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 000h], xmm0 1072 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 010h], xmm1 1073 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 020h], xmm2 1074 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 030h], xmm3 1075 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 040h], xmm4 1076 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 050h], xmm5 1077 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 060h], xmm6 1078 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 070h], xmm7 1079 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 080h], xmm8 1080 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 090h], xmm9 1081 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 0a0h], xmm10 1082 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 0b0h], xmm11 1083 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 0c0h], xmm12 1084 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 0d0h], xmm13 1085 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 0e0h], xmm14 1086 movdqa [rdx + XMM_OFF_IN_X86FXSTATE + 0f0h], xmm15 1087 jmp .restore_non_volatile_host_xmm_regs 1088 ENDPROC hmR0SVMRunWrapXMM 1089 1090 %endif ; VBOX_WITH_KERNEL_USING_XMM 1091 1091 1092 ;; 1092 1093 ; Prepares for and executes VMRUN (32-bit and 64-bit guests).
Note:
See TracChangeset
for help on using the changeset viewer.