VirtualBox

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

Last change on this file since 400 was 19, checked in by vboxsync, 18 years ago

nasm.mac -> asmdefs.mac + header adjustments.

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