VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMGC/CPUMGCA.asm@ 23911

Last change on this file since 23911 was 13960, checked in by vboxsync, 16 years ago

Moved guest and host CPU contexts into per-VCPU array.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 11.8 KB
Line 
1; $Id: CPUMGCA.asm 13960 2008-11-07 13:04:45Z vboxsync $
2;; @file
3; CPUM - Guest Context Assembly Routines.
4;
5
6; Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 (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.
15;
16; Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
17; Clara, CA 95054 USA or visit http://www.sun.com if you need
18; additional information or have any questions.
19;
20
21;*******************************************************************************
22;* Header Files *
23;*******************************************************************************
24%include "VMMGC.mac"
25%include "VBox/vm.mac"
26%include "VBox/err.mac"
27%include "VBox/stam.mac"
28%include "CPUMInternal.mac"
29%include "VBox/x86.mac"
30%include "VBox/cpum.mac"
31
32
33;*******************************************************************************
34;* External Symbols *
35;*******************************************************************************
36extern IMPNAME(g_CPUM) ; VMM GC Builtin import
37extern IMPNAME(g_VM) ; VMM GC Builtin import
38extern NAME(cpumGCHandleNPAndGP) ; CPUMGC.cpp
39
40;
41; Enables write protection of Hypervisor memory pages.
42; !note! Must be commented out for Trap8 debug handler.
43;
44%define ENABLE_WRITE_PROTECTION 1
45
46BEGINCODE
47
48
49;;
50; Restores GC context before doing iret.
51;
52; @param [esp + 4] Pointer to interrupt stack frame, i.e. pointer
53; to the a struct with this layout:
54; 00h eip
55; 04h cs
56; 08h eflags
57; 0ch esp
58; 10h ss
59; 14h es (V86 only)
60; 18h ds (V86 only)
61; 1Ch fs (V86 only)
62; 20h gs (V86 only)
63;
64; @uses everything but cs, ss, esp, and eflags.
65;
66; @remark Assumes we're restoring in Ring-0 a context which is not Ring-0.
67; Further assumes flat stack and valid ds.
68
69BEGINPROC CPUMGCRestoreInt
70 ;
71 ; Update iret frame.
72 ;
73 mov eax, [esp + 4] ; get argument
74 mov edx, IMP(g_CPUM)
75 ; Convert to CPUMCPU pointer
76 add edx, [edx + CPUM.ulOffCPUMCPU]
77
78 mov ecx, [edx + CPUMCPU.Guest.eip]
79 mov [eax + 0h], ecx
80 mov ecx, [edx + CPUMCPU.Guest.cs]
81 mov [eax + 4h], ecx
82 mov ecx, [edx + CPUMCPU.Guest.eflags]
83 mov [eax + 8h], ecx
84 mov ecx, [edx + CPUMCPU.Guest.esp]
85 mov [eax + 0ch], ecx
86 mov ecx, [edx + CPUMCPU.Guest.ss]
87 mov [eax + 10h], ecx
88
89 test dword [edx + CPUMCPU.Guest.eflags], X86_EFL_VM
90 jnz short CPUMGCRestoreInt_V86
91
92 ;
93 ; Load registers.
94 ;
95 ; todo: potential trouble loading invalid es,fs,gs,ds because
96 ; of a VMM imposed exception?
97 mov es, [edx + CPUMCPU.Guest.es]
98 mov fs, [edx + CPUMCPU.Guest.fs]
99 mov gs, [edx + CPUMCPU.Guest.gs]
100 mov esi, [edx + CPUMCPU.Guest.esi]
101 mov edi, [edx + CPUMCPU.Guest.edi]
102 mov ebp, [edx + CPUMCPU.Guest.ebp]
103 mov ebx, [edx + CPUMCPU.Guest.ebx]
104 mov ecx, [edx + CPUMCPU.Guest.ecx]
105 mov eax, [edx + CPUMCPU.Guest.eax]
106 push dword [edx + CPUMCPU.Guest.ds]
107 mov edx, [edx + CPUMCPU.Guest.edx]
108 pop ds
109
110 ret
111
112CPUMGCRestoreInt_V86:
113 ; iret restores ds, es, fs & gs
114 mov ecx, [edx + CPUMCPU.Guest.es]
115 mov [eax + 14h], ecx
116 mov ecx, [edx + CPUMCPU.Guest.ds]
117 mov [eax + 18h], ecx
118 mov ecx, [edx + CPUMCPU.Guest.fs]
119 mov [eax + 1Ch], ecx
120 mov ecx, [edx + CPUMCPU.Guest.gs]
121 mov [eax + 20h], ecx
122 mov esi, [edx + CPUMCPU.Guest.esi]
123 mov edi, [edx + CPUMCPU.Guest.edi]
124 mov ebp, [edx + CPUMCPU.Guest.ebp]
125 mov ebx, [edx + CPUMCPU.Guest.ebx]
126 mov ecx, [edx + CPUMCPU.Guest.ecx]
127 mov eax, [edx + CPUMCPU.Guest.eax]
128 mov edx, [edx + CPUMCPU.Guest.edx]
129 ret
130
131ENDPROC CPUMGCRestoreInt
132
133
134;;
135; Calls a guest trap/interrupt handler directly
136; Assumes a trap stack frame has already been setup on the guest's stack!
137;
138; @param pRegFrame [esp + 4] Original trap/interrupt context
139; @param selCS [esp + 8] Code selector of handler
140; @param pHandler [esp + 12] GC virtual address of handler
141; @param eflags [esp + 16] Callee's EFLAGS
142; @param selSS [esp + 20] Stack selector for handler
143; @param pEsp [esp + 24] Stack address for handler
144;
145; @remark This call never returns!
146;
147; VMMRCDECL(void) CPUMGCCallGuestTrapHandler(PCPUMCTXCORE pRegFrame, uint32_t selCS, RTGCPTR pHandler, uint32_t eflags, uint32_t selSS, RTGCPTR pEsp);
148align 16
149BEGINPROC_EXPORTED CPUMGCCallGuestTrapHandler
150 mov ebp, esp
151
152 ; construct iret stack frame
153 push dword [ebp + 20] ; SS
154 push dword [ebp + 24] ; ESP
155 push dword [ebp + 16] ; EFLAGS
156 push dword [ebp + 8] ; CS
157 push dword [ebp + 12] ; EIP
158
159 ;
160 ; enable WP
161 ;
162%ifdef ENABLE_WRITE_PROTECTION
163 mov eax, cr0
164 or eax, X86_CR0_WRITE_PROTECT
165 mov cr0, eax
166%endif
167
168 ; restore CPU context (all except cs, eip, ss, esp & eflags; which are restored or overwritten by iret)
169 mov ebp, [ebp + 4] ; pRegFrame
170 mov ebx, [ebp + CPUMCTXCORE.ebx]
171 mov ecx, [ebp + CPUMCTXCORE.ecx]
172 mov edx, [ebp + CPUMCTXCORE.edx]
173 mov esi, [ebp + CPUMCTXCORE.esi]
174 mov edi, [ebp + CPUMCTXCORE.edi]
175
176 ;; @todo load segment registers *before* enabling WP.
177 TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_GS | CPUM_HANDLER_CTXCORE_IN_EBP
178 mov gs, [ebp + CPUMCTXCORE.gs]
179 TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_FS | CPUM_HANDLER_CTXCORE_IN_EBP
180 mov fs, [ebp + CPUMCTXCORE.fs]
181 TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_ES | CPUM_HANDLER_CTXCORE_IN_EBP
182 mov es, [ebp + CPUMCTXCORE.es]
183 TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_DS | CPUM_HANDLER_CTXCORE_IN_EBP
184 mov ds, [ebp + CPUMCTXCORE.ds]
185
186 mov eax, [ebp + CPUMCTXCORE.eax]
187 mov ebp, [ebp + CPUMCTXCORE.ebp]
188
189 TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_IRET
190 iret
191ENDPROC CPUMGCCallGuestTrapHandler
192
193
194;;
195; Performs an iret to V86 code
196; Assumes a trap stack frame has already been setup on the guest's stack!
197;
198; @param pRegFrame Original trap/interrupt context
199;
200; This function does not return!
201;
202;VMMRCDECL(void) CPUMGCCallV86Code(PCPUMCTXCORE pRegFrame);
203align 16
204BEGINPROC CPUMGCCallV86Code
205 mov ebp, [esp + 4] ; pRegFrame
206
207 ; construct iret stack frame
208 push dword [ebp + CPUMCTXCORE.gs]
209 push dword [ebp + CPUMCTXCORE.fs]
210 push dword [ebp + CPUMCTXCORE.ds]
211 push dword [ebp + CPUMCTXCORE.es]
212 push dword [ebp + CPUMCTXCORE.ss]
213 push dword [ebp + CPUMCTXCORE.esp]
214 push dword [ebp + CPUMCTXCORE.eflags]
215 push dword [ebp + CPUMCTXCORE.cs]
216 push dword [ebp + CPUMCTXCORE.eip]
217
218 ;
219 ; enable WP
220 ;
221%ifdef ENABLE_WRITE_PROTECTION
222 mov eax, cr0
223 or eax, X86_CR0_WRITE_PROTECT
224 mov cr0, eax
225%endif
226
227 ; restore CPU context (all except cs, eip, ss, esp, eflags, ds, es, fs & gs; which are restored or overwritten by iret)
228 mov eax, [ebp + CPUMCTXCORE.eax]
229 mov ebx, [ebp + CPUMCTXCORE.ebx]
230 mov ecx, [ebp + CPUMCTXCORE.ecx]
231 mov edx, [ebp + CPUMCTXCORE.edx]
232 mov esi, [ebp + CPUMCTXCORE.esi]
233 mov edi, [ebp + CPUMCTXCORE.edi]
234 mov ebp, [ebp + CPUMCTXCORE.ebp]
235
236 TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_IRET
237 iret
238ENDPROC CPUMGCCallV86Code
239
240
241;;
242; This is a main entry point for resuming (or starting) guest
243; code execution.
244;
245; We get here directly from VMMSwitcher.asm (jmp at the end
246; of VMMSwitcher_HostToGuest).
247;
248; This call never returns!
249;
250; @param edx Pointer to CPUM structure.
251;
252align 16
253BEGINPROC_EXPORTED CPUMGCResumeGuest
254 ; Convert to CPUMCPU pointer
255 add edx, [edx + CPUM.ulOffCPUMCPU]
256 ;
257 ; Setup iretd
258 ;
259 push dword [edx + CPUMCPU.Guest.ss]
260 push dword [edx + CPUMCPU.Guest.esp]
261 push dword [edx + CPUMCPU.Guest.eflags]
262 push dword [edx + CPUMCPU.Guest.cs]
263 push dword [edx + CPUMCPU.Guest.eip]
264
265 ;
266 ; Restore registers.
267 ;
268 TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_ES
269 mov es, [edx + CPUMCPU.Guest.es]
270 TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_FS
271 mov fs, [edx + CPUMCPU.Guest.fs]
272 TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_GS
273 mov gs, [edx + CPUMCPU.Guest.gs]
274
275%ifdef VBOX_WITH_STATISTICS
276 ;
277 ; Statistics.
278 ;
279 push edx
280 mov edx, IMP(g_VM)
281 lea edx, [edx + VM.StatTotalQemuToGC]
282 STAM_PROFILE_ADV_STOP edx
283
284 mov edx, IMP(g_VM)
285 lea edx, [edx + VM.StatTotalInGC]
286 STAM_PROFILE_ADV_START edx
287 pop edx
288%endif
289
290 ;
291 ; enable WP
292 ;
293%ifdef ENABLE_WRITE_PROTECTION
294 mov eax, cr0
295 or eax, X86_CR0_WRITE_PROTECT
296 mov cr0, eax
297%endif
298
299 ;
300 ; Continue restore.
301 ;
302 mov esi, [edx + CPUMCPU.Guest.esi]
303 mov edi, [edx + CPUMCPU.Guest.edi]
304 mov ebp, [edx + CPUMCPU.Guest.ebp]
305 mov ebx, [edx + CPUMCPU.Guest.ebx]
306 mov ecx, [edx + CPUMCPU.Guest.ecx]
307 mov eax, [edx + CPUMCPU.Guest.eax]
308 push dword [edx + CPUMCPU.Guest.ds]
309 mov edx, [edx + CPUMCPU.Guest.edx]
310 TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_DS
311 pop ds
312
313 ; restart execution.
314 TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_IRET
315 iretd
316ENDPROC CPUMGCResumeGuest
317
318
319;;
320; This is a main entry point for resuming (or starting) guest
321; code execution for raw V86 mode
322;
323; We get here directly from VMMSwitcher.asm (jmp at the end
324; of VMMSwitcher_HostToGuest).
325;
326; This call never returns!
327;
328; @param edx Pointer to CPUM structure.
329;
330align 16
331BEGINPROC_EXPORTED CPUMGCResumeGuestV86
332 ; Convert to CPUMCPU pointer
333 add edx, [edx + CPUM.ulOffCPUMCPU]
334 ;
335 ; Setup iretd
336 ;
337 push dword [edx + CPUMCPU.Guest.gs]
338 push dword [edx + CPUMCPU.Guest.fs]
339 push dword [edx + CPUMCPU.Guest.ds]
340 push dword [edx + CPUMCPU.Guest.es]
341
342 push dword [edx + CPUMCPU.Guest.ss]
343 push dword [edx + CPUMCPU.Guest.esp]
344
345 push dword [edx + CPUMCPU.Guest.eflags]
346 push dword [edx + CPUMCPU.Guest.cs]
347 push dword [edx + CPUMCPU.Guest.eip]
348
349 ;
350 ; Restore registers.
351 ;
352
353%ifdef VBOX_WITH_STATISTICS
354 ;
355 ; Statistics.
356 ;
357 push edx
358 mov edx, IMP(g_VM)
359 lea edx, [edx + VM.StatTotalQemuToGC]
360 STAM_PROFILE_ADV_STOP edx
361
362 mov edx, IMP(g_VM)
363 lea edx, [edx + VM.StatTotalInGC]
364 STAM_PROFILE_ADV_START edx
365 pop edx
366%endif
367
368 ;
369 ; enable WP
370 ;
371%ifdef ENABLE_WRITE_PROTECTION
372 mov eax, cr0
373 or eax, X86_CR0_WRITE_PROTECT
374 mov cr0, eax
375%endif
376
377 ;
378 ; Continue restore.
379 ;
380 mov esi, [edx + CPUMCPU.Guest.esi]
381 mov edi, [edx + CPUMCPU.Guest.edi]
382 mov ebp, [edx + CPUMCPU.Guest.ebp]
383 mov ecx, [edx + CPUMCPU.Guest.ecx]
384 mov ebx, [edx + CPUMCPU.Guest.ebx]
385 mov eax, [edx + CPUMCPU.Guest.eax]
386 mov edx, [edx + CPUMCPU.Guest.edx]
387
388 ; restart execution.
389 TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_IRET
390 iretd
391ENDPROC CPUMGCResumeGuestV86
392
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