VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMRC/TRPMRCHandlersA.asm@ 41823

Last change on this file since 41823 was 38867, checked in by vboxsync, 13 years ago

TRPM: Host interrupt stats.

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