VirtualBox

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

Last change on this file since 4394 was 4394, checked in by vboxsync, 17 years ago

fixed comment

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