VirtualBox

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

Last change on this file since 66250 was 61348, checked in by vboxsync, 8 years ago

CPUM,VMM: Touch the FPU state before doing HM on all platforms which allows us do (VMM_R0_TOUCH_FPU, see Makefile.kmk). No special treatment of win.amd64 (could save a CR0 read, maybe). Cleaned up the fix from this morning.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.0 KB
Line 
1 ; $Id: CPUMR0A.asm 61348 2016-05-31 17:59:34Z vboxsync $
2;; @file
3; CPUM - Ring-0 Assembly Routines (supporting HM and IEM).
4;
5
6;
7; Copyright (C) 2006-2016 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;
68ALIGNCODE(16)
69BEGINPROC CPUMR0TouchHostFpu
70 push xBP
71 SEH64_PUSH_xBP
72 mov xBP, xSP
73 SEH64_SET_FRAME_xBP 0
74SEH64_END_PROLOGUE
75
76 movdqa xmm0, xmm0 ; Hope this is harmless.
77
78 leave
79 ret
80ENDPROC CPUMR0TouchHostFpu
81%endif ; VMM_R0_TOUCH_FPU
82
83
84;;
85; Saves the host FPU/SSE/AVX state and restores the guest FPU/SSE/AVX state.
86;
87; @returns VINF_SUCCESS (0) or VINF_CPUM_HOST_CR0_MODIFIED. (EAX)
88; @param pCpumCpu x86:[ebp+8] gcc:rdi msc:rcx CPUMCPU pointer
89;
90ALIGNCODE(16)
91BEGINPROC cpumR0SaveHostRestoreGuestFPUState
92 push xBP
93 SEH64_PUSH_xBP
94 mov xBP, xSP
95 SEH64_SET_FRAME_xBP 0
96SEH64_END_PROLOGUE
97
98 ;
99 ; Prologue - xAX+xDX must be free for XSAVE/XRSTOR input.
100 ;
101%ifdef RT_ARCH_AMD64
102 %ifdef RT_OS_WINDOWS
103 mov r11, rcx
104 %else
105 mov r11, rdi
106 %endif
107 %define pCpumCpu r11
108 %define pXState r10
109%else
110 push ebx
111 push esi
112 mov ebx, dword [ebp + 8]
113 %define pCpumCpu ebx
114 %define pXState esi
115%endif
116
117 pushf ; The darwin kernel can get upset or upset things if an
118 cli ; interrupt occurs while we're doing fxsave/fxrstor/cr0.
119
120 ;
121 ; Save the host state.
122 ;
123 test dword [pCpumCpu + CPUMCPU.fUseFlags], CPUM_USED_FPU_HOST
124 jnz .already_saved_host
125
126 CPUMRZ_TOUCH_FPU_CLEAR_CR0_FPU_TRAPS_SET_RC xCX, xAX, pCpumCpu ; xCX is the return value for VT-x; xAX is scratch.
127
128 CPUMR0_SAVE_HOST
129
130%ifdef VBOX_WITH_KERNEL_USING_XMM
131 jmp .load_guest
132%endif
133.already_saved_host:
134%ifdef VBOX_WITH_KERNEL_USING_XMM
135 ; If we didn't save the host state, we must save the non-volatile XMM registers.
136 mov pXState, [pCpumCpu + CPUMCPU.Host.pXStateR0]
137 movdqa [pXState + X86FXSTATE.xmm6 ], xmm6
138 movdqa [pXState + X86FXSTATE.xmm7 ], xmm7
139 movdqa [pXState + X86FXSTATE.xmm8 ], xmm8
140 movdqa [pXState + X86FXSTATE.xmm9 ], xmm9
141 movdqa [pXState + X86FXSTATE.xmm10], xmm10
142 movdqa [pXState + X86FXSTATE.xmm11], xmm11
143 movdqa [pXState + X86FXSTATE.xmm12], xmm12
144 movdqa [pXState + X86FXSTATE.xmm13], xmm13
145 movdqa [pXState + X86FXSTATE.xmm14], xmm14
146 movdqa [pXState + X86FXSTATE.xmm15], xmm15
147
148 ;
149 ; Load the guest state.
150 ;
151.load_guest:
152%endif
153 CPUMR0_LOAD_GUEST
154
155%ifdef VBOX_WITH_KERNEL_USING_XMM
156 ; Restore the non-volatile xmm registers. ASSUMING 64-bit host.
157 mov pXState, [pCpumCpu + CPUMCPU.Host.pXStateR0]
158 movdqa xmm6, [pXState + X86FXSTATE.xmm6]
159 movdqa xmm7, [pXState + X86FXSTATE.xmm7]
160 movdqa xmm8, [pXState + X86FXSTATE.xmm8]
161 movdqa xmm9, [pXState + X86FXSTATE.xmm9]
162 movdqa xmm10, [pXState + X86FXSTATE.xmm10]
163 movdqa xmm11, [pXState + X86FXSTATE.xmm11]
164 movdqa xmm12, [pXState + X86FXSTATE.xmm12]
165 movdqa xmm13, [pXState + X86FXSTATE.xmm13]
166 movdqa xmm14, [pXState + X86FXSTATE.xmm14]
167 movdqa xmm15, [pXState + X86FXSTATE.xmm15]
168%endif
169
170 or dword [pCpumCpu + CPUMCPU.fUseFlags], (CPUM_USED_FPU_GUEST | CPUM_USED_FPU_SINCE_REM | CPUM_USED_FPU_HOST)
171 popf
172
173 mov eax, ecx
174.return:
175%ifdef RT_ARCH_X86
176 pop esi
177 pop ebx
178%endif
179 leave
180 ret
181ENDPROC cpumR0SaveHostRestoreGuestFPUState
182
183
184;;
185; Saves the guest FPU/SSE/AVX state and restores the host FPU/SSE/AVX state.
186;
187; @param pCpumCpu x86:[ebp+8] gcc:rdi msc:rcx CPUMCPU pointer
188;
189ALIGNCODE(16)
190BEGINPROC cpumR0SaveGuestRestoreHostFPUState
191 push xBP
192 SEH64_PUSH_xBP
193 mov xBP, xSP
194 SEH64_SET_FRAME_xBP 0
195SEH64_END_PROLOGUE
196
197 ;
198 ; Prologue - xAX+xDX must be free for XSAVE/XRSTOR input.
199 ;
200%ifdef RT_ARCH_AMD64
201 %ifdef RT_OS_WINDOWS
202 mov r11, rcx
203 %else
204 mov r11, rdi
205 %endif
206 %define pCpumCpu r11
207 %define pXState r10
208%else
209 push ebx
210 push esi
211 mov ebx, dword [ebp + 8]
212 %define pCpumCpu ebx
213 %define pXState esi
214%endif
215 pushf ; The darwin kernel can get upset or upset things if an
216 cli ; interrupt occurs while we're doing fxsave/fxrstor/cr0.
217
218 %ifdef VBOX_WITH_KERNEL_USING_XMM
219 ;
220 ; Copy non-volatile XMM registers to the host state so we can use
221 ; them while saving the guest state (we've gotta do this anyway).
222 ;
223 mov pXState, [pCpumCpu + CPUMCPU.Host.pXStateR0]
224 movdqa [pXState + X86FXSTATE.xmm6], xmm6
225 movdqa [pXState + X86FXSTATE.xmm7], xmm7
226 movdqa [pXState + X86FXSTATE.xmm8], xmm8
227 movdqa [pXState + X86FXSTATE.xmm9], xmm9
228 movdqa [pXState + X86FXSTATE.xmm10], xmm10
229 movdqa [pXState + X86FXSTATE.xmm11], xmm11
230 movdqa [pXState + X86FXSTATE.xmm12], xmm12
231 movdqa [pXState + X86FXSTATE.xmm13], xmm13
232 movdqa [pXState + X86FXSTATE.xmm14], xmm14
233 movdqa [pXState + X86FXSTATE.xmm15], xmm15
234 %endif
235
236 ;
237 ; Save the guest state if necessary.
238 ;
239 test dword [pCpumCpu + CPUMCPU.fUseFlags], CPUM_USED_FPU_GUEST
240 jz .load_only_host
241
242 %ifdef VBOX_WITH_KERNEL_USING_XMM
243 ; Load the guest XMM register values we already saved in HMR0VMXStartVMWrapXMM.
244 mov pXState, [pCpumCpu + CPUMCPU.Guest.pXStateR0]
245 movdqa xmm0, [pXState + X86FXSTATE.xmm0]
246 movdqa xmm1, [pXState + X86FXSTATE.xmm1]
247 movdqa xmm2, [pXState + X86FXSTATE.xmm2]
248 movdqa xmm3, [pXState + X86FXSTATE.xmm3]
249 movdqa xmm4, [pXState + X86FXSTATE.xmm4]
250 movdqa xmm5, [pXState + X86FXSTATE.xmm5]
251 movdqa xmm6, [pXState + X86FXSTATE.xmm6]
252 movdqa xmm7, [pXState + X86FXSTATE.xmm7]
253 movdqa xmm8, [pXState + X86FXSTATE.xmm8]
254 movdqa xmm9, [pXState + X86FXSTATE.xmm9]
255 movdqa xmm10, [pXState + X86FXSTATE.xmm10]
256 movdqa xmm11, [pXState + X86FXSTATE.xmm11]
257 movdqa xmm12, [pXState + X86FXSTATE.xmm12]
258 movdqa xmm13, [pXState + X86FXSTATE.xmm13]
259 movdqa xmm14, [pXState + X86FXSTATE.xmm14]
260 movdqa xmm15, [pXState + X86FXSTATE.xmm15]
261 %endif
262 CPUMR0_SAVE_GUEST
263
264 ;
265 ; Load the host state.
266 ;
267.load_only_host:
268 CPUMR0_LOAD_HOST
269
270 ; Restore the CR0 value we saved in cpumR0SaveHostRestoreGuestFPUState or
271 ; in cpumRZSaveHostFPUState.
272 mov xCX, [pCpumCpu + CPUMCPU.Host.cr0Fpu]
273 CPUMRZ_RESTORE_CR0_IF_TS_OR_EM_SET xCX
274 and dword [pCpumCpu + CPUMCPU.fUseFlags], ~(CPUM_USED_FPU_GUEST | CPUM_USED_FPU_HOST)
275
276 popf
277%ifdef RT_ARCH_X86
278 pop esi
279 pop ebx
280%endif
281 leave
282 ret
283%undef pCpumCpu
284%undef pXState
285ENDPROC cpumR0SaveGuestRestoreHostFPUState
286
287
288%if ARCH_BITS == 32
289 %ifdef VBOX_WITH_64_BITS_GUESTS
290;;
291; Restores the host's FPU/SSE/AVX state from pCpumCpu->Host.
292;
293; @param pCpumCpu x86:[ebp+8] gcc:rdi msc:rcx CPUMCPU pointer
294;
295ALIGNCODE(16)
296BEGINPROC cpumR0RestoreHostFPUState
297 ;
298 ; Prologue - xAX+xDX must be free for XSAVE/XRSTOR input.
299 ;
300 push ebp
301 mov ebp, esp
302 push ebx
303 push esi
304 mov ebx, dword [ebp + 8]
305 %define pCpumCpu ebx
306 %define pXState esi
307
308 ;
309 ; Restore host CPU state.
310 ;
311 pushf ; The darwin kernel can get upset or upset things if an
312 cli ; interrupt occurs while we're doing fxsave/fxrstor/cr0.
313
314 CPUMR0_LOAD_HOST
315
316 ; Restore the CR0 value we saved in cpumR0SaveHostRestoreGuestFPUState or
317 ; in cpumRZSaveHostFPUState.
318 ;; @todo What about XCR0?
319 mov xCX, [pCpumCpu + CPUMCPU.Host.cr0Fpu]
320 CPUMRZ_RESTORE_CR0_IF_TS_OR_EM_SET xCX
321
322 and dword [pCpumCpu + CPUMCPU.fUseFlags], ~CPUM_USED_FPU_HOST
323 popf
324
325 pop esi
326 pop ebx
327 leave
328 ret
329 %undef pCpumCPu
330 %undef pXState
331ENDPROC cpumR0RestoreHostFPUState
332 %endif ; VBOX_WITH_64_BITS_GUESTS
333%endif ; ARCH_BITS == 32
334
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