VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMRZ/CPUMRZA.asm@ 64468

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

CPUMRZA.asm: raw-mode fixes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.3 KB
Line 
1 ; $Id: CPUMRZA.asm 61368 2016-06-01 12:46:59Z vboxsync $
2;; @file
3; CPUM - Raw-mode and Ring-0 Context Assembly Routines.
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 "VBox/asmdefs.mac"
24%include "CPUMInternal.mac"
25%include "iprt/x86.mac"
26%include "VBox/vmm/cpum.mac"
27%include "VBox/err.mac"
28
29
30
31BEGINCODE
32
33
34;;
35; Saves the host FPU/SSE/AVX state.
36;
37; Will return with CR0.EM and CR0.TS cleared! This is the normal state in
38; ring-0, whereas in raw-mode the caller will probably set VMCPU_FF_CPUM to
39; re-evaluate the situation before executing more guest code.
40;
41; @returns VINF_SUCCESS (0) or VINF_CPUM_HOST_CR0_MODIFIED. (EAX)
42; @param pCpumCpu x86:[ebp+8] gcc:rdi msc:rcx CPUMCPU pointer
43;
44align 16
45BEGINPROC cpumRZSaveHostFPUState
46 push xBP
47 SEH64_PUSH_xBP
48 mov xBP, xSP
49 SEH64_SET_FRAME_xBP 0
50SEH64_END_PROLOGUE
51
52 ;
53 ; Prologue - xAX+xDX must be free for XSAVE/XRSTOR input.
54 ;
55%ifdef RT_ARCH_AMD64
56 %ifdef ASM_CALL64_MSC
57 mov r11, rcx
58 %else
59 mov r11, rdi
60 %endif
61 %define pCpumCpu r11
62 %define pXState r10
63%else
64 push ebx
65 push esi
66 mov ebx, dword [ebp + 8]
67 %define pCpumCpu ebx
68 %define pXState esi
69%endif
70
71 pushf ; The darwin kernel can get upset or upset things if an
72 cli ; interrupt occurs while we're doing fxsave/fxrstor/cr0.
73
74 ;
75 ; We may have to update CR0, indirectly or directly. We must report any
76 ; changes to the VT-x code.
77 ;
78 CPUMRZ_TOUCH_FPU_CLEAR_CR0_FPU_TRAPS_SET_RC xCX, xAX, pCpumCpu ; xCX is the return value (xAX scratch)
79
80 ;
81 ; Save the host state (xsave/fxsave will cause thread FPU state to be
82 ; loaded on systems where we are allowed to use it in ring-0.
83 ;
84 CPUMR0_SAVE_HOST
85
86 or dword [pCpumCpu + CPUMCPU.fUseFlags], (CPUM_USED_FPU_HOST | CPUM_USED_FPU_SINCE_REM) ; Latter is not necessarily true, but normally yes.
87 popf
88
89 mov eax, ecx ; The return value from above.
90%ifdef RT_ARCH_X86
91 pop esi
92 pop ebx
93%endif
94 leave
95 ret
96%undef pCpumCpu
97%undef pXState
98ENDPROC cpumRZSaveHostFPUState
99
100
101;;
102; Saves the guest FPU/SSE/AVX state.
103;
104; @param pCpumCpu x86:[ebp+8] gcc:rdi msc:rcx CPUMCPU pointer
105; @param fLeaveFpuAccessible x86:[ebp+c] gcc:sil msc:dl Whether to restore CR0 and XCR0 on
106; the way out. Only really applicable to RC.
107;
108align 16
109BEGINPROC cpumRZSaveGuestFpuState
110 push xBP
111 SEH64_PUSH_xBP
112 mov xBP, xSP
113 SEH64_SET_FRAME_xBP 0
114SEH64_END_PROLOGUE
115
116 ;
117 ; Prologue - xAX+xDX must be free for XSAVE/XRSTOR input.
118 ;
119%ifdef RT_ARCH_AMD64
120 %ifdef ASM_CALL64_MSC
121 mov r11, rcx
122 %else
123 mov r11, rdi
124 %endif
125 %define pCpumCpu r11
126 %define pXState r10
127%else
128 push ebx
129 push esi
130 mov ebx, dword [ebp + 8]
131 %define pCpumCpu ebx
132 %define pXState esi
133%endif
134 pushf ; The darwin kernel can get upset or upset things if an
135 cli ; interrupt occurs while we're doing fxsave/fxrstor/cr0.
136
137 %ifdef IN_RC
138 mov ecx, cr0 ; ecx = saved cr0
139 test ecx, X86_CR0_TS | X86_CR0_EM
140 jz .skip_cr0_write
141 mov eax, ecx
142 and eax, ~(X86_CR0_TS | X86_CR0_EM)
143 mov cr0, eax
144.skip_cr0_write:
145 %endif
146
147 %ifndef VBOX_WITH_KERNEL_USING_XMM
148 CPUMR0_SAVE_GUEST
149 %else
150 ;
151 ; The XMM0..XMM15 registers have been saved already. We exploit the
152 ; host state here to temporarly save the non-volatile XMM registers,
153 ; so we can load the guest ones while saving. This is safe.
154 ;
155
156 ; Save caller's XMM registers.
157 mov pXState, [pCpumCpu + CPUMCPU.Host.pXStateR0]
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
168
169 ; Load the guest XMM register values we already saved in HMR0VMXStartVMWrapXMM.
170 mov pXState, [pCpumCpu + CPUMCPU.Guest.pXStateR0]
171 movdqa xmm0, [pXState + X86FXSTATE.xmm0]
172 movdqa xmm1, [pXState + X86FXSTATE.xmm1]
173 movdqa xmm2, [pXState + X86FXSTATE.xmm2]
174 movdqa xmm3, [pXState + X86FXSTATE.xmm3]
175 movdqa xmm4, [pXState + X86FXSTATE.xmm4]
176 movdqa xmm5, [pXState + X86FXSTATE.xmm5]
177 movdqa xmm6, [pXState + X86FXSTATE.xmm6]
178 movdqa xmm7, [pXState + X86FXSTATE.xmm7]
179 movdqa xmm8, [pXState + X86FXSTATE.xmm8]
180 movdqa xmm9, [pXState + X86FXSTATE.xmm9]
181 movdqa xmm10, [pXState + X86FXSTATE.xmm10]
182 movdqa xmm11, [pXState + X86FXSTATE.xmm11]
183 movdqa xmm12, [pXState + X86FXSTATE.xmm12]
184 movdqa xmm13, [pXState + X86FXSTATE.xmm13]
185 movdqa xmm14, [pXState + X86FXSTATE.xmm14]
186 movdqa xmm15, [pXState + X86FXSTATE.xmm15]
187
188 CPUMR0_SAVE_GUEST
189
190 ; Restore caller's XMM registers.
191 mov pXState, [pCpumCpu + CPUMCPU.Host.pXStateR0]
192 movdqa xmm6, [pXState + X86FXSTATE.xmm6 ]
193 movdqa xmm7, [pXState + X86FXSTATE.xmm7 ]
194 movdqa xmm8, [pXState + X86FXSTATE.xmm8 ]
195 movdqa xmm9, [pXState + X86FXSTATE.xmm9 ]
196 movdqa xmm10, [pXState + X86FXSTATE.xmm10]
197 movdqa xmm11, [pXState + X86FXSTATE.xmm11]
198 movdqa xmm12, [pXState + X86FXSTATE.xmm12]
199 movdqa xmm13, [pXState + X86FXSTATE.xmm13]
200 movdqa xmm14, [pXState + X86FXSTATE.xmm14]
201 movdqa xmm15, [pXState + X86FXSTATE.xmm15]
202
203 %endif
204
205 and dword [pCpumCpu + CPUMCPU.fUseFlags], ~CPUM_USED_FPU_GUEST
206 %ifdef IN_RC
207 test byte [ebp + 0ch], 1 ; fLeaveFpuAccessible
208 jz .no_cr0_restore
209 CPUMRZ_RESTORE_CR0_IF_TS_OR_EM_SET ecx
210.no_cr0_restore:
211 %endif
212 popf
213%ifdef RT_ARCH_X86
214 pop esi
215 pop ebx
216%endif
217 leave
218 ret
219%undef pCpumCpu
220%undef pXState
221ENDPROC cpumRZSaveGuestFpuState
222
223
224;;
225; Saves the guest XMM0..15 registers.
226;
227; The purpose is to actualize the register state for read-only use, so CR0 is
228; restored in raw-mode context (so, the FPU/SSE/AVX CPU features can be
229; inaccessible upon return).
230;
231; @param pCpumCpu x86:[ebp+8] gcc:rdi msc:rcx CPUMCPU pointer
232;
233align 16
234BEGINPROC cpumRZSaveGuestSseRegisters
235 push xBP
236 SEH64_PUSH_xBP
237 mov xBP, xSP
238 SEH64_SET_FRAME_xBP 0
239SEH64_END_PROLOGUE
240
241%ifndef VBOX_WITH_KERNEL_USING_XMM
242 ;
243 ; Load xCX with the guest pXStateR0.
244 ;
245 %ifdef ASM_CALL64_GCC
246 mov xCX, rdi
247 %elifdef RT_ARCH_X86
248 mov xCX, dword [ebp + 8]
249 %endif
250 %ifdef IN_RING0
251 mov xCX, [xCX + CPUMCPU.Guest.pXStateR0]
252 %elifdef IN_RC
253 mov xCX, [xCX + CPUMCPU.Guest.pXStateRC]
254 %else
255 %error "Invalid context!"
256 %endif
257
258 %ifdef IN_RC
259 ; Temporarily grant access to the SSE state. xDX must be preserved until CR0 is restored!
260 mov edx, cr0
261 test edx, X86_CR0_TS | X86_CR0_EM
262 jz .skip_cr0_write
263 mov eax, edx
264 and eax, ~(X86_CR0_TS | X86_CR0_EM)
265 mov cr0, eax
266.skip_cr0_write:
267 %endif
268
269 ;
270 ; Do the job.
271 ;
272 movdqa [xCX + X86FXSTATE.xmm0 ], xmm0
273 movdqa [xCX + X86FXSTATE.xmm1 ], xmm1
274 movdqa [xCX + X86FXSTATE.xmm2 ], xmm2
275 movdqa [xCX + X86FXSTATE.xmm3 ], xmm3
276 movdqa [xCX + X86FXSTATE.xmm4 ], xmm4
277 movdqa [xCX + X86FXSTATE.xmm5 ], xmm5
278 movdqa [xCX + X86FXSTATE.xmm6 ], xmm6
279 movdqa [xCX + X86FXSTATE.xmm7 ], xmm7
280 %if ARCH_BITS == 64
281 movdqa [xCX + X86FXSTATE.xmm8 ], xmm8
282 movdqa [xCX + X86FXSTATE.xmm9 ], xmm9
283 movdqa [xCX + X86FXSTATE.xmm10], xmm10
284 movdqa [xCX + X86FXSTATE.xmm11], xmm11
285 movdqa [xCX + X86FXSTATE.xmm12], xmm12
286 movdqa [xCX + X86FXSTATE.xmm13], xmm13
287 movdqa [xCX + X86FXSTATE.xmm14], xmm14
288 movdqa [xCX + X86FXSTATE.xmm15], xmm15
289 %endif
290
291 %ifdef IN_RC
292 CPUMRZ_RESTORE_CR0_IF_TS_OR_EM_SET edx ; Restore CR0 if we changed it above.
293 %endif
294
295%endif ; !VBOX_WITH_KERNEL_USING_XMM
296
297 leave
298 ret
299ENDPROC cpumRZSaveGuestSseRegisters
300
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