VirtualBox

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

Last change on this file since 94800 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

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

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