VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMR0/HMR0UtilA.asm

Last change on this file was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 10.9 KB
Line 
1; $Id: HMR0UtilA.asm 98103 2023-01-17 14:15:46Z vboxsync $
2;; @file
3; HM - Ring-0 VMX & SVM Helpers.
4;
5
6;
7; Copyright (C) 2006-2023 Oracle and/or its affiliates.
8;
9; This file is part of VirtualBox base platform packages, as
10; available from https://www.virtualbox.org.
11;
12; This program is free software; you can redistribute it and/or
13; modify it under the terms of the GNU General Public License
14; as published by the Free Software Foundation, in version 3 of the
15; License.
16;
17; This program is distributed in the hope that it will be useful, but
18; WITHOUT ANY WARRANTY; without even the implied warranty of
19; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20; General Public License for more details.
21;
22; You should have received a copy of the GNU General Public License
23; along with this program; if not, see <https://www.gnu.org/licenses>.
24;
25; SPDX-License-Identifier: GPL-3.0-only
26;
27
28;*********************************************************************************************************************************
29;* Header Files *
30;*********************************************************************************************************************************
31%include "VBox/asmdefs.mac"
32%include "VBox/err.mac"
33%include "VBox/vmm/hm_vmx.mac"
34%include "iprt/x86.mac"
35
36
37
38BEGINCODE
39
40;;
41; Executes VMWRITE, 64-bit value.
42;
43; @returns VBox status code.
44; @param idxField x86: [ebp + 08h] msc: rcx gcc: rdi VMCS index.
45; @param u64Data x86: [ebp + 0ch] msc: rdx gcc: rsi VM field value.
46;
47ALIGNCODE(16)
48BEGINPROC VMXWriteVmcs64
49%ifdef RT_ARCH_AMD64
50 %ifdef ASM_CALL64_GCC
51 and edi, 0ffffffffh
52 xor rax, rax
53 vmwrite rdi, rsi
54 %else
55 and ecx, 0ffffffffh
56 xor rax, rax
57 vmwrite rcx, rdx
58 %endif
59%else ; RT_ARCH_X86
60 mov ecx, [esp + 4] ; idxField
61 lea edx, [esp + 8] ; &u64Data
62 vmwrite ecx, [edx] ; low dword
63 jz .done
64 jc .done
65 inc ecx
66 xor eax, eax
67 vmwrite ecx, [edx + 4] ; high dword
68.done:
69%endif ; RT_ARCH_X86
70 jnc .valid_vmcs
71 mov eax, VERR_VMX_INVALID_VMCS_PTR
72 ret
73.valid_vmcs:
74 jnz .the_end
75 mov eax, VERR_VMX_INVALID_VMCS_FIELD
76.the_end:
77 ret
78ENDPROC VMXWriteVmcs64
79
80
81;;
82; Executes VMREAD, 64-bit value.
83;
84; @returns VBox status code.
85; @param idxField VMCS index.
86; @param pData Where to store VM field value.
87;
88;DECLASM(int) VMXReadVmcs64(uint32_t idxField, uint64_t *pData);
89ALIGNCODE(16)
90BEGINPROC VMXReadVmcs64
91%ifdef RT_ARCH_AMD64
92 %ifdef ASM_CALL64_GCC
93 and edi, 0ffffffffh
94 xor rax, rax
95 vmread [rsi], rdi
96 %else
97 and ecx, 0ffffffffh
98 xor rax, rax
99 vmread [rdx], rcx
100 %endif
101%else ; RT_ARCH_X86
102 mov ecx, [esp + 4] ; idxField
103 mov edx, [esp + 8] ; pData
104 vmread [edx], ecx ; low dword
105 jz .done
106 jc .done
107 inc ecx
108 xor eax, eax
109 vmread [edx + 4], ecx ; high dword
110.done:
111%endif ; RT_ARCH_X86
112 jnc .valid_vmcs
113 mov eax, VERR_VMX_INVALID_VMCS_PTR
114 ret
115.valid_vmcs:
116 jnz .the_end
117 mov eax, VERR_VMX_INVALID_VMCS_FIELD
118.the_end:
119 ret
120ENDPROC VMXReadVmcs64
121
122
123;;
124; Executes VMREAD, 32-bit value.
125;
126; @returns VBox status code.
127; @param idxField VMCS index.
128; @param pu32Data Where to store VM field value.
129;
130;DECLASM(int) VMXReadVmcs32(uint32_t idxField, uint32_t *pu32Data);
131ALIGNCODE(16)
132BEGINPROC VMXReadVmcs32
133%ifdef RT_ARCH_AMD64
134 %ifdef ASM_CALL64_GCC
135 and edi, 0ffffffffh
136 xor rax, rax
137 vmread r10, rdi
138 mov [rsi], r10d
139 %else
140 and ecx, 0ffffffffh
141 xor rax, rax
142 vmread r10, rcx
143 mov [rdx], r10d
144 %endif
145%else ; RT_ARCH_X86
146 mov ecx, [esp + 4] ; idxField
147 mov edx, [esp + 8] ; pu32Data
148 xor eax, eax
149 vmread [edx], ecx
150%endif ; RT_ARCH_X86
151 jnc .valid_vmcs
152 mov eax, VERR_VMX_INVALID_VMCS_PTR
153 ret
154.valid_vmcs:
155 jnz .the_end
156 mov eax, VERR_VMX_INVALID_VMCS_FIELD
157.the_end:
158 ret
159ENDPROC VMXReadVmcs32
160
161
162;;
163; Executes VMWRITE, 32-bit value.
164;
165; @returns VBox status code.
166; @param idxField VMCS index.
167; @param u32Data Where to store VM field value.
168;
169;DECLASM(int) VMXWriteVmcs32(uint32_t idxField, uint32_t u32Data);
170ALIGNCODE(16)
171BEGINPROC VMXWriteVmcs32
172%ifdef RT_ARCH_AMD64
173 %ifdef ASM_CALL64_GCC
174 and edi, 0ffffffffh
175 and esi, 0ffffffffh
176 xor rax, rax
177 vmwrite rdi, rsi
178 %else
179 and ecx, 0ffffffffh
180 and edx, 0ffffffffh
181 xor rax, rax
182 vmwrite rcx, rdx
183 %endif
184%else ; RT_ARCH_X86
185 mov ecx, [esp + 4] ; idxField
186 mov edx, [esp + 8] ; u32Data
187 xor eax, eax
188 vmwrite ecx, edx
189%endif ; RT_ARCH_X86
190 jnc .valid_vmcs
191 mov eax, VERR_VMX_INVALID_VMCS_PTR
192 ret
193.valid_vmcs:
194 jnz .the_end
195 mov eax, VERR_VMX_INVALID_VMCS_FIELD
196.the_end:
197 ret
198ENDPROC VMXWriteVmcs32
199
200
201;;
202; Executes VMXON.
203;
204; @returns VBox status code.
205; @param HCPhysVMXOn Physical address of VMXON structure.
206;
207;DECLASM(int) VMXEnable(RTHCPHYS HCPhysVMXOn);
208BEGINPROC VMXEnable
209%ifdef RT_ARCH_AMD64
210 xor rax, rax
211 %ifdef ASM_CALL64_GCC
212 push rdi
213 %else
214 push rcx
215 %endif
216 vmxon [rsp]
217%else ; RT_ARCH_X86
218 xor eax, eax
219 vmxon [esp + 4]
220%endif ; RT_ARCH_X86
221 jnc .good
222 mov eax, VERR_VMX_INVALID_VMXON_PTR
223 jmp .the_end
224
225.good:
226 jnz .the_end
227 mov eax, VERR_VMX_VMXON_FAILED
228
229.the_end:
230%ifdef RT_ARCH_AMD64
231 add rsp, 8
232%endif
233 ret
234ENDPROC VMXEnable
235
236
237;;
238; Executes VMXOFF.
239;
240;DECLASM(void) VMXDisable(void);
241BEGINPROC VMXDisable
242 vmxoff
243.the_end:
244 ret
245ENDPROC VMXDisable
246
247
248;;
249; Executes VMCLEAR.
250;
251; @returns VBox status code.
252; @param HCPhysVmcs Physical address of VM control structure.
253;
254;DECLASM(int) VMXClearVmcs(RTHCPHYS HCPhysVmcs);
255ALIGNCODE(16)
256BEGINPROC VMXClearVmcs
257%ifdef RT_ARCH_AMD64
258 xor rax, rax
259 %ifdef ASM_CALL64_GCC
260 push rdi
261 %else
262 push rcx
263 %endif
264 vmclear [rsp]
265%else ; RT_ARCH_X86
266 xor eax, eax
267 vmclear [esp + 4]
268%endif ; RT_ARCH_X86
269 jnc .the_end
270 mov eax, VERR_VMX_INVALID_VMCS_PTR
271.the_end:
272%ifdef RT_ARCH_AMD64
273 add rsp, 8
274%endif
275 ret
276ENDPROC VMXClearVmcs
277
278
279;;
280; Executes VMPTRLD.
281;
282; @returns VBox status code.
283; @param HCPhysVmcs Physical address of VMCS structure.
284;
285;DECLASM(int) VMXLoadVmcs(RTHCPHYS HCPhysVmcs);
286ALIGNCODE(16)
287BEGINPROC VMXLoadVmcs
288%ifdef RT_ARCH_AMD64
289 xor rax, rax
290 %ifdef ASM_CALL64_GCC
291 push rdi
292 %else
293 push rcx
294 %endif
295 vmptrld [rsp]
296%else
297 xor eax, eax
298 vmptrld [esp + 4]
299%endif
300 jnc .the_end
301 mov eax, VERR_VMX_INVALID_VMCS_PTR
302.the_end:
303%ifdef RT_ARCH_AMD64
304 add rsp, 8
305%endif
306 ret
307ENDPROC VMXLoadVmcs
308
309
310;;
311; Executes VMPTRST.
312;
313; @returns VBox status code.
314; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - Address that will receive the current pointer.
315;
316;DECLASM(int) VMXGetCurrentVmcs(RTHCPHYS *pVMCS);
317BEGINPROC VMXGetCurrentVmcs
318%ifdef RT_OS_OS2
319 mov eax, VERR_NOT_SUPPORTED
320 ret
321%else
322 %ifdef RT_ARCH_AMD64
323 %ifdef ASM_CALL64_GCC
324 vmptrst qword [rdi]
325 %else
326 vmptrst qword [rcx]
327 %endif
328 %else
329 vmptrst qword [esp+04h]
330 %endif
331 xor eax, eax
332.the_end:
333 ret
334%endif
335ENDPROC VMXGetCurrentVmcs
336
337
338;;
339; Invalidate a page using INVEPT.
340;
341; @param enmTlbFlush msc:ecx gcc:edi x86:[esp+04] Type of flush.
342; @param pDescriptor msc:edx gcc:esi x86:[esp+08] Descriptor pointer.
343;
344;DECLASM(int) VMXR0InvEPT(VMXTLBFLUSHEPT enmTlbFlush, uint64_t *pDescriptor);
345BEGINPROC VMXR0InvEPT
346%ifdef RT_ARCH_AMD64
347 %ifdef ASM_CALL64_GCC
348 and edi, 0ffffffffh
349 xor rax, rax
350; invept rdi, qword [rsi]
351 DB 0x66, 0x0F, 0x38, 0x80, 0x3E
352 %else
353 and ecx, 0ffffffffh
354 xor rax, rax
355; invept rcx, qword [rdx]
356 DB 0x66, 0x0F, 0x38, 0x80, 0xA
357 %endif
358%else
359 mov ecx, [esp + 4]
360 mov edx, [esp + 8]
361 xor eax, eax
362; invept ecx, qword [edx]
363 DB 0x66, 0x0F, 0x38, 0x80, 0xA
364%endif
365 jnc .valid_vmcs
366 mov eax, VERR_VMX_INVALID_VMCS_PTR
367 ret
368.valid_vmcs:
369 jnz .the_end
370 mov eax, VERR_INVALID_PARAMETER
371.the_end:
372 ret
373ENDPROC VMXR0InvEPT
374
375
376;;
377; Invalidate a page using INVVPID.
378;
379; @param enmTlbFlush msc:ecx gcc:edi x86:[esp+04] Type of flush
380; @param pDescriptor msc:edx gcc:esi x86:[esp+08] Descriptor pointer
381;
382;DECLASM(int) VMXR0InvVPID(VMXTLBFLUSHVPID enmTlbFlush, uint64_t *pDescriptor);
383BEGINPROC VMXR0InvVPID
384%ifdef RT_ARCH_AMD64
385 %ifdef ASM_CALL64_GCC
386 and edi, 0ffffffffh
387 xor rax, rax
388; invvpid rdi, qword [rsi]
389 DB 0x66, 0x0F, 0x38, 0x81, 0x3E
390 %else
391 and ecx, 0ffffffffh
392 xor rax, rax
393; invvpid rcx, qword [rdx]
394 DB 0x66, 0x0F, 0x38, 0x81, 0xA
395 %endif
396%else
397 mov ecx, [esp + 4]
398 mov edx, [esp + 8]
399 xor eax, eax
400; invvpid ecx, qword [edx]
401 DB 0x66, 0x0F, 0x38, 0x81, 0xA
402%endif
403 jnc .valid_vmcs
404 mov eax, VERR_VMX_INVALID_VMCS_PTR
405 ret
406.valid_vmcs:
407 jnz .the_end
408 mov eax, VERR_INVALID_PARAMETER
409.the_end:
410 ret
411ENDPROC VMXR0InvVPID
412
413
414%if GC_ARCH_BITS == 64
415;;
416; Executes INVLPGA.
417;
418; @param pPageGC msc:rcx gcc:rdi x86:[esp+04] Virtual page to invalidate
419; @param uASID msc:rdx gcc:rsi x86:[esp+0C] Tagged TLB id
420;
421;DECLASM(void) SVMR0InvlpgA(RTGCPTR pPageGC, uint32_t uASID);
422BEGINPROC SVMR0InvlpgA
423%ifdef RT_ARCH_AMD64
424 %ifdef ASM_CALL64_GCC
425 mov rax, rdi
426 mov rcx, rsi
427 %else
428 mov rax, rcx
429 mov rcx, rdx
430 %endif
431%else
432 mov eax, [esp + 4]
433 mov ecx, [esp + 0Ch]
434%endif
435 invlpga [xAX], ecx
436 ret
437ENDPROC SVMR0InvlpgA
438
439%else ; GC_ARCH_BITS != 64
440;;
441; Executes INVLPGA
442;
443; @param pPageGC msc:ecx gcc:edi x86:[esp+04] Virtual page to invalidate
444; @param uASID msc:edx gcc:esi x86:[esp+08] Tagged TLB id
445;
446;DECLASM(void) SVMR0InvlpgA(RTGCPTR pPageGC, uint32_t uASID);
447BEGINPROC SVMR0InvlpgA
448%ifdef RT_ARCH_AMD64
449 %ifdef ASM_CALL64_GCC
450 movzx rax, edi
451 mov ecx, esi
452 %else
453 ; from http://www.cs.cmu.edu/~fp/courses/15213-s06/misc/asm64-handout.pdf:
454 ; "Perhaps unexpectedly, instructions that move or generate 32-bit register
455 ; values also set the upper 32 bits of the register to zero. Consequently
456 ; there is no need for an instruction movzlq."
457 mov eax, ecx
458 mov ecx, edx
459 %endif
460%else
461 mov eax, [esp + 4]
462 mov ecx, [esp + 8]
463%endif
464 invlpga [xAX], ecx
465 ret
466ENDPROC SVMR0InvlpgA
467
468%endif ; GC_ARCH_BITS != 64
469
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use