VirtualBox

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

Last change on this file since 28800 was 28800, checked in by vboxsync, 15 years ago

Automated rebranding to Oracle copyright/license strings via filemuncher

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