VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac@ 34991

Last change on this file since 34991 was 34991, checked in by vboxsync, 14 years ago

VMMSwitcher/PAEand32Bit,LegacyandAMD64: restore the Local APIC NMI vectors _after_ we restored the host CS

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.2 KB
Line 
1; VMM - World Switchers, 32Bit to AMD64.
2;
3
4;
5; Copyright (C) 2006-2007 Oracle Corporation
6;
7; This file is part of VirtualBox Open Source Edition (OSE), as
8; available from http://www.virtualbox.org. This file is free software;
9; you can redistribute it and/or modify it under the terms of the GNU
10; General Public License (GPL) as published by the Free Software
11; Foundation, in version 2 as it comes in the "COPYING" file of the
12; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
13; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
14;
15
16;%define DEBUG_STUFF 1
17;%define STRICT_IF 1
18
19;*******************************************************************************
20;* Defined Constants And Macros *
21;*******************************************************************************
22
23
24;*******************************************************************************
25;* Header Files *
26;*******************************************************************************
27%include "VBox/asmdefs.mac"
28%include "VBox/apic.mac"
29%include "VBox/x86.mac"
30%include "VBox/cpum.mac"
31%include "VBox/stam.mac"
32%include "VBox/vm.mac"
33%include "CPUMInternal.mac"
34%include "VMMSwitcher/VMMSwitcher.mac"
35
36
37;
38; Start the fixup records
39; We collect the fixups in the .data section as we go along
40; It is therefore VITAL that no-one is using the .data section
41; for anything else between 'Start' and 'End'.
42;
43BEGINDATA
44GLOBALNAME Fixups
45
46
47
48BEGINCODE
49GLOBALNAME Start
50
51BITS 32
52
53;;
54; The C interface.
55; @param [esp + 04h] Param 1 - VM handle
56; @param [esp + 08h] Param 2 - VMCPU offset
57;
58BEGINPROC vmmR0HostToGuest
59%ifdef DEBUG_STUFF
60 COM32_S_NEWLINE
61 COM32_S_CHAR '^'
62%endif
63
64%ifdef VBOX_WITH_STATISTICS
65 ;
66 ; Switcher stats.
67 ;
68 FIXUP FIX_HC_VM_OFF, 1, VM.StatSwitcherToGC
69 mov edx, 0ffffffffh
70 STAM_PROFILE_ADV_START edx
71%endif
72
73 push ebp
74 mov ebp, [esp + 12] ; VMCPU offset
75
76 ; turn off interrupts
77 pushf
78 cli
79
80 ;
81 ; Call worker.
82 ;
83 FIXUP FIX_HC_CPUM_OFF, 1, 0
84 mov edx, 0ffffffffh
85 push cs ; allow for far return and restore cs correctly.
86 call NAME(vmmR0HostToGuestAsm)
87
88%ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
89 CPUM_FROM_CPUMCPU(edx)
90 ; Restore blocked Local APIC NMI vectors
91 mov ecx, [edx + CPUM.fApicDisVectors]
92 mov edx, [edx + CPUM.pvApicBase]
93 shr ecx, 1
94 jnc gth_nolint0
95 and dword [edx + APIC_REG_LVT_LINT0], ~APIC_REG_LVT_MASKED
96gth_nolint0:
97 shr ecx, 1
98 jnc gth_nolint1
99 and dword [edx + APIC_REG_LVT_LINT1], ~APIC_REG_LVT_MASKED
100gth_nolint1:
101 shr ecx, 1
102 jnc gth_nopc
103 and dword [edx + APIC_REG_LVT_PC], ~APIC_REG_LVT_MASKED
104gth_nopc:
105 shr ecx, 1
106 jnc gth_notherm
107 and dword [edx + APIC_REG_LVT_THMR], ~APIC_REG_LVT_MASKED
108gth_notherm:
109%endif
110
111 ; restore original flags
112 popf
113 pop ebp
114
115%ifdef VBOX_WITH_STATISTICS
116 ;
117 ; Switcher stats.
118 ;
119 FIXUP FIX_HC_VM_OFF, 1, VM.StatSwitcherToHC
120 mov edx, 0ffffffffh
121 STAM_PROFILE_ADV_STOP edx
122%endif
123
124 ret
125
126ENDPROC vmmR0HostToGuest
127
128; *****************************************************************************
129; vmmR0HostToGuestAsm
130;
131; Phase one of the switch from host to guest context (host MMU context)
132;
133; INPUT:
134; - edx virtual address of CPUM structure (valid in host context)
135; - ebp offset of the CPUMCPU structure
136;
137; USES/DESTROYS:
138; - eax, ecx, edx, esi
139;
140; ASSUMPTION:
141; - current CS and DS selectors are wide open
142;
143; *****************************************************************************
144ALIGNCODE(16)
145BEGINPROC vmmR0HostToGuestAsm
146 ;;
147 ;; Save CPU host context
148 ;; Skip eax, edx and ecx as these are not preserved over calls.
149 ;;
150 CPUMCPU_FROM_CPUM_WITH_OFFSET edx, ebp
151%ifdef VBOX_WITH_CRASHDUMP_MAGIC
152 ; phys address of scratch page
153 mov eax, dword [edx + CPUMCPU.Guest.dr + 4*8]
154 mov cr2, eax
155
156 mov dword [edx + CPUMCPU.Guest.dr + 4*8], 1
157%endif
158
159 ; general registers.
160 mov [edx + CPUMCPU.Host.ebx], ebx
161 mov [edx + CPUMCPU.Host.edi], edi
162 mov [edx + CPUMCPU.Host.esi], esi
163 mov [edx + CPUMCPU.Host.esp], esp
164 mov [edx + CPUMCPU.Host.ebp], ebp
165 ; selectors.
166 mov [edx + CPUMCPU.Host.ds], ds
167 mov [edx + CPUMCPU.Host.es], es
168 mov [edx + CPUMCPU.Host.fs], fs
169 mov [edx + CPUMCPU.Host.gs], gs
170 mov [edx + CPUMCPU.Host.ss], ss
171 ; special registers.
172 sldt [edx + CPUMCPU.Host.ldtr]
173 sidt [edx + CPUMCPU.Host.idtr]
174 sgdt [edx + CPUMCPU.Host.gdtr]
175 str [edx + CPUMCPU.Host.tr]
176
177%ifdef VBOX_WITH_CRASHDUMP_MAGIC
178 mov dword [edx + CPUMCPU.Guest.dr + 4*8], 2
179%endif
180
181%ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
182 CPUM_FROM_CPUMCPU_WITH_OFFSET edx, ebp
183 mov ebx, [edx + CPUM.pvApicBase]
184 or ebx, ebx
185 jz htg_noapic
186 mov eax, [ebx + APIC_REG_LVT_LINT0]
187 mov ecx, eax
188 and ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
189 cmp ecx, APIC_REG_LVT_MODE_NMI
190 jne htg_nolint0
191 or edi, 0x01
192 or eax, APIC_REG_LVT_MASKED
193 mov [ebx + APIC_REG_LVT_LINT0], eax
194 mov eax, [ebx + APIC_REG_LVT_LINT0] ; write completion
195htg_nolint0:
196 mov eax, [ebx + APIC_REG_LVT_LINT1]
197 mov ecx, eax
198 and ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
199 cmp ecx, APIC_REG_LVT_MODE_NMI
200 jne htg_nolint1
201 or edi, 0x02
202 or eax, APIC_REG_LVT_MASKED
203 mov [ebx + APIC_REG_LVT_LINT1], eax
204 mov eax, [ebx + APIC_REG_LVT_LINT1] ; write completion
205htg_nolint1:
206 mov eax, [ebx + APIC_REG_LVT_PC]
207 mov ecx, eax
208 and ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
209 cmp ecx, APIC_REG_LVT_MODE_NMI
210 jne htg_nopc
211 or edi, 0x04
212 or eax, APIC_REG_LVT_MASKED
213 mov [ebx + APIC_REG_LVT_PC], eax
214 mov eax, [ebx + APIC_REG_LVT_PC] ; write completion
215htg_nopc:
216 mov eax, [ebx + APIC_REG_VERSION]
217 shr eax, 16
218 cmp al, 5
219 jb htg_notherm
220 mov eax, [ebx + APIC_REG_LVT_THMR]
221 mov ecx, eax
222 and ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
223 cmp ecx, APIC_REG_LVT_MODE_NMI
224 jne htg_notherm
225 or edi, 0x08
226 or eax, APIC_REG_LVT_MASKED
227 mov [ebx + APIC_REG_LVT_THMR], eax
228 mov eax, [ebx + APIC_REG_LVT_THMR] ; write completion
229htg_notherm:
230 mov [edx + CPUM.fApicDisVectors], edi
231htg_noapic:
232 CPUMCPU_FROM_CPUM_WITH_OFFSET edx, ebp
233%endif
234
235 ; control registers.
236 mov eax, cr0
237 mov [edx + CPUMCPU.Host.cr0], eax
238 ;Skip cr2; assume host os don't stuff things in cr2. (safe)
239 mov eax, cr3
240 mov [edx + CPUMCPU.Host.cr3], eax
241 mov eax, cr4
242 mov [edx + CPUMCPU.Host.cr4], eax
243
244 ; save the host EFER msr
245 mov ebx, edx
246 mov ecx, MSR_K6_EFER
247 rdmsr
248 mov [ebx + CPUMCPU.Host.efer], eax
249 mov [ebx + CPUMCPU.Host.efer + 4], edx
250 mov edx, ebx
251
252%ifdef VBOX_WITH_CRASHDUMP_MAGIC
253 mov dword [edx + CPUMCPU.Guest.dr + 4*8], 3
254%endif
255
256 ; Load new gdt so we can do a far jump after going into 64 bits mode
257 lgdt [edx + CPUMCPU.Hyper.gdtr]
258
259%ifdef VBOX_WITH_CRASHDUMP_MAGIC
260 mov dword [edx + CPUMCPU.Guest.dr + 4*8], 4
261%endif
262
263 ;;
264 ;; Load Intermediate memory context.
265 ;;
266 FIXUP SWITCHER_FIX_INTER_CR3_HC, 1
267 mov eax, 0ffffffffh
268 mov cr3, eax
269 DEBUG_CHAR('?')
270
271 ;;
272 ;; Jump to identity mapped location
273 ;;
274 FIXUP FIX_HC_2_ID_NEAR_REL, 1, NAME(IDEnterTarget) - NAME(Start)
275 jmp near NAME(IDEnterTarget)
276
277
278 ; We're now on identity mapped pages!
279ALIGNCODE(16)
280GLOBALNAME IDEnterTarget
281 DEBUG_CHAR('2')
282
283 ; 1. Disable paging.
284 mov ebx, cr0
285 and ebx, ~X86_CR0_PG
286 mov cr0, ebx
287 DEBUG_CHAR('2')
288
289%ifdef VBOX_WITH_CRASHDUMP_MAGIC
290 mov eax, cr2
291 mov dword [eax], 3
292%endif
293
294 ; 2. Enable PAE.
295 mov ecx, cr4
296 or ecx, X86_CR4_PAE
297 mov cr4, ecx
298
299 ; 3. Load long mode intermediate CR3.
300 FIXUP FIX_INTER_AMD64_CR3, 1
301 mov ecx, 0ffffffffh
302 mov cr3, ecx
303 DEBUG_CHAR('3')
304
305%ifdef VBOX_WITH_CRASHDUMP_MAGIC
306 mov eax, cr2
307 mov dword [eax], 4
308%endif
309
310 ; 4. Enable long mode.
311 mov esi, edx
312 mov ecx, MSR_K6_EFER
313 rdmsr
314 FIXUP FIX_EFER_OR_MASK, 1
315 or eax, 0ffffffffh
316 and eax, ~(MSR_K6_EFER_FFXSR) ; turn off fast fxsave/fxrstor (skipping xmm regs)
317 wrmsr
318 mov edx, esi
319 DEBUG_CHAR('4')
320
321%ifdef VBOX_WITH_CRASHDUMP_MAGIC
322 mov eax, cr2
323 mov dword [eax], 5
324%endif
325
326 ; 5. Enable paging.
327 or ebx, X86_CR0_PG
328 ; Disable ring 0 write protection too
329 and ebx, ~X86_CR0_WRITE_PROTECT
330 mov cr0, ebx
331 DEBUG_CHAR('5')
332
333 ; Jump from compatibility mode to 64-bit mode.
334 FIXUP FIX_ID_FAR32_TO_64BIT_MODE, 1, NAME(IDEnter64Mode) - NAME(Start)
335 jmp 0ffffh:0fffffffeh
336
337 ;
338 ; We're in 64-bit mode (ds, ss, es, fs, gs are all bogus).
339BITS 64
340ALIGNCODE(16)
341NAME(IDEnter64Mode):
342 DEBUG_CHAR('6')
343 jmp [NAME(pICEnterTarget) wrt rip]
344
345; 64-bit jump target
346NAME(pICEnterTarget):
347FIXUP FIX_HC_64BIT_NOCHECK, 0, NAME(ICEnterTarget) - NAME(Start)
348dq 0ffffffffffffffffh
349
350; 64-bit pCpum address.
351NAME(pCpumIC):
352FIXUP FIX_GC_64_BIT_CPUM_OFF, 0, 0
353dq 0ffffffffffffffffh
354
355%ifdef VBOX_WITH_CRASHDUMP_MAGIC
356NAME(pMarker):
357db 'Switch_marker'
358%endif
359
360 ;
361 ; When we arrive here we're in 64 bits mode in the intermediate context
362 ;
363ALIGNCODE(16)
364GLOBALNAME ICEnterTarget
365 ; Load CPUM pointer into rdx
366 mov rdx, [NAME(pCpumIC) wrt rip]
367 CPUMCPU_FROM_CPUM_WITH_OFFSET edx, ebp
368
369 mov rax, cs
370 mov ds, rax
371 mov es, rax
372
373 ; Invalidate fs & gs
374 mov rax, 0
375 mov fs, rax
376 mov gs, rax
377
378%ifdef VBOX_WITH_CRASHDUMP_MAGIC
379 mov dword [rdx + CPUMCPU.Guest.dr + 4*8], 5
380%endif
381
382 ; Setup stack; use the lss_esp, ss pair for lss
383 DEBUG_CHAR('7')
384 mov rsp, 0
385 mov eax, [rdx + CPUMCPU.Hyper.esp]
386 mov [rdx + CPUMCPU.Hyper.lss_esp], eax
387 lss esp, [rdx + CPUMCPU.Hyper.lss_esp]
388
389%ifdef VBOX_WITH_CRASHDUMP_MAGIC
390 mov dword [rdx + CPUMCPU.Guest.dr + 4*8], 6
391%endif
392
393
394 ; load the hypervisor function address
395 mov r9, [rdx + CPUMCPU.Hyper.eip]
396
397 ; Check if we need to restore the guest FPU state
398 mov esi, [rdx + CPUMCPU.fUseFlags] ; esi == use flags.
399 test esi, CPUM_SYNC_FPU_STATE
400 jz near gth_fpu_no
401
402%ifdef VBOX_WITH_CRASHDUMP_MAGIC
403 mov dword [rdx + CPUMCPU.Guest.dr + 4*8], 7
404%endif
405
406 mov rax, cr0
407 mov rcx, rax ; save old CR0
408 and rax, ~(X86_CR0_TS | X86_CR0_EM)
409 mov cr0, rax
410 fxrstor [rdx + CPUMCPU.Guest.fpu]
411 mov cr0, rcx ; and restore old CR0 again
412
413 and dword [rdx + CPUMCPU.fUseFlags], ~CPUM_SYNC_FPU_STATE
414
415gth_fpu_no:
416 ; Check if we need to restore the guest debug state
417 test esi, CPUM_SYNC_DEBUG_STATE
418 jz near gth_debug_no
419
420%ifdef VBOX_WITH_CRASHDUMP_MAGIC
421 mov dword [rdx + CPUMCPU.Guest.dr + 4*8], 8
422%endif
423
424 mov rax, qword [rdx + CPUMCPU.Guest.dr + 0*8]
425 mov dr0, rax
426 mov rax, qword [rdx + CPUMCPU.Guest.dr + 1*8]
427 mov dr1, rax
428 mov rax, qword [rdx + CPUMCPU.Guest.dr + 2*8]
429 mov dr2, rax
430 mov rax, qword [rdx + CPUMCPU.Guest.dr + 3*8]
431 mov dr3, rax
432 mov rax, qword [rdx + CPUMCPU.Guest.dr + 6*8]
433 mov dr6, rax ; not required for AMD-V
434
435 and dword [rdx + CPUMCPU.fUseFlags], ~CPUM_SYNC_DEBUG_STATE
436
437gth_debug_no:
438
439%ifdef VBOX_WITH_CRASHDUMP_MAGIC
440 mov dword [rdx + CPUMCPU.Guest.dr + 4*8], 9
441%endif
442
443 ; parameter for all helper functions (pCtx)
444 lea rsi, [rdx + CPUMCPU.Guest.fpu]
445 call r9
446
447 ; Load CPUM pointer into rdx
448 mov rdx, [NAME(pCpumIC) wrt rip]
449 CPUMCPU_FROM_CPUM_WITH_OFFSET edx, ebp
450
451%ifdef VBOX_WITH_CRASHDUMP_MAGIC
452 mov dword [rdx + CPUMCPU.Guest.dr + 4*8], 10
453%endif
454
455 ; Save the return code
456 mov dword [rdx + CPUMCPU.u32RetCode], eax
457
458 ; now let's switch back
459 jmp NAME(VMMGCGuestToHostAsm) ; rax = returncode.
460
461ENDPROC vmmR0HostToGuestAsm
462
463
464;;
465; Trampoline for doing a call when starting the hyper visor execution.
466;
467; Push any arguments to the routine.
468; Push the argument frame size (cArg * 4).
469; Push the call target (_cdecl convention).
470; Push the address of this routine.
471;
472;
473BITS 64
474ALIGNCODE(16)
475BEGINPROC vmmGCCallTrampoline
476%ifdef DEBUG_STUFF
477 COM64_S_CHAR 'c'
478 COM64_S_CHAR 't'
479 COM64_S_CHAR '!'
480%endif
481 int3
482ENDPROC vmmGCCallTrampoline
483
484
485;;
486; The C interface.
487;
488BITS 64
489ALIGNCODE(16)
490BEGINPROC vmmGCGuestToHost
491%ifdef DEBUG_STUFF
492 push rsi
493 COM_NEWLINE
494 DEBUG_CHAR('b')
495 DEBUG_CHAR('a')
496 DEBUG_CHAR('c')
497 DEBUG_CHAR('k')
498 DEBUG_CHAR('!')
499 COM_NEWLINE
500 pop rsi
501%endif
502 int3
503ENDPROC vmmGCGuestToHost
504
505;;
506; VMMGCGuestToHostAsm
507;
508; This is an alternative entry point which we'll be using
509; when the we have saved the guest state already or we haven't
510; been messing with the guest at all.
511;
512; @param eax Return code.
513; @uses eax, edx, ecx (or it may use them in the future)
514;
515BITS 64
516ALIGNCODE(16)
517BEGINPROC VMMGCGuestToHostAsm
518 ;; We're still in the intermediate memory context!
519
520 ;;
521 ;; Switch to compatibility mode, placing ourselves in identity mapped code.
522 ;;
523 jmp far [NAME(fpIDEnterTarget) wrt rip]
524
525; 16:32 Pointer to IDEnterTarget.
526NAME(fpIDEnterTarget):
527 FIXUP FIX_ID_32BIT, 0, NAME(IDExitTarget) - NAME(Start)
528dd 0
529 FIXUP FIX_HYPER_CS, 0
530dd 0
531
532 ; We're now on identity mapped pages!
533ALIGNCODE(16)
534GLOBALNAME IDExitTarget
535BITS 32
536 DEBUG_CHAR('1')
537
538 ; 1. Deactivate long mode by turning off paging.
539 mov ebx, cr0
540 and ebx, ~X86_CR0_PG
541 mov cr0, ebx
542 DEBUG_CHAR('2')
543
544 ; 2. Load intermediate page table.
545 FIXUP SWITCHER_FIX_INTER_CR3_HC, 1
546 mov edx, 0ffffffffh
547 mov cr3, edx
548 DEBUG_CHAR('3')
549
550 ; 3. Disable long mode.
551 mov ecx, MSR_K6_EFER
552 rdmsr
553 DEBUG_CHAR('5')
554 and eax, ~(MSR_K6_EFER_LME)
555 wrmsr
556 DEBUG_CHAR('6')
557
558%ifndef NEED_PAE_ON_HOST
559 ; 3b. Disable PAE.
560 mov eax, cr4
561 and eax, ~X86_CR4_PAE
562 mov cr4, eax
563 DEBUG_CHAR('7')
564%endif
565
566 ; 4. Enable paging.
567 or ebx, X86_CR0_PG
568 mov cr0, ebx
569 jmp short just_a_jump
570just_a_jump:
571 DEBUG_CHAR('8')
572
573 ;;
574 ;; 5. Jump to guest code mapping of the code and load the Hypervisor CS.
575 ;;
576 FIXUP FIX_ID_2_HC_NEAR_REL, 1, NAME(ICExitTarget) - NAME(Start)
577 jmp near NAME(ICExitTarget)
578
579 ;;
580 ;; When we arrive at this label we're at the
581 ;; intermediate mapping of the switching code.
582 ;;
583BITS 32
584ALIGNCODE(16)
585GLOBALNAME ICExitTarget
586 DEBUG_CHAR('8')
587
588 ; load the hypervisor data selector into ds & es
589 FIXUP FIX_HYPER_DS, 1
590 mov eax, 0ffffh
591 mov ds, eax
592 mov es, eax
593
594 FIXUP FIX_GC_CPUM_OFF, 1, 0
595 mov edx, 0ffffffffh
596 CPUMCPU_FROM_CPUM_WITH_OFFSET edx, ebp
597 mov esi, [edx + CPUMCPU.Host.cr3]
598 mov cr3, esi
599
600 ;; now we're in host memory context, let's restore regs
601 FIXUP FIX_HC_CPUM_OFF, 1, 0
602 mov edx, 0ffffffffh
603 CPUMCPU_FROM_CPUM_WITH_OFFSET edx, ebp
604
605 ; restore the host EFER
606 mov ebx, edx
607 mov ecx, MSR_K6_EFER
608 mov eax, [ebx + CPUMCPU.Host.efer]
609 mov edx, [ebx + CPUMCPU.Host.efer + 4]
610 wrmsr
611 mov edx, ebx
612
613 ; activate host gdt and idt
614 lgdt [edx + CPUMCPU.Host.gdtr]
615 DEBUG_CHAR('0')
616 lidt [edx + CPUMCPU.Host.idtr]
617 DEBUG_CHAR('1')
618
619 ; Restore TSS selector; must mark it as not busy before using ltr (!)
620 ; ASSUME that this is supposed to be 'BUSY'. (saves 20-30 ticks on the T42p)
621 movzx eax, word [edx + CPUMCPU.Host.tr] ; eax <- TR
622 and al, 0F8h ; mask away TI and RPL bits, get descriptor offset.
623 add eax, [edx + CPUMCPU.Host.gdtr + 2] ; eax <- GDTR.address + descriptor offset.
624 and dword [eax + 4], ~0200h ; clear busy flag (2nd type2 bit)
625 ltr word [edx + CPUMCPU.Host.tr]
626
627 ; activate ldt
628 DEBUG_CHAR('2')
629 lldt [edx + CPUMCPU.Host.ldtr]
630
631 ; Restore segment registers
632 mov eax, [edx + CPUMCPU.Host.ds]
633 mov ds, eax
634 mov eax, [edx + CPUMCPU.Host.es]
635 mov es, eax
636 mov eax, [edx + CPUMCPU.Host.fs]
637 mov fs, eax
638 mov eax, [edx + CPUMCPU.Host.gs]
639 mov gs, eax
640 ; restore stack
641 lss esp, [edx + CPUMCPU.Host.esp]
642
643 ; Control registers.
644 mov ecx, [edx + CPUMCPU.Host.cr4]
645 mov cr4, ecx
646 mov ecx, [edx + CPUMCPU.Host.cr0]
647 mov cr0, ecx
648 ;mov ecx, [edx + CPUMCPU.Host.cr2] ; assumes this is waste of time.
649 ;mov cr2, ecx
650
651 ; restore general registers.
652 mov edi, [edx + CPUMCPU.Host.edi]
653 mov esi, [edx + CPUMCPU.Host.esi]
654 mov ebx, [edx + CPUMCPU.Host.ebx]
655 mov ebp, [edx + CPUMCPU.Host.ebp]
656
657 ; store the return code in eax
658 mov eax, [edx + CPUMCPU.u32RetCode]
659 retf
660ENDPROC VMMGCGuestToHostAsm
661
662;;
663; VMMGCGuestToHostAsmHyperCtx
664;
665; This is an alternative entry point which we'll be using
666; when the we have the hypervisor context and need to save
667; that before going to the host.
668;
669; This is typically useful when abandoning the hypervisor
670; because of a trap and want the trap state to be saved.
671;
672; @param eax Return code.
673; @param ecx Points to CPUMCTXCORE.
674; @uses eax,edx,ecx
675ALIGNCODE(16)
676BEGINPROC VMMGCGuestToHostAsmHyperCtx
677 int3
678
679;;
680; VMMGCGuestToHostAsmGuestCtx
681;
682; Switches from Guest Context to Host Context.
683; Of course it's only called from within the GC.
684;
685; @param eax Return code.
686; @param esp + 4 Pointer to CPUMCTXCORE.
687;
688; @remark ASSUMES interrupts disabled.
689;
690ALIGNCODE(16)
691BEGINPROC VMMGCGuestToHostAsmGuestCtx
692 int3
693
694GLOBALNAME End
695;
696; The description string (in the text section).
697;
698NAME(Description):
699 db SWITCHER_DESCRIPTION
700 db 0
701
702extern NAME(Relocate)
703
704;
705; End the fixup records.
706;
707BEGINDATA
708 db FIX_THE_END ; final entry.
709GLOBALNAME FixupsEnd
710
711;;
712; The switcher definition structure.
713ALIGNDATA(16)
714GLOBALNAME Def
715 istruc VMMSWITCHERDEF
716 at VMMSWITCHERDEF.pvCode, RTCCPTR_DEF NAME(Start)
717 at VMMSWITCHERDEF.pvFixups, RTCCPTR_DEF NAME(Fixups)
718 at VMMSWITCHERDEF.pszDesc, RTCCPTR_DEF NAME(Description)
719 at VMMSWITCHERDEF.pfnRelocate, RTCCPTR_DEF NAME(Relocate)
720 at VMMSWITCHERDEF.enmType, dd SWITCHER_TYPE
721 at VMMSWITCHERDEF.cbCode, dd NAME(End) - NAME(Start)
722 at VMMSWITCHERDEF.offR0HostToGuest, dd NAME(vmmR0HostToGuest) - NAME(Start)
723 at VMMSWITCHERDEF.offGCGuestToHost, dd NAME(vmmGCGuestToHost) - NAME(Start)
724 at VMMSWITCHERDEF.offGCCallTrampoline, dd NAME(vmmGCCallTrampoline) - NAME(Start)
725 at VMMSWITCHERDEF.offGCGuestToHostAsm, dd NAME(VMMGCGuestToHostAsm) - NAME(Start)
726 at VMMSWITCHERDEF.offGCGuestToHostAsmHyperCtx, dd NAME(VMMGCGuestToHostAsmHyperCtx)- NAME(Start)
727 at VMMSWITCHERDEF.offGCGuestToHostAsmGuestCtx, dd NAME(VMMGCGuestToHostAsmGuestCtx)- NAME(Start)
728 ; disasm help
729 at VMMSWITCHERDEF.offHCCode0, dd 0
730 at VMMSWITCHERDEF.cbHCCode0, dd NAME(IDEnterTarget) - NAME(Start)
731 at VMMSWITCHERDEF.offHCCode1, dd NAME(ICExitTarget) - NAME(Start)
732 at VMMSWITCHERDEF.cbHCCode1, dd NAME(End) - NAME(ICExitTarget)
733 at VMMSWITCHERDEF.offIDCode0, dd NAME(IDEnterTarget) - NAME(Start)
734 at VMMSWITCHERDEF.cbIDCode0, dd NAME(ICEnterTarget) - NAME(IDEnterTarget)
735 at VMMSWITCHERDEF.offIDCode1, dd NAME(IDExitTarget) - NAME(Start)
736 at VMMSWITCHERDEF.cbIDCode1, dd NAME(ICExitTarget) - NAME(Start)
737 at VMMSWITCHERDEF.offGCCode, dd 0
738 at VMMSWITCHERDEF.cbGCCode, dd 0
739
740 iend
741
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