VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMR0/CPUMR0A.asm

Last change on this file was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.7 KB
RevLine 
[55059]1 ; $Id: CPUMR0A.asm 98103 2023-01-17 14:15:46Z vboxsync $
[14978]2;; @file
[55048]3; CPUM - Ring-0 Assembly Routines (supporting HM and IEM).
[14978]4;
5
6;
[98103]7; Copyright (C) 2006-2023 Oracle and/or its affiliates.
[14978]8;
[96407]9; This file is part of VirtualBox base platform packages, as
10; available from https://www.virtualbox.org.
[14978]11;
[96407]12; This program is free software; you can redistribute it and/or
13; modify it under the terms of the GNU General Public License
14; as published by the Free Software Foundation, in version 3 of the
15; License.
16;
17; This program is distributed in the hope that it will be useful, but
18; WITHOUT ANY WARRANTY; without even the implied warranty of
19; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20; General Public License for more details.
21;
22; You should have received a copy of the GNU General Public License
23; along with this program; if not, see <https://www.gnu.org/licenses>.
24;
25; SPDX-License-Identifier: GPL-3.0-only
26;
[14978]27
[61058]28
[14978]29;*******************************************************************************
30;* Header Files *
31;*******************************************************************************
[61058]32%define RT_ASM_WITH_SEH64
33%include "iprt/asmdefs.mac"
[14978]34%include "VBox/asmdefs.mac"
[35346]35%include "VBox/vmm/vm.mac"
[14978]36%include "VBox/err.mac"
[35346]37%include "VBox/vmm/stam.mac"
[14978]38%include "CPUMInternal.mac"
[37955]39%include "iprt/x86.mac"
[35346]40%include "VBox/vmm/cpum.mac"
[14978]41
42
[61144]43BEGINCODE
[15416]44
[61144]45;;
46; Makes sure the EMTs have a FPU state associated with them on hosts where we're
47; allowed to use it in ring-0 too.
48;
49; This ensure that we don't have to allocate the state lazily while trying to execute
50; guest code with preemption disabled or worse.
51;
52; @cproto VMMR0_INT_DECL(void) CPUMR0RegisterVCpuThread(PVMCPU pVCpu);
53;
54BEGINPROC CPUMR0RegisterVCpuThread
55 push xBP
56 SEH64_PUSH_xBP
57 mov xBP, xSP
58 SEH64_SET_FRAME_xBP 0
59SEH64_END_PROLOGUE
[20997]60
[61348]61%ifdef VMM_R0_TOUCH_FPU
62 movdqa xmm0, xmm0 ; hope this is harmless.
[61144]63%endif
[55106]64
[61144]65.return:
66 xor eax, eax ; paranoia
67 leave
68 ret
69ENDPROC CPUMR0RegisterVCpuThread
[14978]70
71
[61348]72%ifdef VMM_R0_TOUCH_FPU
[55106]73;;
[61348]74; Touches the host FPU state.
75;
76; @uses nothing (well, maybe cr0)
77;
[66878]78 %ifndef RT_ASM_WITH_SEH64 ; workaround for yasm 1.3.0 bug (error: prologue -1 bytes, must be <256)
[61348]79ALIGNCODE(16)
[66878]80 %endif
[61348]81BEGINPROC CPUMR0TouchHostFpu
82 push xBP
83 SEH64_PUSH_xBP
84 mov xBP, xSP
85 SEH64_SET_FRAME_xBP 0
86SEH64_END_PROLOGUE
87
88 movdqa xmm0, xmm0 ; Hope this is harmless.
89
90 leave
91 ret
92ENDPROC CPUMR0TouchHostFpu
93%endif ; VMM_R0_TOUCH_FPU
94
95
96;;
[55048]97; Saves the host FPU/SSE/AVX state and restores the guest FPU/SSE/AVX state.
[14978]98;
[61317]99; @returns VINF_SUCCESS (0) or VINF_CPUM_HOST_CR0_MODIFIED. (EAX)
[55059]100; @param pCpumCpu x86:[ebp+8] gcc:rdi msc:rcx CPUMCPU pointer
[14978]101;
[66878]102; @remarks 64-bit Windows drivers shouldn't use AVX registers without saving+loading:
103; https://msdn.microsoft.com/en-us/library/windows/hardware/ff545910%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
104; However the compiler docs have different idea:
105; https://msdn.microsoft.com/en-us/library/9z1stfyw.aspx
106; We'll go with the former for now.
107;
108%ifndef RT_ASM_WITH_SEH64 ; workaround for yasm 1.3.0 bug (error: prologue -1 bytes, must be <256)
[61348]109ALIGNCODE(16)
[66878]110%endif
[16108]111BEGINPROC cpumR0SaveHostRestoreGuestFPUState
[61058]112 push xBP
113 SEH64_PUSH_xBP
114 mov xBP, xSP
115 SEH64_SET_FRAME_xBP 0
116SEH64_END_PROLOGUE
117
[55048]118 ;
119 ; Prologue - xAX+xDX must be free for XSAVE/XRSTOR input.
120 ;
[16108]121%ifdef RT_ARCH_AMD64
122 %ifdef RT_OS_WINDOWS
[55048]123 mov r11, rcx
[16108]124 %else
[55048]125 mov r11, rdi
[16108]126 %endif
[55048]127 %define pCpumCpu r11
128 %define pXState r10
[16108]129%else
[55048]130 push ebx
131 push esi
[55059]132 mov ebx, dword [ebp + 8]
[55048]133 %define pCpumCpu ebx
134 %define pXState esi
[16108]135%endif
136
[55048]137 pushf ; The darwin kernel can get upset or upset things if an
138 cli ; interrupt occurs while we're doing fxsave/fxrstor/cr0.
[16108]139
[61058]140 ;
141 ; Save the host state.
142 ;
143 test dword [pCpumCpu + CPUMCPU.fUseFlags], CPUM_USED_FPU_HOST
144 jnz .already_saved_host
[61144]145
[61348]146 CPUMRZ_TOUCH_FPU_CLEAR_CR0_FPU_TRAPS_SET_RC xCX, xAX, pCpumCpu ; xCX is the return value for VT-x; xAX is scratch.
[61144]147
[55106]148 CPUMR0_SAVE_HOST
[61144]149
[61058]150%ifdef VBOX_WITH_KERNEL_USING_XMM
151 jmp .load_guest
152%endif
153.already_saved_host:
154%ifdef VBOX_WITH_KERNEL_USING_XMM
155 ; If we didn't save the host state, we must save the non-volatile XMM registers.
[91283]156 lea pXState, [pCpumCpu + CPUMCPU.Host.XState]
[66878]157 stmxcsr [pXState + X86FXSTATE.MXCSR]
[61068]158 movdqa [pXState + X86FXSTATE.xmm6 ], xmm6
159 movdqa [pXState + X86FXSTATE.xmm7 ], xmm7
160 movdqa [pXState + X86FXSTATE.xmm8 ], xmm8
161 movdqa [pXState + X86FXSTATE.xmm9 ], xmm9
162 movdqa [pXState + X86FXSTATE.xmm10], xmm10
163 movdqa [pXState + X86FXSTATE.xmm11], xmm11
164 movdqa [pXState + X86FXSTATE.xmm12], xmm12
165 movdqa [pXState + X86FXSTATE.xmm13], xmm13
166 movdqa [pXState + X86FXSTATE.xmm14], xmm14
167 movdqa [pXState + X86FXSTATE.xmm15], xmm15
[61058]168
169 ;
170 ; Load the guest state.
171 ;
172.load_guest:
173%endif
[55106]174 CPUMR0_LOAD_GUEST
[55048]175
[20997]176%ifdef VBOX_WITH_KERNEL_USING_XMM
[55048]177 ; Restore the non-volatile xmm registers. ASSUMING 64-bit host.
[91283]178 lea pXState, [pCpumCpu + CPUMCPU.Host.XState]
[61068]179 movdqa xmm6, [pXState + X86FXSTATE.xmm6]
180 movdqa xmm7, [pXState + X86FXSTATE.xmm7]
181 movdqa xmm8, [pXState + X86FXSTATE.xmm8]
182 movdqa xmm9, [pXState + X86FXSTATE.xmm9]
183 movdqa xmm10, [pXState + X86FXSTATE.xmm10]
184 movdqa xmm11, [pXState + X86FXSTATE.xmm11]
185 movdqa xmm12, [pXState + X86FXSTATE.xmm12]
186 movdqa xmm13, [pXState + X86FXSTATE.xmm13]
187 movdqa xmm14, [pXState + X86FXSTATE.xmm14]
188 movdqa xmm15, [pXState + X86FXSTATE.xmm15]
[66878]189 ldmxcsr [pXState + X86FXSTATE.MXCSR]
[20997]190%endif
191
[61058]192 or dword [pCpumCpu + CPUMCPU.fUseFlags], (CPUM_USED_FPU_GUEST | CPUM_USED_FPU_SINCE_REM | CPUM_USED_FPU_HOST)
[87361]193 mov byte [pCpumCpu + CPUMCPU.Guest.fUsedFpuGuest], 1
[55048]194 popf
[16108]195
[61348]196 mov eax, ecx
[61317]197.return:
[55048]198%ifdef RT_ARCH_X86
199 pop esi
200 pop ebx
[61058]201%endif
[55059]202 leave
[55048]203 ret
[16108]204ENDPROC cpumR0SaveHostRestoreGuestFPUState
205
[20540]206
[16113]207;;
[55048]208; Saves the guest FPU/SSE/AVX state and restores the host FPU/SSE/AVX state.
[16108]209;
[55059]210; @param pCpumCpu x86:[ebp+8] gcc:rdi msc:rcx CPUMCPU pointer
[16108]211;
[66878]212; @remarks 64-bit Windows drivers shouldn't use AVX registers without saving+loading:
213; https://msdn.microsoft.com/en-us/library/windows/hardware/ff545910%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
214; However the compiler docs have different idea:
215; https://msdn.microsoft.com/en-us/library/9z1stfyw.aspx
216; We'll go with the former for now.
217;
218%ifndef RT_ASM_WITH_SEH64 ; workaround for yasm 1.3.0 bug (error: prologue -1 bytes, must be <256)
[61348]219ALIGNCODE(16)
[66878]220%endif
[15416]221BEGINPROC cpumR0SaveGuestRestoreHostFPUState
[61058]222 push xBP
223 SEH64_PUSH_xBP
224 mov xBP, xSP
225 SEH64_SET_FRAME_xBP 0
226SEH64_END_PROLOGUE
227
[55048]228 ;
229 ; Prologue - xAX+xDX must be free for XSAVE/XRSTOR input.
230 ;
[14978]231%ifdef RT_ARCH_AMD64
232 %ifdef RT_OS_WINDOWS
[55048]233 mov r11, rcx
[14978]234 %else
[55048]235 mov r11, rdi
[14978]236 %endif
[55048]237 %define pCpumCpu r11
238 %define pXState r10
[14978]239%else
[55048]240 push ebx
241 push esi
[55059]242 mov ebx, dword [ebp + 8]
[61058]243 %define pCpumCpu ebx
244 %define pXState esi
[14978]245%endif
[61058]246 pushf ; The darwin kernel can get upset or upset things if an
247 cli ; interrupt occurs while we're doing fxsave/fxrstor/cr0.
[14978]248
[61058]249 %ifdef VBOX_WITH_KERNEL_USING_XMM
[55048]250 ;
[61058]251 ; Copy non-volatile XMM registers to the host state so we can use
252 ; them while saving the guest state (we've gotta do this anyway).
[55048]253 ;
[91283]254 lea pXState, [pCpumCpu + CPUMCPU.Host.XState]
[66878]255 stmxcsr [pXState + X86FXSTATE.MXCSR]
[61068]256 movdqa [pXState + X86FXSTATE.xmm6], xmm6
257 movdqa [pXState + X86FXSTATE.xmm7], xmm7
258 movdqa [pXState + X86FXSTATE.xmm8], xmm8
259 movdqa [pXState + X86FXSTATE.xmm9], xmm9
260 movdqa [pXState + X86FXSTATE.xmm10], xmm10
261 movdqa [pXState + X86FXSTATE.xmm11], xmm11
262 movdqa [pXState + X86FXSTATE.xmm12], xmm12
263 movdqa [pXState + X86FXSTATE.xmm13], xmm13
264 movdqa [pXState + X86FXSTATE.xmm14], xmm14
265 movdqa [pXState + X86FXSTATE.xmm15], xmm15
[61058]266 %endif
[14978]267
[61058]268 ;
269 ; Save the guest state if necessary.
270 ;
271 test dword [pCpumCpu + CPUMCPU.fUseFlags], CPUM_USED_FPU_GUEST
272 jz .load_only_host
[20535]273
[61058]274 %ifdef VBOX_WITH_KERNEL_USING_XMM
275 ; Load the guest XMM register values we already saved in HMR0VMXStartVMWrapXMM.
[91281]276 lea pXState, [pCpumCpu + CPUMCPU.Guest.XState]
[61068]277 movdqa xmm0, [pXState + X86FXSTATE.xmm0]
278 movdqa xmm1, [pXState + X86FXSTATE.xmm1]
279 movdqa xmm2, [pXState + X86FXSTATE.xmm2]
280 movdqa xmm3, [pXState + X86FXSTATE.xmm3]
281 movdqa xmm4, [pXState + X86FXSTATE.xmm4]
282 movdqa xmm5, [pXState + X86FXSTATE.xmm5]
283 movdqa xmm6, [pXState + X86FXSTATE.xmm6]
284 movdqa xmm7, [pXState + X86FXSTATE.xmm7]
285 movdqa xmm8, [pXState + X86FXSTATE.xmm8]
286 movdqa xmm9, [pXState + X86FXSTATE.xmm9]
287 movdqa xmm10, [pXState + X86FXSTATE.xmm10]
288 movdqa xmm11, [pXState + X86FXSTATE.xmm11]
289 movdqa xmm12, [pXState + X86FXSTATE.xmm12]
290 movdqa xmm13, [pXState + X86FXSTATE.xmm13]
291 movdqa xmm14, [pXState + X86FXSTATE.xmm14]
292 movdqa xmm15, [pXState + X86FXSTATE.xmm15]
[66878]293 ldmxcsr [pXState + X86FXSTATE.MXCSR]
[61058]294 %endif
[55106]295 CPUMR0_SAVE_GUEST
[61058]296
297 ;
298 ; Load the host state.
299 ;
300.load_only_host:
[55106]301 CPUMR0_LOAD_HOST
[14978]302
[61144]303 ; Restore the CR0 value we saved in cpumR0SaveHostRestoreGuestFPUState or
304 ; in cpumRZSaveHostFPUState.
305 mov xCX, [pCpumCpu + CPUMCPU.Host.cr0Fpu]
[61348]306 CPUMRZ_RESTORE_CR0_IF_TS_OR_EM_SET xCX
[61058]307 and dword [pCpumCpu + CPUMCPU.fUseFlags], ~(CPUM_USED_FPU_GUEST | CPUM_USED_FPU_HOST)
[87361]308 mov byte [pCpumCpu + CPUMCPU.Guest.fUsedFpuGuest], 0
[61058]309
[55048]310 popf
311%ifdef RT_ARCH_X86
312 pop esi
313 pop ebx
[61058]314%endif
[55059]315 leave
[55048]316 ret
317%undef pCpumCpu
318%undef pXState
[15416]319ENDPROC cpumR0SaveGuestRestoreHostFPUState
320
[16108]321
[61058]322%if ARCH_BITS == 32
323 %ifdef VBOX_WITH_64_BITS_GUESTS
[14978]324;;
[55048]325; Restores the host's FPU/SSE/AVX state from pCpumCpu->Host.
[14978]326;
[55059]327; @param pCpumCpu x86:[ebp+8] gcc:rdi msc:rcx CPUMCPU pointer
[14978]328;
[66878]329 %ifndef RT_ASM_WITH_SEH64 ; workaround for yasm 1.3.0 bug (error: prologue -1 bytes, must be <256)
[61348]330ALIGNCODE(16)
[66878]331 %endif
[15416]332BEGINPROC cpumR0RestoreHostFPUState
[55048]333 ;
334 ; Prologue - xAX+xDX must be free for XSAVE/XRSTOR input.
335 ;
[55059]336 push ebp
337 mov ebp, esp
[55048]338 push ebx
339 push esi
[55059]340 mov ebx, dword [ebp + 8]
[61058]341 %define pCpumCpu ebx
342 %define pXState esi
[14978]343
[55048]344 ;
[61058]345 ; Restore host CPU state.
[55048]346 ;
347 pushf ; The darwin kernel can get upset or upset things if an
348 cli ; interrupt occurs while we're doing fxsave/fxrstor/cr0.
[20535]349
[55106]350 CPUMR0_LOAD_HOST
[14978]351
[61144]352 ; Restore the CR0 value we saved in cpumR0SaveHostRestoreGuestFPUState or
353 ; in cpumRZSaveHostFPUState.
354 ;; @todo What about XCR0?
355 mov xCX, [pCpumCpu + CPUMCPU.Host.cr0Fpu]
[61348]356 CPUMRZ_RESTORE_CR0_IF_TS_OR_EM_SET xCX
357
[61058]358 and dword [pCpumCpu + CPUMCPU.fUseFlags], ~CPUM_USED_FPU_HOST
[55048]359 popf
360
361 pop esi
362 pop ebx
[55059]363 leave
[55048]364 ret
[61058]365 %undef pCpumCPu
366 %undef pXState
[15416]367ENDPROC cpumR0RestoreHostFPUState
[61058]368 %endif ; VBOX_WITH_64_BITS_GUESTS
369%endif ; ARCH_BITS == 32
[15416]370
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use