VirtualBox

source: vbox/trunk/src/VBox/VMM/include/CPUMInternal.mac@ 74758

Last change on this file since 74758 was 74479, checked in by vboxsync, 6 years ago

VMM/CPUM: Nested VMX: bugref:9180 Rather than dereference pVCpu or pass yet another pVM pointer to all the inline nested hwvirt.
helper functions in cpum.h, we cache the hwvirt type in the CPUMCTX structure itself.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 30.4 KB
Line 
1; $Id: CPUMInternal.mac 74479 2018-09-26 14:28:55Z vboxsync $
2;; @file
3; CPUM - Internal header file (asm).
4;
5
6;
7; Copyright (C) 2006-2017 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%include "VBox/asmdefs.mac"
19%include "VBox/vmm/cpum.mac"
20
21;; Check sanity.
22%ifdef VBOX_WITH_KERNEL_USING_XMM
23 %ifndef IN_RING0
24 %error "What? We've got code assuming VBOX_WITH_KERNEL_USING_XMM is only defined in ring-0!"
25 %endif
26%endif
27
28;; For numeric expressions
29%ifdef RT_ARCH_AMD64
30 %define CPUM_IS_AMD64 1
31%else
32 %define CPUM_IS_AMD64 0
33%endif
34
35
36;;
37; CPU info
38struc CPUMINFO
39 .cMsrRanges resd 1 ; uint32_t
40 .fMsrMask resd 1 ; uint32_t
41 .fMxCsrMask resd 1 ; uint32_t
42 .cCpuIdLeaves resd 1 ; uint32_t
43 .iFirstExtCpuIdLeaf resd 1 ; uint32_t
44 .enmUnknownCpuIdMethod resd 1 ; CPUMUNKNOWNCPUID
45 .DefCpuId resb CPUMCPUID_size ; CPUMCPUID
46 .uScalableBusFreq resq 1 ; uint64_t
47 .paMsrRangesR0 RTR0PTR_RES 1 ; R0PTRTYPE(PCPUMMSRRANGE)
48 .paCpuIdLeavesR0 RTR0PTR_RES 1 ; R0PTRTYPE(PCPUMCPUIDLEAF)
49 .paMsrRangesR3 RTR3PTR_RES 1 ; R3PTRTYPE(PCPUMMSRRANGE)
50 .paCpuIdLeavesR3 RTR3PTR_RES 1 ; R3PTRTYPE(PCPUMCPUIDLEAF)
51 .paMsrRangesRC RTRCPTR_RES 1 ; RCPTRTYPE(PCPUMMSRRANGE)
52 .paCpuIdLeavesRC RTRCPTR_RES 1 ; RCPTRTYPE(PCPUMCPUIDLEAF)
53endstruc
54
55
56%define CPUM_USED_FPU_HOST RT_BIT(0)
57%define CPUM_USED_FPU_GUEST RT_BIT(10)
58%define CPUM_USED_FPU_SINCE_REM RT_BIT(1)
59%define CPUM_USED_MANUAL_XMM_RESTORE RT_BIT(2)
60%define CPUM_USE_SYSENTER RT_BIT(3)
61%define CPUM_USE_SYSCALL RT_BIT(4)
62%define CPUM_USE_DEBUG_REGS_HOST RT_BIT(5)
63%define CPUM_USED_DEBUG_REGS_HOST RT_BIT(6)
64%define CPUM_USE_DEBUG_REGS_HYPER RT_BIT(7)
65%define CPUM_USED_DEBUG_REGS_HYPER RT_BIT(8)
66%define CPUM_USED_DEBUG_REGS_GUEST RT_BIT(9)
67%define CPUM_SYNC_FPU_STATE RT_BIT(16)
68%define CPUM_SYNC_DEBUG_REGS_GUEST RT_BIT(17)
69%define CPUM_SYNC_DEBUG_REGS_HYPER RT_BIT(18)
70%define CPUM_USE_FFXSR_LEAKY RT_BIT(19)
71%define CPUM_USE_SUPPORTS_LONGMODE RT_BIT(20)
72
73%define CPUM_HANDLER_DS 1
74%define CPUM_HANDLER_ES 2
75%define CPUM_HANDLER_FS 3
76%define CPUM_HANDLER_GS 4
77%define CPUM_HANDLER_IRET 5
78%define CPUM_HANDLER_TYPEMASK 0ffh
79%define CPUM_HANDLER_CTXCORE_IN_EBP RT_BIT(31)
80
81
82struc CPUM
83 ;...
84 .offCPUMCPU0 resd 1
85 .fHostUseFlags resd 1
86
87 ; CR4 masks
88 .CR4.AndMask resd 1
89 .CR4.OrMask resd 1
90 ; entered rawmode?
91 .u8PortableCpuIdLevel resb 1
92 .fPendingRestore resb 1
93
94 alignb 8
95 .fXStateGuestMask resq 1
96 .fXStateHostMask resq 1
97
98 alignb 64
99 .HostFeatures resb 48
100 .GuestFeatures resb 48
101 .GuestInfo resb RTHCPTR_CB*4 + RTRCPTR_CB*2 + 4*12
102
103 ; Patch manager saved state compatability CPUID leaf arrays
104 .aGuestCpuIdPatmStd resb 16*6
105 .aGuestCpuIdPatmExt resb 16*10
106 .aGuestCpuIdPatmCentaur resb 16*4
107
108 alignb 8
109 .cMsrWrites resq 1
110 .cMsrWritesToIgnoredBits resq 1
111 .cMsrWritesRaiseGp resq 1
112 .cMsrWritesUnknown resq 1
113 .cMsrReads resq 1
114 .cMsrReadsRaiseGp resq 1
115 .cMsrReadsUnknown resq 1
116endstruc
117
118struc CPUMCPU
119 ;
120 ; Guest context state
121 ; (Identical to the .Hyper chunk below and to CPUMCTX in cpum.mac.)
122 ;
123 .Guest resq 0
124 .Guest.eax resq 1
125 .Guest.ecx resq 1
126 .Guest.edx resq 1
127 .Guest.ebx resq 1
128 .Guest.esp resq 1
129 .Guest.ebp resq 1
130 .Guest.esi resq 1
131 .Guest.edi resq 1
132 .Guest.r8 resq 1
133 .Guest.r9 resq 1
134 .Guest.r10 resq 1
135 .Guest.r11 resq 1
136 .Guest.r12 resq 1
137 .Guest.r13 resq 1
138 .Guest.r14 resq 1
139 .Guest.r15 resq 1
140 .Guest.es.Sel resw 1
141 .Guest.es.PaddingSel resw 1
142 .Guest.es.ValidSel resw 1
143 .Guest.es.fFlags resw 1
144 .Guest.es.u64Base resq 1
145 .Guest.es.u32Limit resd 1
146 .Guest.es.Attr resd 1
147 .Guest.cs.Sel resw 1
148 .Guest.cs.PaddingSel resw 1
149 .Guest.cs.ValidSel resw 1
150 .Guest.cs.fFlags resw 1
151 .Guest.cs.u64Base resq 1
152 .Guest.cs.u32Limit resd 1
153 .Guest.cs.Attr resd 1
154 .Guest.ss.Sel resw 1
155 .Guest.ss.PaddingSel resw 1
156 .Guest.ss.ValidSel resw 1
157 .Guest.ss.fFlags resw 1
158 .Guest.ss.u64Base resq 1
159 .Guest.ss.u32Limit resd 1
160 .Guest.ss.Attr resd 1
161 .Guest.ds.Sel resw 1
162 .Guest.ds.PaddingSel resw 1
163 .Guest.ds.ValidSel resw 1
164 .Guest.ds.fFlags resw 1
165 .Guest.ds.u64Base resq 1
166 .Guest.ds.u32Limit resd 1
167 .Guest.ds.Attr resd 1
168 .Guest.fs.Sel resw 1
169 .Guest.fs.PaddingSel resw 1
170 .Guest.fs.ValidSel resw 1
171 .Guest.fs.fFlags resw 1
172 .Guest.fs.u64Base resq 1
173 .Guest.fs.u32Limit resd 1
174 .Guest.fs.Attr resd 1
175 .Guest.gs.Sel resw 1
176 .Guest.gs.PaddingSel resw 1
177 .Guest.gs.ValidSel resw 1
178 .Guest.gs.fFlags resw 1
179 .Guest.gs.u64Base resq 1
180 .Guest.gs.u32Limit resd 1
181 .Guest.gs.Attr resd 1
182 .Guest.eip resq 1
183 .Guest.eflags resq 1
184 .Guest.cr0 resq 1
185 .Guest.cr2 resq 1
186 .Guest.cr3 resq 1
187 .Guest.cr4 resq 1
188 .Guest.dr resq 8
189 .Guest.gdtrPadding resw 3
190 .Guest.gdtr resw 0
191 .Guest.gdtr.cbGdt resw 1
192 .Guest.gdtr.pGdt resq 1
193 .Guest.idtrPadding resw 3
194 .Guest.idtr resw 0
195 .Guest.idtr.cbIdt resw 1
196 .Guest.idtr.pIdt resq 1
197 .Guest.ldtr.Sel resw 1
198 .Guest.ldtr.PaddingSel resw 1
199 .Guest.ldtr.ValidSel resw 1
200 .Guest.ldtr.fFlags resw 1
201 .Guest.ldtr.u64Base resq 1
202 .Guest.ldtr.u32Limit resd 1
203 .Guest.ldtr.Attr resd 1
204 .Guest.tr.Sel resw 1
205 .Guest.tr.PaddingSel resw 1
206 .Guest.tr.ValidSel resw 1
207 .Guest.tr.fFlags resw 1
208 .Guest.tr.u64Base resq 1
209 .Guest.tr.u32Limit resd 1
210 .Guest.tr.Attr resd 1
211 .Guest.SysEnter.cs resb 8
212 .Guest.SysEnter.eip resb 8
213 .Guest.SysEnter.esp resb 8
214 .Guest.msrEFER resb 8
215 .Guest.msrSTAR resb 8
216 .Guest.msrPAT resb 8
217 .Guest.msrLSTAR resb 8
218 .Guest.msrCSTAR resb 8
219 .Guest.msrSFMASK resb 8
220 .Guest.msrKERNELGSBASE resb 8
221 .Guest.uMsrPadding0 resb 8
222 alignb 8
223 .Guest.aXcr resq 2
224 .Guest.fXStateMask resq 1
225 .Guest.pXStateR0 RTR0PTR_RES 1
226 alignb 8
227 .Guest.pXStateR3 RTR3PTR_RES 1
228 alignb 8
229 .Guest.pXStateRC RTRCPTR_RES 1
230 .Guest.aoffXState resw 64
231 .Guest.fWorldSwitcher resd 1
232 .Guest.fExtrn resq 1
233 alignb 8
234 .Guest.hwvirt.svm.uMsrHSavePa resq 1
235 .Guest.hwvirt.svm.GCPhysVmcb resq 1
236 .Guest.hwvirt.svm.pVmcbR0 RTR0PTR_RES 1
237 alignb 8
238 .Guest.hwvirt.svm.pVmcbR3 RTR3PTR_RES 1
239 alignb 8
240 .Guest.hwvirt.svm.HostState resb 184
241 .Guest.hwvirt.svm.uPrevPauseTick resq 1
242 .Guest.hwvirt.svm.cPauseFilter resw 1
243 .Guest.hwvirt.svm.cPauseFilterThreshold resw 1
244 .Guest.hwvirt.svm.fInterceptEvents resb 1
245 alignb 8
246 .Guest.hwvirt.svm.pvMsrBitmapR0 RTR0PTR_RES 1
247 alignb 8
248 .Guest.hwvirt.svm.pvMsrBitmapR3 RTR3PTR_RES 1
249 alignb 8
250 .Guest.hwvirt.svm.pvIoBitmapR0 RTR0PTR_RES 1
251 alignb 8
252 .Guest.hwvirt.svm.pvIoBitmapR3 RTR3PTR_RES 1
253 alignb 8
254 .Guest.hwvirt.svm.HCPhysVmcb RTHCPHYS_RES 1
255 .Guest.hwvirt.enmHwvirt resd 1
256 .Guest.hwvirt.fLocalForcedActions resd 1
257 .Guest.hwvirt.fGif resb 1
258 alignb 64
259
260 .GuestMsrs resq 0
261 .GuestMsrs.au64 resq 64
262
263 ;
264 ; Other stuff.
265 ;
266 .fUseFlags resd 1
267 .fChanged resd 1
268 .offCPUM resd 1
269 .u32RetCode resd 1
270
271%ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
272 .pvApicBase RTR0PTR_RES 1
273 .fApicDisVectors resd 1
274 .fX2Apic resb 1
275%else
276 .abPadding3 resb (RTR0PTR_CB + 4 + 1)
277%endif
278
279 .fRawEntered resb 1
280 .fRemEntered resb 1
281 .fCpuIdApicFeatureVisible resb 1
282
283 .abPadding2 resb (64 - 16 - RTR0PTR_CB - 4 - 1 - 3)
284
285 ;
286 ; Host context state
287 ;
288 alignb 64
289 .Host resb 0
290%if HC_ARCH_BITS == 64
291 ;.Host.rax resq 1 - scratch
292 .Host.rbx resq 1
293 ;.Host.rcx resq 1 - scratch
294 ;.Host.rdx resq 1 - scratch
295 .Host.rdi resq 1
296 .Host.rsi resq 1
297 .Host.rbp resq 1
298 .Host.rsp resq 1
299 ;.Host.r8 resq 1 - scratch
300 ;.Host.r9 resq 1 - scratch
301 .Host.r10 resq 1
302 .Host.r11 resq 1
303 .Host.r12 resq 1
304 .Host.r13 resq 1
305 .Host.r14 resq 1
306 .Host.r15 resq 1
307 ;.Host.rip resd 1 - scratch
308 .Host.rflags resq 1
309%endif
310%if HC_ARCH_BITS == 32
311 ;.Host.eax resd 1 - scratch
312 .Host.ebx resd 1
313 ;.Host.edx resd 1 - scratch
314 ;.Host.ecx resd 1 - scratch
315 .Host.edi resd 1
316 .Host.esi resd 1
317 .Host.ebp resd 1
318 .Host.eflags resd 1
319 ;.Host.eip resd 1 - scratch
320 ; lss pair!
321 .Host.esp resd 1
322%endif
323 .Host.ss resw 1
324 .Host.ssPadding resw 1
325 .Host.gs resw 1
326 .Host.gsPadding resw 1
327 .Host.fs resw 1
328 .Host.fsPadding resw 1
329 .Host.es resw 1
330 .Host.esPadding resw 1
331 .Host.ds resw 1
332 .Host.dsPadding resw 1
333 .Host.cs resw 1
334 .Host.csPadding resw 1
335
336%if HC_ARCH_BITS == 32
337 .Host.cr0 resd 1
338 ;.Host.cr2 resd 1 - scratch
339 .Host.cr3 resd 1
340 .Host.cr4 resd 1
341 .Host.cr0Fpu resd 1
342
343 .Host.dr0 resd 1
344 .Host.dr1 resd 1
345 .Host.dr2 resd 1
346 .Host.dr3 resd 1
347 .Host.dr6 resd 1
348 .Host.dr7 resd 1
349
350 .Host.gdtr resb 6 ; GDT limit + linear address
351 .Host.gdtrPadding resw 1
352 .Host.idtr resb 6 ; IDT limit + linear address
353 .Host.idtrPadding resw 1
354 .Host.ldtr resw 1
355 .Host.ldtrPadding resw 1
356 .Host.tr resw 1
357 .Host.trPadding resw 1
358
359 alignb 8
360 .Host.SysEnter.cs resq 1
361 .Host.SysEnter.eip resq 1
362 .Host.SysEnter.esp resq 1
363 .Host.efer resq 1
364 .Host.auPadding resb (20)
365
366%else ; 64-bit
367
368 .Host.cr0Fpu:
369 .Host.cr0 resq 1
370 ;.Host.cr2 resq 1 - scratch
371 .Host.cr3 resq 1
372 .Host.cr4 resq 1
373 .Host.cr8 resq 1
374
375 .Host.dr0 resq 1
376 .Host.dr1 resq 1
377 .Host.dr2 resq 1
378 .Host.dr3 resq 1
379 .Host.dr6 resq 1
380 .Host.dr7 resq 1
381
382 .Host.gdtr resb 10 ; GDT limit + linear address
383 .Host.gdtrPadding resw 1
384 .Host.idtr resb 10 ; IDT limit + linear address
385 .Host.idtrPadding resw 1
386 .Host.ldtr resw 1
387 .Host.ldtrPadding resw 1
388 .Host.tr resw 1
389 .Host.trPadding resw 1
390
391 .Host.SysEnter.cs resq 1
392 .Host.SysEnter.eip resq 1
393 .Host.SysEnter.esp resq 1
394 .Host.FSbase resq 1
395 .Host.GSbase resq 1
396 .Host.efer resq 1
397 .Host.auPadding resb 4
398%endif ; 64-bit
399 .Host.pXStateRC RTRCPTR_RES 1
400 alignb RTR0PTR_CB
401 .Host.pXStateR0 RTR0PTR_RES 1
402 .Host.pXStateR3 RTR3PTR_RES 1
403 alignb 8
404 .Host.xcr0 resq 1
405 .Host.fXStateMask resq 1
406
407 ;
408 ; Hypervisor Context (same as .Guest above).
409 ;
410 alignb 64
411 .Hyper resq 0
412 .Hyper.eax resq 1
413 .Hyper.ecx resq 1
414 .Hyper.edx resq 1
415 .Hyper.ebx resq 1
416 .Hyper.esp resq 1
417 .Hyper.ebp resq 1
418 .Hyper.esi resq 1
419 .Hyper.edi resq 1
420 .Hyper.r8 resq 1
421 .Hyper.r9 resq 1
422 .Hyper.r10 resq 1
423 .Hyper.r11 resq 1
424 .Hyper.r12 resq 1
425 .Hyper.r13 resq 1
426 .Hyper.r14 resq 1
427 .Hyper.r15 resq 1
428 .Hyper.es.Sel resw 1
429 .Hyper.es.PaddingSel resw 1
430 .Hyper.es.ValidSel resw 1
431 .Hyper.es.fFlags resw 1
432 .Hyper.es.u64Base resq 1
433 .Hyper.es.u32Limit resd 1
434 .Hyper.es.Attr resd 1
435 .Hyper.cs.Sel resw 1
436 .Hyper.cs.PaddingSel resw 1
437 .Hyper.cs.ValidSel resw 1
438 .Hyper.cs.fFlags resw 1
439 .Hyper.cs.u64Base resq 1
440 .Hyper.cs.u32Limit resd 1
441 .Hyper.cs.Attr resd 1
442 .Hyper.ss.Sel resw 1
443 .Hyper.ss.PaddingSel resw 1
444 .Hyper.ss.ValidSel resw 1
445 .Hyper.ss.fFlags resw 1
446 .Hyper.ss.u64Base resq 1
447 .Hyper.ss.u32Limit resd 1
448 .Hyper.ss.Attr resd 1
449 .Hyper.ds.Sel resw 1
450 .Hyper.ds.PaddingSel resw 1
451 .Hyper.ds.ValidSel resw 1
452 .Hyper.ds.fFlags resw 1
453 .Hyper.ds.u64Base resq 1
454 .Hyper.ds.u32Limit resd 1
455 .Hyper.ds.Attr resd 1
456 .Hyper.fs.Sel resw 1
457 .Hyper.fs.PaddingSel resw 1
458 .Hyper.fs.ValidSel resw 1
459 .Hyper.fs.fFlags resw 1
460 .Hyper.fs.u64Base resq 1
461 .Hyper.fs.u32Limit resd 1
462 .Hyper.fs.Attr resd 1
463 .Hyper.gs.Sel resw 1
464 .Hyper.gs.PaddingSel resw 1
465 .Hyper.gs.ValidSel resw 1
466 .Hyper.gs.fFlags resw 1
467 .Hyper.gs.u64Base resq 1
468 .Hyper.gs.u32Limit resd 1
469 .Hyper.gs.Attr resd 1
470 .Hyper.eip resq 1
471 .Hyper.eflags resq 1
472 .Hyper.cr0 resq 1
473 .Hyper.cr2 resq 1
474 .Hyper.cr3 resq 1
475 .Hyper.cr4 resq 1
476 .Hyper.dr resq 8
477 .Hyper.gdtrPadding resw 3
478 .Hyper.gdtr resw 0
479 .Hyper.gdtr.cbGdt resw 1
480 .Hyper.gdtr.pGdt resq 1
481 .Hyper.idtrPadding resw 3
482 .Hyper.idtr resw 0
483 .Hyper.idtr.cbIdt resw 1
484 .Hyper.idtr.pIdt resq 1
485 .Hyper.ldtr.Sel resw 1
486 .Hyper.ldtr.PaddingSel resw 1
487 .Hyper.ldtr.ValidSel resw 1
488 .Hyper.ldtr.fFlags resw 1
489 .Hyper.ldtr.u64Base resq 1
490 .Hyper.ldtr.u32Limit resd 1
491 .Hyper.ldtr.Attr resd 1
492 .Hyper.tr.Sel resw 1
493 .Hyper.tr.PaddingSel resw 1
494 .Hyper.tr.ValidSel resw 1
495 .Hyper.tr.fFlags resw 1
496 .Hyper.tr.u64Base resq 1
497 .Hyper.tr.u32Limit resd 1
498 .Hyper.tr.Attr resd 1
499 .Hyper.SysEnter.cs resb 8
500 .Hyper.SysEnter.eip resb 8
501 .Hyper.SysEnter.esp resb 8
502 .Hyper.msrEFER resb 8
503 .Hyper.msrSTAR resb 8
504 .Hyper.msrPAT resb 8
505 .Hyper.msrLSTAR resb 8
506 .Hyper.msrCSTAR resb 8
507 .Hyper.msrSFMASK resb 8
508 .Hyper.msrKERNELGSBASE resb 8
509 .Hyper.uMsrPadding0 resb 8
510 alignb 8
511 .Hyper.aXcr resq 2
512 .Hyper.fXStateMask resq 1
513 .Hyper.pXStateR0 RTR0PTR_RES 1
514 alignb 8
515 .Hyper.pXStateR3 RTR3PTR_RES 1
516 alignb 8
517 .Hyper.pXStateRC RTRCPTR_RES 1
518 .Hyper.aoffXState resw 64
519 .Hyper.fWorldSwitcher resd 1
520 .Hyper.fExtrn resq 1
521 alignb 8
522 .Hyper.hwvirt.svm.uMsrHSavePa resq 1
523 .Hyper.hwvirt.svm.GCPhysVmcb resq 1
524 .Hyper.hwvirt.svm.pVmcbR0 RTR0PTR_RES 1
525 alignb 8
526 .Hyper.hwvirt.svm.pVmcbR3 RTR3PTR_RES 1
527 alignb 8
528 .Hyper.hwvirt.svm.HostState resb 184
529 .Hyper.hwvirt.svm.uPrevPauseTick resq 1
530 .Hyper.hwvirt.svm.cPauseFilter resw 1
531 .Hyper.hwvirt.svm.cPauseFilterThreshold resw 1
532 .Hyper.hwvirt.svm.fInterceptEvents resb 1
533 alignb 8
534 .Hyper.hwvirt.svm.pvMsrBitmapR0 RTR0PTR_RES 1
535 alignb 8
536 .Hyper.hwvirt.svm.pvMsrBitmapR3 RTR3PTR_RES 1
537 alignb 8
538 .Hyper.hwvirt.svm.pvIoBitmapR0 RTR0PTR_RES 1
539 alignb 8
540 .Hyper.hwvirt.svm.pvIoBitmapR3 RTR3PTR_RES 1
541 alignb 8
542 .Hyper.hwvirt.svm.HCPhysVmcb RTHCPHYS_RES 1
543 .Hyper.hwvirt.enmHwvirt resd 1
544 .Hyper.hwvirt.fLocalForcedActions resd 1
545 .Hyper.hwvirt.fGif resb 1
546 alignb 64
547
548%ifdef VBOX_WITH_CRASHDUMP_MAGIC
549 .aMagic resb 56
550 .uMagic resq 1
551%endif
552endstruc
553
554
555;;
556; Converts the CPUM pointer to CPUMCPU
557; @param %1 register name
558%macro CPUMCPU_FROM_CPUM 1
559 add %1, dword [%1 + CPUM.offCPUMCPU0]
560%endmacro
561
562;;
563; Converts the CPUM pointer to CPUMCPU
564; @param %1 register name (CPUM)
565; @param %2 register name (CPUMCPU offset)
566%macro CPUMCPU_FROM_CPUM_WITH_OFFSET 2
567 add %1, %2
568%endmacro
569
570;;
571; Converts the CPUMCPU pointer to CPUM
572; @param %1 register name
573%macro CPUM_FROM_CPUMCPU 1
574 sub %1, dword [%1 + CPUMCPU.offCPUM]
575%endmacro
576
577;;
578; Converts the CPUMCPU pointer to CPUM
579; @param %1 register name (CPUM)
580; @param %2 register name (CPUMCPU offset)
581%macro CPUM_FROM_CPUMCPU_WITH_OFFSET 2
582 sub %1, %2
583%endmacro
584
585
586
587%if 0 ; Currently not used anywhere.
588;;
589; Macro for FXSAVE/FXRSTOR leaky behaviour on AMD CPUs, see cpumR3CheckLeakyFpu().
590;
591; Cleans the FPU state, if necessary, before restoring the FPU.
592;
593; This macro ASSUMES CR0.TS is not set!
594;
595; @param xDX Pointer to CPUMCPU.
596; @uses xAX, EFLAGS
597;
598; Changes here should also be reflected in CPUMRCA.asm's copy!
599;
600%macro CLEANFPU 0
601 test dword [xDX + CPUMCPU.fUseFlags], CPUM_USE_FFXSR_LEAKY
602 jz .nothing_to_clean
603
604 xor eax, eax
605 fnstsw ax ; FSW -> AX.
606 test eax, RT_BIT(7) ; If FSW.ES (bit 7) is set, clear it to not cause FPU exceptions
607 ; while clearing & loading the FPU bits in 'clean_fpu' below.
608 jz .clean_fpu
609 fnclex
610
611.clean_fpu:
612 ffree st7 ; Clear FPU stack register(7)'s tag entry to prevent overflow if a wraparound occurs.
613 ; for the upcoming push (load)
614 fild dword [g_r32_Zero xWrtRIP] ; Explicit FPU load to overwrite FIP, FOP, FDP registers in the FPU.
615.nothing_to_clean:
616%endmacro
617%endif ; Unused.
618
619
620;;
621; Makes sure we don't trap (#NM) accessing the FPU.
622;
623; In ring-0 this is a bit of work since we may have try convince the host kernel
624; to do the work for us, also, we must report any CR0 changes back to HMR0VMX
625; via the VINF_CPUM_HOST_CR0_MODIFIED status code.
626;
627; If we end up clearing CR0.TS/EM ourselves in ring-0, we'll save the original
628; value in CPUMCPU.Host.cr0Fpu. If we don't, we'll store zero there. (See also
629; CPUMRZ_RESTORE_CR0_IF_TS_OR_EM_SET.)
630;
631; In raw-mode we will always have to clear TS and it will be recalculated
632; elsewhere and thus needs no saving.
633;
634; @param %1 Register to return the return status code in.
635; @param %2 Temporary scratch register.
636; @param %3 Ring-0 only, register pointing to the CPUMCPU structure
637; of the EMT we're on.
638; @uses EFLAGS, CR0, %1, %2
639;
640%macro CPUMRZ_TOUCH_FPU_CLEAR_CR0_FPU_TRAPS_SET_RC 3
641 %ifdef IN_RC
642 ;
643 ; raw-mode - always clear it. We won't be here otherwise.
644 ;
645 mov %2, cr0
646 and %2, ~(X86_CR0_TS | X86_CR0_EM)
647 mov cr0, %2
648
649 %else
650 ;
651 ; ring-0 - slightly complicated.
652 ;
653 xor %1, %1 ; 0 / VINF_SUCCESS. Wishing for no CR0 changes.
654 mov [%3 + CPUMCPU.Host.cr0Fpu], %1
655
656 mov %2, cr0
657 test %2, X86_CR0_TS | X86_CR0_EM ; Make sure its safe to access the FPU state.
658 jz %%no_cr0_change
659
660 %ifdef VMM_R0_TOUCH_FPU
661 ; Touch the state and check that the kernel updated CR0 for us.
662 movdqa xmm0, xmm0
663 mov %2, cr0
664 test %2, X86_CR0_TS | X86_CR0_EM
665 jz %%cr0_changed
666 %endif
667
668 ; Save CR0 and clear them flags ourselves.
669 mov [%3 + CPUMCPU.Host.cr0Fpu], %2
670 and %2, ~(X86_CR0_TS | X86_CR0_EM)
671 mov cr0, %2
672 %endif ; IN_RING0
673
674%%cr0_changed:
675 mov %1, VINF_CPUM_HOST_CR0_MODIFIED
676%%no_cr0_change:
677%endmacro
678
679
680;;
681; Restore CR0 if CR0.TS or CR0.EM were non-zero in the original state.
682;
683; @param %1 The original state to restore (or zero).
684;
685%macro CPUMRZ_RESTORE_CR0_IF_TS_OR_EM_SET 1
686 test %1, X86_CR0_TS | X86_CR0_EM
687 jz %%skip_cr0_restore
688 mov cr0, %1
689%%skip_cr0_restore:
690%endmacro
691
692
693;;
694; Saves the host state.
695;
696; @uses rax, rdx
697; @param pCpumCpu Define for the register containing the CPUMCPU pointer.
698; @param pXState Define for the register containing the extended state pointer.
699;
700%macro CPUMR0_SAVE_HOST 0
701 ;
702 ; Load a couple of registers we'll use later in all branches.
703 ;
704 %ifdef IN_RING0
705 mov pXState, [pCpumCpu + CPUMCPU.Host.pXStateR0]
706 %elifdef IN_RC
707 mov pXState, [pCpumCpu + CPUMCPU.Host.pXStateRC]
708 %else
709 %error "Unsupported context!"
710 %endif
711 mov eax, [pCpumCpu + CPUMCPU.Host.fXStateMask]
712
713 ;
714 ; XSAVE or FXSAVE?
715 ;
716 or eax, eax
717 jz %%host_fxsave
718
719 ; XSAVE
720 mov edx, [pCpumCpu + CPUMCPU.Host.fXStateMask + 4]
721 %ifdef RT_ARCH_AMD64
722 o64 xsave [pXState]
723 %else
724 xsave [pXState]
725 %endif
726 jmp %%host_done
727
728 ; FXSAVE
729%%host_fxsave:
730 %ifdef RT_ARCH_AMD64
731 o64 fxsave [pXState] ; Use explicit REX prefix. See @bugref{6398}.
732 %else
733 fxsave [pXState]
734 %endif
735
736%%host_done:
737%endmacro ; CPUMR0_SAVE_HOST
738
739
740;;
741; Loads the host state.
742;
743; @uses rax, rdx
744; @param pCpumCpu Define for the register containing the CPUMCPU pointer.
745; @param pXState Define for the register containing the extended state pointer.
746;
747%macro CPUMR0_LOAD_HOST 0
748 ;
749 ; Load a couple of registers we'll use later in all branches.
750 ;
751 %ifdef IN_RING0
752 mov pXState, [pCpumCpu + CPUMCPU.Host.pXStateR0]
753 %elifdef IN_RC
754 mov pXState, [pCpumCpu + CPUMCPU.Host.pXStateRC]
755 %else
756 %error "Unsupported context!"
757 %endif
758 mov eax, [pCpumCpu + CPUMCPU.Host.fXStateMask]
759
760 ;
761 ; XRSTOR or FXRSTOR?
762 ;
763 or eax, eax
764 jz %%host_fxrstor
765
766 ; XRSTOR
767 mov edx, [pCpumCpu + CPUMCPU.Host.fXStateMask + 4]
768 %ifdef RT_ARCH_AMD64
769 o64 xrstor [pXState]
770 %else
771 xrstor [pXState]
772 %endif
773 jmp %%host_done
774
775 ; FXRSTOR
776%%host_fxrstor:
777 %ifdef RT_ARCH_AMD64
778 o64 fxrstor [pXState] ; Use explicit REX prefix. See @bugref{6398}.
779 %else
780 fxrstor [pXState]
781 %endif
782
783%%host_done:
784%endmacro ; CPUMR0_LOAD_HOST
785
786
787
788;; Macro for XSAVE/FXSAVE for the guest FPU but tries to figure out whether to
789; save the 32-bit FPU state or 64-bit FPU state.
790;
791; @param %1 Pointer to CPUMCPU.
792; @param %2 Pointer to XState.
793; @param %3 Force AMD64
794; @param %4 The instruction to use (xsave or fxsave)
795; @uses xAX, xDX, EFLAGS, 20h of stack.
796;
797%macro SAVE_32_OR_64_FPU 4
798%if CPUM_IS_AMD64 || %3
799 ; Save the guest FPU (32-bit or 64-bit), preserves existing broken state. See @bugref{7138}.
800 test dword [pCpumCpu + CPUMCPU.fUseFlags], CPUM_USE_SUPPORTS_LONGMODE
801 jnz short %%save_long_mode_guest
802%endif
803 %4 [pXState]
804%if CPUM_IS_AMD64 || %3
805 jmp %%save_done_32bit_cs_ds
806
807%%save_long_mode_guest:
808 o64 %4 [pXState]
809
810 xor edx, edx
811 cmp dword [pXState + X86FXSTATE.FPUCS], 0
812 jne short %%save_done
813
814 sub rsp, 20h ; Only need 1ch bytes but keep stack aligned otherwise we #GP(0).
815 fnstenv [rsp]
816 movzx eax, word [rsp + 10h]
817 mov [pXState + X86FXSTATE.FPUCS], eax
818 movzx eax, word [rsp + 18h]
819 add rsp, 20h
820 mov [pXState + X86FXSTATE.FPUDS], eax
821%endif
822%%save_done_32bit_cs_ds:
823 mov edx, X86_FXSTATE_RSVD_32BIT_MAGIC
824%%save_done:
825 mov dword [pXState + X86_OFF_FXSTATE_RSVD], edx
826%endmacro ; SAVE_32_OR_64_FPU
827
828
829;;
830; Save the guest state.
831;
832; @uses rax, rdx
833; @param pCpumCpu Define for the register containing the CPUMCPU pointer.
834; @param pXState Define for the register containing the extended state pointer.
835;
836%macro CPUMR0_SAVE_GUEST 0
837 ;
838 ; Load a couple of registers we'll use later in all branches.
839 ;
840 %ifdef IN_RING0
841 mov pXState, [pCpumCpu + CPUMCPU.Guest.pXStateR0]
842 %elifdef IN_RC
843 mov pXState, [pCpumCpu + CPUMCPU.Guest.pXStateRC]
844 %else
845 %error "Unsupported context!"
846 %endif
847 mov eax, [pCpumCpu + CPUMCPU.Guest.fXStateMask]
848
849 ;
850 ; XSAVE or FXSAVE?
851 ;
852 or eax, eax
853 jz %%guest_fxsave
854
855 ; XSAVE
856 mov edx, [pCpumCpu + CPUMCPU.Guest.fXStateMask + 4]
857 %ifdef VBOX_WITH_KERNEL_USING_XMM
858 and eax, ~CPUM_VOLATILE_XSAVE_GUEST_COMPONENTS ; Already saved in HMR0A.asm.
859 %endif
860 SAVE_32_OR_64_FPU pCpumCpu, pXState, 0, xsave
861 jmp %%guest_done
862
863 ; FXSAVE
864%%guest_fxsave:
865 SAVE_32_OR_64_FPU pCpumCpu, pXState, 0, fxsave
866
867%%guest_done:
868%endmacro ; CPUMR0_SAVE_GUEST
869
870
871;;
872; Wrapper for selecting 32-bit or 64-bit XRSTOR/FXRSTOR according to what SAVE_32_OR_64_FPU did.
873;
874; @param %1 Pointer to CPUMCPU.
875; @param %2 Pointer to XState.
876; @param %3 Force AMD64.
877; @param %4 The instruction to use (xrstor or fxrstor).
878; @uses xAX, xDX, EFLAGS
879;
880%macro RESTORE_32_OR_64_FPU 4
881%if CPUM_IS_AMD64 || %3
882 ; Restore the guest FPU (32-bit or 64-bit), preserves existing broken state. See @bugref{7138}.
883 test dword [pCpumCpu + CPUMCPU.fUseFlags], CPUM_USE_SUPPORTS_LONGMODE
884 jz %%restore_32bit_fpu
885 cmp dword [pXState + X86_OFF_FXSTATE_RSVD], X86_FXSTATE_RSVD_32BIT_MAGIC
886 jne short %%restore_64bit_fpu
887%%restore_32bit_fpu:
888%endif
889 %4 [pXState]
890%if CPUM_IS_AMD64 || %3
891 ; TODO: Restore XMM8-XMM15!
892 jmp short %%restore_fpu_done
893%%restore_64bit_fpu:
894 o64 %4 [pXState]
895%%restore_fpu_done:
896%endif
897%endmacro ; RESTORE_32_OR_64_FPU
898
899
900;;
901; Loads the guest state.
902;
903; @uses rax, rdx
904; @param pCpumCpu Define for the register containing the CPUMCPU pointer.
905; @param pXState Define for the register containing the extended state pointer.
906;
907%macro CPUMR0_LOAD_GUEST 0
908 ;
909 ; Load a couple of registers we'll use later in all branches.
910 ;
911 %ifdef IN_RING0
912 mov pXState, [pCpumCpu + CPUMCPU.Guest.pXStateR0]
913 %elifdef IN_RC
914 mov pXState, [pCpumCpu + CPUMCPU.Guest.pXStateRC]
915 %else
916 %error "Unsupported context!"
917 %endif
918 mov eax, [pCpumCpu + CPUMCPU.Guest.fXStateMask]
919
920 ;
921 ; XRSTOR or FXRSTOR?
922 ;
923 or eax, eax
924 jz %%guest_fxrstor
925
926 ; XRSTOR
927 mov edx, [pCpumCpu + CPUMCPU.Guest.fXStateMask + 4]
928 %ifdef VBOX_WITH_KERNEL_USING_XMM
929 and eax, ~CPUM_VOLATILE_XSAVE_GUEST_COMPONENTS ; Will be loaded by HMR0A.asm.
930 %endif
931 RESTORE_32_OR_64_FPU pCpumCpu, pXState, 0, xrstor
932 jmp %%guest_done
933
934 ; FXRSTOR
935%%guest_fxrstor:
936 RESTORE_32_OR_64_FPU pCpumCpu, pXState, 0, fxrstor
937
938%%guest_done:
939%endmacro ; CPUMR0_LOAD_GUEST
940
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