VirtualBox

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

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

Zero out the high parts of all registers in the RC trap handler.

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