VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMR0/HWACCMR0A.asm@ 59

Last change on this file since 59 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: 10.3 KB
Line 
1; $Id: HWACCMR0A.asm 19 2007-01-15 13:07:05Z vboxsync $
2;; @file
3; VMXM - R0 vmx helpers
4;
5
6;
7; Copyright (C) 2006 InnoTek Systemberatung GmbH
8;
9; This file is part of VirtualBox Open Source Edition (OSE), as
10; available from http://www.virtualbox.org. This file is free software;
11; you can redistribute it and/or modify it under the terms of the GNU
12; General Public License as published by the Free Software Foundation,
13; in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14; distribution. VirtualBox OSE is distributed in the hope that it will
15; be useful, but WITHOUT ANY WARRANTY of any kind.
16;
17; If you received this file as part of a commercial VirtualBox
18; distribution, then only the terms of your commercial VirtualBox
19; license agreement apply instead of the previous paragraph.
20;
21
22;*******************************************************************************
23;* Header Files *
24;*******************************************************************************
25%include "VBox/asmdefs.mac"
26%include "VBox/err.mac"
27%include "VBox/hwacc_vmx.mac"
28%include "VBox/cpum.mac"
29%include "VBox/x86.mac"
30
31%ifdef __OS2__ ;; @todo build cvs nasm like on OS X.
32%macro vmwrite 2,
33 int3
34%endmacro
35%define vmlaunch int3
36%define vmresume int3
37%endif
38
39BEGINCODE
40
41;/**
42; * Prepares for and executes VMLAUNCH
43; *
44; * @note identical to VMXResumeVM, except for the vmlaunch/vmresume opcode
45; *
46; * @returns VBox status code
47; * @param pCtx Guest context
48; */
49BEGINPROC VMXStartVM
50 push ebp
51 mov ebp, esp
52
53 ;/* First we have to save some final CPU context registers. */
54 push vmlaunch_done
55 mov eax, VMX_VMCS_HOST_RIP ;/* return address (too difficult to continue after VMLAUNCH?) */
56 vmwrite eax, [esp]
57 ;/* @todo assumes success... */
58 add esp, 4
59
60 ;/* Manual save and restore:
61 ; * - General purpose registers except RIP, RSP
62 ; *
63 ; * Trashed:
64 ; * - CR2 (we don't care)
65 ; * - LDTR (reset to 0)
66 ; * - DRx (presumably not changed at all)
67 ; * - DR7 (reset to 0x400)
68 ; * - EFLAGS (reset to BIT(1); not relevant)
69 ; *
70 ; */
71
72 ;/* Save all general purpose host registers. */
73 pushad
74
75 ;/* Save segment registers */
76 push ds
77 push es
78 push fs
79 push gs
80
81 ;/* Save the Guest CPU context pointer. */
82 mov esi, [ebp + 8] ; pCtx
83 push esi
84
85 ; Save LDTR
86 xor eax, eax
87 sldt ax
88 push eax
89
90 ; Restore CR2
91 mov ebx, [esi + CPUMCTX.cr2]
92 mov cr2, ebx
93
94 mov eax, VMX_VMCS_HOST_RSP
95 vmwrite eax, esp
96 ;/* @todo assumes success... */
97 ;/* Don't mess with ESP anymore!! */
98
99 ;/* Restore Guest's general purpose registers. */
100 mov eax, [esi + CPUMCTX.eax]
101 mov ebx, [esi + CPUMCTX.ebx]
102 mov ecx, [esi + CPUMCTX.ecx]
103 mov edx, [esi + CPUMCTX.edx]
104 mov edi, [esi + CPUMCTX.edi]
105 mov ebp, [esi + CPUMCTX.ebp]
106 mov esi, [esi + CPUMCTX.esi]
107
108 vmlaunch
109 jmp vmlaunch_done; ;/* here if vmlaunch detected a failure. */
110
111ALIGNCODE(16)
112vmlaunch_done:
113 jnc vmxstart_good
114
115 pop eax ; saved LDTR
116 lldt ax
117
118 add esp, 4 ; pCtx
119
120 ; Restore segment registers
121 pop gs
122 pop fs
123 pop es
124 pop ds
125
126 ;/* Restore all general purpose host registers. */
127 popad
128 mov eax, VERR_VMX_INVALID_VMXON_PTR
129 jmp vmstart_end
130
131vmxstart_good:
132 jnz vmxstart_success
133
134 pop eax ; saved LDTR
135 lldt ax
136
137 add esp, 4 ; pCtx
138
139 ; Restore segment registers
140 pop gs
141 pop fs
142 pop es
143 pop ds
144 ;/* Restore all general purpose host registers. */
145 popad
146 mov eax, VERR_VMX_UNABLE_TO_START_VM
147 jmp vmstart_end
148
149vmxstart_success:
150 push edi
151 mov edi, dword [esp+8] ;/* pCtx */
152
153 mov [ss:edi + CPUMCTX.eax], eax
154 mov [ss:edi + CPUMCTX.ebx], ebx
155 mov [ss:edi + CPUMCTX.ecx], ecx
156 mov [ss:edi + CPUMCTX.edx], edx
157 mov [ss:edi + CPUMCTX.esi], esi
158 mov [ss:edi + CPUMCTX.ebp], ebp
159 pop dword [ss:edi + CPUMCTX.edi] ; guest edi we pushed above
160
161 pop eax ; saved LDTR
162 lldt ax
163
164 add esp, 4 ; pCtx
165
166 ; Restore segment registers
167 pop gs
168 pop fs
169 pop es
170 pop ds
171
172 ; Restore general purpose registers
173 popad
174
175 mov eax, VINF_SUCCESS
176
177vmstart_end:
178 pop ebp
179 ret
180ENDPROC VMStartVM
181
182
183;/**
184; * Prepares for and executes VMRESUME
185; *
186; * @note identical to VMXStartVM, except for the vmlaunch/vmresume opcode
187; *
188; * @returns VBox status code
189; * @param pCtx Guest context
190; */
191BEGINPROC VMXResumeVM
192 push ebp
193 mov ebp, esp
194
195 ;/* First we have to save some final CPU context registers. */
196 push vmresume_done
197 mov eax, VMX_VMCS_HOST_RIP ;/* return address (too difficult to continue after VMLAUNCH?) */
198 vmwrite eax, [esp]
199 ;/* @todo assumes success... */
200 add esp, 4
201
202 ;/* Manual save and restore:
203 ; * - General purpose registers except RIP, RSP
204 ; *
205 ; * Trashed:
206 ; * - CR2 (we don't care)
207 ; * - LDTR (reset to 0)
208 ; * - DRx (presumably not changed at all)
209 ; * - DR7 (reset to 0x400)
210 ; * - EFLAGS (reset to BIT(1); not relevant)
211 ; *
212 ; */
213
214 ;/* Save all general purpose host registers. */
215 pushad
216
217 ;/* Save segment registers */
218 push ds
219 push es
220 push fs
221 push gs
222
223 ;/* Save the Guest CPU context pointer. */
224 mov esi, [ebp + 8] ; pCtx
225 push esi
226
227 ; Save LDTR
228 xor eax, eax
229 sldt ax
230 push eax
231
232 ; Restore CR2
233 mov ebx, [esi + CPUMCTX.cr2]
234 mov cr2, ebx
235
236 mov eax, VMX_VMCS_HOST_RSP
237 vmwrite eax, esp
238 ;/* @todo assumes success... */
239 ;/* Don't mess with ESP anymore!! */
240
241 ;/* Restore Guest's general purpose registers. */
242 mov eax, [esi + CPUMCTX.eax]
243 mov ebx, [esi + CPUMCTX.ebx]
244 mov ecx, [esi + CPUMCTX.ecx]
245 mov edx, [esi + CPUMCTX.edx]
246 mov edi, [esi + CPUMCTX.edi]
247 mov ebp, [esi + CPUMCTX.ebp]
248 mov esi, [esi + CPUMCTX.esi]
249
250 vmresume
251 jmp vmresume_done; ;/* here if vmresume detected a failure. */
252
253ALIGNCODE(16)
254vmresume_done:
255 jnc vmresume_good
256
257 pop eax ; saved LDTR
258 lldt ax
259
260 add esp, 4 ; pCtx
261
262 ; Restore segment registers
263 pop gs
264 pop fs
265 pop es
266 pop ds
267
268 ;/* Restore all general purpose host registers. */
269 popad
270 mov eax, VERR_VMX_INVALID_VMXON_PTR
271 jmp vmresume_end
272
273vmresume_good:
274 jnz vmresume_success
275
276 pop eax ; saved LDTR
277 lldt ax
278
279 add esp, 4 ; pCtx
280
281 ; Restore segment registers
282 pop gs
283 pop fs
284 pop es
285 pop ds
286 ;/* Restore all general purpose host registers. */
287 popad
288 mov eax, VERR_VMX_UNABLE_TO_RESUME_VM
289 jmp vmresume_end
290
291vmresume_success:
292 push edi
293 mov edi, dword [esp+8] ;/* pCtx */
294
295 mov [ss:edi + CPUMCTX.eax], eax
296 mov [ss:edi + CPUMCTX.ebx], ebx
297 mov [ss:edi + CPUMCTX.ecx], ecx
298 mov [ss:edi + CPUMCTX.edx], edx
299 mov [ss:edi + CPUMCTX.esi], esi
300 mov [ss:edi + CPUMCTX.ebp], ebp
301 pop dword [ss:edi + CPUMCTX.edi] ; guest edi we pushed above
302
303 pop eax ; saved LDTR
304 lldt ax
305
306 add esp, 4 ; pCtx
307
308 ; Restore segment registers
309 pop gs
310 pop fs
311 pop es
312 pop ds
313
314 ; Restore general purpose registers
315 popad
316
317 mov eax, VINF_SUCCESS
318
319vmresume_end:
320 pop ebp
321 ret
322ENDPROC VMXResumeVM
323
324
325
326
327;/**
328; * Prepares for and executes VMRUN
329; *
330; * @returns VBox status code
331; * @param pVMCBHostPhys Physical address of host VMCB
332; * @param pVMCBPhys Physical address of guest VMCB
333; * @param pCtx Guest context
334; */
335BEGINPROC SVMVMRun
336 push ebp
337 mov ebp, esp
338
339 ;/* Manual save and restore:
340 ; * - General purpose registers except RIP, RSP, RAX
341 ; *
342 ; * Trashed:
343 ; * - CR2 (we don't care)
344 ; * - LDTR (reset to 0)
345 ; * - DRx (presumably not changed at all)
346 ; * - DR7 (reset to 0x400)
347 ; */
348
349 ;/* Save all general purpose host registers. */
350 pushad
351
352 ; /* Clear fs and gs as a safety precaution. Maybe not necessary. */
353 push fs
354 push gs
355 xor eax, eax
356 mov fs, eax
357 mov gs, eax
358
359 ;/* Save the Guest CPU context pointer. */
360 mov esi, [ebp + 24] ; pCtx
361 push esi
362
363 ; Restore CR2
364 mov ebx, [esi + CPUMCTX.cr2]
365 mov cr2, ebx
366
367 ; save host fs, gs, sysenter msr etc
368 mov eax, [ebp + 8] ; pVMCBHostPhys (64 bits physical address; take low dword only)
369 push eax ; save for the vmload after vmrun
370 DB 0x0F, 0x01, 0xDB ; VMSAVE
371
372 ; setup eax for VMLOAD
373 mov eax, [ebp + 16] ; pVMCBPhys (64 bits physical address; take low dword only)
374
375 ;/* Restore Guest's general purpose registers. */
376 ;/* EAX is loaded from the VMCB by VMRUN */
377 mov ebx, [esi + CPUMCTX.ebx]
378 mov ecx, [esi + CPUMCTX.ecx]
379 mov edx, [esi + CPUMCTX.edx]
380 mov edi, [esi + CPUMCTX.edi]
381 mov ebp, [esi + CPUMCTX.ebp]
382 mov esi, [esi + CPUMCTX.esi]
383
384 ; Clear the global interrupt flag & execute sti to make sure external interrupts cause a world switch
385 DB 0x0f, 0x01, 0xDD ; CLGI
386 sti
387
388 ; load guest fs, gs, sysenter msr etc
389 DB 0x0f, 0x01, 0xDA ; VMLOAD
390 ; run the VM
391 DB 0x0F, 0x01, 0xD8 ; VMRUN
392
393 ;/* EAX is in the VMCB already; we can use it here. */
394
395 ; save guest fs, gs, sysenter msr etc
396 DB 0x0F, 0x01, 0xDB ; VMSAVE
397
398 ; load host fs, gs, sysenter msr etc
399 pop eax ; pushed above
400 DB 0x0F, 0x01, 0xDA ; VMLOAD
401
402 ; Set the global interrupt flag again, but execute cli to make sure IF=0.
403 cli
404 DB 0x0f, 0x01, 0xDC ; STGI
405
406 pop eax ; pCtx
407
408 mov [ss:eax + CPUMCTX.ebx], ebx
409 mov [ss:eax + CPUMCTX.ecx], ecx
410 mov [ss:eax + CPUMCTX.edx], edx
411 mov [ss:eax + CPUMCTX.esi], esi
412 mov [ss:eax + CPUMCTX.edi], edi
413 mov [ss:eax + CPUMCTX.ebp], ebp
414
415 ; Restore fs & gs
416 pop gs
417 pop fs
418
419 ; Restore general purpose registers
420 popad
421
422 mov eax, VINF_SUCCESS
423
424 pop ebp
425 ret
426ENDPROC SVMVMRun
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette