VirtualBox

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

Last change on this file since 1868 was 1645, checked in by vboxsync, 18 years ago

removed some leftover debug code (amd64 tripple-fault)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 41.7 KB
Line 
1; $Id: TRPMGCHandlersA.asm 1645 2007-03-22 18:13:16Z 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 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 + 1ch + ESPOFF], eax ; es
500 mov eax, dword [esp + CPUMCTXCORE.ds]
501 mov [esp + 20h + ESPOFF], eax ; ds
502 mov eax, dword [esp + CPUMCTXCORE.fs]
503 mov [esp + 24h + ESPOFF], eax ; fs
504 mov eax, dword [esp + CPUMCTXCORE.gs]
505 mov [esp + 28h + 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 ; In V86 mode DS, ES, FS & GS are restored by the iret
910 test dword [esp + CPUMCTXCORE.eflags], X86_EFL_VM
911 jnz short ti_SkipSelRegs
912
913 mov eax, [esp + CPUMCTXCORE.gs]
914 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_GS | TRPM_TRAP_IN_HYPER
915 mov gs, eax
916
917 mov eax, [esp + CPUMCTXCORE.fs]
918 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_FS | TRPM_TRAP_IN_HYPER
919 mov fs, eax
920
921 mov eax, [esp + CPUMCTXCORE.es]
922 mov es, eax
923 mov eax, [esp + CPUMCTXCORE.ds]
924 mov ds, eax
925
926ti_SkipSelRegs:
927 ; finally restore our scratch register eax
928 mov eax, [esp + CPUMCTXCORE.eax]
929
930 ; skip esp, ss, cs, eip & eflags. Done by iret
931
932 add esp, ESPOFF + 4h ; skip CPUMCTXCORE structure & vector number.
933
934 iret
935%undef ESPOFF
936ENDPROC TRPMGCHandlerInterupt
937
938
939
940;;
941; Trap handler for #MC
942;
943; This handler will forward the #MC to the host OS. Since this
944; is generalized in the generic interrupt handler, we just disable
945; interrupts and push vector number and jump to the generic code.
946;
947; Stack:
948; 10 SS (only if ring transition.)
949; c ESP (only if ring transition.)
950; 8 EFLAGS
951; 4 CS
952; 0 EIP
953;
954; @uses none
955;
956ALIGNCODE(16)
957BEGINPROC_EXPORTED TRPMGCHandlerTrap12
958 cli
959 push byte 12h
960 jmp ti_GenericInterrupt
961ENDPROC TRPMGCHandlerTrap12
962
963
964
965
966;;
967; Trap handler for double fault (#DF).
968;
969; This is a special trap handler executes in separate task with own TSS, with
970; one of the intermediate memory contexts instead of the shadow context.
971; The handler will unconditionally print an report to the comport configured
972; for the COM_S_* macros before attempting to return to the host. If it it ends
973; up double faulting more than 10 times, it will simply cause an tripple fault
974; to get us out of the mess.
975;
976; @param esp Half way down the hypvervisor stack + the trap frame.
977; @param ebp Half way down the hypvervisor stack.
978; @param eflags Interrupts disabled, nested flag is probably set (we don't care).
979; @param ecx The address of the hypervisor TSS.
980; @param edi Same as ecx.
981; @param eax Same as ecx.
982; @param edx Address of the VM structure.
983; @param esi Same as edx.
984; @param ebx Same as edx.
985; @param ss Hypervisor DS.
986; @param ds Hypervisor DS.
987; @param es Hypervisor DS.
988; @param fs 0
989; @param gs 0
990;
991;
992; @remark To be able to catch errors with WP turned off, it is required that the
993; TSS GDT descriptor and the TSSes are writable (X86_PTE_RW). See SELM.cpp
994; for how to enable this.
995;
996; @remark It is *not* safe to resume the VMM after a double fault. (At least not
997; without clearing the busy flag of the TssTrap8 and fixing whatever cause it.)
998;
999ALIGNCODE(16)
1000BEGINPROC_EXPORTED TRPMGCHandlerTrap08
1001 cli ; slight paranoia
1002 cld ; more paranoia
1003
1004 ;
1005 ; Load Hypervisor DS and ES (get it from the SS) - paranoia, but the TSS could be overwritten.. :)
1006 ;
1007 mov eax, ss
1008 mov ds, eax
1009 mov es, eax
1010
1011 COM_S_PRINT 10,13,'*** Guru Mediation 00000008 - Double Fault! ***',10,13
1012
1013 ;
1014 ; Disable write protection.
1015 ;
1016 mov eax, cr0
1017 and eax, ~X86_CR0_WRITE_PROTECT
1018 mov cr0, eax
1019
1020
1021 COM_S_PRINT 'VM='
1022 COM_S_DWORD_REG edx
1023 COM_S_PRINT ' prevTSS='
1024 COM_S_DWORD_REG ecx
1025 COM_S_PRINT ' prevCR3='
1026 mov eax, [ecx + VBOXTSS.cr3]
1027 COM_S_DWORD_REG eax
1028 COM_S_PRINT ' prevLdtr='
1029 movzx eax, word [ecx + VBOXTSS.selLdt]
1030 COM_S_DWORD_REG eax
1031 COM_S_NEWLINE
1032
1033 ;
1034 ; Create CPUMCTXCORE structure.
1035 ;
1036 sub esp, CPUMCTXCORE_size
1037
1038 mov eax, [ecx + VBOXTSS.eip]
1039 mov [esp + CPUMCTXCORE.eip], eax
1040 mov eax, [ecx + VBOXTSS.eflags]
1041 mov [esp + CPUMCTXCORE.eflags], eax
1042
1043 movzx eax, word [ecx + VBOXTSS.cs]
1044 mov dword [esp + CPUMCTXCORE.cs], eax
1045 movzx eax, word [ecx + VBOXTSS.ds]
1046 mov dword [esp + CPUMCTXCORE.ds], eax
1047 movzx eax, word [ecx + VBOXTSS.es]
1048 mov dword [esp + CPUMCTXCORE.es], eax
1049 movzx eax, word [ecx + VBOXTSS.fs]
1050 mov dword [esp + CPUMCTXCORE.fs], eax
1051 movzx eax, word [ecx + VBOXTSS.gs]
1052 mov dword [esp + CPUMCTXCORE.gs], eax
1053 movzx eax, word [ecx + VBOXTSS.ss]
1054 mov [esp + CPUMCTXCORE.ss], eax
1055 mov eax, [ecx + VBOXTSS.esp]
1056 mov [esp + CPUMCTXCORE.esp], eax
1057 mov eax, [ecx + VBOXTSS.ecx]
1058 mov [esp + CPUMCTXCORE.ecx], eax
1059 mov eax, [ecx + VBOXTSS.edx]
1060 mov [esp + CPUMCTXCORE.edx], eax
1061 mov eax, [ecx + VBOXTSS.ebx]
1062 mov [esp + CPUMCTXCORE.ebx], eax
1063 mov eax, [ecx + VBOXTSS.eax]
1064 mov [esp + CPUMCTXCORE.eax], eax
1065 mov eax, [ecx + VBOXTSS.ebp]
1066 mov [esp + CPUMCTXCORE.ebp], eax
1067 mov eax, [ecx + VBOXTSS.esi]
1068 mov [esp + CPUMCTXCORE.esi], eax
1069 mov eax, [ecx + VBOXTSS.edi]
1070 mov [esp + CPUMCTXCORE.edi], eax
1071
1072 ;
1073 ; Show regs
1074 ;
1075 mov ebx, 0ffffffffh
1076 mov ecx, 'trpH' ; indicate trap.
1077 mov edx, 08h ; vector number
1078 lea eax, [esp]
1079 call trpmDbgDumpRegisterFrame
1080
1081 ;
1082 ; Should we try go back?
1083 ;
1084 inc dword [df_Count]
1085 cmp dword [df_Count], byte 10
1086 jb df_to_host
1087 jmp df_tripple_fault
1088df_Count: dd 0
1089
1090 ;
1091 ; Try return to the host.
1092 ;
1093df_to_host:
1094 COM_S_PRINT 'Trying to return to host...',10,13
1095 mov ecx, esp
1096 mov edx, IMP(g_VM)
1097 mov eax, VERR_TRPM_PANIC
1098 call [edx + VM.pfnVMMGCGuestToHostAsmHyperCtx]
1099 jmp short df_to_host
1100
1101 ;
1102 ; Perform a tripple fault.
1103 ;
1104df_tripple_fault:
1105 COM_S_PRINT 'Giving up - tripple faulting the machine...',10,13
1106 push byte 0
1107 push byte 0
1108 sidt [esp]
1109 mov word [esp], 0
1110 lidt [esp]
1111 xor eax, eax
1112 mov dword [eax], 0
1113 jmp df_tripple_fault
1114
1115ENDPROC TRPMGCHandlerTrap08
1116
1117
1118
1119
1120;;
1121; Internal procedure used to dump registers.
1122;
1123; @param eax Pointer to CPUMCTXCORE.
1124; @param edx Vector number
1125; @param ecx 'trap' if trap, 'int' if interrupt.
1126; @param ebx Error code if trap.
1127;
1128trpmDbgDumpRegisterFrame:
1129 sub esp, byte 8 ; working space for sidt/sgdt/etc
1130
1131; Init _must_ be done on host before crashing!
1132; push edx
1133; push eax
1134; COM_INIT
1135; pop eax
1136; pop edx
1137
1138 cmp ecx, 'trpH'
1139 je near tddrf_trpH
1140 cmp ecx, 'trpG'
1141 je near tddrf_trpG
1142 cmp ecx, 'intH'
1143 je near tddrf_intH
1144 cmp ecx, 'intG'
1145 je near tddrf_intG
1146 cmp ecx, 'resH'
1147 je near tddrf_resH
1148 COM_S_PRINT 10,13,'*** Bogus Dump Code '
1149 jmp tddrf_regs
1150
1151%if 1 ; the verbose version
1152
1153tddrf_intG:
1154 COM_S_PRINT 10,13,'*** Interrupt (Guest) '
1155 COM_S_DWORD_REG edx
1156 jmp tddrf_regs
1157
1158tddrf_intH:
1159 COM_S_PRINT 10,13,'*** Interrupt (Hypervisor) '
1160 COM_S_DWORD_REG edx
1161 jmp tddrf_regs
1162
1163tddrf_trpG:
1164 COM_S_PRINT 10,13,'*** Trap '
1165 jmp tddrf_trap_rest
1166
1167%else ; the short version
1168
1169tddrf_intG:
1170 COM_S_CHAR 'I'
1171 jmp tddrf_ret
1172
1173tddrf_intH:
1174 COM_S_CHAR 'i'
1175 jmp tddrf_ret
1176
1177tddrf_trpG:
1178 COM_S_CHAR 'T'
1179 jmp tddrf_ret
1180
1181%endif ; the short version
1182
1183tddrf_trpH:
1184 COM_S_PRINT 10,13,'*** Guru Meditation '
1185 jmp tddrf_trap_rest
1186
1187tddrf_resH:
1188 COM_S_PRINT 10,13,'*** Resuming Hypervisor Trap '
1189 jmp tddrf_trap_rest
1190
1191tddrf_trap_rest:
1192 COM_S_DWORD_REG edx
1193 COM_S_PRINT ' ErrorCode='
1194 COM_S_DWORD_REG ebx
1195 COM_S_PRINT ' cr2='
1196 mov ecx, cr2
1197 COM_S_DWORD_REG ecx
1198
1199tddrf_regs:
1200 COM_S_PRINT ' ***',10,13,'cs:eip='
1201 movzx ecx, word [eax + CPUMCTXCORE.cs]
1202 COM_S_DWORD_REG ecx
1203 COM_S_CHAR ':'
1204 mov ecx, [eax + CPUMCTXCORE.eip]
1205 COM_S_DWORD_REG ecx
1206
1207 COM_S_PRINT ' ss:esp='
1208 movzx ecx, word [eax + CPUMCTXCORE.ss]
1209 COM_S_DWORD_REG ecx
1210 COM_S_CHAR ':'
1211 mov ecx, [eax + CPUMCTXCORE.esp]
1212 COM_S_DWORD_REG ecx
1213
1214
1215 sgdt [esp]
1216 COM_S_PRINT 10,13,' gdtr='
1217 movzx ecx, word [esp]
1218 COM_S_DWORD_REG ecx
1219 COM_S_CHAR ':'
1220 mov ecx, [esp + 2]
1221 COM_S_DWORD_REG ecx
1222
1223 sidt [esp]
1224 COM_S_PRINT ' idtr='
1225 movzx ecx, word [esp]
1226 COM_S_DWORD_REG ecx
1227 COM_S_CHAR ':'
1228 mov ecx, [esp + 2]
1229 COM_S_DWORD_REG ecx
1230
1231
1232 str [esp] ; yasm BUG! it generates sldt [esp] here! YASMCHECK!
1233 COM_S_PRINT 10,13,' tr='
1234 movzx ecx, word [esp]
1235 COM_S_DWORD_REG ecx
1236
1237 sldt [esp]
1238 COM_S_PRINT ' ldtr='
1239 movzx ecx, word [esp]
1240 COM_S_DWORD_REG ecx
1241
1242 COM_S_PRINT ' eflags='
1243 mov ecx, [eax + CPUMCTXCORE.eflags]
1244 COM_S_DWORD_REG ecx
1245
1246
1247 COM_S_PRINT 10,13,'cr0='
1248 mov ecx, cr0
1249 COM_S_DWORD_REG ecx
1250
1251 COM_S_PRINT ' cr2='
1252 mov ecx, cr2
1253 COM_S_DWORD_REG ecx
1254
1255 COM_S_PRINT ' cr3='
1256 mov ecx, cr3
1257 COM_S_DWORD_REG ecx
1258 COM_S_PRINT ' cr4='
1259 mov ecx, cr4
1260 COM_S_DWORD_REG ecx
1261
1262
1263 COM_S_PRINT 10,13,' ds='
1264 movzx ecx, word [eax + CPUMCTXCORE.ds]
1265 COM_S_DWORD_REG ecx
1266
1267 COM_S_PRINT ' es='
1268 movzx ecx, word [eax + CPUMCTXCORE.es]
1269 COM_S_DWORD_REG ecx
1270
1271 COM_S_PRINT ' fs='
1272 movzx ecx, word [eax + CPUMCTXCORE.fs]
1273 COM_S_DWORD_REG ecx
1274
1275 COM_S_PRINT ' gs='
1276 movzx ecx, word [eax + CPUMCTXCORE.gs]
1277 COM_S_DWORD_REG ecx
1278
1279
1280 COM_S_PRINT 10,13,'eax='
1281 mov ecx, [eax + CPUMCTXCORE.eax]
1282 COM_S_DWORD_REG ecx
1283
1284 COM_S_PRINT ' ebx='
1285 mov ecx, [eax + CPUMCTXCORE.ebx]
1286 COM_S_DWORD_REG ecx
1287
1288 COM_S_PRINT ' ecx='
1289 mov ecx, [eax + CPUMCTXCORE.ecx]
1290 COM_S_DWORD_REG ecx
1291
1292 COM_S_PRINT ' edx='
1293 mov ecx, [eax + CPUMCTXCORE.edx]
1294 COM_S_DWORD_REG ecx
1295
1296
1297 COM_S_PRINT 10,13,'esi='
1298 mov ecx, [eax + CPUMCTXCORE.esi]
1299 COM_S_DWORD_REG ecx
1300
1301 COM_S_PRINT ' edi='
1302 mov ecx, [eax + CPUMCTXCORE.edi]
1303 COM_S_DWORD_REG ecx
1304
1305 COM_S_PRINT ' ebp='
1306 mov ecx, [eax + CPUMCTXCORE.ebp]
1307 COM_S_DWORD_REG ecx
1308
1309
1310 COM_S_NEWLINE
1311
1312tddrf_ret:
1313 add esp, byte 8
1314 ret
1315
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