VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMGC/TRPMGCHandlersA.asm@ 9713

Last change on this file since 9713 was 9713, checked in by vboxsync, 16 years ago

More eip -> rip changes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 42.4 KB
Line 
1; $Id: TRPMGCHandlersA.asm 9713 2008-06-16 11:53:37Z vboxsync $
2;; @file
3; TRPM - Guest Context Trap Handlers
4;
5
6; Copyright (C) 2006-2007 Sun Microsystems, Inc.
7;
8; This file is part of VirtualBox Open Source Edition (OSE), as
9; available from http://www.virtualbox.org. This file is free software;
10; you can redistribute it and/or modify it under the terms of the GNU
11; General Public License (GPL) as published by the Free Software
12; Foundation, in version 2 as it comes in the "COPYING" file of the
13; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15;
16; Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
17; Clara, CA 95054 USA or visit http://www.sun.com if you need
18; additional information or have any questions.
19;
20
21;*******************************************************************************
22;* Header Files *
23;*******************************************************************************
24%include "VMMGC.mac"
25%include "VBox/x86.mac"
26%include "VBox/cpum.mac"
27%include "VBox/stam.mac"
28%include "VBox/vm.mac"
29%include "TRPMInternal.mac"
30%include "VBox/err.mac"
31%include "VBox/trpm.mac"
32
33
34;*******************************************************************************
35;* External Symbols *
36;*******************************************************************************
37extern IMPNAME(g_CPUM) ; These IMPNAME(g_*) symbols resolve to the import table
38extern IMPNAME(g_TRPM) ; where there is a pointer to the real symbol. PE imports
39extern IMPNAME(g_VM) ; are a bit confusing at first... :-)
40extern NAME(CPUMGCRestoreInt)
41extern NAME(CPUMHandleLazyFPUAsm)
42extern NAME(CPUMHyperSetCtxCore)
43extern NAME(trpmGCTrapInGeneric)
44extern NAME(TRPMGCHyperTrap0bHandler)
45extern NAME(TRPMGCHyperTrap0dHandler)
46extern NAME(TRPMGCHyperTrap0eHandler)
47extern NAME(TRPMGCTrap01Handler)
48%ifdef VBOX_WITH_NMI
49extern NAME(TRPMGCTrap02Handler)
50%endif
51extern NAME(TRPMGCTrap03Handler)
52extern NAME(TRPMGCTrap06Handler)
53extern NAME(TRPMGCTrap0bHandler)
54extern NAME(TRPMGCTrap0dHandler)
55extern NAME(TRPMGCTrap0eHandler)
56extern NAME(TRPMGCTrap07Handler)
57
58;; IMPORTANT all COM_ functions trashes esi, some edi and the LOOP_SHORT_WHILE kills ecx.
59;%define DEBUG_STUFF 1
60;%define DEBUG_STUFF_TRPG 1
61;%define DEBUG_STUFF_INT 1
62
63BEGINCODE
64
65;;
66; Jump table for trap handlers for hypervisor traps.
67;
68g_apfnStaticTrapHandlersHyper:
69 ; N - M M - T - C - D i
70 ; o - n o - y - o - e p
71 ; - e n - p - d - s t
72 ; - i - e - e - c .
73 ; - c - - - r
74 ; =============================================================
75 dd 0 ; 0 - #DE - F - N - Divide error
76 dd NAME(TRPMGCTrap01Handler) ; 1 - #DB - F/T - N - Single step, INT 1 instruction
77%ifdef VBOX_WITH_NMI
78 dd NAME(TRPMGCTrap02Handler) ; 2 - - I - N - Non-Maskable Interrupt (NMI)
79%else
80 dd 0 ; 2 - - I - N - Non-Maskable Interrupt (NMI)
81%endif
82 dd NAME(TRPMGCTrap03Handler) ; 3 - #BP - T - N - Breakpoint, INT 3 instruction.
83 dd 0 ; 4 - #OF - T - N - Overflow, INTO instruction.
84 dd 0 ; 5 - #BR - F - N - BOUND Range Exceeded, BOUND instruction.
85 dd 0 ; 6 - #UD - F - N - Undefined(/Invalid) Opcode.
86 dd 0 ; 7 - #NM - F - N - Device not available, FP or (F)WAIT instruction.
87 dd 0 ; 8 - #DF - A - 0 - Double fault.
88 dd 0 ; 9 - - F - N - Coprocessor Segment Overrun (obsolete).
89 dd 0 ; a - #TS - F - Y - Invalid TSS, Taskswitch or TSS access.
90 dd NAME(TRPMGCHyperTrap0bHandler) ; b - #NP - F - Y - Segment not present.
91 dd 0 ; c - #SS - F - Y - Stack-Segment fault.
92 dd NAME(TRPMGCHyperTrap0dHandler) ; d - #GP - F - Y - General protection fault.
93 dd NAME(TRPMGCHyperTrap0eHandler) ; e - #PF - F - Y - Page fault.
94 dd 0 ; f - - - - Intel Reserved. Do not use.
95 dd 0 ; 10 - #MF - F - N - x86 FPU Floating-Point Error (Math fault), FP or (F)WAIT instruction.
96 dd 0 ; 11 - #AC - F - 0 - Alignment Check.
97 dd 0 ; 12 - #MC - A - N - Machine Check.
98 dd 0 ; 13 - #XF - F - N - SIMD Floating-Point Exception.
99 dd 0 ; 14 - - - - Intel Reserved. Do not use.
100 dd 0 ; 15 - - - - Intel Reserved. Do not use.
101 dd 0 ; 16 - - - - Intel Reserved. Do not use.
102 dd 0 ; 17 - - - - Intel Reserved. Do not use.
103 dd 0 ; 18 - - - - Intel Reserved. Do not use.
104
105
106;;
107; Jump table for trap handlers for guest traps
108;
109g_apfnStaticTrapHandlersGuest:
110 ; N - M M - T - C - D i
111 ; o - n o - y - o - e p
112 ; - e n - p - d - s t
113 ; - i - e - e - c .
114 ; - c - - - r
115 ; =============================================================
116 dd 0 ; 0 - #DE - F - N - Divide error
117 dd NAME(TRPMGCTrap01Handler) ; 1 - #DB - F/T - N - Single step, INT 1 instruction
118%ifdef VBOX_WITH_NMI
119 dd NAME(TRPMGCTrap02Handler) ; 2 - - I - N - Non-Maskable Interrupt (NMI)
120%else
121 dd 0 ; 2 - - I - N - Non-Maskable Interrupt (NMI)
122%endif
123 dd NAME(TRPMGCTrap03Handler) ; 3 - #BP - T - N - Breakpoint, INT 3 instruction.
124 dd 0 ; 4 - #OF - T - N - Overflow, INTO instruction.
125 dd 0 ; 5 - #BR - F - N - BOUND Range Exceeded, BOUND instruction.
126 dd NAME(TRPMGCTrap06Handler) ; 6 - #UD - F - N - Undefined(/Invalid) Opcode.
127 dd NAME(TRPMGCTrap07Handler) ; 7 - #NM - F - N - Device not available, FP or (F)WAIT instruction.
128 dd 0 ; 8 - #DF - A - 0 - Double fault.
129 dd 0 ; 9 - - F - N - Coprocessor Segment Overrun (obsolete).
130 dd 0 ; a - #TS - F - Y - Invalid TSS, Taskswitch or TSS access.
131 dd NAME(TRPMGCTrap0bHandler) ; b - #NP - F - Y - Segment not present.
132 dd 0 ; c - #SS - F - Y - Stack-Segment fault.
133 dd NAME(TRPMGCTrap0dHandler) ; d - #GP - F - Y - General protection fault.
134 dd NAME(TRPMGCTrap0eHandler) ; e - #PF - F - Y - Page fault.
135 dd 0 ; f - - - - Intel Reserved. Do not use.
136 dd 0 ; 10 - #MF - F - N - x86 FPU Floating-Point Error (Math fault), FP or (F)WAIT instruction.
137 dd 0 ; 11 - #AC - F - 0 - Alignment Check.
138 dd 0 ; 12 - #MC - A - N - Machine Check.
139 dd 0 ; 13 - #XF - F - N - SIMD Floating-Point Exception.
140 dd 0 ; 14 - - - - Intel Reserved. Do not use.
141 dd 0 ; 15 - - - - Intel Reserved. Do not use.
142 dd 0 ; 16 - - - - Intel Reserved. Do not use.
143 dd 0 ; 17 - - - - Intel Reserved. Do not use.
144 dd 0 ; 18 - - - - Intel Reserved. Do not use.
145
146
147
148;;
149; We start by 24 push <vector no.> + jmp <generic entry point>
150;
151ALIGNCODE(16)
152BEGINPROC_EXPORTED TRPMGCHandlerGeneric
153%macro TRPMGenericEntry 1
154 db 06ah, i ; push imm8 - note that this is a signextended value.
155 jmp %1
156 ALIGNCODE(8)
157%assign i i+1
158%endmacro
159
160%assign i 0 ; start counter.
161 TRPMGenericEntry GenericTrap ; 0
162 TRPMGenericEntry GenericTrap ; 1
163 TRPMGenericEntry GenericTrap ; 2
164 TRPMGenericEntry GenericTrap ; 3
165 TRPMGenericEntry GenericTrap ; 4
166 TRPMGenericEntry GenericTrap ; 5
167 TRPMGenericEntry GenericTrap ; 6
168 TRPMGenericEntry GenericTrap ; 7
169 TRPMGenericEntry GenericTrapErrCode ; 8
170 TRPMGenericEntry GenericTrap ; 9
171 TRPMGenericEntry GenericTrapErrCode ; a
172 TRPMGenericEntry GenericTrapErrCode ; b
173 TRPMGenericEntry GenericTrapErrCode ; c
174 TRPMGenericEntry GenericTrapErrCode ; d
175 TRPMGenericEntry GenericTrapErrCode ; e
176 TRPMGenericEntry GenericTrap ; f (reserved)
177 TRPMGenericEntry GenericTrap ; 10
178 TRPMGenericEntry GenericTrapErrCode ; 11
179 TRPMGenericEntry GenericTrap ; 12
180 TRPMGenericEntry GenericTrap ; 13
181 TRPMGenericEntry GenericTrap ; 14 (reserved)
182 TRPMGenericEntry GenericTrap ; 15 (reserved)
183 TRPMGenericEntry GenericTrap ; 16 (reserved)
184 TRPMGenericEntry GenericTrap ; 17 (reserved)
185%undef i
186%undef TRPMGenericEntry
187
188;;
189; Main exception handler for the guest context
190;
191; Stack:
192; 14 SS
193; 10 ESP
194; c EFLAGS
195; 8 CS
196; 4 EIP
197; 0 vector number
198;
199; @uses none
200;
201ALIGNCODE(8)
202GenericTrap:
203 ;
204 ; for the present we fake an error code ~0
205 ;
206 push eax
207 mov eax, 0ffffffffh
208 xchg [esp + 4], eax ; get vector number, set error code
209 xchg [esp], eax ; get saved eax, set vector number
210 jmp short GenericTrapErrCode
211
212
213;;
214; Main exception handler for the guest context with error code
215;
216; Stack:
217; 28 GS (V86 only)
218; 24 FS (V86 only)
219; 20 DS (V86 only)
220; 1C ES (V86 only)
221; 18 SS (only if ring transition.)
222; 14 ESP (only if ring transition.)
223; 10 EFLAGS
224; c CS
225; 8 EIP
226; 4 Error code. (~0 for vectors which don't take an error code.)
227; 0 vector number
228;
229; Error code:
230;
231; 31 16 15 3 2 1 0
232;
233; reserved segment TI IDT EXT
234; selector GDT/LDT (1) IDT External interrupt
235; index (IDT=0) index
236;
237; NOTE: Page faults (trap 14) have a different error code
238;
239; @uses none
240;
241ALIGNCODE(8)
242GenericTrapErrCode:
243 cld
244
245 ;
246 ; Setup CPUMCTXCORE frame
247 ;
248 ; ASSUMPTION: If trap in hypervisor, we assume that we can read two dword
249 ; under the bottom of the stack. This is atm safe.
250 ; ASSUMPTION: There is sufficient stack space.
251 ; ASSUMPTION: The stack is not write protected.
252 ;
253%define ESPOFF CPUMCTXCORE_size
254
255 sub esp, CPUMCTXCORE_size
256 mov [esp + CPUMCTXCORE.eax], eax
257 mov [esp + CPUMCTXCORE.ecx], ecx
258 mov [esp + CPUMCTXCORE.edx], edx
259 mov [esp + CPUMCTXCORE.ebx], ebx
260 mov [esp + CPUMCTXCORE.esi], esi
261 mov [esp + CPUMCTXCORE.edi], edi
262 mov [esp + CPUMCTXCORE.ebp], ebp
263
264 mov eax, [esp + 14h + ESPOFF] ; esp
265 mov [esp + CPUMCTXCORE.esp], eax
266 mov eax, [esp + 18h + ESPOFF] ; ss
267 mov dword [esp + CPUMCTXCORE.ss], eax
268
269 mov eax, [esp + 0ch + ESPOFF] ; cs
270 mov dword [esp + CPUMCTXCORE.cs], eax
271 mov eax, [esp + 08h + ESPOFF] ; eip
272 mov [esp + CPUMCTXCORE.eip], eax
273%if GC_ARCH_BITS == 64
274 ; zero out the high dword
275 mov dword [esp + CPUMCTXCORE.eip + 4], 0
276%endif
277 mov eax, [esp + 10h + ESPOFF] ; eflags
278 mov [esp + CPUMCTXCORE.eflags], eax
279
280 mov eax, es
281 mov dword [esp + CPUMCTXCORE.es], eax
282 mov eax, ds
283 mov dword [esp + CPUMCTXCORE.ds], eax
284 mov eax, fs
285 mov dword [esp + CPUMCTXCORE.fs], eax
286 mov eax, gs
287 mov dword [esp + CPUMCTXCORE.gs], eax
288
289 test dword [esp + CPUMCTXCORE.eflags], X86_EFL_VM
290 jz short gt_SkipV86Entry
291
292 ;
293 ; The DS, ES, FS and GS registers are zeroed in V86 mode and their real values are on the stack
294 ;
295 mov eax, dword [esp + ESPOFF + 1Ch]
296 mov dword [esp + CPUMCTXCORE.es], eax
297
298 mov eax, dword [esp + ESPOFF + 20h]
299 mov dword [esp + CPUMCTXCORE.ds], eax
300
301 mov eax, dword [esp + ESPOFF + 24h]
302 mov dword [esp + CPUMCTXCORE.fs], eax
303
304 mov eax, dword [esp + ESPOFF + 28h]
305 mov dword [esp + CPUMCTXCORE.gs], eax
306
307gt_SkipV86Entry:
308 ;
309 ; Disable Ring-0 WP
310 ;
311 mov eax, cr0 ;; @todo elimitate this read?
312 and eax, ~X86_CR0_WRITE_PROTECT
313 mov cr0, eax
314
315 ;
316 ; Load Hypervisor DS and ES (get it from the SS)
317 ;
318 mov eax, ss
319 mov ds, eax
320 mov es, eax
321
322%ifdef VBOX_WITH_STATISTICS
323 ;
324 ; Start profiling.
325 ;
326 mov edx, [esp + 0h + ESPOFF] ; vector number
327 imul edx, edx, byte STAMPROFILEADV_size ; assumes < 128.
328 add edx, TRPM.aStatGCTraps
329 add edx, IMP(g_TRPM)
330 STAM_PROFILE_ADV_START edx
331%endif
332
333 ;
334 ; Store the information about the active trap/interrupt.
335 ;
336 mov eax, IMP(g_TRPM)
337 movzx edx, byte [esp + 0h + ESPOFF] ; vector number
338 mov [eax + TRPM.uActiveVector], edx
339 mov edx, [esp + 4h + ESPOFF] ; error code
340 mov [eax + TRPM.uActiveErrorCode], edx
341 mov dword [eax + TRPM.enmActiveType], TRPM_TRAP
342 mov edx, cr2 ;; @todo Check how expensive cr2 reads are!
343 mov dword [eax + TRPM.uActiveCR2], edx
344
345%if GC_ARCH_BITS == 64
346 ; zero out the high dword
347 mov dword [eax + TRPM.uActiveErrorCode + 4], 0
348 mov dword [eax + TRPM.uActiveCR2 + 4], 0
349%endif
350
351 ;
352 ; Check if we're in Hypervisor when this happend.
353 ;
354 test dword [esp + CPUMCTXCORE.eflags], X86_EFL_VM
355 jnz short gt_NotHyperVisor
356
357 test byte [esp + 0ch + ESPOFF], 3h ; check CPL of the cs selector
358 jz near gt_InHypervisor
359
360 ;
361 ; Trap in guest code.
362 ;
363gt_NotHyperVisor:
364%ifdef DEBUG_STUFF_TRPG
365 mov ebx, [esp + 4h + ESPOFF] ; error code
366 mov ecx, 'trpG' ; indicate trap.
367 mov edx, [esp + 0h + ESPOFF] ; vector number
368 lea eax, [esp]
369 call trpmDbgDumpRegisterFrame
370%endif
371
372 ;
373 ; Do we have a GC handler for these traps?
374 ;
375 mov edx, [esp + 0h + ESPOFF] ; vector number
376 mov eax, [g_apfnStaticTrapHandlersGuest + edx * 4]
377 or eax, eax
378 jnz short gt_HaveHandler
379 mov eax, VINF_EM_RAW_GUEST_TRAP
380 jmp short gt_GuestTrap
381
382 ;
383 ; Call static handler.
384 ;
385gt_HaveHandler:
386 push esp ; Param 2 - CPUMCTXCORE pointer.
387 push dword IMP(g_TRPM) ; Param 1 - Pointer to TRPM
388 call eax
389 add esp, byte 8 ; cleanup stack (cdecl)
390 or eax, eax
391 je near gt_continue_guest
392
393 ;
394 ; Switch back to the host and process it there.
395 ;
396gt_GuestTrap:
397%ifdef VBOX_WITH_STATISTICS
398 mov edx, [esp + 0h + ESPOFF] ; vector number
399 imul edx, edx, byte STAMPROFILEADV_size ; assume < 128
400 add edx, IMP(g_TRPM)
401 add edx, TRPM.aStatGCTraps
402 STAM_PROFILE_ADV_STOP edx
403%endif
404 mov edx, IMP(g_VM)
405 call [edx + VM.pfnVMMGCGuestToHostAsmGuestCtx]
406
407 ;; @todo r=bird: is this path actually every taken? if not we should replace this code with a panic.
408 ;
409 ; We've returned!
410 ; N.B. The stack has been changed now! No CPUMCTXCORE any longer. esp = vector number.
411 ; N.B. Current scheduling design causes this code path to be unused.
412 ; N.B. Better not use it when in V86 mode!
413 ;
414
415 ; Enable WP
416 mov eax, cr0 ;; @todo try elimiate this read.
417 or eax, X86_CR0_WRITE_PROTECT
418 mov cr0, eax
419 ; Restore guest context and continue execution.
420 mov edx, IMP(g_CPUM)
421 lea eax, [esp + 8]
422 push eax
423 call NAME(CPUMGCRestoreInt)
424 lea esp, [esp + 0ch] ; cleanup call and skip vector & error code.
425
426 iret
427
428
429 ;
430 ; Continue(/Resume/Restart/Whatever) guest execution.
431 ;
432ALIGNCODE(16)
433gt_continue_guest:
434%ifdef VBOX_WITH_STATISTICS
435 mov edx, [esp + 0h + ESPOFF] ; vector number
436 imul edx, edx, byte STAMPROFILEADV_size ; assumes < 128
437 add edx, TRPM.aStatGCTraps
438 add edx, IMP(g_TRPM)
439 STAM_PROFILE_ADV_STOP edx
440%endif
441
442 ; enable WP
443 mov eax, cr0 ;; @todo try elimiate this read.
444 or eax, X86_CR0_WRITE_PROTECT
445 mov cr0, eax
446
447 ; restore guest state and start executing again.
448 test dword [esp + CPUMCTXCORE.eflags], X86_EFL_VM
449 jnz gt_V86Return
450
451 mov ecx, [esp + CPUMCTXCORE.ecx]
452 mov edx, [esp + CPUMCTXCORE.edx]
453 mov ebx, [esp + CPUMCTXCORE.ebx]
454 mov ebp, [esp + CPUMCTXCORE.ebp]
455 mov esi, [esp + CPUMCTXCORE.esi]
456 mov edi, [esp + CPUMCTXCORE.edi]
457
458 mov eax, [esp + CPUMCTXCORE.esp]
459 mov [esp + 14h + ESPOFF], eax ; esp
460 mov eax, dword [esp + CPUMCTXCORE.ss]
461 mov [esp + 18h + ESPOFF], eax ; ss
462
463 mov eax, dword [esp + CPUMCTXCORE.gs]
464 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_GS
465 mov gs, eax
466
467 mov eax, dword [esp + CPUMCTXCORE.fs]
468 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_FS
469 mov fs, eax
470
471 mov eax, dword [esp + CPUMCTXCORE.es]
472 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_ES
473 mov es, eax
474
475 mov eax, dword [esp + CPUMCTXCORE.ds]
476 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_DS
477 mov ds, eax
478
479 mov eax, dword [esp + CPUMCTXCORE.cs]
480 mov [esp + 0ch + ESPOFF], eax ; cs
481 mov eax, [esp + CPUMCTXCORE.eflags]
482 mov [esp + 10h + ESPOFF], eax ; eflags
483 mov eax, [esp + CPUMCTXCORE.eip]
484 mov [esp + 08h + ESPOFF], eax ; eip
485
486 ; finally restore our scratch register eax
487 mov eax, [esp + CPUMCTXCORE.eax]
488
489 add esp, ESPOFF + 8 ; skip CPUMCTXCORE structure, error code and vector number
490
491 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_IRET
492 iret
493
494ALIGNCODE(16)
495gt_V86Return:
496 mov ecx, [esp + CPUMCTXCORE.ecx]
497 mov edx, [esp + CPUMCTXCORE.edx]
498 mov ebx, [esp + CPUMCTXCORE.ebx]
499 mov ebp, [esp + CPUMCTXCORE.ebp]
500 mov esi, [esp + CPUMCTXCORE.esi]
501 mov edi, [esp + CPUMCTXCORE.edi]
502
503 mov eax, [esp + CPUMCTXCORE.esp]
504 mov [esp + 14h + ESPOFF], eax ; esp
505 mov eax, dword [esp + CPUMCTXCORE.ss]
506 mov [esp + 18h + ESPOFF], eax ; ss
507
508 mov eax, dword [esp + CPUMCTXCORE.es]
509 mov [esp + 1ch + ESPOFF], eax ; es
510 mov eax, dword [esp + CPUMCTXCORE.ds]
511 mov [esp + 20h + ESPOFF], eax ; ds
512 mov eax, dword [esp + CPUMCTXCORE.fs]
513 mov [esp + 24h + ESPOFF], eax ; fs
514 mov eax, dword [esp + CPUMCTXCORE.gs]
515 mov [esp + 28h + ESPOFF], eax ; gs
516
517 mov eax, [esp + CPUMCTXCORE.eip]
518 mov [esp + 08h + ESPOFF], eax ; eip
519 mov eax, dword [esp + CPUMCTXCORE.cs]
520 mov [esp + 0ch + ESPOFF], eax ; cs
521 mov eax, [esp + CPUMCTXCORE.eflags]
522 mov [esp + 10h + ESPOFF], eax ; eflags
523
524 ; finally restore our scratch register eax
525 mov eax, [esp + CPUMCTXCORE.eax]
526
527 add esp, ESPOFF + 8 ; skip CPUMCTXCORE structure, error code and vector number
528
529 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_IRET | TRPM_TRAP_IN_V86
530 iret
531
532 ;
533 ; Trap in Hypervisor, try to handle it.
534 ;
535 ; (eax = pTRPM)
536 ;
537ALIGNCODE(16)
538gt_InHypervisor:
539 ; fix ss:esp.
540 lea ebx, [esp + 14h + ESPOFF] ; calc esp at trap
541 mov [esp + CPUMCTXCORE.esp], ebx; update esp in register frame
542 mov [esp + CPUMCTXCORE.ss], ss ; update ss in register frame
543
544 ; tell cpum about the context core.
545 xchg esi, eax ; save pTRPM - @todo reallocate this variable to esi, edi, or ebx
546 push esp ; Param 2 - The new CPUMCTXCORE pointer.
547 push IMP(g_VM) ; Param 1 - Pointer to the VM.
548 call NAME(CPUMHyperSetCtxCore)
549 add esp, byte 8 ; stack cleanup (cdecl)
550 xchg eax, esi ; restore pTRPM
551
552 ; check for temporary handler.
553 movzx ebx, byte [eax + TRPM.uActiveVector]
554 xor ecx, ecx
555 xchg ecx, [eax + TRPM.aTmpTrapHandlers + ebx * 4] ; ecx = Temp handler pointer or 0
556 or ecx, ecx
557 jnz short gt_Hyper_HaveTemporaryHandler
558
559 ; check for static trap handler.
560 mov ecx, [g_apfnStaticTrapHandlersHyper + ebx * 4] ; ecx = Static handler pointer or 0
561 or ecx, ecx
562 jnz short gt_Hyper_HaveStaticHandler
563 jmp gt_Hyper_AbandonShip
564
565
566 ;
567 ; Temporary trap handler present, call it (CDECL).
568 ;
569gt_Hyper_HaveTemporaryHandler:
570 push esp ; Param 2 - Pointer to CPUMCTXCORE.
571 push IMP(g_VM) ; Param 1 - Pointer to VM.
572 call ecx
573 add esp, byte 8 ; cleanup stack (cdecl)
574
575 cmp eax, byte VINF_SUCCESS ; If completely handled Then resume execution.
576 je near gt_Hyper_Continue
577 ;; @todo Handle ALL returns types from temporary handlers!
578 jmp gt_Hyper_AbandonShip
579
580
581 ;
582 ; Static trap handler present, call it (CDECL).
583 ;
584gt_Hyper_HaveStaticHandler:
585 push esp ; Param 2 - Pointer to CPUMCTXCORE.
586 push eax ; Param 1 - Pointer to TRPM
587 call ecx
588 add esp, byte 8 ; cleanup stack (cdecl)
589
590 cmp eax, byte VINF_SUCCESS ; If completely handled Then resume execution.
591 je short gt_Hyper_Continue
592 cmp eax, VINF_EM_DBG_HYPER_STEPPED
593 je short gt_Hyper_ToHost
594 cmp eax, VINF_EM_DBG_HYPER_BREAKPOINT
595 je short gt_Hyper_ToHost
596 cmp eax, VINF_EM_DBG_HYPER_ASSERTION
597 je short gt_Hyper_ToHost
598 jmp gt_Hyper_AbandonShip
599
600 ;
601 ; Pop back to the host to service the error.
602 ;
603gt_Hyper_ToHost:
604 mov ecx, esp
605 mov edx, IMP(g_VM)
606 call [edx + VM.pfnVMMGCGuestToHostAsm]
607 jmp short gt_Hyper_Continue
608
609 ;
610 ; Continue(/Resume/Restart/Whatever) hypervisor execution.
611 ; Don't reset the TRPM state. Caller takes care of that.
612 ;
613ALIGNCODE(16)
614gt_Hyper_Continue:
615%ifdef DEBUG_STUFF
616 mov ebx, [esp + 4h + ESPOFF] ; error code
617 mov ecx, 'resH' ; indicate trap.
618 mov edx, [esp + 0h + ESPOFF] ; vector number
619 lea eax, [esp]
620 call trpmDbgDumpRegisterFrame
621%endif
622 ; tell CPUM to use the default CPUMCTXCORE.
623 push byte 0 ; Param 2 - NULL indicating use default context core.
624 push IMP(g_VM) ; Param 1 - The VM pointer.
625 call NAME(CPUMHyperSetCtxCore)
626 add esp, byte 8 ; stack cleanup (cdecl)
627
628%ifdef VBOX_WITH_STATISTICS
629 mov edx, [esp + 0h + ESPOFF] ; vector number
630 imul edx, edx, byte STAMPROFILEADV_size ; assumes < 128
631 add edx, TRPM.aStatGCTraps
632 add edx, IMP(g_TRPM)
633 STAM_PROFILE_ADV_STOP edx
634%endif
635
636 ; restore
637 mov ecx, [esp + CPUMCTXCORE.ecx]
638 mov edx, [esp + CPUMCTXCORE.edx]
639 mov ebx, [esp + CPUMCTXCORE.ebx]
640 mov ebp, [esp + CPUMCTXCORE.ebp]
641 mov esi, [esp + CPUMCTXCORE.esi]
642 mov edi, [esp + CPUMCTXCORE.edi]
643
644 mov eax, dword [esp + CPUMCTXCORE.gs]
645 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_GS | TRPM_TRAP_IN_HYPER
646 mov gs, eax
647
648 mov eax, dword [esp + CPUMCTXCORE.fs]
649 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_FS | TRPM_TRAP_IN_HYPER
650 mov fs, eax
651
652 mov eax, dword [esp + CPUMCTXCORE.es]
653 mov es, eax
654 mov eax, dword [esp + CPUMCTXCORE.ds]
655 mov ds, eax
656
657 ; skip esp & ss
658
659 mov eax, [esp + CPUMCTXCORE.eip]
660 mov [esp + 08h + ESPOFF], eax ; eip
661 mov eax, dword [esp + CPUMCTXCORE.cs]
662 mov [esp + 0ch + ESPOFF], eax ; cs
663 mov eax, [esp + CPUMCTXCORE.eflags]
664 mov [esp + 10h + ESPOFF], eax ; eflags
665
666 ; finally restore our scratch register eax
667 mov eax, [esp + CPUMCTXCORE.eax]
668
669 add esp, ESPOFF + 8 ; skip CPUMCTXCORE structure, error code and vector number
670
671 iret
672
673
674 ;
675 ; ABANDON SHIP! DON'T PANIC!
676 ;
677gt_Hyper_AbandonShip:
678%ifdef DEBUG_STUFF
679 mov ebx, [esp + 4h + ESPOFF] ; error code
680 mov ecx, 'trpH' ; indicate trap.
681 mov edx, [esp + 0h + ESPOFF] ; vector number
682 lea eax, [esp]
683 call trpmDbgDumpRegisterFrame
684%endif
685
686gt_Hyper_DontPanic:
687 mov ecx, esp
688 mov edx, IMP(g_VM)
689 mov eax, VERR_TRPM_DONT_PANIC
690 call [edx + VM.pfnVMMGCGuestToHostAsmHyperCtx]
691%ifdef DEBUG_STUFF
692 COM_S_PRINT 'bad!!!'
693%endif
694 jmp gt_Hyper_DontPanic ; this shall never ever happen!
695%undef ESPOFF
696ENDPROC TRPMGCHandlerGeneric
697
698
699
700
701
702;;
703; We start by 256 push <vector no.> + jmp interruptworker
704;
705ALIGNCODE(16)
706BEGINPROC_EXPORTED TRPMGCHandlerInterupt
707 ; NASM has some nice features, here an example of a loop.
708%assign i 0
709%rep 256
710 db 06ah, i ; push imm8 - note that this is a signextended value.
711 jmp ti_GenericInterrupt
712 ALIGNCODE(8)
713%assign i i+1
714%endrep
715
716;;
717; Main interrupt handler for the guest context
718;
719; Stack:
720; 24 GS (V86 only)
721; 20 FS (V86 only)
722; 1C DS (V86 only)
723; 18 ES (V86 only)
724; 14 SS
725; 10 ESP
726; c EFLAGS
727; 8 CS
728; 4 EIP
729; ESP -> 0 Vector number (only use low byte!).
730;
731; @uses none
732ti_GenericInterrupt:
733 cld
734
735 ;
736 ; Setup CPUMCTXCORE frame
737 ;
738 ; ASSUMPTION: If trap in hypervisor, we assume that we can read two dword
739 ; under the bottom of the stack. This is atm safe.
740 ; ASSUMPTION: There is sufficient stack space.
741 ; ASSUMPTION: The stack is not write protected.
742 ;
743%define ESPOFF CPUMCTXCORE_size
744
745 sub esp, CPUMCTXCORE_size
746 mov [esp + CPUMCTXCORE.eax], eax
747 mov [esp + CPUMCTXCORE.ecx], ecx
748 mov [esp + CPUMCTXCORE.edx], edx
749 mov [esp + CPUMCTXCORE.ebx], ebx
750 mov [esp + CPUMCTXCORE.esi], esi
751 mov [esp + CPUMCTXCORE.edi], edi
752 mov [esp + CPUMCTXCORE.ebp], ebp
753
754 mov eax, [esp + 04h + ESPOFF] ; eip
755 mov [esp + CPUMCTXCORE.eip], eax
756%if GC_ARCH_BITS == 64
757 ; zero out the high dword
758 mov dword [esp + CPUMCTXCORE.eip + 4], 0
759%endif
760 mov eax, dword [esp + 08h + ESPOFF] ; cs
761 mov [esp + CPUMCTXCORE.cs], eax
762 mov eax, [esp + 0ch + ESPOFF] ; eflags
763 mov [esp + CPUMCTXCORE.eflags], eax
764
765 mov eax, [esp + 10h + ESPOFF] ; esp
766 mov [esp + CPUMCTXCORE.esp], eax
767 mov eax, dword [esp + 14h + ESPOFF] ; ss
768 mov [esp + CPUMCTXCORE.ss], eax
769
770 mov eax, es
771 mov dword [esp + CPUMCTXCORE.es], eax
772 mov eax, ds
773 mov dword [esp + CPUMCTXCORE.ds], eax
774 mov eax, fs
775 mov dword [esp + CPUMCTXCORE.fs], eax
776 mov eax, gs
777 mov dword [esp + CPUMCTXCORE.gs], eax
778
779 test dword [esp + CPUMCTXCORE.eflags], X86_EFL_VM
780 jz short ti_SkipV86Entry
781
782 ;
783 ; The DS, ES, FS and GS registers are zeroed in V86 mode and their real values are on the stack
784 ;
785 mov eax, dword [esp + ESPOFF + 18h]
786 mov dword [esp + CPUMCTXCORE.es], eax
787
788 mov eax, dword [esp + ESPOFF + 1Ch]
789 mov dword [esp + CPUMCTXCORE.ds], eax
790
791 mov eax, dword [esp + ESPOFF + 20h]
792 mov dword [esp + CPUMCTXCORE.fs], eax
793
794 mov eax, dword [esp + ESPOFF + 24h]
795 mov dword [esp + CPUMCTXCORE.gs], eax
796
797ti_SkipV86Entry:
798
799 ;
800 ; Disable Ring-0 WP
801 ;
802 mov eax, cr0 ;; @todo try elimiate this read.
803 and eax, ~X86_CR0_WRITE_PROTECT
804 mov cr0, eax
805
806 ;
807 ; Load Hypervisor DS and ES (get it from the SS)
808 ;
809 mov eax, ss
810 mov ds, eax
811 mov es, eax
812
813 ;
814 ; Store the information about the active trap/interrupt.
815 ;
816 mov eax, IMP(g_TRPM)
817 movzx edx, byte [esp + 0h + ESPOFF] ; vector number
818 mov [eax + TRPM.uActiveVector], edx
819 xor edx, edx
820 mov dword [eax + TRPM.enmActiveType], TRPM_HARDWARE_INT
821 dec edx
822 mov [eax + TRPM.uActiveErrorCode], edx
823 mov [eax + TRPM.uActiveCR2], edx
824%if GC_ARCH_BITS == 64
825 ; zero out the high dword
826 mov dword [eax + TRPM.uActiveErrorCode + 4], 0
827 mov dword [eax + TRPM.uActiveCR2 + 4], 0
828%endif
829
830 ;
831 ; Check if we're in Hypervisor when this happend.
832 ;
833 test byte [esp + 08h + ESPOFF], 3h ; check CPL of the cs selector
834 jnz short gi_NotHyperVisor
835 jmp gi_HyperVisor
836
837 ;
838 ; Trap in guest code.
839 ;
840gi_NotHyperVisor:
841 and dword [esp + CPUMCTXCORE.eflags], ~010000h ; Clear RF (Resume Flag). @todo make %defines for eflags.
842 ; The guest shall not see this in it's state.
843%ifdef DEBUG_STUFF_INT
844 mov ecx, 'intG' ; indicate trap.
845 movzx edx, byte [esp + 0h + ESPOFF] ; vector number
846 lea eax, [esp]
847 call trpmDbgDumpRegisterFrame
848%endif
849
850 ;
851 ; Switch back to the host and process it there.
852 ;
853 mov edx, IMP(g_VM)
854 mov eax, VINF_EM_RAW_INTERRUPT
855 call [edx + VM.pfnVMMGCGuestToHostAsmGuestCtx]
856
857 ;
858 ; We've returned!
859 ; NOTE that the stack has been changed now!
860 ; there is no longer any CPUMCTXCORE around and esp points to vector number!
861 ;
862 ; Reset TRPM state
863 mov eax, IMP(g_TRPM)
864 xor edx, edx
865 dec edx ; edx = 0ffffffffh
866 xchg [eax + TRPM.uActiveVector], edx
867 mov [eax + TRPM.uPrevVector], edx
868
869 ; Enable WP
870 mov eax, cr0 ;; @todo try elimiate this read.
871 or eax, X86_CR0_WRITE_PROTECT
872 mov cr0, eax
873 ; restore guest context and continue execution.
874 lea eax, [esp + 8]
875 push eax
876 call NAME(CPUMGCRestoreInt)
877 lea esp, [esp + 0ch] ; cleanup call and skip vector & error code.
878
879 iret
880
881 ; -+- Entry point -+-
882 ;
883 ; We're in hypervisor mode which means no guest context
884 ; and special care to be taken to restore the hypervisor
885 ; context correctely.
886 ;
887 ; ATM the only place this can happen is when entering a trap handler.
888 ; We make ASSUMPTIONS about this in respects to the WP CR0 bit
889 ;
890gi_HyperVisor:
891 lea eax, [esp + 14h + ESPOFF] ; calc esp at trap
892 mov [esp + CPUMCTXCORE.esp], eax ; update esp in register frame
893 mov [esp + CPUMCTXCORE.ss], ss ; update ss in register frame
894
895%ifdef DEBUG_STUFF_INT
896 mov ebx, [esp + 4h + ESPOFF] ; error code
897 mov ecx, 'intH' ; indicate hypervisor interrupt.
898 movzx edx, byte [esp + 0h + ESPOFF] ; vector number
899 lea eax, [esp]
900 call trpmDbgDumpRegisterFrame
901%endif
902
903 mov ecx, esp
904 mov edx, IMP(g_VM)
905 mov eax, VINF_EM_RAW_INTERRUPT_HYPER
906 call [edx + VM.pfnVMMGCGuestToHostAsm]
907%ifdef DEBUG_STUFF_INT
908 COM_CHAR '!'
909%endif
910
911 ;
912 ; We've returned!
913 ;
914 ; Reset TRPM state - don't record this.
915 mov eax, IMP(g_TRPM)
916 mov dword [eax + TRPM.uActiveVector], 0ffffffffh
917
918 ;
919 ; Restore the hypervisor context and return.
920 ;
921 mov ecx, [esp + CPUMCTXCORE.ecx]
922 mov edx, [esp + CPUMCTXCORE.edx]
923 mov ebx, [esp + CPUMCTXCORE.ebx]
924 mov ebp, [esp + CPUMCTXCORE.ebp]
925 mov esi, [esp + CPUMCTXCORE.esi]
926 mov edi, [esp + CPUMCTXCORE.edi]
927
928 ; In V86 mode DS, ES, FS & GS are restored by the iret
929 test dword [esp + CPUMCTXCORE.eflags], X86_EFL_VM
930 jnz short ti_SkipSelRegs
931
932 mov eax, [esp + CPUMCTXCORE.gs]
933 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_GS | TRPM_TRAP_IN_HYPER
934 mov gs, eax
935
936 mov eax, [esp + CPUMCTXCORE.fs]
937 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_FS | TRPM_TRAP_IN_HYPER
938 mov fs, eax
939
940 mov eax, [esp + CPUMCTXCORE.es]
941 mov es, eax
942 mov eax, [esp + CPUMCTXCORE.ds]
943 mov ds, eax
944
945ti_SkipSelRegs:
946 ; finally restore our scratch register eax
947 mov eax, [esp + CPUMCTXCORE.eax]
948
949 ; skip esp, ss, cs, eip & eflags. Done by iret
950
951 add esp, ESPOFF + 4h ; skip CPUMCTXCORE structure & vector number.
952
953 iret
954%undef ESPOFF
955ENDPROC TRPMGCHandlerInterupt
956
957
958
959;;
960; Trap handler for #MC
961;
962; This handler will forward the #MC to the host OS. Since this
963; is generalized in the generic interrupt handler, we just disable
964; interrupts and push vector number and jump to the generic code.
965;
966; Stack:
967; 10 SS (only if ring transition.)
968; c ESP (only if ring transition.)
969; 8 EFLAGS
970; 4 CS
971; 0 EIP
972;
973; @uses none
974;
975ALIGNCODE(16)
976BEGINPROC_EXPORTED TRPMGCHandlerTrap12
977 push byte 12h
978 jmp ti_GenericInterrupt
979ENDPROC TRPMGCHandlerTrap12
980
981
982
983
984;;
985; Trap handler for double fault (#DF).
986;
987; This is a special trap handler executes in separate task with own TSS, with
988; one of the intermediate memory contexts instead of the shadow context.
989; The handler will unconditionally print an report to the comport configured
990; for the COM_S_* macros before attempting to return to the host. If it it ends
991; up double faulting more than 10 times, it will simply cause an tripple fault
992; to get us out of the mess.
993;
994; @param esp Half way down the hypvervisor stack + the trap frame.
995; @param ebp Half way down the hypvervisor stack.
996; @param eflags Interrupts disabled, nested flag is probably set (we don't care).
997; @param ecx The address of the hypervisor TSS.
998; @param edi Same as ecx.
999; @param eax Same as ecx.
1000; @param edx Address of the VM structure.
1001; @param esi Same as edx.
1002; @param ebx Same as edx.
1003; @param ss Hypervisor DS.
1004; @param ds Hypervisor DS.
1005; @param es Hypervisor DS.
1006; @param fs 0
1007; @param gs 0
1008;
1009;
1010; @remark To be able to catch errors with WP turned off, it is required that the
1011; TSS GDT descriptor and the TSSes are writable (X86_PTE_RW). See SELM.cpp
1012; for how to enable this.
1013;
1014; @remark It is *not* safe to resume the VMM after a double fault. (At least not
1015; without clearing the busy flag of the TssTrap8 and fixing whatever cause it.)
1016;
1017ALIGNCODE(16)
1018BEGINPROC_EXPORTED TRPMGCHandlerTrap08
1019 ; be careful.
1020 cli
1021 cld
1022
1023 ;
1024 ; Load Hypervisor DS and ES (get it from the SS) - paranoia, but the TSS could be overwritten.. :)
1025 ;
1026 mov eax, ss
1027 mov ds, eax
1028 mov es, eax
1029
1030 COM_S_PRINT 10,13,'*** Guru Mediation 00000008 - Double Fault! ***',10,13
1031
1032 ;
1033 ; Disable write protection.
1034 ;
1035 mov eax, cr0
1036 and eax, ~X86_CR0_WRITE_PROTECT
1037 mov cr0, eax
1038
1039
1040 COM_S_PRINT 'VM='
1041 COM_S_DWORD_REG edx
1042 COM_S_PRINT ' prevTSS='
1043 COM_S_DWORD_REG ecx
1044 COM_S_PRINT ' prevCR3='
1045 mov eax, [ecx + VBOXTSS.cr3]
1046 COM_S_DWORD_REG eax
1047 COM_S_PRINT ' prevLdtr='
1048 movzx eax, word [ecx + VBOXTSS.selLdt]
1049 COM_S_DWORD_REG eax
1050 COM_S_NEWLINE
1051
1052 ;
1053 ; Create CPUMCTXCORE structure.
1054 ;
1055 sub esp, CPUMCTXCORE_size
1056
1057 mov eax, [ecx + VBOXTSS.eip]
1058 mov [esp + CPUMCTXCORE.eip], eax
1059%if GC_ARCH_BITS == 64
1060 ; zero out the high dword
1061 mov dword [esp + CPUMCTXCORE.eip + 4], 0
1062%endif
1063 mov eax, [ecx + VBOXTSS.eflags]
1064 mov [esp + CPUMCTXCORE.eflags], eax
1065
1066 movzx eax, word [ecx + VBOXTSS.cs]
1067 mov dword [esp + CPUMCTXCORE.cs], eax
1068 movzx eax, word [ecx + VBOXTSS.ds]
1069 mov dword [esp + CPUMCTXCORE.ds], eax
1070 movzx eax, word [ecx + VBOXTSS.es]
1071 mov dword [esp + CPUMCTXCORE.es], eax
1072 movzx eax, word [ecx + VBOXTSS.fs]
1073 mov dword [esp + CPUMCTXCORE.fs], eax
1074 movzx eax, word [ecx + VBOXTSS.gs]
1075 mov dword [esp + CPUMCTXCORE.gs], eax
1076 movzx eax, word [ecx + VBOXTSS.ss]
1077 mov [esp + CPUMCTXCORE.ss], eax
1078 mov eax, [ecx + VBOXTSS.esp]
1079 mov [esp + CPUMCTXCORE.esp], eax
1080 mov eax, [ecx + VBOXTSS.ecx]
1081 mov [esp + CPUMCTXCORE.ecx], eax
1082 mov eax, [ecx + VBOXTSS.edx]
1083 mov [esp + CPUMCTXCORE.edx], eax
1084 mov eax, [ecx + VBOXTSS.ebx]
1085 mov [esp + CPUMCTXCORE.ebx], eax
1086 mov eax, [ecx + VBOXTSS.eax]
1087 mov [esp + CPUMCTXCORE.eax], eax
1088 mov eax, [ecx + VBOXTSS.ebp]
1089 mov [esp + CPUMCTXCORE.ebp], eax
1090 mov eax, [ecx + VBOXTSS.esi]
1091 mov [esp + CPUMCTXCORE.esi], eax
1092 mov eax, [ecx + VBOXTSS.edi]
1093 mov [esp + CPUMCTXCORE.edi], eax
1094
1095 ;
1096 ; Show regs
1097 ;
1098 mov ebx, 0ffffffffh
1099 mov ecx, 'trpH' ; indicate trap.
1100 mov edx, 08h ; vector number
1101 lea eax, [esp]
1102 call trpmDbgDumpRegisterFrame
1103
1104 ;
1105 ; Should we try go back?
1106 ;
1107 inc dword [df_Count]
1108 cmp dword [df_Count], byte 10
1109 jb df_to_host
1110 jmp df_tripple_fault
1111df_Count: dd 0
1112
1113 ;
1114 ; Try return to the host.
1115 ;
1116df_to_host:
1117 COM_S_PRINT 'Trying to return to host...',10,13
1118 mov ecx, esp
1119 mov edx, IMP(g_VM)
1120 mov eax, VERR_TRPM_PANIC
1121 call [edx + VM.pfnVMMGCGuestToHostAsmHyperCtx]
1122 jmp short df_to_host
1123
1124 ;
1125 ; Perform a tripple fault.
1126 ;
1127df_tripple_fault:
1128 COM_S_PRINT 'Giving up - tripple faulting the machine...',10,13
1129 push byte 0
1130 push byte 0
1131 sidt [esp]
1132 mov word [esp], 0
1133 lidt [esp]
1134 xor eax, eax
1135 mov dword [eax], 0
1136 jmp df_tripple_fault
1137
1138ENDPROC TRPMGCHandlerTrap08
1139
1140
1141
1142
1143;;
1144; Internal procedure used to dump registers.
1145;
1146; @param eax Pointer to CPUMCTXCORE.
1147; @param edx Vector number
1148; @param ecx 'trap' if trap, 'int' if interrupt.
1149; @param ebx Error code if trap.
1150;
1151trpmDbgDumpRegisterFrame:
1152 sub esp, byte 8 ; working space for sidt/sgdt/etc
1153
1154; Init _must_ be done on host before crashing!
1155; push edx
1156; push eax
1157; COM_INIT
1158; pop eax
1159; pop edx
1160
1161 cmp ecx, 'trpH'
1162 je near tddrf_trpH
1163 cmp ecx, 'trpG'
1164 je near tddrf_trpG
1165 cmp ecx, 'intH'
1166 je near tddrf_intH
1167 cmp ecx, 'intG'
1168 je near tddrf_intG
1169 cmp ecx, 'resH'
1170 je near tddrf_resH
1171 COM_S_PRINT 10,13,'*** Bogus Dump Code '
1172 jmp tddrf_regs
1173
1174%if 1 ; the verbose version
1175
1176tddrf_intG:
1177 COM_S_PRINT 10,13,'*** Interrupt (Guest) '
1178 COM_S_DWORD_REG edx
1179 jmp tddrf_regs
1180
1181tddrf_intH:
1182 COM_S_PRINT 10,13,'*** Interrupt (Hypervisor) '
1183 COM_S_DWORD_REG edx
1184 jmp tddrf_regs
1185
1186tddrf_trpG:
1187 COM_S_PRINT 10,13,'*** Trap '
1188 jmp tddrf_trap_rest
1189
1190%else ; the short version
1191
1192tddrf_intG:
1193 COM_S_CHAR 'I'
1194 jmp tddrf_ret
1195
1196tddrf_intH:
1197 COM_S_CHAR 'i'
1198 jmp tddrf_ret
1199
1200tddrf_trpG:
1201 COM_S_CHAR 'T'
1202 jmp tddrf_ret
1203
1204%endif ; the short version
1205
1206tddrf_trpH:
1207 COM_S_PRINT 10,13,'*** Guru Meditation '
1208 jmp tddrf_trap_rest
1209
1210tddrf_resH:
1211 COM_S_PRINT 10,13,'*** Resuming Hypervisor Trap '
1212 jmp tddrf_trap_rest
1213
1214tddrf_trap_rest:
1215 COM_S_DWORD_REG edx
1216 COM_S_PRINT ' ErrorCode='
1217 COM_S_DWORD_REG ebx
1218 COM_S_PRINT ' cr2='
1219 mov ecx, cr2
1220 COM_S_DWORD_REG ecx
1221
1222tddrf_regs:
1223 COM_S_PRINT ' ***',10,13,'cs:eip='
1224 movzx ecx, word [eax + CPUMCTXCORE.cs]
1225 COM_S_DWORD_REG ecx
1226 COM_S_CHAR ':'
1227 mov ecx, [eax + CPUMCTXCORE.eip]
1228 COM_S_DWORD_REG ecx
1229
1230 COM_S_PRINT ' ss:esp='
1231 movzx ecx, word [eax + CPUMCTXCORE.ss]
1232 COM_S_DWORD_REG ecx
1233 COM_S_CHAR ':'
1234 mov ecx, [eax + CPUMCTXCORE.esp]
1235 COM_S_DWORD_REG ecx
1236
1237
1238 sgdt [esp]
1239 COM_S_PRINT 10,13,' gdtr='
1240 movzx ecx, word [esp]
1241 COM_S_DWORD_REG ecx
1242 COM_S_CHAR ':'
1243 mov ecx, [esp + 2]
1244 COM_S_DWORD_REG ecx
1245
1246 sidt [esp]
1247 COM_S_PRINT ' idtr='
1248 movzx ecx, word [esp]
1249 COM_S_DWORD_REG ecx
1250 COM_S_CHAR ':'
1251 mov ecx, [esp + 2]
1252 COM_S_DWORD_REG ecx
1253
1254
1255 str [esp] ; yasm BUG! it generates sldt [esp] here! YASMCHECK!
1256 COM_S_PRINT 10,13,' tr='
1257 movzx ecx, word [esp]
1258 COM_S_DWORD_REG ecx
1259
1260 sldt [esp]
1261 COM_S_PRINT ' ldtr='
1262 movzx ecx, word [esp]
1263 COM_S_DWORD_REG ecx
1264
1265 COM_S_PRINT ' eflags='
1266 mov ecx, [eax + CPUMCTXCORE.eflags]
1267 COM_S_DWORD_REG ecx
1268
1269
1270 COM_S_PRINT 10,13,'cr0='
1271 mov ecx, cr0
1272 COM_S_DWORD_REG ecx
1273
1274 COM_S_PRINT ' cr2='
1275 mov ecx, cr2
1276 COM_S_DWORD_REG ecx
1277
1278 COM_S_PRINT ' cr3='
1279 mov ecx, cr3
1280 COM_S_DWORD_REG ecx
1281 COM_S_PRINT ' cr4='
1282 mov ecx, cr4
1283 COM_S_DWORD_REG ecx
1284
1285
1286 COM_S_PRINT 10,13,' ds='
1287 movzx ecx, word [eax + CPUMCTXCORE.ds]
1288 COM_S_DWORD_REG ecx
1289
1290 COM_S_PRINT ' es='
1291 movzx ecx, word [eax + CPUMCTXCORE.es]
1292 COM_S_DWORD_REG ecx
1293
1294 COM_S_PRINT ' fs='
1295 movzx ecx, word [eax + CPUMCTXCORE.fs]
1296 COM_S_DWORD_REG ecx
1297
1298 COM_S_PRINT ' gs='
1299 movzx ecx, word [eax + CPUMCTXCORE.gs]
1300 COM_S_DWORD_REG ecx
1301
1302
1303 COM_S_PRINT 10,13,'eax='
1304 mov ecx, [eax + CPUMCTXCORE.eax]
1305 COM_S_DWORD_REG ecx
1306
1307 COM_S_PRINT ' ebx='
1308 mov ecx, [eax + CPUMCTXCORE.ebx]
1309 COM_S_DWORD_REG ecx
1310
1311 COM_S_PRINT ' ecx='
1312 mov ecx, [eax + CPUMCTXCORE.ecx]
1313 COM_S_DWORD_REG ecx
1314
1315 COM_S_PRINT ' edx='
1316 mov ecx, [eax + CPUMCTXCORE.edx]
1317 COM_S_DWORD_REG ecx
1318
1319
1320 COM_S_PRINT 10,13,'esi='
1321 mov ecx, [eax + CPUMCTXCORE.esi]
1322 COM_S_DWORD_REG ecx
1323
1324 COM_S_PRINT ' edi='
1325 mov ecx, [eax + CPUMCTXCORE.edi]
1326 COM_S_DWORD_REG ecx
1327
1328 COM_S_PRINT ' ebp='
1329 mov ecx, [eax + CPUMCTXCORE.ebp]
1330 COM_S_DWORD_REG ecx
1331
1332
1333 COM_S_NEWLINE
1334
1335tddrf_ret:
1336 add esp, byte 8
1337 ret
1338
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