VirtualBox

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

Last change on this file since 2623 was 2124, checked in by vboxsync, 18 years ago

TRPM changes to assert and report trap/interrupt types accurately.

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