VirtualBox

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

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

http://en.wikipedia.org/wiki/Guru_Meditation

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 42.7 KB
Line 
1; $Id: TRPMGCHandlersA.asm 11473 2008-08-19 07:31:58Z 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%if GC_ARCH_BITS == 64
267 ; zero out the high dword
268 mov dword [esp + CPUMCTXCORE.esp + 4], 0
269%endif
270 mov eax, [esp + 18h + ESPOFF] ; ss
271 mov dword [esp + CPUMCTXCORE.ss], eax
272
273 mov eax, [esp + 0ch + ESPOFF] ; cs
274 mov dword [esp + CPUMCTXCORE.cs], eax
275 mov eax, [esp + 08h + ESPOFF] ; eip
276 mov [esp + CPUMCTXCORE.eip], eax
277%if GC_ARCH_BITS == 64
278 ; zero out the high dword
279 mov dword [esp + CPUMCTXCORE.eip + 4], 0
280%endif
281 mov eax, [esp + 10h + ESPOFF] ; eflags
282 mov [esp + CPUMCTXCORE.eflags], eax
283
284 mov eax, es
285 mov dword [esp + CPUMCTXCORE.es], eax
286 mov eax, ds
287 mov dword [esp + CPUMCTXCORE.ds], eax
288 mov eax, fs
289 mov dword [esp + CPUMCTXCORE.fs], eax
290 mov eax, gs
291 mov dword [esp + CPUMCTXCORE.gs], eax
292
293 test dword [esp + CPUMCTXCORE.eflags], X86_EFL_VM
294 jz short gt_SkipV86Entry
295
296 ;
297 ; The DS, ES, FS and GS registers are zeroed in V86 mode and their real values are on the stack
298 ;
299 mov eax, dword [esp + ESPOFF + 1Ch]
300 mov dword [esp + CPUMCTXCORE.es], eax
301
302 mov eax, dword [esp + ESPOFF + 20h]
303 mov dword [esp + CPUMCTXCORE.ds], eax
304
305 mov eax, dword [esp + ESPOFF + 24h]
306 mov dword [esp + CPUMCTXCORE.fs], eax
307
308 mov eax, dword [esp + ESPOFF + 28h]
309 mov dword [esp + CPUMCTXCORE.gs], eax
310
311gt_SkipV86Entry:
312 ;
313 ; Disable Ring-0 WP
314 ;
315 mov eax, cr0 ;; @todo elimitate this read?
316 and eax, ~X86_CR0_WRITE_PROTECT
317 mov cr0, eax
318
319 ;
320 ; Load Hypervisor DS and ES (get it from the SS)
321 ;
322 mov eax, ss
323 mov ds, eax
324 mov es, eax
325
326%ifdef VBOX_WITH_STATISTICS
327 ;
328 ; Start profiling.
329 ;
330 mov edx, [esp + 0h + ESPOFF] ; vector number
331 imul edx, edx, byte STAMPROFILEADV_size ; assumes < 128.
332 add edx, TRPM.aStatGCTraps
333 add edx, IMP(g_TRPM)
334 STAM_PROFILE_ADV_START edx
335%endif
336
337 ;
338 ; Store the information about the active trap/interrupt.
339 ;
340 mov eax, IMP(g_TRPM)
341 movzx edx, byte [esp + 0h + ESPOFF] ; vector number
342 mov [eax + TRPM.uActiveVector], edx
343 mov edx, [esp + 4h + ESPOFF] ; error code
344 mov [eax + TRPM.uActiveErrorCode], edx
345 mov dword [eax + TRPM.enmActiveType], TRPM_TRAP
346 mov edx, cr2 ;; @todo Check how expensive cr2 reads are!
347 mov dword [eax + TRPM.uActiveCR2], edx
348
349%if GC_ARCH_BITS == 64
350 ; zero out the high dword
351 mov dword [eax + TRPM.uActiveErrorCode + 4], 0
352 mov dword [eax + TRPM.uActiveCR2 + 4], 0
353%endif
354
355 ;
356 ; Check if we're in Hypervisor when this happend.
357 ;
358 test dword [esp + CPUMCTXCORE.eflags], X86_EFL_VM
359 jnz short gt_NotHyperVisor
360
361 test byte [esp + 0ch + ESPOFF], 3h ; check CPL of the cs selector
362 jz near gt_InHypervisor
363
364 ;
365 ; Trap in guest code.
366 ;
367gt_NotHyperVisor:
368%ifdef DEBUG_STUFF_TRPG
369 mov ebx, [esp + 4h + ESPOFF] ; error code
370 mov ecx, 'trpG' ; indicate trap.
371 mov edx, [esp + 0h + ESPOFF] ; vector number
372 lea eax, [esp]
373 call trpmDbgDumpRegisterFrame
374%endif
375
376 ;
377 ; Do we have a GC handler for these traps?
378 ;
379 mov edx, [esp + 0h + ESPOFF] ; vector number
380 mov eax, [g_apfnStaticTrapHandlersGuest + edx * 4]
381 or eax, eax
382 jnz short gt_HaveHandler
383 mov eax, VINF_EM_RAW_GUEST_TRAP
384 jmp short gt_GuestTrap
385
386 ;
387 ; Call static handler.
388 ;
389gt_HaveHandler:
390 push esp ; Param 2 - CPUMCTXCORE pointer.
391 push dword IMP(g_TRPM) ; Param 1 - Pointer to TRPM
392 call eax
393 add esp, byte 8 ; cleanup stack (cdecl)
394 or eax, eax
395 je near gt_continue_guest
396
397 ;
398 ; Switch back to the host and process it there.
399 ;
400gt_GuestTrap:
401%ifdef VBOX_WITH_STATISTICS
402 mov edx, [esp + 0h + ESPOFF] ; vector number
403 imul edx, edx, byte STAMPROFILEADV_size ; assume < 128
404 add edx, IMP(g_TRPM)
405 add edx, TRPM.aStatGCTraps
406 STAM_PROFILE_ADV_STOP edx
407%endif
408 mov edx, IMP(g_VM)
409 call [edx + VM.pfnVMMGCGuestToHostAsmGuestCtx]
410
411 ;; @todo r=bird: is this path actually every taken? if not we should replace this code with a panic.
412 ;
413 ; We've returned!
414 ; N.B. The stack has been changed now! No CPUMCTXCORE any longer. esp = vector number.
415 ; N.B. Current scheduling design causes this code path to be unused.
416 ; N.B. Better not use it when in V86 mode!
417 ;
418
419 ; Enable WP
420 mov eax, cr0 ;; @todo try elimiate this read.
421 or eax, X86_CR0_WRITE_PROTECT
422 mov cr0, eax
423 ; Restore guest context and continue execution.
424 mov edx, IMP(g_CPUM)
425 lea eax, [esp + 8]
426 push eax
427 call NAME(CPUMGCRestoreInt)
428 lea esp, [esp + 0ch] ; cleanup call and skip vector & error code.
429
430 iret
431
432
433 ;
434 ; Continue(/Resume/Restart/Whatever) guest execution.
435 ;
436ALIGNCODE(16)
437gt_continue_guest:
438%ifdef VBOX_WITH_STATISTICS
439 mov edx, [esp + 0h + ESPOFF] ; vector number
440 imul edx, edx, byte STAMPROFILEADV_size ; assumes < 128
441 add edx, TRPM.aStatGCTraps
442 add edx, IMP(g_TRPM)
443 STAM_PROFILE_ADV_STOP edx
444%endif
445
446 ; enable WP
447 mov eax, cr0 ;; @todo try elimiate this read.
448 or eax, X86_CR0_WRITE_PROTECT
449 mov cr0, eax
450
451 ; restore guest state and start executing again.
452 test dword [esp + CPUMCTXCORE.eflags], X86_EFL_VM
453 jnz gt_V86Return
454
455 mov ecx, [esp + CPUMCTXCORE.ecx]
456 mov edx, [esp + CPUMCTXCORE.edx]
457 mov ebx, [esp + CPUMCTXCORE.ebx]
458 mov ebp, [esp + CPUMCTXCORE.ebp]
459 mov esi, [esp + CPUMCTXCORE.esi]
460 mov edi, [esp + CPUMCTXCORE.edi]
461
462 mov eax, [esp + CPUMCTXCORE.esp]
463 mov [esp + 14h + ESPOFF], eax ; esp
464 mov eax, dword [esp + CPUMCTXCORE.ss]
465 mov [esp + 18h + ESPOFF], eax ; ss
466
467 mov eax, dword [esp + CPUMCTXCORE.gs]
468 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_GS
469 mov gs, eax
470
471 mov eax, dword [esp + CPUMCTXCORE.fs]
472 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_FS
473 mov fs, eax
474
475 mov eax, dword [esp + CPUMCTXCORE.es]
476 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_ES
477 mov es, eax
478
479 mov eax, dword [esp + CPUMCTXCORE.ds]
480 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_DS
481 mov ds, eax
482
483 mov eax, dword [esp + CPUMCTXCORE.cs]
484 mov [esp + 0ch + ESPOFF], eax ; cs
485 mov eax, [esp + CPUMCTXCORE.eflags]
486 mov [esp + 10h + ESPOFF], eax ; eflags
487 mov eax, [esp + CPUMCTXCORE.eip]
488 mov [esp + 08h + ESPOFF], eax ; eip
489
490 ; finally restore our scratch register eax
491 mov eax, [esp + CPUMCTXCORE.eax]
492
493 add esp, ESPOFF + 8 ; skip CPUMCTXCORE structure, error code and vector number
494
495 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_IRET
496 iret
497
498ALIGNCODE(16)
499gt_V86Return:
500 mov ecx, [esp + CPUMCTXCORE.ecx]
501 mov edx, [esp + CPUMCTXCORE.edx]
502 mov ebx, [esp + CPUMCTXCORE.ebx]
503 mov ebp, [esp + CPUMCTXCORE.ebp]
504 mov esi, [esp + CPUMCTXCORE.esi]
505 mov edi, [esp + CPUMCTXCORE.edi]
506
507 mov eax, [esp + CPUMCTXCORE.esp]
508 mov [esp + 14h + ESPOFF], eax ; esp
509 mov eax, dword [esp + CPUMCTXCORE.ss]
510 mov [esp + 18h + ESPOFF], eax ; ss
511
512 mov eax, dword [esp + CPUMCTXCORE.es]
513 mov [esp + 1ch + ESPOFF], eax ; es
514 mov eax, dword [esp + CPUMCTXCORE.ds]
515 mov [esp + 20h + ESPOFF], eax ; ds
516 mov eax, dword [esp + CPUMCTXCORE.fs]
517 mov [esp + 24h + ESPOFF], eax ; fs
518 mov eax, dword [esp + CPUMCTXCORE.gs]
519 mov [esp + 28h + ESPOFF], eax ; gs
520
521 mov eax, [esp + CPUMCTXCORE.eip]
522 mov [esp + 08h + ESPOFF], eax ; eip
523 mov eax, dword [esp + CPUMCTXCORE.cs]
524 mov [esp + 0ch + ESPOFF], eax ; cs
525 mov eax, [esp + CPUMCTXCORE.eflags]
526 mov [esp + 10h + ESPOFF], eax ; eflags
527
528 ; finally restore our scratch register eax
529 mov eax, [esp + CPUMCTXCORE.eax]
530
531 add esp, ESPOFF + 8 ; skip CPUMCTXCORE structure, error code and vector number
532
533 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_IRET | TRPM_TRAP_IN_V86
534 iret
535
536 ;
537 ; Trap in Hypervisor, try to handle it.
538 ;
539 ; (eax = pTRPM)
540 ;
541ALIGNCODE(16)
542gt_InHypervisor:
543 ; fix ss:esp.
544 lea ebx, [esp + 14h + ESPOFF] ; calc esp at trap
545 mov [esp + CPUMCTXCORE.esp], ebx; update esp in register frame
546 mov [esp + CPUMCTXCORE.ss], ss ; update ss in register frame
547
548 ; tell cpum about the context core.
549 xchg esi, eax ; save pTRPM - @todo reallocate this variable to esi, edi, or ebx
550 push esp ; Param 2 - The new CPUMCTXCORE pointer.
551 push IMP(g_VM) ; Param 1 - Pointer to the VM.
552 call NAME(CPUMHyperSetCtxCore)
553 add esp, byte 8 ; stack cleanup (cdecl)
554 xchg eax, esi ; restore pTRPM
555
556 ; check for temporary handler.
557 movzx ebx, byte [eax + TRPM.uActiveVector]
558 xor ecx, ecx
559 xchg ecx, [eax + TRPM.aTmpTrapHandlers + ebx * 4] ; ecx = Temp handler pointer or 0
560 or ecx, ecx
561 jnz short gt_Hyper_HaveTemporaryHandler
562
563 ; check for static trap handler.
564 mov ecx, [g_apfnStaticTrapHandlersHyper + ebx * 4] ; ecx = Static handler pointer or 0
565 or ecx, ecx
566 jnz short gt_Hyper_HaveStaticHandler
567 jmp gt_Hyper_AbandonShip
568
569
570 ;
571 ; Temporary trap handler present, call it (CDECL).
572 ;
573gt_Hyper_HaveTemporaryHandler:
574 push esp ; Param 2 - Pointer to CPUMCTXCORE.
575 push IMP(g_VM) ; Param 1 - Pointer to VM.
576 call ecx
577 add esp, byte 8 ; cleanup stack (cdecl)
578
579 cmp eax, byte VINF_SUCCESS ; If completely handled Then resume execution.
580 je near gt_Hyper_Continue
581 ;; @todo Handle ALL returns types from temporary handlers!
582 jmp gt_Hyper_AbandonShip
583
584
585 ;
586 ; Static trap handler present, call it (CDECL).
587 ;
588gt_Hyper_HaveStaticHandler:
589 push esp ; Param 2 - Pointer to CPUMCTXCORE.
590 push eax ; Param 1 - Pointer to TRPM
591 call ecx
592 add esp, byte 8 ; cleanup stack (cdecl)
593
594 cmp eax, byte VINF_SUCCESS ; If completely handled Then resume execution.
595 je short gt_Hyper_Continue
596 cmp eax, VINF_EM_DBG_HYPER_STEPPED
597 je short gt_Hyper_ToHost
598 cmp eax, VINF_EM_DBG_HYPER_BREAKPOINT
599 je short gt_Hyper_ToHost
600 cmp eax, VINF_EM_DBG_HYPER_ASSERTION
601 je short gt_Hyper_ToHost
602 jmp gt_Hyper_AbandonShip
603
604 ;
605 ; Pop back to the host to service the error.
606 ;
607gt_Hyper_ToHost:
608 mov ecx, esp
609 mov edx, IMP(g_VM)
610 call [edx + VM.pfnVMMGCGuestToHostAsm]
611 jmp short gt_Hyper_Continue
612
613 ;
614 ; Continue(/Resume/Restart/Whatever) hypervisor execution.
615 ; Don't reset the TRPM state. Caller takes care of that.
616 ;
617ALIGNCODE(16)
618gt_Hyper_Continue:
619%ifdef DEBUG_STUFF
620 mov ebx, [esp + 4h + ESPOFF] ; error code
621 mov ecx, 'resH' ; indicate trap.
622 mov edx, [esp + 0h + ESPOFF] ; vector number
623 lea eax, [esp]
624 call trpmDbgDumpRegisterFrame
625%endif
626 ; tell CPUM to use the default CPUMCTXCORE.
627 push byte 0 ; Param 2 - NULL indicating use default context core.
628 push IMP(g_VM) ; Param 1 - The VM pointer.
629 call NAME(CPUMHyperSetCtxCore)
630 add esp, byte 8 ; stack cleanup (cdecl)
631
632%ifdef VBOX_WITH_STATISTICS
633 mov edx, [esp + 0h + ESPOFF] ; vector number
634 imul edx, edx, byte STAMPROFILEADV_size ; assumes < 128
635 add edx, TRPM.aStatGCTraps
636 add edx, IMP(g_TRPM)
637 STAM_PROFILE_ADV_STOP edx
638%endif
639
640 ; restore
641 mov ecx, [esp + CPUMCTXCORE.ecx]
642 mov edx, [esp + CPUMCTXCORE.edx]
643 mov ebx, [esp + CPUMCTXCORE.ebx]
644 mov ebp, [esp + CPUMCTXCORE.ebp]
645 mov esi, [esp + CPUMCTXCORE.esi]
646 mov edi, [esp + CPUMCTXCORE.edi]
647
648 mov eax, dword [esp + CPUMCTXCORE.gs]
649 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_GS | TRPM_TRAP_IN_HYPER
650 mov gs, eax
651
652 mov eax, dword [esp + CPUMCTXCORE.fs]
653 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_FS | TRPM_TRAP_IN_HYPER
654 mov fs, eax
655
656 mov eax, dword [esp + CPUMCTXCORE.es]
657 mov es, eax
658 mov eax, dword [esp + CPUMCTXCORE.ds]
659 mov ds, eax
660
661 ; skip esp & ss
662
663 mov eax, [esp + CPUMCTXCORE.eip]
664 mov [esp + 08h + ESPOFF], eax ; eip
665 mov eax, dword [esp + CPUMCTXCORE.cs]
666 mov [esp + 0ch + ESPOFF], eax ; cs
667 mov eax, [esp + CPUMCTXCORE.eflags]
668 mov [esp + 10h + ESPOFF], eax ; eflags
669
670 ; finally restore our scratch register eax
671 mov eax, [esp + CPUMCTXCORE.eax]
672
673 add esp, ESPOFF + 8 ; skip CPUMCTXCORE structure, error code and vector number
674
675 iret
676
677
678 ;
679 ; ABANDON SHIP! DON'T PANIC!
680 ;
681gt_Hyper_AbandonShip:
682%ifdef DEBUG_STUFF
683 mov ebx, [esp + 4h + ESPOFF] ; error code
684 mov ecx, 'trpH' ; indicate trap.
685 mov edx, [esp + 0h + ESPOFF] ; vector number
686 lea eax, [esp]
687 call trpmDbgDumpRegisterFrame
688%endif
689
690gt_Hyper_DontPanic:
691 mov ecx, esp
692 mov edx, IMP(g_VM)
693 mov eax, VERR_TRPM_DONT_PANIC
694 call [edx + VM.pfnVMMGCGuestToHostAsmHyperCtx]
695%ifdef DEBUG_STUFF
696 COM_S_PRINT 'bad!!!'
697%endif
698 jmp gt_Hyper_DontPanic ; this shall never ever happen!
699%undef ESPOFF
700ENDPROC TRPMGCHandlerGeneric
701
702
703
704
705
706;;
707; We start by 256 push <vector no.> + jmp interruptworker
708;
709ALIGNCODE(16)
710BEGINPROC_EXPORTED TRPMGCHandlerInterupt
711 ; NASM has some nice features, here an example of a loop.
712%assign i 0
713%rep 256
714 db 06ah, i ; push imm8 - note that this is a signextended value.
715 jmp ti_GenericInterrupt
716 ALIGNCODE(8)
717%assign i i+1
718%endrep
719
720;;
721; Main interrupt handler for the guest context
722;
723; Stack:
724; 24 GS (V86 only)
725; 20 FS (V86 only)
726; 1C DS (V86 only)
727; 18 ES (V86 only)
728; 14 SS
729; 10 ESP
730; c EFLAGS
731; 8 CS
732; 4 EIP
733; ESP -> 0 Vector number (only use low byte!).
734;
735; @uses none
736ti_GenericInterrupt:
737 cld
738
739 ;
740 ; Setup CPUMCTXCORE frame
741 ;
742 ; ASSUMPTION: If trap in hypervisor, we assume that we can read two dword
743 ; under the bottom of the stack. This is atm safe.
744 ; ASSUMPTION: There is sufficient stack space.
745 ; ASSUMPTION: The stack is not write protected.
746 ;
747%define ESPOFF CPUMCTXCORE_size
748
749 sub esp, CPUMCTXCORE_size
750 mov [esp + CPUMCTXCORE.eax], eax
751 mov [esp + CPUMCTXCORE.ecx], ecx
752 mov [esp + CPUMCTXCORE.edx], edx
753 mov [esp + CPUMCTXCORE.ebx], ebx
754 mov [esp + CPUMCTXCORE.esi], esi
755 mov [esp + CPUMCTXCORE.edi], edi
756 mov [esp + CPUMCTXCORE.ebp], ebp
757
758 mov eax, [esp + 04h + ESPOFF] ; eip
759 mov [esp + CPUMCTXCORE.eip], eax
760%if GC_ARCH_BITS == 64
761 ; zero out the high dword
762 mov dword [esp + CPUMCTXCORE.eip + 4], 0
763%endif
764 mov eax, dword [esp + 08h + ESPOFF] ; cs
765 mov [esp + CPUMCTXCORE.cs], eax
766 mov eax, [esp + 0ch + ESPOFF] ; eflags
767 mov [esp + CPUMCTXCORE.eflags], eax
768
769 mov eax, [esp + 10h + ESPOFF] ; esp
770 mov [esp + CPUMCTXCORE.esp], eax
771%if GC_ARCH_BITS == 64
772 ; zero out the high dword
773 mov dword [esp + CPUMCTXCORE.esp + 4], 0
774%endif
775 mov eax, dword [esp + 14h + ESPOFF] ; ss
776 mov [esp + CPUMCTXCORE.ss], eax
777
778 mov eax, es
779 mov dword [esp + CPUMCTXCORE.es], eax
780 mov eax, ds
781 mov dword [esp + CPUMCTXCORE.ds], eax
782 mov eax, fs
783 mov dword [esp + CPUMCTXCORE.fs], eax
784 mov eax, gs
785 mov dword [esp + CPUMCTXCORE.gs], eax
786
787 test dword [esp + CPUMCTXCORE.eflags], X86_EFL_VM
788 jz short ti_SkipV86Entry
789
790 ;
791 ; The DS, ES, FS and GS registers are zeroed in V86 mode and their real values are on the stack
792 ;
793 mov eax, dword [esp + ESPOFF + 18h]
794 mov dword [esp + CPUMCTXCORE.es], eax
795
796 mov eax, dword [esp + ESPOFF + 1Ch]
797 mov dword [esp + CPUMCTXCORE.ds], eax
798
799 mov eax, dword [esp + ESPOFF + 20h]
800 mov dword [esp + CPUMCTXCORE.fs], eax
801
802 mov eax, dword [esp + ESPOFF + 24h]
803 mov dword [esp + CPUMCTXCORE.gs], eax
804
805ti_SkipV86Entry:
806
807 ;
808 ; Disable Ring-0 WP
809 ;
810 mov eax, cr0 ;; @todo try elimiate this read.
811 and eax, ~X86_CR0_WRITE_PROTECT
812 mov cr0, eax
813
814 ;
815 ; Load Hypervisor DS and ES (get it from the SS)
816 ;
817 mov eax, ss
818 mov ds, eax
819 mov es, eax
820
821 ;
822 ; Store the information about the active trap/interrupt.
823 ;
824 mov eax, IMP(g_TRPM)
825 movzx edx, byte [esp + 0h + ESPOFF] ; vector number
826 mov [eax + TRPM.uActiveVector], edx
827 xor edx, edx
828 mov dword [eax + TRPM.enmActiveType], TRPM_HARDWARE_INT
829 dec edx
830 mov [eax + TRPM.uActiveErrorCode], edx
831 mov [eax + TRPM.uActiveCR2], edx
832%if GC_ARCH_BITS == 64
833 ; zero out the high dword
834 mov dword [eax + TRPM.uActiveErrorCode + 4], 0
835 mov dword [eax + TRPM.uActiveCR2 + 4], 0
836%endif
837
838 ;
839 ; Check if we're in Hypervisor when this happend.
840 ;
841 test byte [esp + 08h + ESPOFF], 3h ; check CPL of the cs selector
842 jnz short gi_NotHyperVisor
843 jmp gi_HyperVisor
844
845 ;
846 ; Trap in guest code.
847 ;
848gi_NotHyperVisor:
849 and dword [esp + CPUMCTXCORE.eflags], ~010000h ; Clear RF (Resume Flag). @todo make %defines for eflags.
850 ; The guest shall not see this in it's state.
851%ifdef DEBUG_STUFF_INT
852 mov ecx, 'intG' ; indicate trap.
853 movzx edx, byte [esp + 0h + ESPOFF] ; vector number
854 lea eax, [esp]
855 call trpmDbgDumpRegisterFrame
856%endif
857
858 ;
859 ; Switch back to the host and process it there.
860 ;
861 mov edx, IMP(g_VM)
862 mov eax, VINF_EM_RAW_INTERRUPT
863 call [edx + VM.pfnVMMGCGuestToHostAsmGuestCtx]
864
865 ;
866 ; We've returned!
867 ; NOTE that the stack has been changed now!
868 ; there is no longer any CPUMCTXCORE around and esp points to vector number!
869 ;
870 ; Reset TRPM state
871 mov eax, IMP(g_TRPM)
872 xor edx, edx
873 dec edx ; edx = 0ffffffffh
874 xchg [eax + TRPM.uActiveVector], edx
875 mov [eax + TRPM.uPrevVector], edx
876
877 ; Enable WP
878 mov eax, cr0 ;; @todo try elimiate this read.
879 or eax, X86_CR0_WRITE_PROTECT
880 mov cr0, eax
881 ; restore guest context and continue execution.
882 lea eax, [esp + 8]
883 push eax
884 call NAME(CPUMGCRestoreInt)
885 lea esp, [esp + 0ch] ; cleanup call and skip vector & error code.
886
887 iret
888
889 ; -+- Entry point -+-
890 ;
891 ; We're in hypervisor mode which means no guest context
892 ; and special care to be taken to restore the hypervisor
893 ; context correctely.
894 ;
895 ; ATM the only place this can happen is when entering a trap handler.
896 ; We make ASSUMPTIONS about this in respects to the WP CR0 bit
897 ;
898gi_HyperVisor:
899 lea eax, [esp + 14h + ESPOFF] ; calc esp at trap
900 mov [esp + CPUMCTXCORE.esp], eax ; update esp in register frame
901 mov [esp + CPUMCTXCORE.ss], ss ; update ss in register frame
902
903%ifdef DEBUG_STUFF_INT
904 mov ebx, [esp + 4h + ESPOFF] ; error code
905 mov ecx, 'intH' ; indicate hypervisor interrupt.
906 movzx edx, byte [esp + 0h + ESPOFF] ; vector number
907 lea eax, [esp]
908 call trpmDbgDumpRegisterFrame
909%endif
910
911 mov ecx, esp
912 mov edx, IMP(g_VM)
913 mov eax, VINF_EM_RAW_INTERRUPT_HYPER
914 call [edx + VM.pfnVMMGCGuestToHostAsm]
915%ifdef DEBUG_STUFF_INT
916 COM_CHAR '!'
917%endif
918
919 ;
920 ; We've returned!
921 ;
922 ; Reset TRPM state - don't record this.
923 mov eax, IMP(g_TRPM)
924 mov dword [eax + TRPM.uActiveVector], 0ffffffffh
925
926 ;
927 ; Restore the hypervisor context and return.
928 ;
929 mov ecx, [esp + CPUMCTXCORE.ecx]
930 mov edx, [esp + CPUMCTXCORE.edx]
931 mov ebx, [esp + CPUMCTXCORE.ebx]
932 mov ebp, [esp + CPUMCTXCORE.ebp]
933 mov esi, [esp + CPUMCTXCORE.esi]
934 mov edi, [esp + CPUMCTXCORE.edi]
935
936 ; In V86 mode DS, ES, FS & GS are restored by the iret
937 test dword [esp + CPUMCTXCORE.eflags], X86_EFL_VM
938 jnz short ti_SkipSelRegs
939
940 mov eax, [esp + CPUMCTXCORE.gs]
941 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_GS | TRPM_TRAP_IN_HYPER
942 mov gs, eax
943
944 mov eax, [esp + CPUMCTXCORE.fs]
945 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_FS | TRPM_TRAP_IN_HYPER
946 mov fs, eax
947
948 mov eax, [esp + CPUMCTXCORE.es]
949 mov es, eax
950 mov eax, [esp + CPUMCTXCORE.ds]
951 mov ds, eax
952
953ti_SkipSelRegs:
954 ; finally restore our scratch register eax
955 mov eax, [esp + CPUMCTXCORE.eax]
956
957 ; skip esp, ss, cs, eip & eflags. Done by iret
958
959 add esp, ESPOFF + 4h ; skip CPUMCTXCORE structure & vector number.
960
961 iret
962%undef ESPOFF
963ENDPROC TRPMGCHandlerInterupt
964
965
966
967;;
968; Trap handler for #MC
969;
970; This handler will forward the #MC to the host OS. Since this
971; is generalized in the generic interrupt handler, we just disable
972; interrupts and push vector number and jump to the generic code.
973;
974; Stack:
975; 10 SS (only if ring transition.)
976; c ESP (only if ring transition.)
977; 8 EFLAGS
978; 4 CS
979; 0 EIP
980;
981; @uses none
982;
983ALIGNCODE(16)
984BEGINPROC_EXPORTED TRPMGCHandlerTrap12
985 push byte 12h
986 jmp ti_GenericInterrupt
987ENDPROC TRPMGCHandlerTrap12
988
989
990
991
992;;
993; Trap handler for double fault (#DF).
994;
995; This is a special trap handler executes in separate task with own TSS, with
996; one of the intermediate memory contexts instead of the shadow context.
997; The handler will unconditionally print an report to the comport configured
998; for the COM_S_* macros before attempting to return to the host. If it it ends
999; up double faulting more than 10 times, it will simply cause an tripple fault
1000; to get us out of the mess.
1001;
1002; @param esp Half way down the hypvervisor stack + the trap frame.
1003; @param ebp Half way down the hypvervisor stack.
1004; @param eflags Interrupts disabled, nested flag is probably set (we don't care).
1005; @param ecx The address of the hypervisor TSS.
1006; @param edi Same as ecx.
1007; @param eax Same as ecx.
1008; @param edx Address of the VM structure.
1009; @param esi Same as edx.
1010; @param ebx Same as edx.
1011; @param ss Hypervisor DS.
1012; @param ds Hypervisor DS.
1013; @param es Hypervisor DS.
1014; @param fs 0
1015; @param gs 0
1016;
1017;
1018; @remark To be able to catch errors with WP turned off, it is required that the
1019; TSS GDT descriptor and the TSSes are writable (X86_PTE_RW). See SELM.cpp
1020; for how to enable this.
1021;
1022; @remark It is *not* safe to resume the VMM after a double fault. (At least not
1023; without clearing the busy flag of the TssTrap8 and fixing whatever cause it.)
1024;
1025ALIGNCODE(16)
1026BEGINPROC_EXPORTED TRPMGCHandlerTrap08
1027 ; be careful.
1028 cli
1029 cld
1030
1031 ;
1032 ; Load Hypervisor DS and ES (get it from the SS) - paranoia, but the TSS could be overwritten.. :)
1033 ;
1034 mov eax, ss
1035 mov ds, eax
1036 mov es, eax
1037
1038 COM_S_PRINT 10,13,'*** Guru Meditation 00000008 - Double Fault! ***',10,13
1039
1040 ;
1041 ; Disable write protection.
1042 ;
1043 mov eax, cr0
1044 and eax, ~X86_CR0_WRITE_PROTECT
1045 mov cr0, eax
1046
1047
1048 COM_S_PRINT 'VM='
1049 COM_S_DWORD_REG edx
1050 COM_S_PRINT ' prevTSS='
1051 COM_S_DWORD_REG ecx
1052 COM_S_PRINT ' prevCR3='
1053 mov eax, [ecx + VBOXTSS.cr3]
1054 COM_S_DWORD_REG eax
1055 COM_S_PRINT ' prevLdtr='
1056 movzx eax, word [ecx + VBOXTSS.selLdt]
1057 COM_S_DWORD_REG eax
1058 COM_S_NEWLINE
1059
1060 ;
1061 ; Create CPUMCTXCORE structure.
1062 ;
1063 sub esp, CPUMCTXCORE_size
1064
1065 mov eax, [ecx + VBOXTSS.eip]
1066 mov [esp + CPUMCTXCORE.eip], eax
1067%if GC_ARCH_BITS == 64
1068 ; zero out the high dword
1069 mov dword [esp + CPUMCTXCORE.eip + 4], 0
1070%endif
1071 mov eax, [ecx + VBOXTSS.eflags]
1072 mov [esp + CPUMCTXCORE.eflags], eax
1073
1074 movzx eax, word [ecx + VBOXTSS.cs]
1075 mov dword [esp + CPUMCTXCORE.cs], eax
1076 movzx eax, word [ecx + VBOXTSS.ds]
1077 mov dword [esp + CPUMCTXCORE.ds], eax
1078 movzx eax, word [ecx + VBOXTSS.es]
1079 mov dword [esp + CPUMCTXCORE.es], eax
1080 movzx eax, word [ecx + VBOXTSS.fs]
1081 mov dword [esp + CPUMCTXCORE.fs], eax
1082 movzx eax, word [ecx + VBOXTSS.gs]
1083 mov dword [esp + CPUMCTXCORE.gs], eax
1084 movzx eax, word [ecx + VBOXTSS.ss]
1085 mov [esp + CPUMCTXCORE.ss], eax
1086 mov eax, [ecx + VBOXTSS.esp]
1087 mov [esp + CPUMCTXCORE.esp], eax
1088%if GC_ARCH_BITS == 64
1089 ; zero out the high dword
1090 mov dword [esp + CPUMCTXCORE.esp + 4], 0
1091%endif
1092 mov eax, [ecx + VBOXTSS.ecx]
1093 mov [esp + CPUMCTXCORE.ecx], eax
1094 mov eax, [ecx + VBOXTSS.edx]
1095 mov [esp + CPUMCTXCORE.edx], eax
1096 mov eax, [ecx + VBOXTSS.ebx]
1097 mov [esp + CPUMCTXCORE.ebx], eax
1098 mov eax, [ecx + VBOXTSS.eax]
1099 mov [esp + CPUMCTXCORE.eax], eax
1100 mov eax, [ecx + VBOXTSS.ebp]
1101 mov [esp + CPUMCTXCORE.ebp], eax
1102 mov eax, [ecx + VBOXTSS.esi]
1103 mov [esp + CPUMCTXCORE.esi], eax
1104 mov eax, [ecx + VBOXTSS.edi]
1105 mov [esp + CPUMCTXCORE.edi], eax
1106
1107 ;
1108 ; Show regs
1109 ;
1110 mov ebx, 0ffffffffh
1111 mov ecx, 'trpH' ; indicate trap.
1112 mov edx, 08h ; vector number
1113 lea eax, [esp]
1114 call trpmDbgDumpRegisterFrame
1115
1116 ;
1117 ; Should we try go back?
1118 ;
1119 inc dword [df_Count]
1120 cmp dword [df_Count], byte 10
1121 jb df_to_host
1122 jmp df_tripple_fault
1123df_Count: dd 0
1124
1125 ;
1126 ; Try return to the host.
1127 ;
1128df_to_host:
1129 COM_S_PRINT 'Trying to return to host...',10,13
1130 mov ecx, esp
1131 mov edx, IMP(g_VM)
1132 mov eax, VERR_TRPM_PANIC
1133 call [edx + VM.pfnVMMGCGuestToHostAsmHyperCtx]
1134 jmp short df_to_host
1135
1136 ;
1137 ; Perform a tripple fault.
1138 ;
1139df_tripple_fault:
1140 COM_S_PRINT 'Giving up - tripple faulting the machine...',10,13
1141 push byte 0
1142 push byte 0
1143 sidt [esp]
1144 mov word [esp], 0
1145 lidt [esp]
1146 xor eax, eax
1147 mov dword [eax], 0
1148 jmp df_tripple_fault
1149
1150ENDPROC TRPMGCHandlerTrap08
1151
1152
1153
1154
1155;;
1156; Internal procedure used to dump registers.
1157;
1158; @param eax Pointer to CPUMCTXCORE.
1159; @param edx Vector number
1160; @param ecx 'trap' if trap, 'int' if interrupt.
1161; @param ebx Error code if trap.
1162;
1163trpmDbgDumpRegisterFrame:
1164 sub esp, byte 8 ; working space for sidt/sgdt/etc
1165
1166; Init _must_ be done on host before crashing!
1167; push edx
1168; push eax
1169; COM_INIT
1170; pop eax
1171; pop edx
1172
1173 cmp ecx, 'trpH'
1174 je near tddrf_trpH
1175 cmp ecx, 'trpG'
1176 je near tddrf_trpG
1177 cmp ecx, 'intH'
1178 je near tddrf_intH
1179 cmp ecx, 'intG'
1180 je near tddrf_intG
1181 cmp ecx, 'resH'
1182 je near tddrf_resH
1183 COM_S_PRINT 10,13,'*** Bogus Dump Code '
1184 jmp tddrf_regs
1185
1186%if 1 ; the verbose version
1187
1188tddrf_intG:
1189 COM_S_PRINT 10,13,'*** Interrupt (Guest) '
1190 COM_S_DWORD_REG edx
1191 jmp tddrf_regs
1192
1193tddrf_intH:
1194 COM_S_PRINT 10,13,'*** Interrupt (Hypervisor) '
1195 COM_S_DWORD_REG edx
1196 jmp tddrf_regs
1197
1198tddrf_trpG:
1199 COM_S_PRINT 10,13,'*** Trap '
1200 jmp tddrf_trap_rest
1201
1202%else ; the short version
1203
1204tddrf_intG:
1205 COM_S_CHAR 'I'
1206 jmp tddrf_ret
1207
1208tddrf_intH:
1209 COM_S_CHAR 'i'
1210 jmp tddrf_ret
1211
1212tddrf_trpG:
1213 COM_S_CHAR 'T'
1214 jmp tddrf_ret
1215
1216%endif ; the short version
1217
1218tddrf_trpH:
1219 COM_S_PRINT 10,13,'*** Guru Meditation '
1220 jmp tddrf_trap_rest
1221
1222tddrf_resH:
1223 COM_S_PRINT 10,13,'*** Resuming Hypervisor Trap '
1224 jmp tddrf_trap_rest
1225
1226tddrf_trap_rest:
1227 COM_S_DWORD_REG edx
1228 COM_S_PRINT ' ErrorCode='
1229 COM_S_DWORD_REG ebx
1230 COM_S_PRINT ' cr2='
1231 mov ecx, cr2
1232 COM_S_DWORD_REG ecx
1233
1234tddrf_regs:
1235 COM_S_PRINT ' ***',10,13,'cs:eip='
1236 movzx ecx, word [eax + CPUMCTXCORE.cs]
1237 COM_S_DWORD_REG ecx
1238 COM_S_CHAR ':'
1239 mov ecx, [eax + CPUMCTXCORE.eip]
1240 COM_S_DWORD_REG ecx
1241
1242 COM_S_PRINT ' ss:esp='
1243 movzx ecx, word [eax + CPUMCTXCORE.ss]
1244 COM_S_DWORD_REG ecx
1245 COM_S_CHAR ':'
1246 mov ecx, [eax + CPUMCTXCORE.esp]
1247 COM_S_DWORD_REG ecx
1248
1249
1250 sgdt [esp]
1251 COM_S_PRINT 10,13,' gdtr='
1252 movzx ecx, word [esp]
1253 COM_S_DWORD_REG ecx
1254 COM_S_CHAR ':'
1255 mov ecx, [esp + 2]
1256 COM_S_DWORD_REG ecx
1257
1258 sidt [esp]
1259 COM_S_PRINT ' idtr='
1260 movzx ecx, word [esp]
1261 COM_S_DWORD_REG ecx
1262 COM_S_CHAR ':'
1263 mov ecx, [esp + 2]
1264 COM_S_DWORD_REG ecx
1265
1266
1267 str [esp] ; yasm BUG! it generates sldt [esp] here! YASMCHECK!
1268 COM_S_PRINT 10,13,' tr='
1269 movzx ecx, word [esp]
1270 COM_S_DWORD_REG ecx
1271
1272 sldt [esp]
1273 COM_S_PRINT ' ldtr='
1274 movzx ecx, word [esp]
1275 COM_S_DWORD_REG ecx
1276
1277 COM_S_PRINT ' eflags='
1278 mov ecx, [eax + CPUMCTXCORE.eflags]
1279 COM_S_DWORD_REG ecx
1280
1281
1282 COM_S_PRINT 10,13,'cr0='
1283 mov ecx, cr0
1284 COM_S_DWORD_REG ecx
1285
1286 COM_S_PRINT ' cr2='
1287 mov ecx, cr2
1288 COM_S_DWORD_REG ecx
1289
1290 COM_S_PRINT ' cr3='
1291 mov ecx, cr3
1292 COM_S_DWORD_REG ecx
1293 COM_S_PRINT ' cr4='
1294 mov ecx, cr4
1295 COM_S_DWORD_REG ecx
1296
1297
1298 COM_S_PRINT 10,13,' ds='
1299 movzx ecx, word [eax + CPUMCTXCORE.ds]
1300 COM_S_DWORD_REG ecx
1301
1302 COM_S_PRINT ' es='
1303 movzx ecx, word [eax + CPUMCTXCORE.es]
1304 COM_S_DWORD_REG ecx
1305
1306 COM_S_PRINT ' fs='
1307 movzx ecx, word [eax + CPUMCTXCORE.fs]
1308 COM_S_DWORD_REG ecx
1309
1310 COM_S_PRINT ' gs='
1311 movzx ecx, word [eax + CPUMCTXCORE.gs]
1312 COM_S_DWORD_REG ecx
1313
1314
1315 COM_S_PRINT 10,13,'eax='
1316 mov ecx, [eax + CPUMCTXCORE.eax]
1317 COM_S_DWORD_REG ecx
1318
1319 COM_S_PRINT ' ebx='
1320 mov ecx, [eax + CPUMCTXCORE.ebx]
1321 COM_S_DWORD_REG ecx
1322
1323 COM_S_PRINT ' ecx='
1324 mov ecx, [eax + CPUMCTXCORE.ecx]
1325 COM_S_DWORD_REG ecx
1326
1327 COM_S_PRINT ' edx='
1328 mov ecx, [eax + CPUMCTXCORE.edx]
1329 COM_S_DWORD_REG ecx
1330
1331
1332 COM_S_PRINT 10,13,'esi='
1333 mov ecx, [eax + CPUMCTXCORE.esi]
1334 COM_S_DWORD_REG ecx
1335
1336 COM_S_PRINT ' edi='
1337 mov ecx, [eax + CPUMCTXCORE.edi]
1338 COM_S_DWORD_REG ecx
1339
1340 COM_S_PRINT ' ebp='
1341 mov ecx, [eax + CPUMCTXCORE.ebp]
1342 COM_S_DWORD_REG ecx
1343
1344
1345 COM_S_NEWLINE
1346
1347tddrf_ret:
1348 add esp, byte 8
1349 ret
1350
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