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
RevLine 
[19]1; $Id: HMR0UtilA.asm 98103 2023-01-17 14:15:46Z vboxsync $
[1]2;; @file
[87310]3; HM - Ring-0 VMX & SVM Helpers.
[1]4;
5
[19]6;
[98103]7; Copyright (C) 2006-2023 Oracle and/or its affiliates.
[5999]8;
[96407]9; This file is part of VirtualBox base platform packages, as
10; available from https://www.virtualbox.org.
[5999]11;
[96407]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;
[1]27
[57493]28;*********************************************************************************************************************************
29;* Header Files *
30;*********************************************************************************************************************************
[19]31%include "VBox/asmdefs.mac"
[1]32%include "VBox/err.mac"
[43387]33%include "VBox/vmm/hm_vmx.mac"
[37955]34%include "iprt/x86.mac"
[1]35
36
[57493]37
[1]38BEGINCODE
39
[83067]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;
[15213]47ALIGNCODE(16)
[43930]48BEGINPROC VMXWriteVmcs64
[14799]49%ifdef RT_ARCH_AMD64
50 %ifdef ASM_CALL64_GCC
51 and edi, 0ffffffffh
[2738]52 xor rax, rax
[2731]53 vmwrite rdi, rsi
[14799]54 %else
55 and ecx, 0ffffffffh
[2750]56 xor rax, rax
[2731]57 vmwrite rcx, rdx
[14799]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
[75]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
[43930]78ENDPROC VMXWriteVmcs64
[1]79
[14799]80
[83067]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;
[43930]88;DECLASM(int) VMXReadVmcs64(uint32_t idxField, uint64_t *pData);
[15213]89ALIGNCODE(16)
[43930]90BEGINPROC VMXReadVmcs64
[14799]91%ifdef RT_ARCH_AMD64
92 %ifdef ASM_CALL64_GCC
93 and edi, 0ffffffffh
[2738]94 xor rax, rax
[75]95 vmread [rsi], rdi
[14799]96 %else
97 and ecx, 0ffffffffh
[2750]98 xor rax, rax
[75]99 vmread [rdx], rcx
[14799]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
[75]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
[43930]120ENDPROC VMXReadVmcs64
[1]121
[75]122
[83067]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;
[43930]130;DECLASM(int) VMXReadVmcs32(uint32_t idxField, uint32_t *pu32Data);
[15213]131ALIGNCODE(16)
[43930]132BEGINPROC VMXReadVmcs32
[14799]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
[43930]159ENDPROC VMXReadVmcs32
[14799]160
161
[83067]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;
[43930]169;DECLASM(int) VMXWriteVmcs32(uint32_t idxField, uint32_t u32Data);
[15213]170ALIGNCODE(16)
[43930]171BEGINPROC VMXWriteVmcs32
[14799]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
[43930]198ENDPROC VMXWriteVmcs32
[14799]199
200
[83067]201;;
202; Executes VMXON.
203;
204; @returns VBox status code.
205; @param HCPhysVMXOn Physical address of VMXON structure.
206;
[75]207;DECLASM(int) VMXEnable(RTHCPHYS HCPhysVMXOn);
208BEGINPROC VMXEnable
[3696]209%ifdef RT_ARCH_AMD64
[2738]210 xor rax, rax
[75]211 %ifdef ASM_CALL64_GCC
212 push rdi
213 %else
[673]214 push rcx
[75]215 %endif
216 vmxon [rsp]
[14799]217%else ; RT_ARCH_X86
[2738]218 xor eax, eax
[75]219 vmxon [esp + 4]
[14799]220%endif ; RT_ARCH_X86
[75]221 jnc .good
222 mov eax, VERR_VMX_INVALID_VMXON_PTR
223 jmp .the_end
224
225.good:
226 jnz .the_end
[45474]227 mov eax, VERR_VMX_VMXON_FAILED
[75]228
229.the_end:
[3696]230%ifdef RT_ARCH_AMD64
[75]231 add rsp, 8
232%endif
233 ret
234ENDPROC VMXEnable
235
[14799]236
[83067]237;;
238; Executes VMXOFF.
239;
[75]240;DECLASM(void) VMXDisable(void);
241BEGINPROC VMXDisable
242 vmxoff
[15198]243.the_end:
[75]244 ret
245ENDPROC VMXDisable
246
247
[83067]248;;
249; Executes VMCLEAR.
250;
251; @returns VBox status code.
252; @param HCPhysVmcs Physical address of VM control structure.
253;
[47760]254;DECLASM(int) VMXClearVmcs(RTHCPHYS HCPhysVmcs);
[15213]255ALIGNCODE(16)
[47760]256BEGINPROC VMXClearVmcs
[3696]257%ifdef RT_ARCH_AMD64
[2733]258 xor rax, rax
[75]259 %ifdef ASM_CALL64_GCC
260 push rdi
261 %else
[673]262 push rcx
[75]263 %endif
264 vmclear [rsp]
[14799]265%else ; RT_ARCH_X86
[2733]266 xor eax, eax
[75]267 vmclear [esp + 4]
[14799]268%endif ; RT_ARCH_X86
[75]269 jnc .the_end
270 mov eax, VERR_VMX_INVALID_VMCS_PTR
271.the_end:
[3696]272%ifdef RT_ARCH_AMD64
[75]273 add rsp, 8
274%endif
275 ret
[47760]276ENDPROC VMXClearVmcs
[75]277
278
[83067]279;;
280; Executes VMPTRLD.
281;
282; @returns VBox status code.
283; @param HCPhysVmcs Physical address of VMCS structure.
284;
[78220]285;DECLASM(int) VMXLoadVmcs(RTHCPHYS HCPhysVmcs);
[15213]286ALIGNCODE(16)
[78220]287BEGINPROC VMXLoadVmcs
[3696]288%ifdef RT_ARCH_AMD64
[2733]289 xor rax, rax
[75]290 %ifdef ASM_CALL64_GCC
291 push rdi
292 %else
[673]293 push rcx
[75]294 %endif
[2732]295 vmptrld [rsp]
[75]296%else
[2733]297 xor eax, eax
[2732]298 vmptrld [esp + 4]
[75]299%endif
300 jnc .the_end
301 mov eax, VERR_VMX_INVALID_VMCS_PTR
302.the_end:
[3696]303%ifdef RT_ARCH_AMD64
[75]304 add rsp, 8
305%endif
306 ret
[78220]307ENDPROC VMXLoadVmcs
[75]308
309
[83067]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;
[78220]316;DECLASM(int) VMXGetCurrentVmcs(RTHCPHYS *pVMCS);
317BEGINPROC VMXGetCurrentVmcs
[13908]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
[12063]324 vmptrst qword [rdi]
[13908]325 %else
326 vmptrst qword [rcx]
327 %endif
[12062]328 %else
[13908]329 vmptrst qword [esp+04h]
[12062]330 %endif
[12069]331 xor eax, eax
[15198]332.the_end:
[12062]333 ret
[13908]334%endif
[78220]335ENDPROC VMXGetCurrentVmcs
[75]336
[87310]337
[83067]338;;
339; Invalidate a page using INVEPT.
340;
[72855]341; @param enmTlbFlush msc:ecx gcc:edi x86:[esp+04] Type of flush.
[57270]342; @param pDescriptor msc:edx gcc:esi x86:[esp+08] Descriptor pointer.
[83067]343;
[72855]344;DECLASM(int) VMXR0InvEPT(VMXTLBFLUSHEPT enmTlbFlush, uint64_t *pDescriptor);
[13089]345BEGINPROC VMXR0InvEPT
[13092]346%ifdef RT_ARCH_AMD64
347 %ifdef ASM_CALL64_GCC
[14799]348 and edi, 0ffffffffh
[13089]349 xor rax, rax
[13092]350; invept rdi, qword [rsi]
351 DB 0x66, 0x0F, 0x38, 0x80, 0x3E
352 %else
[14799]353 and ecx, 0ffffffffh
[13089]354 xor rax, rax
[13092]355; invept rcx, qword [rdx]
[13089]356 DB 0x66, 0x0F, 0x38, 0x80, 0xA
[13092]357 %endif
358%else
[25413]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
[13089]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
[12062]374
[14799]375
[83067]376;;
377; Invalidate a page using INVVPID.
378;
[72855]379; @param enmTlbFlush msc:ecx gcc:edi x86:[esp+04] Type of flush
[13089]380; @param pDescriptor msc:edx gcc:esi x86:[esp+08] Descriptor pointer
[83067]381;
[72855]382;DECLASM(int) VMXR0InvVPID(VMXTLBFLUSHVPID enmTlbFlush, uint64_t *pDescriptor);
[13089]383BEGINPROC VMXR0InvVPID
[13092]384%ifdef RT_ARCH_AMD64
385 %ifdef ASM_CALL64_GCC
[14799]386 and edi, 0ffffffffh
[13089]387 xor rax, rax
[42671]388; invvpid rdi, qword [rsi]
[13092]389 DB 0x66, 0x0F, 0x38, 0x81, 0x3E
390 %else
[14799]391 and ecx, 0ffffffffh
[13089]392 xor rax, rax
[13092]393; invvpid rcx, qword [rdx]
[13089]394 DB 0x66, 0x0F, 0x38, 0x81, 0xA
[13092]395 %endif
396%else
[25413]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
[13089]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
[9896]414%if GC_ARCH_BITS == 64
[682]415;;
[83067]416; Executes INVLPGA.
[3696]417;
[9896]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;
[14366]421;DECLASM(void) SVMR0InvlpgA(RTGCPTR pPageGC, uint32_t uASID);
422BEGINPROC SVMR0InvlpgA
[9896]423%ifdef RT_ARCH_AMD64
424 %ifdef ASM_CALL64_GCC
425 mov rax, rdi
426 mov rcx, rsi
427 %else
[21570]428 mov rax, rcx
[9896]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
[14366]437ENDPROC SVMR0InvlpgA
[9896]438
[14802]439%else ; GC_ARCH_BITS != 64
[9896]440;;
441; Executes INVLPGA
442;
[682]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
[3696]445;
[14366]446;DECLASM(void) SVMR0InvlpgA(RTGCPTR pPageGC, uint32_t uASID);
447BEGINPROC SVMR0InvlpgA
[3696]448%ifdef RT_ARCH_AMD64
[682]449 %ifdef ASM_CALL64_GCC
[9896]450 movzx rax, edi
[682]451 mov ecx, esi
452 %else
[21572]453 ; from http://www.cs.cmu.edu/~fp/courses/15213-s06/misc/asm64-handout.pdf:
[83067]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."
[10849]457 mov eax, ecx
[682]458 mov ecx, edx
459 %endif
460%else
461 mov eax, [esp + 4]
462 mov ecx, [esp + 8]
463%endif
[6258]464 invlpga [xAX], ecx
[682]465 ret
[14366]466ENDPROC SVMR0InvlpgA
[6243]467
[9896]468%endif ; GC_ARCH_BITS != 64
469
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use