3
; CPUM - Guest Context Assembly Routines.
6
; Copyright (C) 2006-2007 Oracle Corporation
8
; This file is part of VirtualBox Open Source Edition (OSE), as
9
; available from http://www.virtualbox.org. This file is free software;
10
; you can redistribute it and/or modify it under the terms of the GNU
11
; General Public License (GPL) as published by the Free Software
12
; Foundation, in version 2 as it comes in the "COPYING" file of the
13
; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14
; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17
;*******************************************************************************
19
;*******************************************************************************
21
%include "VBox/vm.mac"
22
%include "VBox/err.mac"
23
%include "VBox/stam.mac"
24
%include "CPUMInternal.mac"
25
%include "VBox/x86.mac"
26
%include "VBox/cpum.mac"
29
;*******************************************************************************
31
;*******************************************************************************
32
extern IMPNAME(g_CPUM) ; VMM GC Builtin import
33
extern IMPNAME(g_VM) ; VMM GC Builtin import
34
extern NAME(cpumGCHandleNPAndGP) ; CPUMGC.cpp
37
; Enables write protection of Hypervisor memory pages.
38
; !note! Must be commented out for Trap8 debug handler.
40
%define ENABLE_WRITE_PROTECTION 1
46
; Restores GC context before doing iret.
48
; @param [esp + 4] Pointer to interrupt stack frame, i.e. pointer
49
; to the a struct with this layout:
60
; @uses everything but cs, ss, esp, and eflags.
62
; @remark Assumes we're restoring in Ring-0 a context which is not Ring-0.
63
; Further assumes flat stack and valid ds.
65
BEGINPROC CPUMGCRestoreInt
69
mov eax, [esp + 4] ; get argument
71
; Convert to CPUMCPU pointer
72
add edx, [edx + CPUM.offCPUMCPU0]
74
mov ecx, [edx + CPUMCPU.Guest.eip]
76
mov ecx, [edx + CPUMCPU.Guest.cs]
78
mov ecx, [edx + CPUMCPU.Guest.eflags]
80
mov ecx, [edx + CPUMCPU.Guest.esp]
82
mov ecx, [edx + CPUMCPU.Guest.ss]
85
test dword [edx + CPUMCPU.Guest.eflags], X86_EFL_VM
86
jnz short CPUMGCRestoreInt_V86
91
; todo: potential trouble loading invalid es,fs,gs,ds because
92
; of a VMM imposed exception?
93
mov es, [edx + CPUMCPU.Guest.es]
94
mov fs, [edx + CPUMCPU.Guest.fs]
95
mov gs, [edx + CPUMCPU.Guest.gs]
96
mov esi, [edx + CPUMCPU.Guest.esi]
97
mov edi, [edx + CPUMCPU.Guest.edi]
98
mov ebp, [edx + CPUMCPU.Guest.ebp]
99
mov ebx, [edx + CPUMCPU.Guest.ebx]
100
mov ecx, [edx + CPUMCPU.Guest.ecx]
101
mov eax, [edx + CPUMCPU.Guest.eax]
102
push dword [edx + CPUMCPU.Guest.ds]
103
mov edx, [edx + CPUMCPU.Guest.edx]
108
CPUMGCRestoreInt_V86:
109
; iret restores ds, es, fs & gs
110
mov ecx, [edx + CPUMCPU.Guest.es]
112
mov ecx, [edx + CPUMCPU.Guest.ds]
114
mov ecx, [edx + CPUMCPU.Guest.fs]
116
mov ecx, [edx + CPUMCPU.Guest.gs]
118
mov esi, [edx + CPUMCPU.Guest.esi]
119
mov edi, [edx + CPUMCPU.Guest.edi]
120
mov ebp, [edx + CPUMCPU.Guest.ebp]
121
mov ebx, [edx + CPUMCPU.Guest.ebx]
122
mov ecx, [edx + CPUMCPU.Guest.ecx]
123
mov eax, [edx + CPUMCPU.Guest.eax]
124
mov edx, [edx + CPUMCPU.Guest.edx]
127
ENDPROC CPUMGCRestoreInt
131
; Calls a guest trap/interrupt handler directly
132
; Assumes a trap stack frame has already been setup on the guest's stack!
134
; @param pRegFrame [esp + 4] Original trap/interrupt context
135
; @param selCS [esp + 8] Code selector of handler
136
; @param pHandler [esp + 12] GC virtual address of handler
137
; @param eflags [esp + 16] Callee's EFLAGS
138
; @param selSS [esp + 20] Stack selector for handler
139
; @param pEsp [esp + 24] Stack address for handler
141
; @remark This call never returns!
143
; VMMRCDECL(void) CPUMGCCallGuestTrapHandler(PCPUMCTXCORE pRegFrame, uint32_t selCS, RTGCPTR pHandler, uint32_t eflags, uint32_t selSS, RTGCPTR pEsp);
145
BEGINPROC_EXPORTED CPUMGCCallGuestTrapHandler
148
; construct iret stack frame
149
push dword [ebp + 20] ; SS
150
push dword [ebp + 24] ; ESP
151
push dword [ebp + 16] ; EFLAGS
152
push dword [ebp + 8] ; CS
153
push dword [ebp + 12] ; EIP
158
%ifdef ENABLE_WRITE_PROTECTION
160
or eax, X86_CR0_WRITE_PROTECT
164
; restore CPU context (all except cs, eip, ss, esp & eflags; which are restored or overwritten by iret)
165
mov ebp, [ebp + 4] ; pRegFrame
166
mov ebx, [ebp + CPUMCTXCORE.ebx]
167
mov ecx, [ebp + CPUMCTXCORE.ecx]
168
mov edx, [ebp + CPUMCTXCORE.edx]
169
mov esi, [ebp + CPUMCTXCORE.esi]
170
mov edi, [ebp + CPUMCTXCORE.edi]
172
;; @todo load segment registers *before* enabling WP.
173
TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_GS | CPUM_HANDLER_CTXCORE_IN_EBP
174
mov gs, [ebp + CPUMCTXCORE.gs]
175
TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_FS | CPUM_HANDLER_CTXCORE_IN_EBP
176
mov fs, [ebp + CPUMCTXCORE.fs]
177
TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_ES | CPUM_HANDLER_CTXCORE_IN_EBP
178
mov es, [ebp + CPUMCTXCORE.es]
179
TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_DS | CPUM_HANDLER_CTXCORE_IN_EBP
180
mov ds, [ebp + CPUMCTXCORE.ds]
182
mov eax, [ebp + CPUMCTXCORE.eax]
183
mov ebp, [ebp + CPUMCTXCORE.ebp]
185
TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_IRET
187
ENDPROC CPUMGCCallGuestTrapHandler
191
; Performs an iret to V86 code
192
; Assumes a trap stack frame has already been setup on the guest's stack!
194
; @param pRegFrame Original trap/interrupt context
196
; This function does not return!
198
;VMMRCDECL(void) CPUMGCCallV86Code(PCPUMCTXCORE pRegFrame);
200
BEGINPROC CPUMGCCallV86Code
201
mov ebp, [esp + 4] ; pRegFrame
203
; construct iret stack frame
204
push dword [ebp + CPUMCTXCORE.gs]
205
push dword [ebp + CPUMCTXCORE.fs]
206
push dword [ebp + CPUMCTXCORE.ds]
207
push dword [ebp + CPUMCTXCORE.es]
208
push dword [ebp + CPUMCTXCORE.ss]
209
push dword [ebp + CPUMCTXCORE.esp]
210
push dword [ebp + CPUMCTXCORE.eflags]
211
push dword [ebp + CPUMCTXCORE.cs]
212
push dword [ebp + CPUMCTXCORE.eip]
217
%ifdef ENABLE_WRITE_PROTECTION
219
or eax, X86_CR0_WRITE_PROTECT
223
; restore CPU context (all except cs, eip, ss, esp, eflags, ds, es, fs & gs; which are restored or overwritten by iret)
224
mov eax, [ebp + CPUMCTXCORE.eax]
225
mov ebx, [ebp + CPUMCTXCORE.ebx]
226
mov ecx, [ebp + CPUMCTXCORE.ecx]
227
mov edx, [ebp + CPUMCTXCORE.edx]
228
mov esi, [ebp + CPUMCTXCORE.esi]
229
mov edi, [ebp + CPUMCTXCORE.edi]
230
mov ebp, [ebp + CPUMCTXCORE.ebp]
232
TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_IRET
234
ENDPROC CPUMGCCallV86Code
238
; This is a main entry point for resuming (or starting) guest
241
; We get here directly from VMMSwitcher.asm (jmp at the end
242
; of VMMSwitcher_HostToGuest).
244
; This call never returns!
246
; @param edx Pointer to CPUM structure.
249
BEGINPROC_EXPORTED CPUMGCResumeGuest
250
; Convert to CPUMCPU pointer
251
add edx, [edx + CPUM.offCPUMCPU0]
255
push dword [edx + CPUMCPU.Guest.ss]
256
push dword [edx + CPUMCPU.Guest.esp]
257
push dword [edx + CPUMCPU.Guest.eflags]
258
push dword [edx + CPUMCPU.Guest.cs]
259
push dword [edx + CPUMCPU.Guest.eip]
264
TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_ES
265
mov es, [edx + CPUMCPU.Guest.es]
266
TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_FS
267
mov fs, [edx + CPUMCPU.Guest.fs]
268
TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_GS
269
mov gs, [edx + CPUMCPU.Guest.gs]
271
%ifdef VBOX_WITH_STATISTICS
277
lea edx, [edx + VM.StatTotalQemuToGC]
278
STAM_PROFILE_ADV_STOP edx
281
lea edx, [edx + VM.StatTotalInGC]
282
STAM_PROFILE_ADV_START edx
289
%ifdef ENABLE_WRITE_PROTECTION
291
or eax, X86_CR0_WRITE_PROTECT
298
mov esi, [edx + CPUMCPU.Guest.esi]
299
mov edi, [edx + CPUMCPU.Guest.edi]
300
mov ebp, [edx + CPUMCPU.Guest.ebp]
301
mov ebx, [edx + CPUMCPU.Guest.ebx]
302
mov ecx, [edx + CPUMCPU.Guest.ecx]
303
mov eax, [edx + CPUMCPU.Guest.eax]
304
push dword [edx + CPUMCPU.Guest.ds]
305
mov edx, [edx + CPUMCPU.Guest.edx]
306
TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_DS
310
TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_IRET
312
ENDPROC CPUMGCResumeGuest
316
; This is a main entry point for resuming (or starting) guest
317
; code execution for raw V86 mode
319
; We get here directly from VMMSwitcher.asm (jmp at the end
320
; of VMMSwitcher_HostToGuest).
322
; This call never returns!
324
; @param edx Pointer to CPUM structure.
327
BEGINPROC_EXPORTED CPUMGCResumeGuestV86
328
; Convert to CPUMCPU pointer
329
add edx, [edx + CPUM.offCPUMCPU0]
333
push dword [edx + CPUMCPU.Guest.gs]
334
push dword [edx + CPUMCPU.Guest.fs]
335
push dword [edx + CPUMCPU.Guest.ds]
336
push dword [edx + CPUMCPU.Guest.es]
338
push dword [edx + CPUMCPU.Guest.ss]
339
push dword [edx + CPUMCPU.Guest.esp]
341
push dword [edx + CPUMCPU.Guest.eflags]
342
push dword [edx + CPUMCPU.Guest.cs]
343
push dword [edx + CPUMCPU.Guest.eip]
349
%ifdef VBOX_WITH_STATISTICS
355
lea edx, [edx + VM.StatTotalQemuToGC]
356
STAM_PROFILE_ADV_STOP edx
359
lea edx, [edx + VM.StatTotalInGC]
360
STAM_PROFILE_ADV_START edx
367
%ifdef ENABLE_WRITE_PROTECTION
369
or eax, X86_CR0_WRITE_PROTECT
376
mov esi, [edx + CPUMCPU.Guest.esi]
377
mov edi, [edx + CPUMCPU.Guest.edi]
378
mov ebp, [edx + CPUMCPU.Guest.ebp]
379
mov ecx, [edx + CPUMCPU.Guest.ecx]
380
mov ebx, [edx + CPUMCPU.Guest.ebx]
381
mov eax, [edx + CPUMCPU.Guest.eax]
382
mov edx, [edx + CPUMCPU.Guest.edx]
385
TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_IRET
387
ENDPROC CPUMGCResumeGuestV86