VirtualBox

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

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

Big step to separate VMM data structures for guest SMP. (pgm, em)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 42.8 KB
Line 
1; $Id: TRPMGCHandlersA.asm 18927 2009-04-16 11:41:38Z 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 mov eax, IMP(g_VM) ; Param 1 - Pointer to the VMCPU.
552 add eax, [eax + VM.offVMCPU]
553 push eax
554 call NAME(CPUMHyperSetCtxCore)
555 add esp, byte 8 ; stack cleanup (cdecl)
556 xchg eax, esi ; restore pTRPM
557
558 ; check for temporary handler.
559 movzx ebx, byte [eax + TRPM.uActiveVector]
560 xor ecx, ecx
561 xchg ecx, [eax + TRPM.aTmpTrapHandlers + ebx * 4] ; ecx = Temp handler pointer or 0
562 or ecx, ecx
563 jnz short gt_Hyper_HaveTemporaryHandler
564
565 ; check for static trap handler.
566 mov ecx, [g_apfnStaticTrapHandlersHyper + ebx * 4] ; ecx = Static handler pointer or 0
567 or ecx, ecx
568 jnz short gt_Hyper_HaveStaticHandler
569 jmp gt_Hyper_AbandonShip
570
571
572 ;
573 ; Temporary trap handler present, call it (CDECL).
574 ;
575gt_Hyper_HaveTemporaryHandler:
576 push esp ; Param 2 - Pointer to CPUMCTXCORE.
577 push IMP(g_VM) ; Param 1 - Pointer to VM.
578 call ecx
579 add esp, byte 8 ; cleanup stack (cdecl)
580
581 cmp eax, byte VINF_SUCCESS ; If completely handled Then resume execution.
582 je near gt_Hyper_Continue
583 ;; @todo Handle ALL returns types from temporary handlers!
584 jmp gt_Hyper_AbandonShip
585
586
587 ;
588 ; Static trap handler present, call it (CDECL).
589 ;
590gt_Hyper_HaveStaticHandler:
591 push esp ; Param 2 - Pointer to CPUMCTXCORE.
592 push eax ; Param 1 - Pointer to TRPM
593 call ecx
594 add esp, byte 8 ; cleanup stack (cdecl)
595
596 cmp eax, byte VINF_SUCCESS ; If completely handled Then resume execution.
597 je short gt_Hyper_Continue
598 cmp eax, VINF_EM_DBG_HYPER_STEPPED
599 je short gt_Hyper_ToHost
600 cmp eax, VINF_EM_DBG_HYPER_BREAKPOINT
601 je short gt_Hyper_ToHost
602 cmp eax, VINF_EM_DBG_HYPER_ASSERTION
603 je short gt_Hyper_ToHost
604 jmp gt_Hyper_AbandonShip
605
606 ;
607 ; Pop back to the host to service the error.
608 ;
609gt_Hyper_ToHost:
610 mov ecx, esp
611 mov edx, IMP(g_VM)
612 call [edx + VM.pfnVMMGCGuestToHostAsm]
613 jmp short gt_Hyper_Continue
614
615 ;
616 ; Continue(/Resume/Restart/Whatever) hypervisor execution.
617 ; Don't reset the TRPM state. Caller takes care of that.
618 ;
619ALIGNCODE(16)
620gt_Hyper_Continue:
621%ifdef DEBUG_STUFF
622 mov ebx, [esp + 4h + ESPOFF] ; error code
623 mov ecx, 'resH' ; indicate trap.
624 mov edx, [esp + 0h + ESPOFF] ; vector number
625 lea eax, [esp]
626 call trpmDbgDumpRegisterFrame
627%endif
628 ; tell CPUM to use the default CPUMCTXCORE.
629 push byte 0 ; Param 2 - NULL indicating use default context core.
630 mov eax, IMP(g_VM) ; Param 1 - Pointer to the VMCPU.
631 add eax, [eax + VM.offVMCPU]
632 push eax
633 call NAME(CPUMHyperSetCtxCore)
634 add esp, byte 8 ; stack cleanup (cdecl)
635
636%ifdef VBOX_WITH_STATISTICS
637 mov edx, [esp + 0h + ESPOFF] ; vector number
638 imul edx, edx, byte STAMPROFILEADV_size ; assumes < 128
639 add edx, TRPM.aStatGCTraps
640 add edx, IMP(g_TRPM)
641 STAM_PROFILE_ADV_STOP edx
642%endif
643
644 ; restore
645 mov ecx, [esp + CPUMCTXCORE.ecx]
646 mov edx, [esp + CPUMCTXCORE.edx]
647 mov ebx, [esp + CPUMCTXCORE.ebx]
648 mov ebp, [esp + CPUMCTXCORE.ebp]
649 mov esi, [esp + CPUMCTXCORE.esi]
650 mov edi, [esp + CPUMCTXCORE.edi]
651
652 mov eax, dword [esp + CPUMCTXCORE.gs]
653 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_GS | TRPM_TRAP_IN_HYPER
654 mov gs, eax
655
656 mov eax, dword [esp + CPUMCTXCORE.fs]
657 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_FS | TRPM_TRAP_IN_HYPER
658 mov fs, eax
659
660 mov eax, dword [esp + CPUMCTXCORE.es]
661 mov es, eax
662 mov eax, dword [esp + CPUMCTXCORE.ds]
663 mov ds, eax
664
665 ; skip esp & ss
666
667 mov eax, [esp + CPUMCTXCORE.eip]
668 mov [esp + 08h + ESPOFF], eax ; eip
669 mov eax, dword [esp + CPUMCTXCORE.cs]
670 mov [esp + 0ch + ESPOFF], eax ; cs
671 mov eax, [esp + CPUMCTXCORE.eflags]
672 mov [esp + 10h + ESPOFF], eax ; eflags
673
674 ; finally restore our scratch register eax
675 mov eax, [esp + CPUMCTXCORE.eax]
676
677 add esp, ESPOFF + 8 ; skip CPUMCTXCORE structure, error code and vector number
678
679 iret
680
681
682 ;
683 ; ABANDON SHIP! DON'T PANIC!
684 ;
685gt_Hyper_AbandonShip:
686%ifdef DEBUG_STUFF
687 mov ebx, [esp + 4h + ESPOFF] ; error code
688 mov ecx, 'trpH' ; indicate trap.
689 mov edx, [esp + 0h + ESPOFF] ; vector number
690 lea eax, [esp]
691 call trpmDbgDumpRegisterFrame
692%endif
693
694gt_Hyper_DontPanic:
695 mov ecx, esp
696 mov edx, IMP(g_VM)
697 mov eax, VERR_TRPM_DONT_PANIC
698 call [edx + VM.pfnVMMGCGuestToHostAsmHyperCtx]
699%ifdef DEBUG_STUFF
700 COM_S_PRINT 'bad!!!'
701%endif
702 jmp gt_Hyper_DontPanic ; this shall never ever happen!
703%undef ESPOFF
704ENDPROC TRPMGCHandlerGeneric
705
706
707
708
709
710;;
711; We start by 256 push <vector no.> + jmp interruptworker
712;
713ALIGNCODE(16)
714BEGINPROC_EXPORTED TRPMGCHandlerInterupt
715 ; NASM has some nice features, here an example of a loop.
716%assign i 0
717%rep 256
718 db 06ah, i ; push imm8 - note that this is a signextended value.
719 jmp ti_GenericInterrupt
720 ALIGNCODE(8)
721%assign i i+1
722%endrep
723
724;;
725; Main interrupt handler for the guest context
726;
727; Stack:
728; 24 GS (V86 only)
729; 20 FS (V86 only)
730; 1C DS (V86 only)
731; 18 ES (V86 only)
732; 14 SS
733; 10 ESP
734; c EFLAGS
735; 8 CS
736; 4 EIP
737; ESP -> 0 Vector number (only use low byte!).
738;
739; @uses none
740ti_GenericInterrupt:
741 cld
742
743 ;
744 ; Setup CPUMCTXCORE frame
745 ;
746 ; ASSUMPTION: If trap in hypervisor, we assume that we can read two dword
747 ; under the bottom of the stack. This is atm safe.
748 ; ASSUMPTION: There is sufficient stack space.
749 ; ASSUMPTION: The stack is not write protected.
750 ;
751%define ESPOFF CPUMCTXCORE_size
752
753 sub esp, CPUMCTXCORE_size
754 mov [esp + CPUMCTXCORE.eax], eax
755 mov [esp + CPUMCTXCORE.ecx], ecx
756 mov [esp + CPUMCTXCORE.edx], edx
757 mov [esp + CPUMCTXCORE.ebx], ebx
758 mov [esp + CPUMCTXCORE.esi], esi
759 mov [esp + CPUMCTXCORE.edi], edi
760 mov [esp + CPUMCTXCORE.ebp], ebp
761
762 mov eax, [esp + 04h + ESPOFF] ; eip
763 mov [esp + CPUMCTXCORE.eip], eax
764%if GC_ARCH_BITS == 64
765 ; zero out the high dword
766 mov dword [esp + CPUMCTXCORE.eip + 4], 0
767%endif
768 mov eax, dword [esp + 08h + ESPOFF] ; cs
769 mov [esp + CPUMCTXCORE.cs], eax
770 mov eax, [esp + 0ch + ESPOFF] ; eflags
771 mov [esp + CPUMCTXCORE.eflags], eax
772
773 mov eax, [esp + 10h + ESPOFF] ; esp
774 mov [esp + CPUMCTXCORE.esp], eax
775%if GC_ARCH_BITS == 64
776 ; zero out the high dword
777 mov dword [esp + CPUMCTXCORE.esp + 4], 0
778%endif
779 mov eax, dword [esp + 14h + ESPOFF] ; ss
780 mov [esp + CPUMCTXCORE.ss], eax
781
782 mov eax, es
783 mov dword [esp + CPUMCTXCORE.es], eax
784 mov eax, ds
785 mov dword [esp + CPUMCTXCORE.ds], eax
786 mov eax, fs
787 mov dword [esp + CPUMCTXCORE.fs], eax
788 mov eax, gs
789 mov dword [esp + CPUMCTXCORE.gs], eax
790
791 test dword [esp + CPUMCTXCORE.eflags], X86_EFL_VM
792 jz short ti_SkipV86Entry
793
794 ;
795 ; The DS, ES, FS and GS registers are zeroed in V86 mode and their real values are on the stack
796 ;
797 mov eax, dword [esp + ESPOFF + 18h]
798 mov dword [esp + CPUMCTXCORE.es], eax
799
800 mov eax, dword [esp + ESPOFF + 1Ch]
801 mov dword [esp + CPUMCTXCORE.ds], eax
802
803 mov eax, dword [esp + ESPOFF + 20h]
804 mov dword [esp + CPUMCTXCORE.fs], eax
805
806 mov eax, dword [esp + ESPOFF + 24h]
807 mov dword [esp + CPUMCTXCORE.gs], eax
808
809ti_SkipV86Entry:
810
811 ;
812 ; Disable Ring-0 WP
813 ;
814 mov eax, cr0 ;; @todo try elimiate this read.
815 and eax, ~X86_CR0_WRITE_PROTECT
816 mov cr0, eax
817
818 ;
819 ; Load Hypervisor DS and ES (get it from the SS)
820 ;
821 mov eax, ss
822 mov ds, eax
823 mov es, eax
824
825 ;
826 ; Store the information about the active trap/interrupt.
827 ;
828 mov eax, IMP(g_TRPM)
829 movzx edx, byte [esp + 0h + ESPOFF] ; vector number
830 mov [eax + TRPM.uActiveVector], edx
831 xor edx, edx
832 mov dword [eax + TRPM.enmActiveType], TRPM_HARDWARE_INT
833 dec edx
834 mov [eax + TRPM.uActiveErrorCode], edx
835 mov [eax + TRPM.uActiveCR2], edx
836%if GC_ARCH_BITS == 64
837 ; zero out the high dword
838 mov dword [eax + TRPM.uActiveErrorCode + 4], 0
839 mov dword [eax + TRPM.uActiveCR2 + 4], 0
840%endif
841
842 ;
843 ; Check if we're in Hypervisor when this happend.
844 ;
845 test byte [esp + 08h + ESPOFF], 3h ; check CPL of the cs selector
846 jnz short gi_NotHyperVisor
847 jmp gi_HyperVisor
848
849 ;
850 ; Trap in guest code.
851 ;
852gi_NotHyperVisor:
853 and dword [esp + CPUMCTXCORE.eflags], ~010000h ; Clear RF (Resume Flag). @todo make %defines for eflags.
854 ; The guest shall not see this in it's state.
855%ifdef DEBUG_STUFF_INT
856 mov ecx, 'intG' ; indicate trap.
857 movzx edx, byte [esp + 0h + ESPOFF] ; vector number
858 lea eax, [esp]
859 call trpmDbgDumpRegisterFrame
860%endif
861
862 ;
863 ; Switch back to the host and process it there.
864 ;
865 mov edx, IMP(g_VM)
866 mov eax, VINF_EM_RAW_INTERRUPT
867 call [edx + VM.pfnVMMGCGuestToHostAsmGuestCtx]
868
869 ;
870 ; We've returned!
871 ; NOTE that the stack has been changed now!
872 ; there is no longer any CPUMCTXCORE around and esp points to vector number!
873 ;
874 ; Reset TRPM state
875 mov eax, IMP(g_TRPM)
876 xor edx, edx
877 dec edx ; edx = 0ffffffffh
878 xchg [eax + TRPM.uActiveVector], edx
879 mov [eax + TRPM.uPrevVector], edx
880
881 ; Enable WP
882 mov eax, cr0 ;; @todo try elimiate this read.
883 or eax, X86_CR0_WRITE_PROTECT
884 mov cr0, eax
885 ; restore guest context and continue execution.
886 lea eax, [esp + 8]
887 push eax
888 call NAME(CPUMGCRestoreInt)
889 lea esp, [esp + 0ch] ; cleanup call and skip vector & error code.
890
891 iret
892
893 ; -+- Entry point -+-
894 ;
895 ; We're in hypervisor mode which means no guest context
896 ; and special care to be taken to restore the hypervisor
897 ; context correctely.
898 ;
899 ; ATM the only place this can happen is when entering a trap handler.
900 ; We make ASSUMPTIONS about this in respects to the WP CR0 bit
901 ;
902gi_HyperVisor:
903 lea eax, [esp + 14h + ESPOFF] ; calc esp at trap
904 mov [esp + CPUMCTXCORE.esp], eax ; update esp in register frame
905 mov [esp + CPUMCTXCORE.ss], ss ; update ss in register frame
906
907%ifdef DEBUG_STUFF_INT
908 mov ebx, [esp + 4h + ESPOFF] ; error code
909 mov ecx, 'intH' ; indicate hypervisor interrupt.
910 movzx edx, byte [esp + 0h + ESPOFF] ; vector number
911 lea eax, [esp]
912 call trpmDbgDumpRegisterFrame
913%endif
914
915 mov ecx, esp
916 mov edx, IMP(g_VM)
917 mov eax, VINF_EM_RAW_INTERRUPT_HYPER
918 call [edx + VM.pfnVMMGCGuestToHostAsm]
919%ifdef DEBUG_STUFF_INT
920 COM_CHAR '!'
921%endif
922
923 ;
924 ; We've returned!
925 ;
926 ; Reset TRPM state - don't record this.
927 mov eax, IMP(g_TRPM)
928 mov dword [eax + TRPM.uActiveVector], 0ffffffffh
929
930 ;
931 ; Restore the hypervisor context and return.
932 ;
933 mov ecx, [esp + CPUMCTXCORE.ecx]
934 mov edx, [esp + CPUMCTXCORE.edx]
935 mov ebx, [esp + CPUMCTXCORE.ebx]
936 mov ebp, [esp + CPUMCTXCORE.ebp]
937 mov esi, [esp + CPUMCTXCORE.esi]
938 mov edi, [esp + CPUMCTXCORE.edi]
939
940 ; In V86 mode DS, ES, FS & GS are restored by the iret
941 test dword [esp + CPUMCTXCORE.eflags], X86_EFL_VM
942 jnz short ti_SkipSelRegs
943
944 mov eax, [esp + CPUMCTXCORE.gs]
945 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_GS | TRPM_TRAP_IN_HYPER
946 mov gs, eax
947
948 mov eax, [esp + CPUMCTXCORE.fs]
949 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_FS | TRPM_TRAP_IN_HYPER
950 mov fs, eax
951
952 mov eax, [esp + CPUMCTXCORE.es]
953 mov es, eax
954 mov eax, [esp + CPUMCTXCORE.ds]
955 mov ds, eax
956
957ti_SkipSelRegs:
958 ; finally restore our scratch register eax
959 mov eax, [esp + CPUMCTXCORE.eax]
960
961 ; skip esp, ss, cs, eip & eflags. Done by iret
962
963 add esp, ESPOFF + 4h ; skip CPUMCTXCORE structure & vector number.
964
965 iret
966%undef ESPOFF
967ENDPROC TRPMGCHandlerInterupt
968
969
970
971;;
972; Trap handler for #MC
973;
974; This handler will forward the #MC to the host OS. Since this
975; is generalized in the generic interrupt handler, we just disable
976; interrupts and push vector number and jump to the generic code.
977;
978; Stack:
979; 10 SS (only if ring transition.)
980; c ESP (only if ring transition.)
981; 8 EFLAGS
982; 4 CS
983; 0 EIP
984;
985; @uses none
986;
987ALIGNCODE(16)
988BEGINPROC_EXPORTED TRPMGCHandlerTrap12
989 push byte 12h
990 jmp ti_GenericInterrupt
991ENDPROC TRPMGCHandlerTrap12
992
993
994
995
996;;
997; Trap handler for double fault (#DF).
998;
999; This is a special trap handler executes in separate task with own TSS, with
1000; one of the intermediate memory contexts instead of the shadow context.
1001; The handler will unconditionally print an report to the comport configured
1002; for the COM_S_* macros before attempting to return to the host. If it it ends
1003; up double faulting more than 10 times, it will simply cause an tripple fault
1004; to get us out of the mess.
1005;
1006; @param esp Half way down the hypvervisor stack + the trap frame.
1007; @param ebp Half way down the hypvervisor stack.
1008; @param eflags Interrupts disabled, nested flag is probably set (we don't care).
1009; @param ecx The address of the hypervisor TSS.
1010; @param edi Same as ecx.
1011; @param eax Same as ecx.
1012; @param edx Address of the VM structure.
1013; @param esi Same as edx.
1014; @param ebx Same as edx.
1015; @param ss Hypervisor DS.
1016; @param ds Hypervisor DS.
1017; @param es Hypervisor DS.
1018; @param fs 0
1019; @param gs 0
1020;
1021;
1022; @remark To be able to catch errors with WP turned off, it is required that the
1023; TSS GDT descriptor and the TSSes are writable (X86_PTE_RW). See SELM.cpp
1024; for how to enable this.
1025;
1026; @remark It is *not* safe to resume the VMM after a double fault. (At least not
1027; without clearing the busy flag of the TssTrap8 and fixing whatever cause it.)
1028;
1029ALIGNCODE(16)
1030BEGINPROC_EXPORTED TRPMGCHandlerTrap08
1031 ; be careful.
1032 cli
1033 cld
1034
1035 ;
1036 ; Load Hypervisor DS and ES (get it from the SS) - paranoia, but the TSS could be overwritten.. :)
1037 ;
1038 mov eax, ss
1039 mov ds, eax
1040 mov es, eax
1041
1042 COM_S_PRINT 10,13,'*** Guru Meditation 00000008 - Double Fault! ***',10,13
1043
1044 ;
1045 ; Disable write protection.
1046 ;
1047 mov eax, cr0
1048 and eax, ~X86_CR0_WRITE_PROTECT
1049 mov cr0, eax
1050
1051
1052 COM_S_PRINT 'VM='
1053 COM_S_DWORD_REG edx
1054 COM_S_PRINT ' prevTSS='
1055 COM_S_DWORD_REG ecx
1056 COM_S_PRINT ' prevCR3='
1057 mov eax, [ecx + VBOXTSS.cr3]
1058 COM_S_DWORD_REG eax
1059 COM_S_PRINT ' prevLdtr='
1060 movzx eax, word [ecx + VBOXTSS.selLdt]
1061 COM_S_DWORD_REG eax
1062 COM_S_NEWLINE
1063
1064 ;
1065 ; Create CPUMCTXCORE structure.
1066 ;
1067 sub esp, CPUMCTXCORE_size
1068
1069 mov eax, [ecx + VBOXTSS.eip]
1070 mov [esp + CPUMCTXCORE.eip], eax
1071%if GC_ARCH_BITS == 64
1072 ; zero out the high dword
1073 mov dword [esp + CPUMCTXCORE.eip + 4], 0
1074%endif
1075 mov eax, [ecx + VBOXTSS.eflags]
1076 mov [esp + CPUMCTXCORE.eflags], eax
1077
1078 movzx eax, word [ecx + VBOXTSS.cs]
1079 mov dword [esp + CPUMCTXCORE.cs], eax
1080 movzx eax, word [ecx + VBOXTSS.ds]
1081 mov dword [esp + CPUMCTXCORE.ds], eax
1082 movzx eax, word [ecx + VBOXTSS.es]
1083 mov dword [esp + CPUMCTXCORE.es], eax
1084 movzx eax, word [ecx + VBOXTSS.fs]
1085 mov dword [esp + CPUMCTXCORE.fs], eax
1086 movzx eax, word [ecx + VBOXTSS.gs]
1087 mov dword [esp + CPUMCTXCORE.gs], eax
1088 movzx eax, word [ecx + VBOXTSS.ss]
1089 mov [esp + CPUMCTXCORE.ss], eax
1090 mov eax, [ecx + VBOXTSS.esp]
1091 mov [esp + CPUMCTXCORE.esp], eax
1092%if GC_ARCH_BITS == 64
1093 ; zero out the high dword
1094 mov dword [esp + CPUMCTXCORE.esp + 4], 0
1095%endif
1096 mov eax, [ecx + VBOXTSS.ecx]
1097 mov [esp + CPUMCTXCORE.ecx], eax
1098 mov eax, [ecx + VBOXTSS.edx]
1099 mov [esp + CPUMCTXCORE.edx], eax
1100 mov eax, [ecx + VBOXTSS.ebx]
1101 mov [esp + CPUMCTXCORE.ebx], eax
1102 mov eax, [ecx + VBOXTSS.eax]
1103 mov [esp + CPUMCTXCORE.eax], eax
1104 mov eax, [ecx + VBOXTSS.ebp]
1105 mov [esp + CPUMCTXCORE.ebp], eax
1106 mov eax, [ecx + VBOXTSS.esi]
1107 mov [esp + CPUMCTXCORE.esi], eax
1108 mov eax, [ecx + VBOXTSS.edi]
1109 mov [esp + CPUMCTXCORE.edi], eax
1110
1111 ;
1112 ; Show regs
1113 ;
1114 mov ebx, 0ffffffffh
1115 mov ecx, 'trpH' ; indicate trap.
1116 mov edx, 08h ; vector number
1117 lea eax, [esp]
1118 call trpmDbgDumpRegisterFrame
1119
1120 ;
1121 ; Should we try go back?
1122 ;
1123 inc dword [df_Count]
1124 cmp dword [df_Count], byte 10
1125 jb df_to_host
1126 jmp df_tripple_fault
1127df_Count: dd 0
1128
1129 ;
1130 ; Try return to the host.
1131 ;
1132df_to_host:
1133 COM_S_PRINT 'Trying to return to host...',10,13
1134 mov ecx, esp
1135 mov edx, IMP(g_VM)
1136 mov eax, VERR_TRPM_PANIC
1137 call [edx + VM.pfnVMMGCGuestToHostAsmHyperCtx]
1138 jmp short df_to_host
1139
1140 ;
1141 ; Perform a tripple fault.
1142 ;
1143df_tripple_fault:
1144 COM_S_PRINT 'Giving up - tripple faulting the machine...',10,13
1145 push byte 0
1146 push byte 0
1147 sidt [esp]
1148 mov word [esp], 0
1149 lidt [esp]
1150 xor eax, eax
1151 mov dword [eax], 0
1152 jmp df_tripple_fault
1153
1154ENDPROC TRPMGCHandlerTrap08
1155
1156
1157
1158
1159;;
1160; Internal procedure used to dump registers.
1161;
1162; @param eax Pointer to CPUMCTXCORE.
1163; @param edx Vector number
1164; @param ecx 'trap' if trap, 'int' if interrupt.
1165; @param ebx Error code if trap.
1166;
1167trpmDbgDumpRegisterFrame:
1168 sub esp, byte 8 ; working space for sidt/sgdt/etc
1169
1170; Init _must_ be done on host before crashing!
1171; push edx
1172; push eax
1173; COM_INIT
1174; pop eax
1175; pop edx
1176
1177 cmp ecx, 'trpH'
1178 je near tddrf_trpH
1179 cmp ecx, 'trpG'
1180 je near tddrf_trpG
1181 cmp ecx, 'intH'
1182 je near tddrf_intH
1183 cmp ecx, 'intG'
1184 je near tddrf_intG
1185 cmp ecx, 'resH'
1186 je near tddrf_resH
1187 COM_S_PRINT 10,13,'*** Bogus Dump Code '
1188 jmp tddrf_regs
1189
1190%if 1 ; the verbose version
1191
1192tddrf_intG:
1193 COM_S_PRINT 10,13,'*** Interrupt (Guest) '
1194 COM_S_DWORD_REG edx
1195 jmp tddrf_regs
1196
1197tddrf_intH:
1198 COM_S_PRINT 10,13,'*** Interrupt (Hypervisor) '
1199 COM_S_DWORD_REG edx
1200 jmp tddrf_regs
1201
1202tddrf_trpG:
1203 COM_S_PRINT 10,13,'*** Trap '
1204 jmp tddrf_trap_rest
1205
1206%else ; the short version
1207
1208tddrf_intG:
1209 COM_S_CHAR 'I'
1210 jmp tddrf_ret
1211
1212tddrf_intH:
1213 COM_S_CHAR 'i'
1214 jmp tddrf_ret
1215
1216tddrf_trpG:
1217 COM_S_CHAR 'T'
1218 jmp tddrf_ret
1219
1220%endif ; the short version
1221
1222tddrf_trpH:
1223 COM_S_PRINT 10,13,'*** Guru Meditation '
1224 jmp tddrf_trap_rest
1225
1226tddrf_resH:
1227 COM_S_PRINT 10,13,'*** Resuming Hypervisor Trap '
1228 jmp tddrf_trap_rest
1229
1230tddrf_trap_rest:
1231 COM_S_DWORD_REG edx
1232 COM_S_PRINT ' ErrorCode='
1233 COM_S_DWORD_REG ebx
1234 COM_S_PRINT ' cr2='
1235 mov ecx, cr2
1236 COM_S_DWORD_REG ecx
1237
1238tddrf_regs:
1239 COM_S_PRINT ' ***',10,13,'cs:eip='
1240 movzx ecx, word [eax + CPUMCTXCORE.cs]
1241 COM_S_DWORD_REG ecx
1242 COM_S_CHAR ':'
1243 mov ecx, [eax + CPUMCTXCORE.eip]
1244 COM_S_DWORD_REG ecx
1245
1246 COM_S_PRINT ' ss:esp='
1247 movzx ecx, word [eax + CPUMCTXCORE.ss]
1248 COM_S_DWORD_REG ecx
1249 COM_S_CHAR ':'
1250 mov ecx, [eax + CPUMCTXCORE.esp]
1251 COM_S_DWORD_REG ecx
1252
1253
1254 sgdt [esp]
1255 COM_S_PRINT 10,13,' gdtr='
1256 movzx ecx, word [esp]
1257 COM_S_DWORD_REG ecx
1258 COM_S_CHAR ':'
1259 mov ecx, [esp + 2]
1260 COM_S_DWORD_REG ecx
1261
1262 sidt [esp]
1263 COM_S_PRINT ' idtr='
1264 movzx ecx, word [esp]
1265 COM_S_DWORD_REG ecx
1266 COM_S_CHAR ':'
1267 mov ecx, [esp + 2]
1268 COM_S_DWORD_REG ecx
1269
1270
1271 str [esp] ; yasm BUG! it generates sldt [esp] here! YASMCHECK!
1272 COM_S_PRINT 10,13,' tr='
1273 movzx ecx, word [esp]
1274 COM_S_DWORD_REG ecx
1275
1276 sldt [esp]
1277 COM_S_PRINT ' ldtr='
1278 movzx ecx, word [esp]
1279 COM_S_DWORD_REG ecx
1280
1281 COM_S_PRINT ' eflags='
1282 mov ecx, [eax + CPUMCTXCORE.eflags]
1283 COM_S_DWORD_REG ecx
1284
1285
1286 COM_S_PRINT 10,13,'cr0='
1287 mov ecx, cr0
1288 COM_S_DWORD_REG ecx
1289
1290 COM_S_PRINT ' cr2='
1291 mov ecx, cr2
1292 COM_S_DWORD_REG ecx
1293
1294 COM_S_PRINT ' cr3='
1295 mov ecx, cr3
1296 COM_S_DWORD_REG ecx
1297 COM_S_PRINT ' cr4='
1298 mov ecx, cr4
1299 COM_S_DWORD_REG ecx
1300
1301
1302 COM_S_PRINT 10,13,' ds='
1303 movzx ecx, word [eax + CPUMCTXCORE.ds]
1304 COM_S_DWORD_REG ecx
1305
1306 COM_S_PRINT ' es='
1307 movzx ecx, word [eax + CPUMCTXCORE.es]
1308 COM_S_DWORD_REG ecx
1309
1310 COM_S_PRINT ' fs='
1311 movzx ecx, word [eax + CPUMCTXCORE.fs]
1312 COM_S_DWORD_REG ecx
1313
1314 COM_S_PRINT ' gs='
1315 movzx ecx, word [eax + CPUMCTXCORE.gs]
1316 COM_S_DWORD_REG ecx
1317
1318
1319 COM_S_PRINT 10,13,'eax='
1320 mov ecx, [eax + CPUMCTXCORE.eax]
1321 COM_S_DWORD_REG ecx
1322
1323 COM_S_PRINT ' ebx='
1324 mov ecx, [eax + CPUMCTXCORE.ebx]
1325 COM_S_DWORD_REG ecx
1326
1327 COM_S_PRINT ' ecx='
1328 mov ecx, [eax + CPUMCTXCORE.ecx]
1329 COM_S_DWORD_REG ecx
1330
1331 COM_S_PRINT ' edx='
1332 mov ecx, [eax + CPUMCTXCORE.edx]
1333 COM_S_DWORD_REG ecx
1334
1335
1336 COM_S_PRINT 10,13,'esi='
1337 mov ecx, [eax + CPUMCTXCORE.esi]
1338 COM_S_DWORD_REG ecx
1339
1340 COM_S_PRINT ' edi='
1341 mov ecx, [eax + CPUMCTXCORE.edi]
1342 COM_S_DWORD_REG ecx
1343
1344 COM_S_PRINT ' ebp='
1345 mov ecx, [eax + CPUMCTXCORE.ebp]
1346 COM_S_DWORD_REG ecx
1347
1348
1349 COM_S_NEWLINE
1350
1351tddrf_ret:
1352 add esp, byte 8
1353 ret
1354
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette