VirtualBox

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

Last change on this file since 84044 was 82968, checked in by vboxsync, 4 years 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.3 KB
Line 
1 ; $Id: CPUMR0A.asm 82968 2020-02-04 10:35:17Z vboxsync $
2;; @file
3; CPUM - Ring-0 Assembly Routines (supporting HM and IEM).
4;
5
6;
7; Copyright (C) 2006-2020 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 mov pXState, [pCpumCpu + CPUMCPU.Host.pXStateR0]
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 mov pXState, [pCpumCpu + CPUMCPU.Host.pXStateR0]
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 popf
184
185 mov eax, ecx
186.return:
187%ifdef RT_ARCH_X86
188 pop esi
189 pop ebx
190%endif
191 leave
192 ret
193ENDPROC cpumR0SaveHostRestoreGuestFPUState
194
195
196;;
197; Saves the guest FPU/SSE/AVX state and restores the host FPU/SSE/AVX state.
198;
199; @param pCpumCpu x86:[ebp+8] gcc:rdi msc:rcx CPUMCPU pointer
200;
201; @remarks 64-bit Windows drivers shouldn't use AVX registers without saving+loading:
202; https://msdn.microsoft.com/en-us/library/windows/hardware/ff545910%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
203; However the compiler docs have different idea:
204; https://msdn.microsoft.com/en-us/library/9z1stfyw.aspx
205; We'll go with the former for now.
206;
207%ifndef RT_ASM_WITH_SEH64 ; workaround for yasm 1.3.0 bug (error: prologue -1 bytes, must be <256)
208ALIGNCODE(16)
209%endif
210BEGINPROC cpumR0SaveGuestRestoreHostFPUState
211 push xBP
212 SEH64_PUSH_xBP
213 mov xBP, xSP
214 SEH64_SET_FRAME_xBP 0
215SEH64_END_PROLOGUE
216
217 ;
218 ; Prologue - xAX+xDX must be free for XSAVE/XRSTOR input.
219 ;
220%ifdef RT_ARCH_AMD64
221 %ifdef RT_OS_WINDOWS
222 mov r11, rcx
223 %else
224 mov r11, rdi
225 %endif
226 %define pCpumCpu r11
227 %define pXState r10
228%else
229 push ebx
230 push esi
231 mov ebx, dword [ebp + 8]
232 %define pCpumCpu ebx
233 %define pXState esi
234%endif
235 pushf ; The darwin kernel can get upset or upset things if an
236 cli ; interrupt occurs while we're doing fxsave/fxrstor/cr0.
237
238 %ifdef VBOX_WITH_KERNEL_USING_XMM
239 ;
240 ; Copy non-volatile XMM registers to the host state so we can use
241 ; them while saving the guest state (we've gotta do this anyway).
242 ;
243 mov pXState, [pCpumCpu + CPUMCPU.Host.pXStateR0]
244 stmxcsr [pXState + X86FXSTATE.MXCSR]
245 movdqa [pXState + X86FXSTATE.xmm6], xmm6
246 movdqa [pXState + X86FXSTATE.xmm7], xmm7
247 movdqa [pXState + X86FXSTATE.xmm8], xmm8
248 movdqa [pXState + X86FXSTATE.xmm9], xmm9
249 movdqa [pXState + X86FXSTATE.xmm10], xmm10
250 movdqa [pXState + X86FXSTATE.xmm11], xmm11
251 movdqa [pXState + X86FXSTATE.xmm12], xmm12
252 movdqa [pXState + X86FXSTATE.xmm13], xmm13
253 movdqa [pXState + X86FXSTATE.xmm14], xmm14
254 movdqa [pXState + X86FXSTATE.xmm15], xmm15
255 %endif
256
257 ;
258 ; Save the guest state if necessary.
259 ;
260 test dword [pCpumCpu + CPUMCPU.fUseFlags], CPUM_USED_FPU_GUEST
261 jz .load_only_host
262
263 %ifdef VBOX_WITH_KERNEL_USING_XMM
264 ; Load the guest XMM register values we already saved in HMR0VMXStartVMWrapXMM.
265 mov pXState, [pCpumCpu + CPUMCPU.Guest.pXStateR0]
266 movdqa xmm0, [pXState + X86FXSTATE.xmm0]
267 movdqa xmm1, [pXState + X86FXSTATE.xmm1]
268 movdqa xmm2, [pXState + X86FXSTATE.xmm2]
269 movdqa xmm3, [pXState + X86FXSTATE.xmm3]
270 movdqa xmm4, [pXState + X86FXSTATE.xmm4]
271 movdqa xmm5, [pXState + X86FXSTATE.xmm5]
272 movdqa xmm6, [pXState + X86FXSTATE.xmm6]
273 movdqa xmm7, [pXState + X86FXSTATE.xmm7]
274 movdqa xmm8, [pXState + X86FXSTATE.xmm8]
275 movdqa xmm9, [pXState + X86FXSTATE.xmm9]
276 movdqa xmm10, [pXState + X86FXSTATE.xmm10]
277 movdqa xmm11, [pXState + X86FXSTATE.xmm11]
278 movdqa xmm12, [pXState + X86FXSTATE.xmm12]
279 movdqa xmm13, [pXState + X86FXSTATE.xmm13]
280 movdqa xmm14, [pXState + X86FXSTATE.xmm14]
281 movdqa xmm15, [pXState + X86FXSTATE.xmm15]
282 ldmxcsr [pXState + X86FXSTATE.MXCSR]
283 %endif
284 CPUMR0_SAVE_GUEST
285
286 ;
287 ; Load the host state.
288 ;
289.load_only_host:
290 CPUMR0_LOAD_HOST
291
292 ; Restore the CR0 value we saved in cpumR0SaveHostRestoreGuestFPUState or
293 ; in cpumRZSaveHostFPUState.
294 mov xCX, [pCpumCpu + CPUMCPU.Host.cr0Fpu]
295 CPUMRZ_RESTORE_CR0_IF_TS_OR_EM_SET xCX
296 and dword [pCpumCpu + CPUMCPU.fUseFlags], ~(CPUM_USED_FPU_GUEST | CPUM_USED_FPU_HOST)
297
298 popf
299%ifdef RT_ARCH_X86
300 pop esi
301 pop ebx
302%endif
303 leave
304 ret
305%undef pCpumCpu
306%undef pXState
307ENDPROC cpumR0SaveGuestRestoreHostFPUState
308
309
310%if ARCH_BITS == 32
311 %ifdef VBOX_WITH_64_BITS_GUESTS
312;;
313; Restores the host's FPU/SSE/AVX state from pCpumCpu->Host.
314;
315; @param pCpumCpu x86:[ebp+8] gcc:rdi msc:rcx CPUMCPU pointer
316;
317 %ifndef RT_ASM_WITH_SEH64 ; workaround for yasm 1.3.0 bug (error: prologue -1 bytes, must be <256)
318ALIGNCODE(16)
319 %endif
320BEGINPROC cpumR0RestoreHostFPUState
321 ;
322 ; Prologue - xAX+xDX must be free for XSAVE/XRSTOR input.
323 ;
324 push ebp
325 mov ebp, esp
326 push ebx
327 push esi
328 mov ebx, dword [ebp + 8]
329 %define pCpumCpu ebx
330 %define pXState esi
331
332 ;
333 ; Restore host CPU state.
334 ;
335 pushf ; The darwin kernel can get upset or upset things if an
336 cli ; interrupt occurs while we're doing fxsave/fxrstor/cr0.
337
338 CPUMR0_LOAD_HOST
339
340 ; Restore the CR0 value we saved in cpumR0SaveHostRestoreGuestFPUState or
341 ; in cpumRZSaveHostFPUState.
342 ;; @todo What about XCR0?
343 mov xCX, [pCpumCpu + CPUMCPU.Host.cr0Fpu]
344 CPUMRZ_RESTORE_CR0_IF_TS_OR_EM_SET xCX
345
346 and dword [pCpumCpu + CPUMCPU.fUseFlags], ~CPUM_USED_FPU_HOST
347 popf
348
349 pop esi
350 pop ebx
351 leave
352 ret
353 %undef pCpumCPu
354 %undef pXState
355ENDPROC cpumR0RestoreHostFPUState
356 %endif ; VBOX_WITH_64_BITS_GUESTS
357%endif ; ARCH_BITS == 32
358
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use