VirtualBox

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

Last change on this file since 61317 was 61317, checked in by vboxsync, 9 years ago

CPUM,HM: CPUM must tell VT-x that it modified the host CR0 because it caches the value in the VMCS and state corruption may ensue if it restores it because we'll take a #NM when saving the guest state, probably ending up with the FPU state of the EMT instead.

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