1 /* $NetBSD: nvmm_x86_vmx.c,v 1.97 2026/08/08 12:47:47 riastradh Exp $ */ 2 3 /* 4 * Copyright (c) 2018-2020 Maxime Villard, m00nbsd.net 5 * All rights reserved. 6 * 7 * This code is part of the NVMM hypervisor. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 #include <sys/cdefs.h> 32 __KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.97 2026/08/08 12:47:47 riastradh Exp $"); 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/kernel.h> 37 #include <sys/kmem.h> 38 #include <sys/cpu.h> 39 #include <sys/xcall.h> 40 #include <sys/mman.h> 41 #include <sys/bitops.h> 42 43 #include <uvm/uvm_extern.h> 44 #include <uvm/uvm_page.h> 45 46 #include <x86/cputypes.h> 47 #include <x86/specialreg.h> 48 #include <x86/dbregs.h> 49 #include <x86/cpu_counter.h> 50 #include <x86/nmi.h> 51 52 #include <machine/cpuvar.h> 53 #include <machine/pmap_private.h> 54 55 #include <dev/nvmm/nvmm.h> 56 #include <dev/nvmm/nvmm_internal.h> 57 #include <dev/nvmm/x86/nvmm_x86.h> 58 59 int _vmx_vmxon(paddr_t *pa); 60 int _vmx_vmxoff(void); 61 int vmx_vmlaunch(uint64_t *gprs); 62 int vmx_vmresume(uint64_t *gprs); 63 64 #define vmx_vmxon(a) \ 65 if (__predict_false(_vmx_vmxon(a) != 0)) { \ 66 panic("%s: VMXON failed", __func__); \ 67 } 68 #define vmx_vmxoff() \ 69 if (__predict_false(_vmx_vmxoff() != 0)) { \ 70 panic("%s: VMXOFF failed", __func__); \ 71 } 72 73 struct ept_desc { 74 uint64_t eptp; 75 uint64_t mbz; 76 } __packed; 77 78 struct vpid_desc { 79 uint64_t vpid; 80 uint64_t addr; 81 } __packed; 82 83 static inline void 84 vmx_invept(uint64_t op, struct ept_desc *desc) 85 { 86 asm volatile ( 87 "invept %[desc],%[op];" 88 "jz vmx_insn_failvalid;" 89 "jc vmx_insn_failinvalid;" 90 : 91 : [desc] "m" (*desc), [op] "r" (op) 92 : "memory", "cc" 93 ); 94 } 95 96 static inline void 97 vmx_invvpid(uint64_t op, struct vpid_desc *desc) 98 { 99 asm volatile ( 100 "invvpid %[desc],%[op];" 101 "jz vmx_insn_failvalid;" 102 "jc vmx_insn_failinvalid;" 103 : 104 : [desc] "m" (*desc), [op] "r" (op) 105 : "memory", "cc" 106 ); 107 } 108 109 static inline uint64_t 110 vmx_vmread(uint64_t field) 111 { 112 uint64_t value; 113 114 asm volatile ( 115 "vmread %[field],%[value];" 116 "jz vmx_insn_failvalid;" 117 "jc vmx_insn_failinvalid;" 118 : [value] "=r" (value) 119 : [field] "r" (field) 120 : "cc" 121 ); 122 123 return value; 124 } 125 126 static inline void 127 vmx_vmwrite(uint64_t field, uint64_t value) 128 { 129 asm volatile ( 130 "vmwrite %[value],%[field];" 131 "jz vmx_insn_failvalid;" 132 "jc vmx_insn_failinvalid;" 133 : 134 : [field] "r" (field), [value] "r" (value) 135 : "cc" 136 ); 137 } 138 139 static inline paddr_t __diagused 140 vmx_vmptrst(void) 141 { 142 paddr_t pa; 143 144 asm volatile ( 145 "vmptrst %[pa];" 146 : 147 : [pa] "m" (*(paddr_t *)&pa) 148 : "memory" 149 ); 150 151 return pa; 152 } 153 154 static inline void 155 vmx_vmptrld(paddr_t *pa) 156 { 157 asm volatile ( 158 "vmptrld %[pa];" 159 "jz vmx_insn_failvalid;" 160 "jc vmx_insn_failinvalid;" 161 : 162 : [pa] "m" (*pa) 163 : "memory", "cc" 164 ); 165 } 166 167 static inline void 168 vmx_vmclear(paddr_t *pa) 169 { 170 asm volatile ( 171 "vmclear %[pa];" 172 "jz vmx_insn_failvalid;" 173 "jc vmx_insn_failinvalid;" 174 : 175 : [pa] "m" (*pa) 176 : "memory", "cc" 177 ); 178 } 179 180 static inline void 181 vmx_cli(void) 182 { 183 asm volatile ("cli" ::: "memory"); 184 } 185 186 static inline void 187 vmx_sti(void) 188 { 189 asm volatile ("sti" ::: "memory"); 190 } 191 192 #define MSR_IA32_FEATURE_CONTROL 0x003A 193 #define IA32_FEATURE_CONTROL_LOCK __BIT(0) 194 #define IA32_FEATURE_CONTROL_IN_SMX __BIT(1) 195 #define IA32_FEATURE_CONTROL_OUT_SMX __BIT(2) 196 197 #define MSR_IA32_VMX_BASIC 0x0480 198 #define IA32_VMX_BASIC_IDENT __BITS(30,0) 199 #define IA32_VMX_BASIC_DATA_SIZE __BITS(44,32) 200 #define IA32_VMX_BASIC_MEM_WIDTH __BIT(48) 201 #define IA32_VMX_BASIC_DUAL __BIT(49) 202 #define IA32_VMX_BASIC_MEM_TYPE __BITS(53,50) 203 #define MEM_TYPE_UC 0 204 #define MEM_TYPE_WB 6 205 #define IA32_VMX_BASIC_IO_REPORT __BIT(54) 206 #define IA32_VMX_BASIC_TRUE_CTLS __BIT(55) 207 208 #define MSR_IA32_VMX_PINBASED_CTLS 0x0481 209 #define MSR_IA32_VMX_PROCBASED_CTLS 0x0482 210 #define MSR_IA32_VMX_EXIT_CTLS 0x0483 211 #define MSR_IA32_VMX_ENTRY_CTLS 0x0484 212 #define MSR_IA32_VMX_PROCBASED_CTLS2 0x048B 213 214 #define MSR_IA32_VMX_TRUE_PINBASED_CTLS 0x048D 215 #define MSR_IA32_VMX_TRUE_PROCBASED_CTLS 0x048E 216 #define MSR_IA32_VMX_TRUE_EXIT_CTLS 0x048F 217 #define MSR_IA32_VMX_TRUE_ENTRY_CTLS 0x0490 218 219 #define MSR_IA32_VMX_CR0_FIXED0 0x0486 220 #define MSR_IA32_VMX_CR0_FIXED1 0x0487 221 #define MSR_IA32_VMX_CR4_FIXED0 0x0488 222 #define MSR_IA32_VMX_CR4_FIXED1 0x0489 223 224 #define MSR_IA32_VMX_EPT_VPID_CAP 0x048C 225 #define IA32_VMX_EPT_VPID_XO __BIT(0) 226 #define IA32_VMX_EPT_VPID_WALKLENGTH_4 __BIT(6) 227 #define IA32_VMX_EPT_VPID_UC __BIT(8) 228 #define IA32_VMX_EPT_VPID_WB __BIT(14) 229 #define IA32_VMX_EPT_VPID_2MB __BIT(16) 230 #define IA32_VMX_EPT_VPID_1GB __BIT(17) 231 #define IA32_VMX_EPT_VPID_INVEPT __BIT(20) 232 #define IA32_VMX_EPT_VPID_FLAGS_AD __BIT(21) 233 #define IA32_VMX_EPT_VPID_ADVANCED_VMEXIT_INFO __BIT(22) 234 #define IA32_VMX_EPT_VPID_SHSTK __BIT(23) 235 #define IA32_VMX_EPT_VPID_INVEPT_CONTEXT __BIT(25) 236 #define IA32_VMX_EPT_VPID_INVEPT_ALL __BIT(26) 237 #define IA32_VMX_EPT_VPID_INVVPID __BIT(32) 238 #define IA32_VMX_EPT_VPID_INVVPID_ADDR __BIT(40) 239 #define IA32_VMX_EPT_VPID_INVVPID_CONTEXT __BIT(41) 240 #define IA32_VMX_EPT_VPID_INVVPID_ALL __BIT(42) 241 #define IA32_VMX_EPT_VPID_INVVPID_CONTEXT_NOG __BIT(43) 242 243 /* -------------------------------------------------------------------------- */ 244 245 /* 16-bit control fields */ 246 #define VMCS_VPID 0x00000000 247 #define VMCS_PIR_VECTOR 0x00000002 248 #define VMCS_EPTP_INDEX 0x00000004 249 /* 16-bit guest-state fields */ 250 #define VMCS_GUEST_ES_SELECTOR 0x00000800 251 #define VMCS_GUEST_CS_SELECTOR 0x00000802 252 #define VMCS_GUEST_SS_SELECTOR 0x00000804 253 #define VMCS_GUEST_DS_SELECTOR 0x00000806 254 #define VMCS_GUEST_FS_SELECTOR 0x00000808 255 #define VMCS_GUEST_GS_SELECTOR 0x0000080A 256 #define VMCS_GUEST_LDTR_SELECTOR 0x0000080C 257 #define VMCS_GUEST_TR_SELECTOR 0x0000080E 258 #define VMCS_GUEST_INTR_STATUS 0x00000810 259 #define VMCS_PML_INDEX 0x00000812 260 /* 16-bit host-state fields */ 261 #define VMCS_HOST_ES_SELECTOR 0x00000C00 262 #define VMCS_HOST_CS_SELECTOR 0x00000C02 263 #define VMCS_HOST_SS_SELECTOR 0x00000C04 264 #define VMCS_HOST_DS_SELECTOR 0x00000C06 265 #define VMCS_HOST_FS_SELECTOR 0x00000C08 266 #define VMCS_HOST_GS_SELECTOR 0x00000C0A 267 #define VMCS_HOST_TR_SELECTOR 0x00000C0C 268 /* 64-bit control fields */ 269 #define VMCS_IO_BITMAP_A 0x00002000 270 #define VMCS_IO_BITMAP_B 0x00002002 271 #define VMCS_MSR_BITMAP 0x00002004 272 #define VMCS_EXIT_MSR_STORE_ADDRESS 0x00002006 273 #define VMCS_EXIT_MSR_LOAD_ADDRESS 0x00002008 274 #define VMCS_ENTRY_MSR_LOAD_ADDRESS 0x0000200A 275 #define VMCS_EXECUTIVE_VMCS 0x0000200C 276 #define VMCS_PML_ADDRESS 0x0000200E 277 #define VMCS_TSC_OFFSET 0x00002010 278 #define VMCS_VIRTUAL_APIC 0x00002012 279 #define VMCS_APIC_ACCESS 0x00002014 280 #define VMCS_PIR_DESC 0x00002016 281 #define VMCS_VM_CONTROL 0x00002018 282 #define VMCS_EPTP 0x0000201A 283 #define EPTP_TYPE __BITS(2,0) 284 #define EPTP_TYPE_UC 0 285 #define EPTP_TYPE_WB 6 286 #define EPTP_WALKLEN __BITS(5,3) 287 #define EPTP_FLAGS_AD __BIT(6) 288 #define EPTP_SSS __BIT(7) 289 #define EPTP_PHYSADDR __BITS(63,12) 290 #define VMCS_EOI_EXIT0 0x0000201C 291 #define VMCS_EOI_EXIT1 0x0000201E 292 #define VMCS_EOI_EXIT2 0x00002020 293 #define VMCS_EOI_EXIT3 0x00002022 294 #define VMCS_EPTP_LIST 0x00002024 295 #define VMCS_VMREAD_BITMAP 0x00002026 296 #define VMCS_VMWRITE_BITMAP 0x00002028 297 #define VMCS_VIRTUAL_EXCEPTION 0x0000202A 298 #define VMCS_XSS_EXIT_BITMAP 0x0000202C 299 #define VMCS_ENCLS_EXIT_BITMAP 0x0000202E 300 #define VMCS_SUBPAGE_PERM_TABLE_PTR 0x00002030 301 #define VMCS_TSC_MULTIPLIER 0x00002032 302 #define VMCS_ENCLV_EXIT_BITMAP 0x00002036 303 /* 64-bit read-only fields */ 304 #define VMCS_GUEST_PHYSICAL_ADDRESS 0x00002400 305 /* 64-bit guest-state fields */ 306 #define VMCS_LINK_POINTER 0x00002800 307 #define VMCS_GUEST_IA32_DEBUGCTL 0x00002802 308 #define VMCS_GUEST_IA32_PAT 0x00002804 309 #define VMCS_GUEST_IA32_EFER 0x00002806 310 #define VMCS_GUEST_IA32_PERF_GLOBAL_CTRL 0x00002808 311 #define VMCS_GUEST_PDPTE0 0x0000280A 312 #define VMCS_GUEST_PDPTE1 0x0000280C 313 #define VMCS_GUEST_PDPTE2 0x0000280E 314 #define VMCS_GUEST_PDPTE3 0x00002810 315 #define VMCS_GUEST_BNDCFGS 0x00002812 316 #define VMCS_GUEST_RTIT_CTL 0x00002814 317 #define VMCS_GUEST_PKRS 0x00002818 318 /* 64-bit host-state fields */ 319 #define VMCS_HOST_IA32_PAT 0x00002C00 320 #define VMCS_HOST_IA32_EFER 0x00002C02 321 #define VMCS_HOST_IA32_PERF_GLOBAL_CTRL 0x00002C04 322 #define VMCS_HOST_IA32_PKRS 0x00002C06 323 /* 32-bit control fields */ 324 #define VMCS_PINBASED_CTLS 0x00004000 325 #define PIN_CTLS_INT_EXITING __BIT(0) 326 #define PIN_CTLS_NMI_EXITING __BIT(3) 327 #define PIN_CTLS_VIRTUAL_NMIS __BIT(5) 328 #define PIN_CTLS_ACTIVATE_PREEMPT_TIMER __BIT(6) 329 #define PIN_CTLS_PROCESS_POSTED_INTS __BIT(7) 330 #define VMCS_PROCBASED_CTLS 0x00004002 331 #define PROC_CTLS_INT_WINDOW_EXITING __BIT(2) 332 #define PROC_CTLS_USE_TSC_OFFSETTING __BIT(3) 333 #define PROC_CTLS_HLT_EXITING __BIT(7) 334 #define PROC_CTLS_INVLPG_EXITING __BIT(9) 335 #define PROC_CTLS_MWAIT_EXITING __BIT(10) 336 #define PROC_CTLS_RDPMC_EXITING __BIT(11) 337 #define PROC_CTLS_RDTSC_EXITING __BIT(12) 338 #define PROC_CTLS_RCR3_EXITING __BIT(15) 339 #define PROC_CTLS_LCR3_EXITING __BIT(16) 340 #define PROC_CTLS_RCR8_EXITING __BIT(19) 341 #define PROC_CTLS_LCR8_EXITING __BIT(20) 342 #define PROC_CTLS_USE_TPR_SHADOW __BIT(21) 343 #define PROC_CTLS_NMI_WINDOW_EXITING __BIT(22) 344 #define PROC_CTLS_DR_EXITING __BIT(23) 345 #define PROC_CTLS_UNCOND_IO_EXITING __BIT(24) 346 #define PROC_CTLS_USE_IO_BITMAPS __BIT(25) 347 #define PROC_CTLS_MONITOR_TRAP_FLAG __BIT(27) 348 #define PROC_CTLS_USE_MSR_BITMAPS __BIT(28) 349 #define PROC_CTLS_MONITOR_EXITING __BIT(29) 350 #define PROC_CTLS_PAUSE_EXITING __BIT(30) 351 #define PROC_CTLS_ACTIVATE_CTLS2 __BIT(31) 352 #define VMCS_EXCEPTION_BITMAP 0x00004004 353 #define VMCS_PF_ERROR_MASK 0x00004006 354 #define VMCS_PF_ERROR_MATCH 0x00004008 355 #define VMCS_CR3_TARGET_COUNT 0x0000400A 356 #define VMCS_EXIT_CTLS 0x0000400C 357 #define EXIT_CTLS_SAVE_DEBUG_CONTROLS __BIT(2) 358 #define EXIT_CTLS_HOST_LONG_MODE __BIT(9) 359 #define EXIT_CTLS_LOAD_PERFGLOBALCTRL __BIT(12) 360 #define EXIT_CTLS_ACK_INTERRUPT __BIT(15) 361 #define EXIT_CTLS_SAVE_PAT __BIT(18) 362 #define EXIT_CTLS_LOAD_PAT __BIT(19) 363 #define EXIT_CTLS_SAVE_EFER __BIT(20) 364 #define EXIT_CTLS_LOAD_EFER __BIT(21) 365 #define EXIT_CTLS_SAVE_PREEMPT_TIMER __BIT(22) 366 #define EXIT_CTLS_CLEAR_BNDCFGS __BIT(23) 367 #define EXIT_CTLS_CONCEAL_PT __BIT(24) 368 #define EXIT_CTLS_CLEAR_RTIT_CTL __BIT(25) 369 #define EXIT_CTLS_LOAD_CET __BIT(28) 370 #define EXIT_CTLS_LOAD_PKRS __BIT(29) 371 #define VMCS_EXIT_MSR_STORE_COUNT 0x0000400E 372 #define VMCS_EXIT_MSR_LOAD_COUNT 0x00004010 373 #define VMCS_ENTRY_CTLS 0x00004012 374 #define ENTRY_CTLS_LOAD_DEBUG_CONTROLS __BIT(2) 375 #define ENTRY_CTLS_LONG_MODE __BIT(9) 376 #define ENTRY_CTLS_SMM __BIT(10) 377 #define ENTRY_CTLS_DISABLE_DUAL __BIT(11) 378 #define ENTRY_CTLS_LOAD_PERFGLOBALCTRL __BIT(13) 379 #define ENTRY_CTLS_LOAD_PAT __BIT(14) 380 #define ENTRY_CTLS_LOAD_EFER __BIT(15) 381 #define ENTRY_CTLS_LOAD_BNDCFGS __BIT(16) 382 #define ENTRY_CTLS_CONCEAL_PT __BIT(17) 383 #define ENTRY_CTLS_LOAD_RTIT_CTL __BIT(18) 384 #define ENTRY_CTLS_LOAD_CET __BIT(20) 385 #define ENTRY_CTLS_LOAD_PKRS __BIT(22) 386 #define VMCS_ENTRY_MSR_LOAD_COUNT 0x00004014 387 #define VMCS_ENTRY_INTR_INFO 0x00004016 388 #define INTR_INFO_VECTOR __BITS(7,0) 389 #define INTR_INFO_TYPE __BITS(10,8) 390 #define INTR_TYPE_EXT_INT 0 391 #define INTR_TYPE_NMI 2 392 #define INTR_TYPE_HW_EXC 3 393 #define INTR_TYPE_SW_INT 4 394 #define INTR_TYPE_PRIV_SW_EXC 5 395 #define INTR_TYPE_SW_EXC 6 396 #define INTR_TYPE_OTHER 7 397 #define INTR_INFO_ERROR __BIT(11) 398 #define INTR_INFO_VALID __BIT(31) 399 #define VMCS_ENTRY_EXCEPTION_ERROR 0x00004018 400 #define VMCS_ENTRY_INSTRUCTION_LENGTH 0x0000401A 401 #define VMCS_TPR_THRESHOLD 0x0000401C 402 #define VMCS_PROCBASED_CTLS2 0x0000401E 403 #define PROC_CTLS2_VIRT_APIC_ACCESSES __BIT(0) 404 #define PROC_CTLS2_ENABLE_EPT __BIT(1) 405 #define PROC_CTLS2_DESC_TABLE_EXITING __BIT(2) 406 #define PROC_CTLS2_ENABLE_RDTSCP __BIT(3) 407 #define PROC_CTLS2_VIRT_X2APIC __BIT(4) 408 #define PROC_CTLS2_ENABLE_VPID __BIT(5) 409 #define PROC_CTLS2_WBINVD_EXITING __BIT(6) 410 #define PROC_CTLS2_UNRESTRICTED_GUEST __BIT(7) 411 #define PROC_CTLS2_APIC_REG_VIRT __BIT(8) 412 #define PROC_CTLS2_VIRT_INT_DELIVERY __BIT(9) 413 #define PROC_CTLS2_PAUSE_LOOP_EXITING __BIT(10) 414 #define PROC_CTLS2_RDRAND_EXITING __BIT(11) 415 #define PROC_CTLS2_INVPCID_ENABLE __BIT(12) 416 #define PROC_CTLS2_VMFUNC_ENABLE __BIT(13) 417 #define PROC_CTLS2_VMCS_SHADOWING __BIT(14) 418 #define PROC_CTLS2_ENCLS_EXITING __BIT(15) 419 #define PROC_CTLS2_RDSEED_EXITING __BIT(16) 420 #define PROC_CTLS2_PML_ENABLE __BIT(17) 421 #define PROC_CTLS2_EPT_VIOLATION __BIT(18) 422 #define PROC_CTLS2_CONCEAL_VMX_FROM_PT __BIT(19) 423 #define PROC_CTLS2_XSAVES_ENABLE __BIT(20) 424 #define PROC_CTLS2_MODE_BASED_EXEC_EPT __BIT(22) 425 #define PROC_CTLS2_SUBPAGE_PERMISSIONS __BIT(23) 426 #define PROC_CTLS2_PT_USES_GPA __BIT(24) 427 #define PROC_CTLS2_USE_TSC_SCALING __BIT(25) 428 #define PROC_CTLS2_WAIT_PAUSE_ENABLE __BIT(26) 429 #define PROC_CTLS2_ENCLV_EXITING __BIT(28) 430 #define VMCS_PLE_GAP 0x00004020 431 #define VMCS_PLE_WINDOW 0x00004022 432 /* 32-bit read-only data fields */ 433 #define VMCS_INSTRUCTION_ERROR 0x00004400 434 #define VMCS_EXIT_REASON 0x00004402 435 #define VMCS_EXIT_INTR_INFO 0x00004404 436 #define VMCS_EXIT_INTR_ERRCODE 0x00004406 437 #define VMCS_IDT_VECTORING_INFO 0x00004408 438 #define VMCS_IDT_VECTORING_ERROR 0x0000440A 439 #define VMCS_EXIT_INSTRUCTION_LENGTH 0x0000440C 440 #define VMCS_EXIT_INSTRUCTION_INFO 0x0000440E 441 /* 32-bit guest-state fields */ 442 #define VMCS_GUEST_ES_LIMIT 0x00004800 443 #define VMCS_GUEST_CS_LIMIT 0x00004802 444 #define VMCS_GUEST_SS_LIMIT 0x00004804 445 #define VMCS_GUEST_DS_LIMIT 0x00004806 446 #define VMCS_GUEST_FS_LIMIT 0x00004808 447 #define VMCS_GUEST_GS_LIMIT 0x0000480A 448 #define VMCS_GUEST_LDTR_LIMIT 0x0000480C 449 #define VMCS_GUEST_TR_LIMIT 0x0000480E 450 #define VMCS_GUEST_GDTR_LIMIT 0x00004810 451 #define VMCS_GUEST_IDTR_LIMIT 0x00004812 452 #define VMCS_GUEST_ES_ACCESS_RIGHTS 0x00004814 453 #define VMCS_GUEST_CS_ACCESS_RIGHTS 0x00004816 454 #define VMCS_GUEST_SS_ACCESS_RIGHTS 0x00004818 455 #define VMCS_GUEST_DS_ACCESS_RIGHTS 0x0000481A 456 #define VMCS_GUEST_FS_ACCESS_RIGHTS 0x0000481C 457 #define VMCS_GUEST_GS_ACCESS_RIGHTS 0x0000481E 458 #define VMCS_GUEST_LDTR_ACCESS_RIGHTS 0x00004820 459 #define VMCS_GUEST_TR_ACCESS_RIGHTS 0x00004822 460 #define VMCS_GUEST_INTERRUPTIBILITY 0x00004824 461 #define INT_STATE_STI __BIT(0) 462 #define INT_STATE_MOVSS __BIT(1) 463 #define INT_STATE_SMI __BIT(2) 464 #define INT_STATE_NMI __BIT(3) 465 #define INT_STATE_ENCLAVE __BIT(4) 466 #define VMCS_GUEST_ACTIVITY 0x00004826 467 #define VMCS_GUEST_SMBASE 0x00004828 468 #define VMCS_GUEST_IA32_SYSENTER_CS 0x0000482A 469 #define VMCS_PREEMPTION_TIMER_VALUE 0x0000482E 470 /* 32-bit host state fields */ 471 #define VMCS_HOST_IA32_SYSENTER_CS 0x00004C00 472 /* Natural-Width control fields */ 473 #define VMCS_CR0_MASK 0x00006000 474 #define VMCS_CR4_MASK 0x00006002 475 #define VMCS_CR0_SHADOW 0x00006004 476 #define VMCS_CR4_SHADOW 0x00006006 477 #define VMCS_CR3_TARGET0 0x00006008 478 #define VMCS_CR3_TARGET1 0x0000600A 479 #define VMCS_CR3_TARGET2 0x0000600C 480 #define VMCS_CR3_TARGET3 0x0000600E 481 /* Natural-Width read-only fields */ 482 #define VMCS_EXIT_QUALIFICATION 0x00006400 483 #define VMCS_IO_RCX 0x00006402 484 #define VMCS_IO_RSI 0x00006404 485 #define VMCS_IO_RDI 0x00006406 486 #define VMCS_IO_RIP 0x00006408 487 #define VMCS_GUEST_LINEAR_ADDRESS 0x0000640A 488 /* Natural-Width guest-state fields */ 489 #define VMCS_GUEST_CR0 0x00006800 490 #define VMCS_GUEST_CR3 0x00006802 491 #define VMCS_GUEST_CR4 0x00006804 492 #define VMCS_GUEST_ES_BASE 0x00006806 493 #define VMCS_GUEST_CS_BASE 0x00006808 494 #define VMCS_GUEST_SS_BASE 0x0000680A 495 #define VMCS_GUEST_DS_BASE 0x0000680C 496 #define VMCS_GUEST_FS_BASE 0x0000680E 497 #define VMCS_GUEST_GS_BASE 0x00006810 498 #define VMCS_GUEST_LDTR_BASE 0x00006812 499 #define VMCS_GUEST_TR_BASE 0x00006814 500 #define VMCS_GUEST_GDTR_BASE 0x00006816 501 #define VMCS_GUEST_IDTR_BASE 0x00006818 502 #define VMCS_GUEST_DR7 0x0000681A 503 #define VMCS_GUEST_RSP 0x0000681C 504 #define VMCS_GUEST_RIP 0x0000681E 505 #define VMCS_GUEST_RFLAGS 0x00006820 506 #define VMCS_GUEST_PENDING_DBG_EXCEPTIONS 0x00006822 507 #define VMCS_GUEST_IA32_SYSENTER_ESP 0x00006824 508 #define VMCS_GUEST_IA32_SYSENTER_EIP 0x00006826 509 #define VMCS_GUEST_IA32_S_CET 0x00006828 510 #define VMCS_GUEST_SSP 0x0000682A 511 #define VMCS_GUEST_IA32_INTR_SSP_TABLE 0x0000682C 512 /* Natural-Width host-state fields */ 513 #define VMCS_HOST_CR0 0x00006C00 514 #define VMCS_HOST_CR3 0x00006C02 515 #define VMCS_HOST_CR4 0x00006C04 516 #define VMCS_HOST_FS_BASE 0x00006C06 517 #define VMCS_HOST_GS_BASE 0x00006C08 518 #define VMCS_HOST_TR_BASE 0x00006C0A 519 #define VMCS_HOST_GDTR_BASE 0x00006C0C 520 #define VMCS_HOST_IDTR_BASE 0x00006C0E 521 #define VMCS_HOST_IA32_SYSENTER_ESP 0x00006C10 522 #define VMCS_HOST_IA32_SYSENTER_EIP 0x00006C12 523 #define VMCS_HOST_RSP 0x00006C14 524 #define VMCS_HOST_RIP 0x00006C16 525 #define VMCS_HOST_IA32_S_CET 0x00006C18 526 #define VMCS_HOST_SSP 0x00006C1A 527 #define VMCS_HOST_IA32_INTR_SSP_TABLE 0x00006C1C 528 529 /* VMX basic exit reasons. */ 530 #define VMCS_EXITCODE_EXC_NMI 0 531 #define VMCS_EXITCODE_EXT_INT 1 532 #define VMCS_EXITCODE_SHUTDOWN 2 533 #define VMCS_EXITCODE_INIT 3 534 #define VMCS_EXITCODE_SIPI 4 535 #define VMCS_EXITCODE_SMI 5 536 #define VMCS_EXITCODE_OTHER_SMI 6 537 #define VMCS_EXITCODE_INT_WINDOW 7 538 #define VMCS_EXITCODE_NMI_WINDOW 8 539 #define VMCS_EXITCODE_TASK_SWITCH 9 540 #define VMCS_EXITCODE_CPUID 10 541 #define VMCS_EXITCODE_GETSEC 11 542 #define VMCS_EXITCODE_HLT 12 543 #define VMCS_EXITCODE_INVD 13 544 #define VMCS_EXITCODE_INVLPG 14 545 #define VMCS_EXITCODE_RDPMC 15 546 #define VMCS_EXITCODE_RDTSC 16 547 #define VMCS_EXITCODE_RSM 17 548 #define VMCS_EXITCODE_VMCALL 18 549 #define VMCS_EXITCODE_VMCLEAR 19 550 #define VMCS_EXITCODE_VMLAUNCH 20 551 #define VMCS_EXITCODE_VMPTRLD 21 552 #define VMCS_EXITCODE_VMPTRST 22 553 #define VMCS_EXITCODE_VMREAD 23 554 #define VMCS_EXITCODE_VMRESUME 24 555 #define VMCS_EXITCODE_VMWRITE 25 556 #define VMCS_EXITCODE_VMXOFF 26 557 #define VMCS_EXITCODE_VMXON 27 558 #define VMCS_EXITCODE_CR 28 559 #define VMCS_EXITCODE_DR 29 560 #define VMCS_EXITCODE_IO 30 561 #define VMCS_EXITCODE_RDMSR 31 562 #define VMCS_EXITCODE_WRMSR 32 563 #define VMCS_EXITCODE_FAIL_GUEST_INVALID 33 564 #define VMCS_EXITCODE_FAIL_MSR_INVALID 34 565 #define VMCS_EXITCODE_MWAIT 36 566 #define VMCS_EXITCODE_TRAP_FLAG 37 567 #define VMCS_EXITCODE_MONITOR 39 568 #define VMCS_EXITCODE_PAUSE 40 569 #define VMCS_EXITCODE_FAIL_MACHINE_CHECK 41 570 #define VMCS_EXITCODE_TPR_BELOW 43 571 #define VMCS_EXITCODE_APIC_ACCESS 44 572 #define VMCS_EXITCODE_VEOI 45 573 #define VMCS_EXITCODE_GDTR_IDTR 46 574 #define VMCS_EXITCODE_LDTR_TR 47 575 #define VMCS_EXITCODE_EPT_VIOLATION 48 576 #define VMCS_EXITCODE_EPT_MISCONFIG 49 577 #define VMCS_EXITCODE_INVEPT 50 578 #define VMCS_EXITCODE_RDTSCP 51 579 #define VMCS_EXITCODE_PREEMPT_TIMEOUT 52 580 #define VMCS_EXITCODE_INVVPID 53 581 #define VMCS_EXITCODE_WBINVD 54 582 #define VMCS_EXITCODE_XSETBV 55 583 #define VMCS_EXITCODE_APIC_WRITE 56 584 #define VMCS_EXITCODE_RDRAND 57 585 #define VMCS_EXITCODE_INVPCID 58 586 #define VMCS_EXITCODE_VMFUNC 59 587 #define VMCS_EXITCODE_ENCLS 60 588 #define VMCS_EXITCODE_RDSEED 61 589 #define VMCS_EXITCODE_PAGE_LOG_FULL 62 590 #define VMCS_EXITCODE_XSAVES 63 591 #define VMCS_EXITCODE_XRSTORS 64 592 #define VMCS_EXITCODE_SPP 66 593 #define VMCS_EXITCODE_UMWAIT 67 594 #define VMCS_EXITCODE_TPAUSE 68 595 596 /* -------------------------------------------------------------------------- */ 597 598 static void vmx_vcpu_state_provide(struct nvmm_cpu *, uint64_t); 599 static void vmx_vcpu_state_commit(struct nvmm_cpu *); 600 601 #define VMX_MSRLIST_STAR 0 602 #define VMX_MSRLIST_LSTAR 1 603 #define VMX_MSRLIST_CSTAR 2 604 #define VMX_MSRLIST_SFMASK 3 605 #define VMX_MSRLIST_KERNELGSBASE 4 606 #define VMX_MSRLIST_EXIT_NMSR 5 607 #define VMX_MSRLIST_L1DFLUSH 5 608 609 /* On entry, we may do +1 to include L1DFLUSH. */ 610 static size_t vmx_msrlist_entry_nmsr __read_mostly = VMX_MSRLIST_EXIT_NMSR; 611 612 struct vmxon { 613 uint32_t ident; 614 #define VMXON_IDENT_REVISION __BITS(30,0) 615 616 uint8_t data[PAGE_SIZE - 4]; 617 } __packed; 618 619 CTASSERT(sizeof(struct vmxon) == PAGE_SIZE); 620 621 struct vmxoncpu { 622 vaddr_t va; 623 paddr_t pa; 624 }; 625 626 static struct vmxoncpu vmxoncpu[MAXCPUS]; 627 628 struct vmcs { 629 uint32_t ident; 630 #define VMCS_IDENT_REVISION __BITS(30,0) 631 #define VMCS_IDENT_SHADOW __BIT(31) 632 633 uint32_t abort; 634 uint8_t data[PAGE_SIZE - 8]; 635 } __packed; 636 637 CTASSERT(sizeof(struct vmcs) == PAGE_SIZE); 638 639 struct msr_entry { 640 uint32_t msr; 641 uint32_t rsvd; 642 uint64_t val; 643 } __packed; 644 645 #define VPID_MAX 0xFFFF 646 647 /* Make sure we never run out of VPIDs. */ 648 CTASSERT(VPID_MAX-1 >= NVMM_MAX_MACHINES * NVMM_MAX_VCPUS); 649 650 static uint64_t vmx_tlb_flush_op __read_mostly; 651 static uint64_t vmx_ept_flush_op __read_mostly; 652 static uint64_t vmx_eptp_type __read_mostly; 653 654 static uint64_t vmx_pinbased_ctls __read_mostly; 655 static uint64_t vmx_procbased_ctls __read_mostly; 656 static uint64_t vmx_procbased_ctls2 __read_mostly; 657 static uint64_t vmx_entry_ctls __read_mostly; 658 static uint64_t vmx_exit_ctls __read_mostly; 659 660 static uint64_t vmx_cr0_fixed0 __read_mostly; 661 static uint64_t vmx_cr0_fixed1 __read_mostly; 662 static uint64_t vmx_cr4_fixed0 __read_mostly; 663 static uint64_t vmx_cr4_fixed1 __read_mostly; 664 665 extern bool pmap_ept_has_ad; 666 667 #define VMX_PINBASED_CTLS_ONE \ 668 (PIN_CTLS_INT_EXITING| \ 669 PIN_CTLS_NMI_EXITING| \ 670 PIN_CTLS_VIRTUAL_NMIS) 671 672 #define VMX_PINBASED_CTLS_ZERO 0 673 674 #define VMX_PROCBASED_CTLS_ONE \ 675 (PROC_CTLS_USE_TSC_OFFSETTING| \ 676 PROC_CTLS_HLT_EXITING| \ 677 PROC_CTLS_MWAIT_EXITING | \ 678 PROC_CTLS_RDPMC_EXITING | \ 679 PROC_CTLS_RCR8_EXITING | \ 680 PROC_CTLS_LCR8_EXITING | \ 681 PROC_CTLS_UNCOND_IO_EXITING | /* no I/O bitmap */ \ 682 PROC_CTLS_USE_MSR_BITMAPS | \ 683 PROC_CTLS_MONITOR_EXITING | \ 684 PROC_CTLS_ACTIVATE_CTLS2) 685 686 #define VMX_PROCBASED_CTLS_ZERO \ 687 (PROC_CTLS_RCR3_EXITING| \ 688 PROC_CTLS_LCR3_EXITING) 689 690 #define VMX_PROCBASED_CTLS2_ONE \ 691 (PROC_CTLS2_ENABLE_EPT| \ 692 PROC_CTLS2_ENABLE_VPID| \ 693 PROC_CTLS2_UNRESTRICTED_GUEST) 694 695 #define VMX_PROCBASED_CTLS2_ZERO 0 696 697 #define VMX_ENTRY_CTLS_ONE \ 698 (ENTRY_CTLS_LOAD_DEBUG_CONTROLS| \ 699 ENTRY_CTLS_LOAD_EFER| \ 700 ENTRY_CTLS_LOAD_PAT) 701 702 #define VMX_ENTRY_CTLS_ZERO \ 703 (ENTRY_CTLS_SMM| \ 704 ENTRY_CTLS_DISABLE_DUAL) 705 706 #define VMX_EXIT_CTLS_ONE \ 707 (EXIT_CTLS_SAVE_DEBUG_CONTROLS| \ 708 EXIT_CTLS_HOST_LONG_MODE| \ 709 EXIT_CTLS_SAVE_PAT| \ 710 EXIT_CTLS_LOAD_PAT| \ 711 EXIT_CTLS_SAVE_EFER| \ 712 EXIT_CTLS_LOAD_EFER) 713 714 #define VMX_EXIT_CTLS_ZERO 0 715 716 static uint8_t *vmx_asidmap __read_mostly; 717 static uint32_t vmx_maxasid __read_mostly; 718 static kmutex_t vmx_asidlock __cacheline_aligned; 719 720 static uint64_t vmx_xcr0_mask __read_mostly; 721 722 #define VMX_NCPUIDS 32 723 724 #define VMCS_NPAGES 1 725 #define VMCS_SIZE (VMCS_NPAGES * PAGE_SIZE) 726 727 #define MSRBM_NPAGES 1 728 #define MSRBM_SIZE (MSRBM_NPAGES * PAGE_SIZE) 729 730 #define CR0_STATIC_MASK \ 731 (CR0_ET | CR0_NW | CR0_CD) 732 733 #define CR4_VALID \ 734 (CR4_VME | \ 735 CR4_PVI | \ 736 CR4_TSD | \ 737 CR4_DE | \ 738 CR4_PSE | \ 739 CR4_PAE | \ 740 CR4_MCE | \ 741 CR4_PGE | \ 742 CR4_PCE | \ 743 CR4_OSFXSR | \ 744 CR4_OSXMMEXCPT | \ 745 CR4_UMIP | \ 746 /* CR4_LA57 excluded */ \ 747 /* CR4_VMXE excluded */ \ 748 /* CR4_SMXE excluded */ \ 749 CR4_FSGSBASE | \ 750 CR4_PCIDE | \ 751 CR4_OSXSAVE | \ 752 CR4_SMEP | \ 753 CR4_SMAP \ 754 /* CR4_PKE excluded */ \ 755 /* CR4_CET excluded */ \ 756 /* CR4_PKS excluded */) 757 #define CR4_INVALID \ 758 (0xFFFFFFFFFFFFFFFFULL & ~CR4_VALID) 759 760 #define EFER_TLB_FLUSH \ 761 (EFER_NXE|EFER_LMA|EFER_LME) 762 #define CR0_TLB_FLUSH \ 763 (CR0_PG|CR0_WP|CR0_CD|CR0_NW) 764 #define CR4_TLB_FLUSH \ 765 (CR4_PSE|CR4_PAE|CR4_PGE|CR4_PCIDE|CR4_SMEP) 766 767 /* -------------------------------------------------------------------------- */ 768 769 struct vmx_machdata { 770 volatile uint64_t mach_htlb_gen; 771 }; 772 773 static const size_t vmx_vcpu_conf_sizes[NVMM_X86_VCPU_NCONF] = { 774 [NVMM_VCPU_CONF_MD(NVMM_VCPU_CONF_CPUID)] = 775 sizeof(struct nvmm_vcpu_conf_cpuid), 776 [NVMM_VCPU_CONF_MD(NVMM_VCPU_CONF_TPR)] = 777 sizeof(struct nvmm_vcpu_conf_tpr), 778 [NVMM_VCPU_CONF_MD(NVMM_VCPU_CONF_XCR0_MASK)] = 779 sizeof(uint64_t), 780 }; 781 782 struct vmx_cpudata { 783 /* General */ 784 uint64_t asid; 785 bool gtlb_want_flush; 786 bool gtsc_want_update; 787 uint64_t vcpu_htlb_gen; 788 kcpuset_t *htlb_want_flush; 789 790 /* VMCS */ 791 struct vmcs *vmcs; 792 paddr_t vmcs_pa; 793 size_t vmcs_refcnt; 794 struct cpu_info *vmcs_ci; 795 bool vmcs_launched; 796 797 /* MSR bitmap */ 798 uint8_t *msrbm; 799 paddr_t msrbm_pa; 800 801 /* Host state */ 802 uint64_t hxcr0; 803 uint64_t star; 804 uint64_t lstar; 805 uint64_t cstar; 806 uint64_t sfmask; 807 uint64_t kernelgsbase; 808 809 /* Intr state */ 810 bool int_window_exit; 811 bool nmi_window_exit; 812 bool evt_pending; 813 814 /* Guest state */ 815 struct msr_entry *gmsr; 816 paddr_t gmsr_pa; 817 uint64_t gmsr_misc_enable; 818 uint64_t gcr2; 819 uint64_t gcr8; 820 uint64_t gxcr0; 821 uint64_t gprs[NVMM_X64_NGPR]; 822 uint64_t drs[NVMM_X64_NDR]; 823 uint64_t gtsc; 824 825 /* VCPU configuration. */ 826 bool cpuidpresent[VMX_NCPUIDS]; 827 struct nvmm_vcpu_conf_cpuid cpuid[VMX_NCPUIDS]; 828 struct nvmm_vcpu_conf_tpr tpr; 829 uint64_t xcr0_mask; 830 831 /* 832 * Guest XSAVE state. Must be the last member because it may 833 * be extended variably by whatever CPU we're running on. We 834 * add a flexible array member afterward to ward UB-exploiting 835 * compilers away from memset/memcpy calls that access it. 836 */ 837 struct xsave_header gfpu __aligned(64); 838 uint8_t gfpu_ext[]; 839 }; 840 841 static const struct { 842 uint64_t selector; 843 uint64_t attrib; 844 uint64_t limit; 845 uint64_t base; 846 } vmx_guest_segs[NVMM_X64_NSEG] = { 847 [NVMM_X64_SEG_ES] = { 848 VMCS_GUEST_ES_SELECTOR, 849 VMCS_GUEST_ES_ACCESS_RIGHTS, 850 VMCS_GUEST_ES_LIMIT, 851 VMCS_GUEST_ES_BASE 852 }, 853 [NVMM_X64_SEG_CS] = { 854 VMCS_GUEST_CS_SELECTOR, 855 VMCS_GUEST_CS_ACCESS_RIGHTS, 856 VMCS_GUEST_CS_LIMIT, 857 VMCS_GUEST_CS_BASE 858 }, 859 [NVMM_X64_SEG_SS] = { 860 VMCS_GUEST_SS_SELECTOR, 861 VMCS_GUEST_SS_ACCESS_RIGHTS, 862 VMCS_GUEST_SS_LIMIT, 863 VMCS_GUEST_SS_BASE 864 }, 865 [NVMM_X64_SEG_DS] = { 866 VMCS_GUEST_DS_SELECTOR, 867 VMCS_GUEST_DS_ACCESS_RIGHTS, 868 VMCS_GUEST_DS_LIMIT, 869 VMCS_GUEST_DS_BASE 870 }, 871 [NVMM_X64_SEG_FS] = { 872 VMCS_GUEST_FS_SELECTOR, 873 VMCS_GUEST_FS_ACCESS_RIGHTS, 874 VMCS_GUEST_FS_LIMIT, 875 VMCS_GUEST_FS_BASE 876 }, 877 [NVMM_X64_SEG_GS] = { 878 VMCS_GUEST_GS_SELECTOR, 879 VMCS_GUEST_GS_ACCESS_RIGHTS, 880 VMCS_GUEST_GS_LIMIT, 881 VMCS_GUEST_GS_BASE 882 }, 883 [NVMM_X64_SEG_GDT] = { 884 0, /* doesn't exist */ 885 0, /* doesn't exist */ 886 VMCS_GUEST_GDTR_LIMIT, 887 VMCS_GUEST_GDTR_BASE 888 }, 889 [NVMM_X64_SEG_IDT] = { 890 0, /* doesn't exist */ 891 0, /* doesn't exist */ 892 VMCS_GUEST_IDTR_LIMIT, 893 VMCS_GUEST_IDTR_BASE 894 }, 895 [NVMM_X64_SEG_LDT] = { 896 VMCS_GUEST_LDTR_SELECTOR, 897 VMCS_GUEST_LDTR_ACCESS_RIGHTS, 898 VMCS_GUEST_LDTR_LIMIT, 899 VMCS_GUEST_LDTR_BASE 900 }, 901 [NVMM_X64_SEG_TR] = { 902 VMCS_GUEST_TR_SELECTOR, 903 VMCS_GUEST_TR_ACCESS_RIGHTS, 904 VMCS_GUEST_TR_LIMIT, 905 VMCS_GUEST_TR_BASE 906 } 907 }; 908 909 /* -------------------------------------------------------------------------- */ 910 911 static uint64_t 912 vmx_get_revision(void) 913 { 914 uint64_t msr; 915 916 msr = rdmsr(MSR_IA32_VMX_BASIC); 917 msr &= IA32_VMX_BASIC_IDENT; 918 919 return msr; 920 } 921 922 static void 923 vmx_vmclear_ipi(void *arg1, void *arg2) 924 { 925 paddr_t vmcs_pa = (paddr_t)arg1; 926 vmx_vmclear(&vmcs_pa); 927 } 928 929 static void 930 vmx_vmclear_remote(struct cpu_info *ci, paddr_t vmcs_pa) 931 { 932 uint64_t xc; 933 int bound; 934 935 KASSERT(kpreempt_disabled()); 936 937 bound = curlwp_bind(); 938 kpreempt_enable(); 939 940 xc = xc_unicast(XC_HIGHPRI, vmx_vmclear_ipi, (void *)vmcs_pa, NULL, ci); 941 xc_wait(xc); 942 943 kpreempt_disable(); 944 curlwp_bindx(bound); 945 } 946 947 static void 948 vmx_vmcs_enter(struct nvmm_cpu *vcpu) 949 { 950 struct vmx_cpudata *cpudata = vcpu->cpudata; 951 struct cpu_info *vmcs_ci; 952 953 cpudata->vmcs_refcnt++; 954 if (cpudata->vmcs_refcnt > 1) { 955 KASSERT(kpreempt_disabled()); 956 KASSERT(vmx_vmptrst() == cpudata->vmcs_pa); 957 return; 958 } 959 960 vmcs_ci = cpudata->vmcs_ci; 961 cpudata->vmcs_ci = (void *)0x00FFFFFFFFFFFFFF; /* clobber */ 962 963 kpreempt_disable(); 964 965 if (vmcs_ci == NULL) { 966 /* This VMCS is loaded for the first time. */ 967 vmx_vmclear(&cpudata->vmcs_pa); 968 cpudata->vmcs_launched = false; 969 } else if (vmcs_ci != curcpu()) { 970 /* This VMCS is active on a remote CPU. */ 971 vmx_vmclear_remote(vmcs_ci, cpudata->vmcs_pa); 972 cpudata->vmcs_launched = false; 973 } else { 974 /* This VMCS is active on curcpu, nothing to do. */ 975 } 976 977 vmx_vmptrld(&cpudata->vmcs_pa); 978 } 979 980 static void 981 vmx_vmcs_leave(struct nvmm_cpu *vcpu) 982 { 983 struct vmx_cpudata *cpudata = vcpu->cpudata; 984 985 KASSERT(kpreempt_disabled()); 986 KASSERT(vmx_vmptrst() == cpudata->vmcs_pa); 987 KASSERT(cpudata->vmcs_refcnt > 0); 988 cpudata->vmcs_refcnt--; 989 990 if (cpudata->vmcs_refcnt > 0) { 991 return; 992 } 993 994 cpudata->vmcs_ci = curcpu(); 995 kpreempt_enable(); 996 } 997 998 static void 999 vmx_vmcs_destroy(struct nvmm_cpu *vcpu) 1000 { 1001 struct vmx_cpudata *cpudata = vcpu->cpudata; 1002 1003 KASSERT(kpreempt_disabled()); 1004 KASSERT(vmx_vmptrst() == cpudata->vmcs_pa); 1005 KASSERT(cpudata->vmcs_refcnt == 1); 1006 cpudata->vmcs_refcnt--; 1007 1008 vmx_vmclear(&cpudata->vmcs_pa); 1009 kpreempt_enable(); 1010 } 1011 1012 /* -------------------------------------------------------------------------- */ 1013 1014 static void 1015 vmx_event_waitexit_enable(struct nvmm_cpu *vcpu, bool nmi) 1016 { 1017 struct vmx_cpudata *cpudata = vcpu->cpudata; 1018 uint64_t ctls1; 1019 1020 ctls1 = vmx_vmread(VMCS_PROCBASED_CTLS); 1021 1022 if (nmi) { 1023 // XXX INT_STATE_NMI? 1024 ctls1 |= PROC_CTLS_NMI_WINDOW_EXITING; 1025 cpudata->nmi_window_exit = true; 1026 } else { 1027 ctls1 |= PROC_CTLS_INT_WINDOW_EXITING; 1028 cpudata->int_window_exit = true; 1029 } 1030 1031 vmx_vmwrite(VMCS_PROCBASED_CTLS, ctls1); 1032 } 1033 1034 static void 1035 vmx_event_waitexit_disable(struct nvmm_cpu *vcpu, bool nmi) 1036 { 1037 struct vmx_cpudata *cpudata = vcpu->cpudata; 1038 uint64_t ctls1; 1039 1040 ctls1 = vmx_vmread(VMCS_PROCBASED_CTLS); 1041 1042 if (nmi) { 1043 ctls1 &= ~PROC_CTLS_NMI_WINDOW_EXITING; 1044 cpudata->nmi_window_exit = false; 1045 } else { 1046 ctls1 &= ~PROC_CTLS_INT_WINDOW_EXITING; 1047 cpudata->int_window_exit = false; 1048 } 1049 1050 vmx_vmwrite(VMCS_PROCBASED_CTLS, ctls1); 1051 } 1052 1053 static inline bool 1054 vmx_excp_has_rf(uint8_t vector) 1055 { 1056 switch (vector) { 1057 case 1: /* #DB */ 1058 case 4: /* #OF */ 1059 case 8: /* #DF */ 1060 case 18: /* #MC */ 1061 return false; 1062 default: 1063 return true; 1064 } 1065 } 1066 1067 static inline int 1068 vmx_excp_has_error(uint8_t vector) 1069 { 1070 switch (vector) { 1071 case 8: /* #DF */ 1072 case 10: /* #TS */ 1073 case 11: /* #NP */ 1074 case 12: /* #SS */ 1075 case 13: /* #GP */ 1076 case 14: /* #PF */ 1077 case 17: /* #AC */ 1078 case 21: /* #CP */ 1079 case 30: /* #SX */ 1080 return 1; 1081 default: 1082 return 0; 1083 } 1084 } 1085 1086 static int 1087 vmx_vcpu_inject(struct nvmm_cpu *vcpu) 1088 { 1089 struct nvmm_comm_page *comm = vcpu->comm; 1090 struct vmx_cpudata *cpudata = vcpu->cpudata; 1091 int type = 0, err = 0, ret = EINVAL; 1092 uint64_t rflags, info, error; 1093 u_int evtype; 1094 uint8_t vector; 1095 1096 evtype = comm->event.type; 1097 vector = comm->event.vector; 1098 error = comm->event.u.excp.error; 1099 __insn_barrier(); 1100 1101 vmx_vmcs_enter(vcpu); 1102 1103 switch (evtype) { 1104 case NVMM_VCPU_EVENT_EXCP: 1105 if (vector == 2 || vector >= 32) 1106 goto out; 1107 if (vector == 3 || vector == 0) 1108 goto out; 1109 if (vmx_excp_has_rf(vector)) { 1110 rflags = vmx_vmread(VMCS_GUEST_RFLAGS); 1111 vmx_vmwrite(VMCS_GUEST_RFLAGS, rflags | PSL_RF); 1112 } 1113 type = INTR_TYPE_HW_EXC; 1114 err = vmx_excp_has_error(vector); 1115 break; 1116 case NVMM_VCPU_EVENT_INTR: 1117 type = INTR_TYPE_EXT_INT; 1118 if (vector == 2) { 1119 type = INTR_TYPE_NMI; 1120 vmx_event_waitexit_enable(vcpu, true); 1121 } 1122 err = 0; 1123 break; 1124 default: 1125 goto out; 1126 } 1127 1128 info = 1129 __SHIFTIN(vector, INTR_INFO_VECTOR) | 1130 __SHIFTIN(type, INTR_INFO_TYPE) | 1131 __SHIFTIN(err, INTR_INFO_ERROR) | 1132 __SHIFTIN(1, INTR_INFO_VALID); 1133 vmx_vmwrite(VMCS_ENTRY_INTR_INFO, info); 1134 vmx_vmwrite(VMCS_ENTRY_EXCEPTION_ERROR, error); 1135 1136 cpudata->evt_pending = true; 1137 ret = 0; 1138 1139 out: 1140 vmx_vmcs_leave(vcpu); 1141 return ret; 1142 } 1143 1144 static void 1145 vmx_inject_ud(struct nvmm_cpu *vcpu) 1146 { 1147 struct nvmm_comm_page *comm = vcpu->comm; 1148 int ret __diagused; 1149 1150 comm->event.type = NVMM_VCPU_EVENT_EXCP; 1151 comm->event.vector = 6; 1152 comm->event.u.excp.error = 0; 1153 1154 ret = vmx_vcpu_inject(vcpu); 1155 KASSERT(ret == 0); 1156 } 1157 1158 static void 1159 vmx_inject_gp(struct nvmm_cpu *vcpu) 1160 { 1161 struct nvmm_comm_page *comm = vcpu->comm; 1162 int ret __diagused; 1163 1164 comm->event.type = NVMM_VCPU_EVENT_EXCP; 1165 comm->event.vector = 13; 1166 comm->event.u.excp.error = 0; 1167 1168 ret = vmx_vcpu_inject(vcpu); 1169 KASSERT(ret == 0); 1170 } 1171 1172 static inline int 1173 vmx_vcpu_event_commit(struct nvmm_cpu *vcpu) 1174 { 1175 if (__predict_true(!vcpu->comm->event_commit)) { 1176 return 0; 1177 } 1178 vcpu->comm->event_commit = false; 1179 return vmx_vcpu_inject(vcpu); 1180 } 1181 1182 static inline void 1183 vmx_inkernel_advance(void) 1184 { 1185 uint64_t rip, inslen, intstate, rflags; 1186 1187 /* 1188 * Maybe we should also apply single-stepping and debug exceptions. 1189 * Matters for guest-ring3, because it can execute 'cpuid' under a 1190 * debugger. 1191 */ 1192 1193 inslen = vmx_vmread(VMCS_EXIT_INSTRUCTION_LENGTH); 1194 rip = vmx_vmread(VMCS_GUEST_RIP); 1195 vmx_vmwrite(VMCS_GUEST_RIP, rip + inslen); 1196 1197 rflags = vmx_vmread(VMCS_GUEST_RFLAGS); 1198 vmx_vmwrite(VMCS_GUEST_RFLAGS, rflags & ~PSL_RF); 1199 1200 intstate = vmx_vmread(VMCS_GUEST_INTERRUPTIBILITY); 1201 vmx_vmwrite(VMCS_GUEST_INTERRUPTIBILITY, 1202 intstate & ~(INT_STATE_STI|INT_STATE_MOVSS)); 1203 } 1204 1205 static void 1206 vmx_exit_invalid(struct nvmm_vcpu_exit *exit, uint64_t code) 1207 { 1208 exit->u.inv.hwcode = code; 1209 exit->reason = NVMM_VCPU_EXIT_INVALID; 1210 } 1211 1212 static void 1213 vmx_exit_exc_nmi(struct nvmm_machine *mach, struct nvmm_cpu *vcpu, 1214 struct nvmm_vcpu_exit *exit) 1215 { 1216 struct trapframe fake; 1217 uint64_t qual; 1218 1219 qual = vmx_vmread(VMCS_EXIT_INTR_INFO); 1220 1221 if ((qual & INTR_INFO_VALID) == 0) { 1222 goto error; 1223 } 1224 if (__SHIFTOUT(qual, INTR_INFO_TYPE) != INTR_TYPE_NMI) { 1225 goto error; 1226 } 1227 1228 /* 1229 * this fake frame is ok for tprof. 1230 */ 1231 memset(&fake, 0, sizeof(fake)); 1232 #if defined(__x86_64__) 1233 fake.tf_rip = (uintptr_t)vmx_exit_exc_nmi; 1234 #else 1235 fake.tf_eip = (uintptr_t)vmx_exit_exc_nmi; 1236 #endif 1237 if (!nmi_dispatch(&fake)) { 1238 /* XXX what to do for kgdb/ddb? */ 1239 x86_nmi(); 1240 } 1241 1242 exit->reason = NVMM_VCPU_EXIT_NONE; 1243 return; 1244 1245 error: 1246 vmx_exit_invalid(exit, VMCS_EXITCODE_EXC_NMI); 1247 } 1248 1249 #define VMX_CPUID_MAX_BASIC 0x16 1250 #define VMX_CPUID_MAX_HYPERVISOR 0x40000000 1251 #define VMX_CPUID_MAX_EXTENDED 0x80000008 1252 static uint32_t vmx_cpuid_max_basic __read_mostly; 1253 static uint32_t vmx_cpuid_max_extended __read_mostly; 1254 1255 static void 1256 vmx_inkernel_exec_cpuid(struct vmx_cpudata *cpudata, uint64_t eax, uint64_t ecx) 1257 { 1258 u_int descs[4]; 1259 1260 x86_cpuid2(eax, ecx, descs); 1261 cpudata->gprs[NVMM_X64_GPR_RAX] = descs[0]; 1262 cpudata->gprs[NVMM_X64_GPR_RBX] = descs[1]; 1263 cpudata->gprs[NVMM_X64_GPR_RCX] = descs[2]; 1264 cpudata->gprs[NVMM_X64_GPR_RDX] = descs[3]; 1265 } 1266 1267 static void 1268 vmx_inkernel_handle_cpuid(struct nvmm_machine *mach, struct nvmm_cpu *vcpu, 1269 uint64_t eax, uint64_t ecx) 1270 { 1271 struct vmx_cpudata *cpudata = vcpu->cpudata; 1272 unsigned int ncpus; 1273 uint64_t cr4; 1274 1275 /* 1276 * `If a value entered for CPUID.EAX is higher than the maximum 1277 * input value for basic or extended function for that 1278 * processor then the data for the highest basic information 1279 * leaf is returned.' 1280 * 1281 * --Intel 64 and IA-32 Architectures Software Developer's 1282 * Manual, Vol. 2A, Order Number: 325383-077US, April 2022, 1283 * Sec. 3.2 `Instructions (A-L)', CPUID--CPU Identification, 1284 * p. 3-214. 1285 * 1286 * We take the same to hold for the hypervisor range, 1287 * 0x40000000-0x4fffffff. 1288 * 1289 * (Sync with nvmm_x86_svm.c.) 1290 */ 1291 if (eax < 0x40000000) { /* basic CPUID range */ 1292 if (__predict_false(eax > vmx_cpuid_max_basic)) { 1293 eax = vmx_cpuid_max_basic; 1294 vmx_inkernel_exec_cpuid(cpudata, eax, ecx); 1295 } 1296 } else if (eax < 0x80000000) { /* hypervisor CPUID range */ 1297 if (__predict_false(eax > VMX_CPUID_MAX_HYPERVISOR)) { 1298 eax = vmx_cpuid_max_basic; 1299 vmx_inkernel_exec_cpuid(cpudata, eax, ecx); 1300 } 1301 } else { /* extended CPUID range */ 1302 if (__predict_false(eax > vmx_cpuid_max_extended)) { 1303 eax = vmx_cpuid_max_basic; 1304 vmx_inkernel_exec_cpuid(cpudata, eax, ecx); 1305 } 1306 } 1307 1308 switch (eax) { 1309 1310 /* 1311 * basic CPUID range 1312 */ 1313 case 0x00000000: 1314 cpudata->gprs[NVMM_X64_GPR_RAX] = vmx_cpuid_max_basic; 1315 break; 1316 case 0x00000001: 1317 cpudata->gprs[NVMM_X64_GPR_RAX] &= nvmm_cpuid_00000001.eax; 1318 1319 cpudata->gprs[NVMM_X64_GPR_RBX] &= ~CPUID_LOCAL_APIC_ID; 1320 cpudata->gprs[NVMM_X64_GPR_RBX] |= __SHIFTIN(vcpu->cpuid, 1321 CPUID_LOCAL_APIC_ID); 1322 1323 cpudata->gprs[NVMM_X64_GPR_RCX] &= nvmm_cpuid_00000001.ecx; 1324 cpudata->gprs[NVMM_X64_GPR_RCX] |= CPUID2_RAZ; 1325 if (vmx_procbased_ctls2 & PROC_CTLS2_INVPCID_ENABLE) { 1326 cpudata->gprs[NVMM_X64_GPR_RCX] |= CPUID2_PCID; 1327 } 1328 1329 cpudata->gprs[NVMM_X64_GPR_RDX] &= nvmm_cpuid_00000001.edx; 1330 1331 /* CPUID2_OSXSAVE depends on CR4. */ 1332 cr4 = vmx_vmread(VMCS_GUEST_CR4); 1333 if (!(cr4 & CR4_OSXSAVE)) { 1334 cpudata->gprs[NVMM_X64_GPR_RCX] &= ~CPUID2_OSXSAVE; 1335 } 1336 break; 1337 case 0x00000002: 1338 break; 1339 case 0x00000003: 1340 cpudata->gprs[NVMM_X64_GPR_RAX] = 0; 1341 cpudata->gprs[NVMM_X64_GPR_RBX] = 0; 1342 cpudata->gprs[NVMM_X64_GPR_RCX] = 0; 1343 cpudata->gprs[NVMM_X64_GPR_RDX] = 0; 1344 break; 1345 case 0x00000004: /* Deterministic Cache Parameters */ 1346 break; /* TODO? */ 1347 case 0x00000005: /* MONITOR/MWAIT */ 1348 case 0x00000006: /* Thermal and Power Management */ 1349 cpudata->gprs[NVMM_X64_GPR_RAX] = 0; 1350 cpudata->gprs[NVMM_X64_GPR_RBX] = 0; 1351 cpudata->gprs[NVMM_X64_GPR_RCX] = 0; 1352 cpudata->gprs[NVMM_X64_GPR_RDX] = 0; 1353 break; 1354 case 0x00000007: /* Structured Extended Feature Flags Enumeration */ 1355 switch (ecx) { 1356 case 0: 1357 cpudata->gprs[NVMM_X64_GPR_RAX] = 0; 1358 cpudata->gprs[NVMM_X64_GPR_RBX] &= nvmm_cpuid_00000007.ebx; 1359 cpudata->gprs[NVMM_X64_GPR_RCX] &= nvmm_cpuid_00000007.ecx; 1360 cpudata->gprs[NVMM_X64_GPR_RDX] &= nvmm_cpuid_00000007.edx; 1361 if (vmx_procbased_ctls2 & PROC_CTLS2_INVPCID_ENABLE) { 1362 cpudata->gprs[NVMM_X64_GPR_RBX] |= CPUID_SEF_INVPCID; 1363 } 1364 break; 1365 default: 1366 cpudata->gprs[NVMM_X64_GPR_RAX] = 0; 1367 cpudata->gprs[NVMM_X64_GPR_RBX] = 0; 1368 cpudata->gprs[NVMM_X64_GPR_RCX] = 0; 1369 cpudata->gprs[NVMM_X64_GPR_RDX] = 0; 1370 break; 1371 } 1372 break; 1373 case 0x00000008: /* Empty */ 1374 case 0x00000009: /* Direct Cache Access Information */ 1375 cpudata->gprs[NVMM_X64_GPR_RAX] = 0; 1376 cpudata->gprs[NVMM_X64_GPR_RBX] = 0; 1377 cpudata->gprs[NVMM_X64_GPR_RCX] = 0; 1378 cpudata->gprs[NVMM_X64_GPR_RDX] = 0; 1379 break; 1380 case 0x0000000A: /* Architectural Performance Monitoring */ 1381 cpudata->gprs[NVMM_X64_GPR_RAX] = 0; 1382 cpudata->gprs[NVMM_X64_GPR_RBX] = 0; 1383 cpudata->gprs[NVMM_X64_GPR_RCX] = 0; 1384 cpudata->gprs[NVMM_X64_GPR_RDX] = 0; 1385 break; 1386 case 0x0000000B: /* Extended Topology Enumeration */ 1387 switch (ecx) { 1388 case 0: /* Threads */ 1389 cpudata->gprs[NVMM_X64_GPR_RAX] = 0; 1390 cpudata->gprs[NVMM_X64_GPR_RBX] = 0; 1391 cpudata->gprs[NVMM_X64_GPR_RCX] = 1392 __SHIFTIN(ecx, CPUID_TOP_LVLNUM) | 1393 __SHIFTIN(CPUID_TOP_LVLTYPE_SMT, CPUID_TOP_LVLTYPE); 1394 cpudata->gprs[NVMM_X64_GPR_RDX] = vcpu->cpuid; 1395 break; 1396 case 1: /* Cores */ 1397 ncpus = atomic_load_relaxed(&mach->ncpus); 1398 cpudata->gprs[NVMM_X64_GPR_RAX] = ilog2(ncpus); 1399 cpudata->gprs[NVMM_X64_GPR_RBX] = ncpus; 1400 cpudata->gprs[NVMM_X64_GPR_RCX] = 1401 __SHIFTIN(ecx, CPUID_TOP_LVLNUM) | 1402 __SHIFTIN(CPUID_TOP_LVLTYPE_CORE, CPUID_TOP_LVLTYPE); 1403 cpudata->gprs[NVMM_X64_GPR_RDX] = vcpu->cpuid; 1404 break; 1405 default: 1406 cpudata->gprs[NVMM_X64_GPR_RAX] = 0; 1407 cpudata->gprs[NVMM_X64_GPR_RBX] = 0; 1408 cpudata->gprs[NVMM_X64_GPR_RCX] = 0; /* LVLTYPE_INVAL */ 1409 cpudata->gprs[NVMM_X64_GPR_RDX] = 0; 1410 break; 1411 } 1412 break; 1413 case 0x0000000C: /* Empty */ 1414 cpudata->gprs[NVMM_X64_GPR_RAX] = 0; 1415 cpudata->gprs[NVMM_X64_GPR_RBX] = 0; 1416 cpudata->gprs[NVMM_X64_GPR_RCX] = 0; 1417 cpudata->gprs[NVMM_X64_GPR_RDX] = 0; 1418 break; 1419 case 0x0000000D: /* Processor Extended State Enumeration */ 1420 if (cpudata->xcr0_mask == 0) { 1421 cpudata->gprs[NVMM_X64_GPR_RAX] = 0; 1422 cpudata->gprs[NVMM_X64_GPR_RBX] = 0; 1423 cpudata->gprs[NVMM_X64_GPR_RCX] = 0; 1424 cpudata->gprs[NVMM_X64_GPR_RDX] = 0; 1425 break; 1426 } 1427 switch (ecx) { 1428 case 0: 1429 cpudata->gprs[NVMM_X64_GPR_RAX] = 1430 cpudata->xcr0_mask & 0xFFFFFFFF; 1431 cpudata->gprs[NVMM_X64_GPR_RBX] = 1432 nvmm_x86_xsave_size(cpudata->gxcr0); 1433 cpudata->gprs[NVMM_X64_GPR_RCX] = 1434 nvmm_x86_xsave_size(cpudata->xcr0_mask); 1435 cpudata->gprs[NVMM_X64_GPR_RDX] = 1436 cpudata->xcr0_mask >> 32; 1437 break; 1438 case 1: 1439 cpudata->gprs[NVMM_X64_GPR_RAX] &= 1440 (CPUID_PES1_XSAVEOPT | CPUID_PES1_XSAVEC | 1441 CPUID_PES1_XGETBV); 1442 cpudata->gprs[NVMM_X64_GPR_RBX] = 0; 1443 cpudata->gprs[NVMM_X64_GPR_RCX] = 0; 1444 cpudata->gprs[NVMM_X64_GPR_RDX] = 0; 1445 break; 1446 case 2 ... 62: 1447 /* 1448 * CPUID[EAX=0x0d,ECX=n], 2 <= n <= 62: size 1449 * and offset of nth component in XSAVE area. 1450 * If the nth bit of XCR0 is disabled in the 1451 * vCPU configuration, we return all-zero 1452 * instead. 1453 */ 1454 if ((cpudata->xcr0_mask & __BIT(ecx)) == 0) { 1455 cpudata->gprs[NVMM_X64_GPR_RAX] = 0; 1456 cpudata->gprs[NVMM_X64_GPR_RBX] = 0; 1457 cpudata->gprs[NVMM_X64_GPR_RCX] = 0; 1458 cpudata->gprs[NVMM_X64_GPR_RDX] = 0; 1459 } 1460 break; 1461 default: 1462 cpudata->gprs[NVMM_X64_GPR_RAX] = 0; 1463 cpudata->gprs[NVMM_X64_GPR_RBX] = 0; 1464 cpudata->gprs[NVMM_X64_GPR_RCX] = 0; 1465 cpudata->gprs[NVMM_X64_GPR_RDX] = 0; 1466 break; 1467 } 1468 break; 1469 case 0x0000000E: /* Empty */ 1470 case 0x0000000F: /* Intel RDT Monitoring Enumeration */ 1471 case 0x00000010: /* Intel RDT Allocation Enumeration */ 1472 cpudata->gprs[NVMM_X64_GPR_RAX] = 0; 1473 cpudata->gprs[NVMM_X64_GPR_RBX] = 0; 1474 cpudata->gprs[NVMM_X64_GPR_RCX] = 0; 1475 cpudata->gprs[NVMM_X64_GPR_RDX] = 0; 1476 break; 1477 case 0x00000011: /* Empty */ 1478 case 0x00000012: /* Intel SGX Capability Enumeration */ 1479 case 0x00000013: /* Empty */ 1480 case 0x00000014: /* Intel Processor Trace Enumeration */ 1481 cpudata->gprs[NVMM_X64_GPR_RAX] = 0; 1482 cpudata->gprs[NVMM_X64_GPR_RBX] = 0; 1483 cpudata->gprs[NVMM_X64_GPR_RCX] = 0; 1484 cpudata->gprs[NVMM_X64_GPR_RDX] = 0; 1485 break; 1486 case 0x00000015: /* TSC and Nominal Core Crystal Clock Information */ 1487 case 0x00000016: /* Processor Frequency Information */ 1488 break; 1489 1490 /* 1491 * hypervisor CPUID range 1492 */ 1493 case 0x40000000: /* Hypervisor Information */ 1494 cpudata->gprs[NVMM_X64_GPR_RAX] = VMX_CPUID_MAX_HYPERVISOR; 1495 cpudata->gprs[NVMM_X64_GPR_RBX] = 0; 1496 cpudata->gprs[NVMM_X64_GPR_RCX] = 0; 1497 cpudata->gprs[NVMM_X64_GPR_RDX] = 0; 1498 memcpy(&cpudata->gprs[NVMM_X64_GPR_RBX], "___ ", 4); 1499 memcpy(&cpudata->gprs[NVMM_X64_GPR_RCX], "NVMM", 4); 1500 memcpy(&cpudata->gprs[NVMM_X64_GPR_RDX], " ___", 4); 1501 break; 1502 1503 /* 1504 * extended CPUID range 1505 */ 1506 case 0x80000000: 1507 cpudata->gprs[NVMM_X64_GPR_RAX] = vmx_cpuid_max_extended; 1508 break; 1509 case 0x80000001: 1510 cpudata->gprs[NVMM_X64_GPR_RAX] &= nvmm_cpuid_80000001.eax; 1511 cpudata->gprs[NVMM_X64_GPR_RBX] &= nvmm_cpuid_80000001.ebx; 1512 cpudata->gprs[NVMM_X64_GPR_RCX] &= nvmm_cpuid_80000001.ecx; 1513 cpudata->gprs[NVMM_X64_GPR_RDX] &= nvmm_cpuid_80000001.edx; 1514 break; 1515 case 0x80000002: /* Processor Brand String */ 1516 case 0x80000003: /* Processor Brand String */ 1517 case 0x80000004: /* Processor Brand String */ 1518 case 0x80000005: /* Reserved Zero */ 1519 case 0x80000006: /* Cache Information */ 1520 break; 1521 case 0x80000007: /* TSC Information */ 1522 cpudata->gprs[NVMM_X64_GPR_RAX] &= nvmm_cpuid_80000007.eax; 1523 cpudata->gprs[NVMM_X64_GPR_RBX] &= nvmm_cpuid_80000007.ebx; 1524 cpudata->gprs[NVMM_X64_GPR_RCX] &= nvmm_cpuid_80000007.ecx; 1525 cpudata->gprs[NVMM_X64_GPR_RDX] &= nvmm_cpuid_80000007.edx; 1526 break; 1527 case 0x80000008: /* Address Sizes */ 1528 cpudata->gprs[NVMM_X64_GPR_RAX] &= nvmm_cpuid_80000008.eax; 1529 cpudata->gprs[NVMM_X64_GPR_RBX] &= nvmm_cpuid_80000008.ebx; 1530 cpudata->gprs[NVMM_X64_GPR_RCX] &= nvmm_cpuid_80000008.ecx; 1531 cpudata->gprs[NVMM_X64_GPR_RDX] &= nvmm_cpuid_80000008.edx; 1532 break; 1533 1534 default: 1535 break; 1536 } 1537 } 1538 1539 static void 1540 vmx_exit_insn(struct nvmm_vcpu_exit *exit, uint64_t reason) 1541 { 1542 uint64_t inslen, rip; 1543 1544 inslen = vmx_vmread(VMCS_EXIT_INSTRUCTION_LENGTH); 1545 rip = vmx_vmread(VMCS_GUEST_RIP); 1546 exit->u.insn.npc = rip + inslen; 1547 exit->reason = reason; 1548 } 1549 1550 static void 1551 vmx_exit_cpuid(struct nvmm_machine *mach, struct nvmm_cpu *vcpu, 1552 struct nvmm_vcpu_exit *exit) 1553 { 1554 struct vmx_cpudata *cpudata = vcpu->cpudata; 1555 struct nvmm_vcpu_conf_cpuid *cpuid; 1556 uint64_t eax, ecx; 1557 size_t i; 1558 1559 eax = cpudata->gprs[NVMM_X64_GPR_RAX]; 1560 ecx = cpudata->gprs[NVMM_X64_GPR_RCX]; 1561 vmx_inkernel_exec_cpuid(cpudata, eax, ecx); 1562 vmx_inkernel_handle_cpuid(mach, vcpu, eax, ecx); 1563 1564 for (i = 0; i < VMX_NCPUIDS; i++) { 1565 if (!cpudata->cpuidpresent[i]) { 1566 continue; 1567 } 1568 cpuid = &cpudata->cpuid[i]; 1569 if (cpuid->leaf != eax) { 1570 continue; 1571 } 1572 1573 if (cpuid->exit) { 1574 vmx_exit_insn(exit, NVMM_VCPU_EXIT_CPUID); 1575 return; 1576 } 1577 KASSERT(cpuid->mask); 1578 1579 /* del */ 1580 cpudata->gprs[NVMM_X64_GPR_RAX] &= ~cpuid->u.mask.del.eax; 1581 cpudata->gprs[NVMM_X64_GPR_RBX] &= ~cpuid->u.mask.del.ebx; 1582 cpudata->gprs[NVMM_X64_GPR_RCX] &= ~cpuid->u.mask.del.ecx; 1583 cpudata->gprs[NVMM_X64_GPR_RDX] &= ~cpuid->u.mask.del.edx; 1584 1585 /* set */ 1586 cpudata->gprs[NVMM_X64_GPR_RAX] |= cpuid->u.mask.set.eax; 1587 cpudata->gprs[NVMM_X64_GPR_RBX] |= cpuid->u.mask.set.ebx; 1588 cpudata->gprs[NVMM_X64_GPR_RCX] |= cpuid->u.mask.set.ecx; 1589 cpudata->gprs[NVMM_X64_GPR_RDX] |= cpuid->u.mask.set.edx; 1590 1591 break; 1592 } 1593 1594 vmx_inkernel_advance(); 1595 exit->reason = NVMM_VCPU_EXIT_NONE; 1596 } 1597 1598 static void 1599 vmx_exit_hlt(struct nvmm_machine *mach, struct nvmm_cpu *vcpu, 1600 struct nvmm_vcpu_exit *exit) 1601 { 1602 struct vmx_cpudata *cpudata = vcpu->cpudata; 1603 uint64_t rflags; 1604 1605 if (cpudata->int_window_exit) { 1606 rflags = vmx_vmread(VMCS_GUEST_RFLAGS); 1607 if (rflags & PSL_I) { 1608 vmx_event_waitexit_disable(vcpu, false); 1609 } 1610 } 1611 1612 vmx_inkernel_advance(); 1613 exit->reason = NVMM_VCPU_EXIT_HALTED; 1614 } 1615 1616 #define VMX_QUAL_CR_NUM __BITS(3,0) 1617 #define VMX_QUAL_CR_TYPE __BITS(5,4) 1618 #define CR_TYPE_WRITE 0 1619 #define CR_TYPE_READ 1 1620 #define CR_TYPE_CLTS 2 1621 #define CR_TYPE_LMSW 3 1622 #define VMX_QUAL_CR_LMSW_OPMEM __BIT(6) 1623 #define VMX_QUAL_CR_GPR __BITS(11,8) 1624 #define VMX_QUAL_CR_LMSW_SRC __BIT(31,16) 1625 1626 static inline int 1627 vmx_check_cr(uint64_t crval, uint64_t fixed0, uint64_t fixed1) 1628 { 1629 /* Bits set to 1 in fixed0 are fixed to 1. */ 1630 if ((crval & fixed0) != fixed0) { 1631 return -1; 1632 } 1633 /* Bits set to 0 in fixed1 are fixed to 0. */ 1634 if (crval & ~fixed1) { 1635 return -1; 1636 } 1637 return 0; 1638 } 1639 1640 static int 1641 vmx_inkernel_handle_cr0(struct nvmm_machine *mach, struct nvmm_cpu *vcpu, 1642 uint64_t qual) 1643 { 1644 struct vmx_cpudata *cpudata = vcpu->cpudata; 1645 uint64_t type, gpr, oldcr0, realcr0, fakecr0; 1646 uint64_t efer, ctls1; 1647 1648 type = __SHIFTOUT(qual, VMX_QUAL_CR_TYPE); 1649 if (type != CR_TYPE_WRITE) { 1650 return -1; 1651 } 1652 1653 gpr = __SHIFTOUT(qual, VMX_QUAL_CR_GPR); 1654 KASSERT(gpr < 16); 1655 1656 if (gpr == NVMM_X64_GPR_RSP) { 1657 fakecr0 = vmx_vmread(VMCS_GUEST_RSP); 1658 } else { 1659 fakecr0 = cpudata->gprs[gpr]; 1660 } 1661 1662 /* 1663 * fakecr0 is the value the guest believes is in %cr0. realcr0 is the 1664 * actual value in %cr0. 1665 * 1666 * In fakecr0 we must force CR0_ET to 1. 1667 * 1668 * In realcr0 we must force CR0_NW and CR0_CD to 0, and CR0_ET and 1669 * CR0_NE to 1. 1670 */ 1671 fakecr0 |= CR0_ET; 1672 realcr0 = (fakecr0 & ~CR0_STATIC_MASK) | CR0_ET | CR0_NE; 1673 1674 if (vmx_check_cr(realcr0, vmx_cr0_fixed0, vmx_cr0_fixed1) == -1) { 1675 return -1; 1676 } 1677 1678 /* 1679 * XXX Handle 32bit PAE paging, need to set PDPTEs, fetched manually 1680 * from CR3. 1681 */ 1682 1683 if (realcr0 & CR0_PG) { 1684 ctls1 = vmx_vmread(VMCS_ENTRY_CTLS); 1685 efer = vmx_vmread(VMCS_GUEST_IA32_EFER); 1686 if (efer & EFER_LME) { 1687 ctls1 |= ENTRY_CTLS_LONG_MODE; 1688 efer |= EFER_LMA; 1689 } else { 1690 ctls1 &= ~ENTRY_CTLS_LONG_MODE; 1691 efer &= ~EFER_LMA; 1692 } 1693 vmx_vmwrite(VMCS_GUEST_IA32_EFER, efer); 1694 vmx_vmwrite(VMCS_ENTRY_CTLS, ctls1); 1695 } 1696 1697 oldcr0 = (vmx_vmread(VMCS_CR0_SHADOW) & CR0_STATIC_MASK) | 1698 (vmx_vmread(VMCS_GUEST_CR0) & ~CR0_STATIC_MASK); 1699 if ((oldcr0 ^ fakecr0) & CR0_TLB_FLUSH) { 1700 cpudata->gtlb_want_flush = true; 1701 } 1702 1703 vmx_vmwrite(VMCS_CR0_SHADOW, fakecr0); 1704 vmx_vmwrite(VMCS_GUEST_CR0, realcr0); 1705 vmx_inkernel_advance(); 1706 return 0; 1707 } 1708 1709 static int 1710 vmx_inkernel_handle_cr4(struct nvmm_machine *mach, struct nvmm_cpu *vcpu, 1711 uint64_t qual) 1712 { 1713 struct vmx_cpudata *cpudata = vcpu->cpudata; 1714 uint64_t type, gpr, oldcr4, cr4; 1715 1716 type = __SHIFTOUT(qual, VMX_QUAL_CR_TYPE); 1717 if (type != CR_TYPE_WRITE) { 1718 return -1; 1719 } 1720 1721 gpr = __SHIFTOUT(qual, VMX_QUAL_CR_GPR); 1722 KASSERT(gpr < 16); 1723 1724 if (gpr == NVMM_X64_GPR_RSP) { 1725 gpr = vmx_vmread(VMCS_GUEST_RSP); 1726 } else { 1727 gpr = cpudata->gprs[gpr]; 1728 } 1729 1730 if (gpr & CR4_INVALID) { 1731 return -1; 1732 } 1733 cr4 = gpr | CR4_VMXE; 1734 if (vmx_check_cr(cr4, vmx_cr4_fixed0, vmx_cr4_fixed1) == -1) { 1735 return -1; 1736 } 1737 1738 oldcr4 = vmx_vmread(VMCS_GUEST_CR4); 1739 if ((oldcr4 ^ gpr) & CR4_TLB_FLUSH) { 1740 cpudata->gtlb_want_flush = true; 1741 } 1742 1743 vmx_vmwrite(VMCS_GUEST_CR4, cr4); 1744 vmx_inkernel_advance(); 1745 return 0; 1746 } 1747 1748 static int 1749 vmx_inkernel_handle_cr8(struct nvmm_machine *mach, struct nvmm_cpu *vcpu, 1750 uint64_t qual, struct nvmm_vcpu_exit *exit) 1751 { 1752 struct vmx_cpudata *cpudata = vcpu->cpudata; 1753 uint64_t type, gpr; 1754 bool write; 1755 1756 type = __SHIFTOUT(qual, VMX_QUAL_CR_TYPE); 1757 if (type == CR_TYPE_WRITE) { 1758 write = true; 1759 } else if (type == CR_TYPE_READ) { 1760 write = false; 1761 } else { 1762 return -1; 1763 } 1764 1765 gpr = __SHIFTOUT(qual, VMX_QUAL_CR_GPR); 1766 KASSERT(gpr < 16); 1767 1768 if (write) { 1769 if (gpr == NVMM_X64_GPR_RSP) { 1770 cpudata->gcr8 = vmx_vmread(VMCS_GUEST_RSP); 1771 } else { 1772 cpudata->gcr8 = cpudata->gprs[gpr]; 1773 } 1774 if (cpudata->tpr.exit_changed) { 1775 exit->reason = NVMM_VCPU_EXIT_TPR_CHANGED; 1776 } 1777 } else { 1778 if (gpr == NVMM_X64_GPR_RSP) { 1779 vmx_vmwrite(VMCS_GUEST_RSP, cpudata->gcr8); 1780 } else { 1781 cpudata->gprs[gpr] = cpudata->gcr8; 1782 } 1783 } 1784 1785 vmx_inkernel_advance(); 1786 return 0; 1787 } 1788 1789 static void 1790 vmx_exit_cr(struct nvmm_machine *mach, struct nvmm_cpu *vcpu, 1791 struct nvmm_vcpu_exit *exit) 1792 { 1793 uint64_t qual; 1794 int ret; 1795 1796 exit->reason = NVMM_VCPU_EXIT_NONE; 1797 1798 qual = vmx_vmread(VMCS_EXIT_QUALIFICATION); 1799 1800 switch (__SHIFTOUT(qual, VMX_QUAL_CR_NUM)) { 1801 case 0: 1802 ret = vmx_inkernel_handle_cr0(mach, vcpu, qual); 1803 break; 1804 case 4: 1805 ret = vmx_inkernel_handle_cr4(mach, vcpu, qual); 1806 break; 1807 case 8: 1808 ret = vmx_inkernel_handle_cr8(mach, vcpu, qual, exit); 1809 break; 1810 default: 1811 ret = -1; 1812 break; 1813 } 1814 1815 if (ret == -1) { 1816 vmx_inject_gp(vcpu); 1817 } 1818 } 1819 1820 #define VMX_QUAL_IO_SIZE __BITS(2,0) 1821 #define IO_SIZE_8 0 1822 #define IO_SIZE_16 1 1823 #define IO_SIZE_32 3 1824 #define VMX_QUAL_IO_IN __BIT(3) 1825 #define VMX_QUAL_IO_STR __BIT(4) 1826 #define VMX_QUAL_IO_REP __BIT(5) 1827 #define VMX_QUAL_IO_DX __BIT(6) 1828 #define VMX_QUAL_IO_PORT __BITS(31,16) 1829 1830 #define VMX_INFO_IO_ADRSIZE __BITS(9,7) 1831 #define IO_ADRSIZE_16 0 1832 #define IO_ADRSIZE_32 1 1833 #define IO_ADRSIZE_64 2 1834 #define VMX_INFO_IO_SEG __BITS(17,15) 1835 1836 static void 1837 vmx_exit_io(struct nvmm_machine *mach, struct nvmm_cpu *vcpu, 1838 struct nvmm_vcpu_exit *exit) 1839 { 1840 uint64_t qual, info, inslen, rip; 1841 1842 qual = vmx_vmread(VMCS_EXIT_QUALIFICATION); 1843 info = vmx_vmread(VMCS_EXIT_INSTRUCTION_INFO); 1844 1845 exit->reason = NVMM_VCPU_EXIT_IO; 1846 1847 exit->u.io.in = (qual & VMX_QUAL_IO_IN) != 0; 1848 exit->u.io.port = __SHIFTOUT(qual, VMX_QUAL_IO_PORT); 1849 1850 KASSERT(__SHIFTOUT(info, VMX_INFO_IO_SEG) < 6); 1851 exit->u.io.seg = __SHIFTOUT(info, VMX_INFO_IO_SEG); 1852 1853 if (__SHIFTOUT(info, VMX_INFO_IO_ADRSIZE) == IO_ADRSIZE_64) { 1854 exit->u.io.address_size = 8; 1855 } else if (__SHIFTOUT(info, VMX_INFO_IO_ADRSIZE) == IO_ADRSIZE_32) { 1856 exit->u.io.address_size = 4; 1857 } else if (__SHIFTOUT(info, VMX_INFO_IO_ADRSIZE) == IO_ADRSIZE_16) { 1858 exit->u.io.address_size = 2; 1859 } 1860 1861 if (__SHIFTOUT(qual, VMX_QUAL_IO_SIZE) == IO_SIZE_32) { 1862 exit->u.io.operand_size = 4; 1863 } else if (__SHIFTOUT(qual, VMX_QUAL_IO_SIZE) == IO_SIZE_16) { 1864 exit->u.io.operand_size = 2; 1865 } else if (__SHIFTOUT(qual, VMX_QUAL_IO_SIZE) == IO_SIZE_8) { 1866 exit->u.io.operand_size = 1; 1867 } 1868 1869 exit->u.io.rep = (qual & VMX_QUAL_IO_REP) != 0; 1870 exit->u.io.str = (qual & VMX_QUAL_IO_STR) != 0; 1871 1872 if (exit->u.io.in && exit->u.io.str) { 1873 exit->u.io.seg = NVMM_X64_SEG_ES; 1874 } 1875 1876 inslen = vmx_vmread(VMCS_EXIT_INSTRUCTION_LENGTH); 1877 rip = vmx_vmread(VMCS_GUEST_RIP); 1878 exit->u.io.npc = rip + inslen; 1879 1880 vmx_vcpu_state_provide(vcpu, 1881 NVMM_X64_STATE_GPRS | NVMM_X64_STATE_SEGS | 1882 NVMM_X64_STATE_CRS | NVMM_X64_STATE_MSRS); 1883 } 1884 1885 static const uint64_t msr_ignore_list[] = { 1886 MSR_BIOS_SIGN, 1887 MSR_IA32_PLATFORM_ID 1888 }; 1889 1890 static bool 1891 vmx_inkernel_handle_msr(struct nvmm_machine *mach, struct nvmm_cpu *vcpu, 1892 struct nvmm_vcpu_exit *exit) 1893 { 1894 struct vmx_cpudata *cpudata = vcpu->cpudata; 1895 uint64_t val; 1896 size_t i; 1897 1898 if (exit->reason == NVMM_VCPU_EXIT_RDMSR) { 1899 if (exit->u.rdmsr.msr == MSR_CR_PAT) { 1900 val = vmx_vmread(VMCS_GUEST_IA32_PAT); 1901 cpudata->gprs[NVMM_X64_GPR_RAX] = (val & 0xFFFFFFFF); 1902 cpudata->gprs[NVMM_X64_GPR_RDX] = (val >> 32); 1903 goto handled; 1904 } 1905 if (exit->u.rdmsr.msr == MSR_MISC_ENABLE) { 1906 val = cpudata->gmsr_misc_enable; 1907 cpudata->gprs[NVMM_X64_GPR_RAX] = (val & 0xFFFFFFFF); 1908 cpudata->gprs[NVMM_X64_GPR_RDX] = (val >> 32); 1909 goto handled; 1910 } 1911 if (exit->u.rdmsr.msr == MSR_IA32_ARCH_CAPABILITIES) { 1912 u_int descs[4]; 1913 if (cpuid_level < 7) { 1914 goto error; 1915 } 1916 x86_cpuid(7, descs); 1917 if (!(descs[3] & CPUID_SEF_ARCH_CAP)) { 1918 goto error; 1919 } 1920 val = rdmsr(MSR_IA32_ARCH_CAPABILITIES); 1921 val &= (IA32_ARCH_RDCL_NO | 1922 IA32_ARCH_SSB_NO | 1923 IA32_ARCH_MDS_NO | 1924 IA32_ARCH_TAA_NO); 1925 cpudata->gprs[NVMM_X64_GPR_RAX] = (val & 0xFFFFFFFF); 1926 cpudata->gprs[NVMM_X64_GPR_RDX] = (val >> 32); 1927 goto handled; 1928 } 1929 for (i = 0; i < __arraycount(msr_ignore_list); i++) { 1930 if (msr_ignore_list[i] != exit->u.rdmsr.msr) 1931 continue; 1932 val = 0; 1933 cpudata->gprs[NVMM_X64_GPR_RAX] = (val & 0xFFFFFFFF); 1934 cpudata->gprs[NVMM_X64_GPR_RDX] = (val >> 32); 1935 goto handled; 1936 } 1937 } else { 1938 if (exit->u.wrmsr.msr == MSR_TSC) { 1939 cpudata->gtsc = exit->u.wrmsr.val; 1940 cpudata->gtsc_want_update = true; 1941 goto handled; 1942 } 1943 if (exit->u.wrmsr.msr == MSR_CR_PAT) { 1944 val = exit->u.wrmsr.val; 1945 if (__predict_false(!nvmm_x86_pat_validate(val))) { 1946 goto error; 1947 } 1948 vmx_vmwrite(VMCS_GUEST_IA32_PAT, val); 1949 goto handled; 1950 } 1951 if (exit->u.wrmsr.msr == MSR_MISC_ENABLE) { 1952 /* Don't care. */ 1953 goto handled; 1954 } 1955 for (i = 0; i < __arraycount(msr_ignore_list); i++) { 1956 if (msr_ignore_list[i] != exit->u.wrmsr.msr) 1957 continue; 1958 goto handled; 1959 } 1960 } 1961 1962 return false; 1963 1964 handled: 1965 vmx_inkernel_advance(); 1966 return true; 1967 1968 error: 1969 vmx_inject_gp(vcpu); 1970 return true; 1971 } 1972 1973 static void 1974 vmx_exit_rdmsr(struct nvmm_machine *mach, struct nvmm_cpu *vcpu, 1975 struct nvmm_vcpu_exit *exit) 1976 { 1977 struct vmx_cpudata *cpudata = vcpu->cpudata; 1978 uint64_t inslen, rip; 1979 1980 exit->reason = NVMM_VCPU_EXIT_RDMSR; 1981 exit->u.rdmsr.msr = (cpudata->gprs[NVMM_X64_GPR_RCX] & 0xFFFFFFFF); 1982 1983 if (vmx_inkernel_handle_msr(mach, vcpu, exit)) { 1984 exit->reason = NVMM_VCPU_EXIT_NONE; 1985 return; 1986 } 1987 1988 inslen = vmx_vmread(VMCS_EXIT_INSTRUCTION_LENGTH); 1989 rip = vmx_vmread(VMCS_GUEST_RIP); 1990 exit->u.rdmsr.npc = rip + inslen; 1991 1992 vmx_vcpu_state_provide(vcpu, NVMM_X64_STATE_GPRS); 1993 } 1994 1995 static void 1996 vmx_exit_wrmsr(struct nvmm_machine *mach, struct nvmm_cpu *vcpu, 1997 struct nvmm_vcpu_exit *exit) 1998 { 1999 struct vmx_cpudata *cpudata = vcpu->cpudata; 2000 uint64_t rdx, rax, inslen, rip; 2001 2002 rdx = cpudata->gprs[NVMM_X64_GPR_RDX]; 2003 rax = cpudata->gprs[NVMM_X64_GPR_RAX]; 2004 2005 exit->reason = NVMM_VCPU_EXIT_WRMSR; 2006 exit->u.wrmsr.msr = (cpudata->gprs[NVMM_X64_GPR_RCX] & 0xFFFFFFFF); 2007 exit->u.wrmsr.val = (rdx << 32) | (rax & 0xFFFFFFFF); 2008 2009 if (vmx_inkernel_handle_msr(mach, vcpu, exit)) { 2010 exit->reason = NVMM_VCPU_EXIT_NONE; 2011 return; 2012 } 2013 2014 inslen = vmx_vmread(VMCS_EXIT_INSTRUCTION_LENGTH); 2015 rip = vmx_vmread(VMCS_GUEST_RIP); 2016 exit->u.wrmsr.npc = rip + inslen; 2017 2018 vmx_vcpu_state_provide(vcpu, NVMM_X64_STATE_GPRS); 2019 } 2020 2021 static void 2022 vmx_exit_xsetbv(struct nvmm_machine *mach, struct nvmm_cpu *vcpu, 2023 struct nvmm_vcpu_exit *exit) 2024 { 2025 struct vmx_cpudata *cpudata = vcpu->cpudata; 2026 uint64_t val; 2027 2028 exit->reason = NVMM_VCPU_EXIT_NONE; 2029 2030 val = (cpudata->gprs[NVMM_X64_GPR_RDX] << 32) | 2031 (cpudata->gprs[NVMM_X64_GPR_RAX] & 0xFFFFFFFF); 2032 2033 if (__predict_false(cpudata->gprs[NVMM_X64_GPR_RCX] != 0)) { 2034 goto error; 2035 } else if (__predict_false(cpudata->xcr0_mask == 0)) { 2036 goto error; 2037 } else if (__predict_false(!nvmm_x86_xcr0_valid(val, 2038 cpudata->xcr0_mask))) { 2039 goto error; 2040 } 2041 2042 KASSERTMSG(nvmm_x86_xcr0_valid(val, cpudata->xcr0_mask), 2043 "val=0x%"PRIx64" xcr0_mask=0x%"PRIx64" (gxcr0=0x%"PRIx64")", 2044 val, cpudata->xcr0_mask, cpudata->gxcr0); 2045 cpudata->gxcr0 = val; 2046 2047 vmx_inkernel_advance(); 2048 return; 2049 2050 error: 2051 vmx_inject_gp(vcpu); 2052 } 2053 2054 #define VMX_EPT_VIOLATION_READ __BIT(0) 2055 #define VMX_EPT_VIOLATION_WRITE __BIT(1) 2056 #define VMX_EPT_VIOLATION_EXECUTE __BIT(2) 2057 2058 static void 2059 vmx_exit_epf(struct nvmm_machine *mach, struct nvmm_cpu *vcpu, 2060 struct nvmm_vcpu_exit *exit) 2061 { 2062 uint64_t perm; 2063 gpaddr_t gpa; 2064 2065 gpa = vmx_vmread(VMCS_GUEST_PHYSICAL_ADDRESS); 2066 2067 exit->reason = NVMM_VCPU_EXIT_MEMORY; 2068 perm = vmx_vmread(VMCS_EXIT_QUALIFICATION); 2069 if (perm & VMX_EPT_VIOLATION_WRITE) 2070 exit->u.mem.prot = PROT_WRITE; 2071 else if (perm & VMX_EPT_VIOLATION_EXECUTE) 2072 exit->u.mem.prot = PROT_EXEC; 2073 else 2074 exit->u.mem.prot = PROT_READ; 2075 exit->u.mem.gpa = gpa; 2076 exit->u.mem.inst_len = 0; 2077 2078 vmx_vcpu_state_provide(vcpu, 2079 NVMM_X64_STATE_GPRS | NVMM_X64_STATE_SEGS | 2080 NVMM_X64_STATE_CRS | NVMM_X64_STATE_MSRS); 2081 } 2082 2083 /* -------------------------------------------------------------------------- */ 2084 2085 static void 2086 vmx_vcpu_guest_fpu_enter(struct nvmm_cpu *vcpu) 2087 { 2088 struct vmx_cpudata *cpudata = vcpu->cpudata; 2089 2090 /* 2091 * The guest's XCR0 had better not have any bits that aren't 2092 * allowed in the vCPU configuration, and the current XSAVE 2093 * area had better not store any either according to 2094 * cpudata->gfpu.xsh_xstate_bv. 2095 * 2096 * Note that XRSTOR will trap if XSTATE_BV has any bits that 2097 * are not set in XCR0. 2098 */ 2099 KASSERTMSG((cpudata->gxcr0 & ~cpudata->xcr0_mask) == 0, 2100 "gxcr0=0x%"PRIx64" xcr0_mask=0x%"PRIx64, 2101 cpudata->gxcr0, cpudata->xcr0_mask); 2102 KASSERTMSG((cpudata->gfpu.xsh_xstate_bv & ~cpudata->xcr0_mask) == 0, 2103 "XSTATE_BV=0x%"PRIx64" xcr0_mask=0x%"PRIx64, 2104 cpudata->gfpu.xsh_xstate_bv, cpudata->xcr0_mask); 2105 2106 /* 2107 * Save anything in the FPU registers that this thread might 2108 * have been using to memory, and raise the IPL to IPL_VM to 2109 * block interrupt handlers that might use the FPU. This also 2110 * zeroes any FPU registers that the NetBSD host uses. 2111 * 2112 * After this point, we are free to use the FPU registers. 2113 */ 2114 fpu_kern_enter(); 2115 2116 /* 2117 * If the host CPU doesn't support XSAVE or we're simulating a 2118 * vCPU without it, just restore the x87 and SSE state. The 2119 * host should already have both x87 and SSE enabled in XCR0, 2120 * if the host uses XSAVE. 2121 */ 2122 if (cpudata->xcr0_mask == 0) { 2123 /* TODO: should we use *XSAVE64 here? */ 2124 fpu_area_restore(&cpudata->gfpu, XCR0_X87|XCR0_SSE, false); 2125 return; 2126 } 2127 2128 /* 2129 * Set XCR0 to allow access to anything the guest has 2130 * previously used and is saved to memory, _and_ to anything 2131 * the guest has asked to use in cpudata->gxcr0. 2132 * 2133 * The guest may have used some extended CPU state like the 2134 * zmmN registers, and then later disabled them in XCR0; in 2135 * that case, the state must be preserved in case the guest 2136 * later enables it in XCR0, but we can only load while all 2137 * bits in cpudata->gfpu.xsh_xstate_bv are set in XCR0. 2138 * 2139 * Similarly, the guest may _not_ have used some extended CPU 2140 * state since reset, but may have since enabled it in XCR0. 2141 * Such state will be clear in cpudata->gfpu.xsh_xstate_bv and 2142 * must be initialized afresh by the CPU, which requires the 2143 * bits be set in XCR0 to allow that. 2144 */ 2145 cpudata->hxcr0 = rdxcr(0); 2146 wrxcr(0, cpudata->xcr0_mask & 2147 (cpudata->gfpu.xsh_xstate_bv | cpudata->gxcr0)); 2148 2149 /* 2150 * Load the guest's saved extended CPU state from memory into 2151 * the CPU. 2152 */ 2153 /* TODO: should we use *XSAVE64 here? */ 2154 fpu_area_restore(&cpudata->gfpu, cpudata->xcr0_mask, true); 2155 2156 /* 2157 * If we temporarily set XCR0 beyond what the guest asked for 2158 * in order to restore state that is currently disabled, reduce 2159 * it down to what the guest asked for. 2160 */ 2161 if (__predict_false(cpudata->gxcr0 != (cpudata->xcr0_mask & 2162 (cpudata->gfpu.xsh_xstate_bv | cpudata->gxcr0)))) 2163 wrxcr(0, cpudata->xcr0_mask & cpudata->gxcr0); 2164 } 2165 2166 static void 2167 vmx_vcpu_guest_fpu_leave(struct nvmm_cpu *vcpu) 2168 { 2169 struct vmx_cpudata *cpudata = vcpu->cpudata; 2170 2171 /* 2172 * If the host CPU doesn't support XSAVE or we're simulating a 2173 * vCPU without it, just save the x87 and SSE state. If the 2174 * host uses XSAVE, it should still have both x87 and SSE 2175 * enabled in XCR0; if the host doesn't use XSAVE, doesn't 2176 * matter. 2177 */ 2178 if (cpudata->xcr0_mask == 0) { 2179 /* TODO: should we use *XSAVE64 here? */ 2180 fpu_area_save(&cpudata->gfpu, XCR0_X87|XCR0_SSE, false); 2181 goto leave; 2182 } 2183 2184 /* 2185 * In case the guest has cleared some XCR0 bits but used the 2186 * corresponding extended CPU state, increase XCR0 to the 2187 * maximum supported for this guest before we XSAVE. 2188 * 2189 * Note that XRSTOR will trap if XSTATE_BV has any bits that 2190 * are not set in XCR0. 2191 */ 2192 cpudata->gxcr0 = rdxcr(0); 2193 wrxcr(0, cpudata->xcr0_mask); 2194 2195 /* 2196 * Paranoia: Ensure the guest's XCR0 has no forbidden bits. 2197 * Should not be possible because we filter them on XSETBV 2198 * exits. 2199 */ 2200 KASSERTMSG((cpudata->gxcr0 & ~cpudata->xcr0_mask) == 0, 2201 "gxcr0=0x%"PRIx64" xcr0_mask=0x%"PRIx64, 2202 cpudata->gxcr0, cpudata->xcr0_mask); 2203 cpudata->gxcr0 &= cpudata->xcr0_mask; 2204 2205 /* 2206 * Save any extended CPU state that could be in use by the 2207 * guest. 2208 */ 2209 /* TODO: should we use *XSAVE64 here? */ 2210 fpu_area_save(&cpudata->gfpu, cpudata->xcr0_mask, false); 2211 2212 /* 2213 * If the host XCR0 is different from the maximum guest XCR0, 2214 * switch back to the host XCR0 so we can restore NetBSD's FPU 2215 * state. 2216 */ 2217 if (cpudata->xcr0_mask != cpudata->hxcr0) 2218 wrxcr(0, cpudata->hxcr0); 2219 2220 leave: /* 2221 * Restore any FPU registers that we might have saved in 2222 * vmx_vcpu_guest_fpu_enter for this thread, and restore the 2223 * IPL from IPL_VM. 2224 * 2225 * After this point, we must not touch the FPU registers. 2226 */ 2227 fpu_kern_leave(); 2228 2229 /* 2230 * The guest's XCR0 had better not have any bits that aren't 2231 * allowed in the vCPU configuration, and the current XSAVE 2232 * area had better not store any either according to 2233 * cpudata->gfpu.xsh_xstate_bv. 2234 */ 2235 KASSERTMSG((cpudata->gxcr0 & ~cpudata->xcr0_mask) == 0, 2236 "gxcr0=0x%"PRIx64" xcr0_mask=0x%"PRIx64, 2237 cpudata->gxcr0, cpudata->xcr0_mask); 2238 KASSERTMSG((cpudata->gfpu.xsh_xstate_bv & ~cpudata->xcr0_mask) == 0, 2239 "XSTATE_BV=0x%"PRIx64" xcr0_mask=0x%"PRIx64, 2240 cpudata->gfpu.xsh_xstate_bv, cpudata->xcr0_mask); 2241 } 2242 2243 static void 2244 vmx_vcpu_guest_dbregs_enter(struct nvmm_cpu *vcpu) 2245 { 2246 struct vmx_cpudata *cpudata = vcpu->cpudata; 2247 2248 x86_dbregs_save(curlwp); 2249 2250 ldr7(0); 2251 2252 ldr0(cpudata->drs[NVMM_X64_DR_DR0]); 2253 ldr1(cpudata->drs[NVMM_X64_DR_DR1]); 2254 ldr2(cpudata->drs[NVMM_X64_DR_DR2]); 2255 ldr3(cpudata->drs[NVMM_X64_DR_DR3]); 2256 ldr6(cpudata->drs[NVMM_X64_DR_DR6]); 2257 } 2258 2259 static void 2260 vmx_vcpu_guest_dbregs_leave(struct nvmm_cpu *vcpu) 2261 { 2262 struct vmx_cpudata *cpudata = vcpu->cpudata; 2263 2264 cpudata->drs[NVMM_X64_DR_DR0] = rdr0(); 2265 cpudata->drs[NVMM_X64_DR_DR1] = rdr1(); 2266 cpudata->drs[NVMM_X64_DR_DR2] = rdr2(); 2267 cpudata->drs[NVMM_X64_DR_DR3] = rdr3(); 2268 cpudata->drs[NVMM_X64_DR_DR6] = rdr6(); 2269 2270 x86_dbregs_restore(curlwp); 2271 } 2272 2273 static void 2274 vmx_vcpu_guest_misc_enter(struct nvmm_cpu *vcpu) 2275 { 2276 struct vmx_cpudata *cpudata = vcpu->cpudata; 2277 2278 /* This gets restored automatically by the CPU. */ 2279 vmx_vmwrite(VMCS_HOST_IDTR_BASE, (uint64_t)curcpu()->ci_idtvec.iv_idt); 2280 vmx_vmwrite(VMCS_HOST_FS_BASE, rdmsr(MSR_FSBASE)); 2281 vmx_vmwrite(VMCS_HOST_CR3, rcr3()); 2282 vmx_vmwrite(VMCS_HOST_CR4, rcr4()); 2283 2284 cpudata->kernelgsbase = rdmsr(MSR_KERNELGSBASE); 2285 } 2286 2287 static void 2288 vmx_vcpu_guest_misc_leave(struct nvmm_cpu *vcpu) 2289 { 2290 struct vmx_cpudata *cpudata = vcpu->cpudata; 2291 2292 wrmsr(MSR_STAR, cpudata->star); 2293 wrmsr(MSR_LSTAR, cpudata->lstar); 2294 wrmsr(MSR_CSTAR, cpudata->cstar); 2295 wrmsr(MSR_SFMASK, cpudata->sfmask); 2296 wrmsr(MSR_KERNELGSBASE, cpudata->kernelgsbase); 2297 } 2298 2299 /* -------------------------------------------------------------------------- */ 2300 2301 #define VMX_INVVPID_ADDRESS 0 2302 #define VMX_INVVPID_CONTEXT 1 2303 #define VMX_INVVPID_ALL 2 2304 #define VMX_INVVPID_CONTEXT_NOGLOBAL 3 2305 2306 #define VMX_INVEPT_CONTEXT 1 2307 #define VMX_INVEPT_ALL 2 2308 2309 static inline void 2310 vmx_gtlb_catchup(struct nvmm_cpu *vcpu, int hcpu) 2311 { 2312 struct vmx_cpudata *cpudata = vcpu->cpudata; 2313 2314 if (vcpu->hcpu_last != hcpu) { 2315 cpudata->gtlb_want_flush = true; 2316 } 2317 } 2318 2319 static inline void 2320 vmx_htlb_catchup(struct nvmm_cpu *vcpu, int hcpu) 2321 { 2322 struct vmx_cpudata *cpudata = vcpu->cpudata; 2323 struct ept_desc ept_desc; 2324 2325 if (__predict_true(!kcpuset_isset(cpudata->htlb_want_flush, hcpu))) { 2326 return; 2327 } 2328 2329 ept_desc.eptp = vmx_vmread(VMCS_EPTP); 2330 ept_desc.mbz = 0; 2331 vmx_invept(vmx_ept_flush_op, &ept_desc); 2332 kcpuset_clear(cpudata->htlb_want_flush, hcpu); 2333 } 2334 2335 static inline uint64_t 2336 vmx_htlb_flush(struct vmx_machdata *machdata, struct vmx_cpudata *cpudata) 2337 { 2338 struct ept_desc ept_desc; 2339 uint64_t machgen; 2340 2341 machgen = machdata->mach_htlb_gen; 2342 if (__predict_true(machgen == cpudata->vcpu_htlb_gen)) { 2343 return machgen; 2344 } 2345 2346 kcpuset_copy(cpudata->htlb_want_flush, kcpuset_running); 2347 2348 ept_desc.eptp = vmx_vmread(VMCS_EPTP); 2349 ept_desc.mbz = 0; 2350 vmx_invept(vmx_ept_flush_op, &ept_desc); 2351 2352 return machgen; 2353 } 2354 2355 static inline void 2356 vmx_htlb_flush_ack(struct vmx_cpudata *cpudata, uint64_t machgen) 2357 { 2358 cpudata->vcpu_htlb_gen = machgen; 2359 kcpuset_clear(cpudata->htlb_want_flush, cpu_number()); 2360 } 2361 2362 static inline void 2363 vmx_exit_evt(struct vmx_cpudata *cpudata) 2364 { 2365 uint64_t info, err, inslen; 2366 2367 cpudata->evt_pending = false; 2368 2369 info = vmx_vmread(VMCS_IDT_VECTORING_INFO); 2370 if (__predict_true((info & INTR_INFO_VALID) == 0)) { 2371 return; 2372 } 2373 err = vmx_vmread(VMCS_IDT_VECTORING_ERROR); 2374 2375 vmx_vmwrite(VMCS_ENTRY_INTR_INFO, info); 2376 vmx_vmwrite(VMCS_ENTRY_EXCEPTION_ERROR, err); 2377 2378 switch (__SHIFTOUT(info, INTR_INFO_TYPE)) { 2379 case INTR_TYPE_SW_INT: 2380 case INTR_TYPE_PRIV_SW_EXC: 2381 case INTR_TYPE_SW_EXC: 2382 inslen = vmx_vmread(VMCS_EXIT_INSTRUCTION_LENGTH); 2383 vmx_vmwrite(VMCS_ENTRY_INSTRUCTION_LENGTH, inslen); 2384 } 2385 2386 cpudata->evt_pending = true; 2387 } 2388 2389 static int 2390 vmx_vcpu_run(struct nvmm_machine *mach, struct nvmm_cpu *vcpu, 2391 struct nvmm_vcpu_exit *exit) 2392 { 2393 struct nvmm_comm_page *comm = vcpu->comm; 2394 struct vmx_machdata *machdata = mach->machdata; 2395 struct vmx_cpudata *cpudata = vcpu->cpudata; 2396 struct vpid_desc vpid_desc; 2397 struct cpu_info *ci; 2398 uint64_t exitcode; 2399 uint64_t intstate; 2400 uint64_t machgen; 2401 int hcpu, ret; 2402 bool launched; 2403 2404 vmx_vmcs_enter(vcpu); 2405 2406 vmx_vcpu_state_commit(vcpu); 2407 comm->state_cached = 0; 2408 2409 if (__predict_false(vmx_vcpu_event_commit(vcpu) != 0)) { 2410 vmx_vmcs_leave(vcpu); 2411 return EINVAL; 2412 } 2413 2414 ci = curcpu(); 2415 hcpu = cpu_number(); 2416 launched = cpudata->vmcs_launched; 2417 2418 vmx_gtlb_catchup(vcpu, hcpu); 2419 vmx_htlb_catchup(vcpu, hcpu); 2420 2421 if (vcpu->hcpu_last != hcpu) { 2422 vmx_vmwrite(VMCS_HOST_TR_SELECTOR, ci->ci_tss_sel); 2423 vmx_vmwrite(VMCS_HOST_TR_BASE, (uint64_t)ci->ci_tss); 2424 vmx_vmwrite(VMCS_HOST_GDTR_BASE, (uint64_t)ci->ci_gdt); 2425 vmx_vmwrite(VMCS_HOST_GS_BASE, rdmsr(MSR_GSBASE)); 2426 cpudata->gtsc_want_update = true; 2427 vcpu->hcpu_last = hcpu; 2428 } 2429 2430 vmx_vcpu_guest_dbregs_enter(vcpu); 2431 vmx_vcpu_guest_misc_enter(vcpu); 2432 2433 while (1) { 2434 if (cpudata->gtlb_want_flush) { 2435 vpid_desc.vpid = cpudata->asid; 2436 vpid_desc.addr = 0; 2437 vmx_invvpid(vmx_tlb_flush_op, &vpid_desc); 2438 cpudata->gtlb_want_flush = false; 2439 } 2440 2441 if (__predict_false(cpudata->gtsc_want_update)) { 2442 vmx_vmwrite(VMCS_TSC_OFFSET, cpudata->gtsc - rdtsc()); 2443 cpudata->gtsc_want_update = false; 2444 } 2445 2446 vmx_vcpu_guest_fpu_enter(vcpu); 2447 vmx_cli(); 2448 machgen = vmx_htlb_flush(machdata, cpudata); 2449 lcr2(cpudata->gcr2); 2450 if (launched) { 2451 ret = vmx_vmresume(cpudata->gprs); 2452 } else { 2453 ret = vmx_vmlaunch(cpudata->gprs); 2454 } 2455 cpudata->gcr2 = rcr2(); 2456 vmx_htlb_flush_ack(cpudata, machgen); 2457 if (__predict_true(ret == 0)) { 2458 exitcode = vmx_vmread(VMCS_EXIT_REASON); 2459 exitcode &= __BITS(15,0); 2460 if (exitcode == VMCS_EXITCODE_EXC_NMI) { 2461 /* handle nmi before vmx_sti() */ 2462 vmx_exit_exc_nmi(mach, vcpu, exit); 2463 } 2464 } 2465 vmx_sti(); 2466 vmx_vcpu_guest_fpu_leave(vcpu); 2467 2468 if (__predict_false(ret != 0)) { 2469 vmx_exit_invalid(exit, -1); 2470 break; 2471 } 2472 vmx_exit_evt(cpudata); 2473 2474 launched = true; 2475 2476 switch (exitcode) { 2477 case VMCS_EXITCODE_EXC_NMI: 2478 /* handled earlier */ 2479 break; 2480 case VMCS_EXITCODE_EXT_INT: 2481 exit->reason = NVMM_VCPU_EXIT_NONE; 2482 break; 2483 case VMCS_EXITCODE_CPUID: 2484 vmx_exit_cpuid(mach, vcpu, exit); 2485 break; 2486 case VMCS_EXITCODE_HLT: 2487 vmx_exit_hlt(mach, vcpu, exit); 2488 break; 2489 case VMCS_EXITCODE_CR: 2490 vmx_exit_cr(mach, vcpu, exit); 2491 break; 2492 case VMCS_EXITCODE_IO: 2493 vmx_exit_io(mach, vcpu, exit); 2494 break; 2495 case VMCS_EXITCODE_RDMSR: 2496 vmx_exit_rdmsr(mach, vcpu, exit); 2497 break; 2498 case VMCS_EXITCODE_WRMSR: 2499 vmx_exit_wrmsr(mach, vcpu, exit); 2500 break; 2501 case VMCS_EXITCODE_SHUTDOWN: 2502 exit->reason = NVMM_VCPU_EXIT_SHUTDOWN; 2503 break; 2504 case VMCS_EXITCODE_MONITOR: 2505 vmx_exit_insn(exit, NVMM_VCPU_EXIT_MONITOR); 2506 break; 2507 case VMCS_EXITCODE_MWAIT: 2508 vmx_exit_insn(exit, NVMM_VCPU_EXIT_MWAIT); 2509 break; 2510 case VMCS_EXITCODE_XSETBV: 2511 vmx_exit_xsetbv(mach, vcpu, exit); 2512 break; 2513 case VMCS_EXITCODE_RDPMC: 2514 case VMCS_EXITCODE_RDTSCP: 2515 case VMCS_EXITCODE_INVVPID: 2516 case VMCS_EXITCODE_INVEPT: 2517 case VMCS_EXITCODE_VMCALL: 2518 case VMCS_EXITCODE_VMCLEAR: 2519 case VMCS_EXITCODE_VMLAUNCH: 2520 case VMCS_EXITCODE_VMPTRLD: 2521 case VMCS_EXITCODE_VMPTRST: 2522 case VMCS_EXITCODE_VMREAD: 2523 case VMCS_EXITCODE_VMRESUME: 2524 case VMCS_EXITCODE_VMWRITE: 2525 case VMCS_EXITCODE_VMXOFF: 2526 case VMCS_EXITCODE_VMXON: 2527 vmx_inject_ud(vcpu); 2528 exit->reason = NVMM_VCPU_EXIT_NONE; 2529 break; 2530 case VMCS_EXITCODE_EPT_VIOLATION: 2531 vmx_exit_epf(mach, vcpu, exit); 2532 break; 2533 case VMCS_EXITCODE_INT_WINDOW: 2534 vmx_event_waitexit_disable(vcpu, false); 2535 exit->reason = NVMM_VCPU_EXIT_INT_READY; 2536 break; 2537 case VMCS_EXITCODE_NMI_WINDOW: 2538 vmx_event_waitexit_disable(vcpu, true); 2539 exit->reason = NVMM_VCPU_EXIT_NMI_READY; 2540 break; 2541 default: 2542 vmx_exit_invalid(exit, exitcode); 2543 break; 2544 } 2545 2546 /* If no reason to return to userland, keep rolling. */ 2547 if (nvmm_return_needed(vcpu, exit)) { 2548 break; 2549 } 2550 if (exit->reason != NVMM_VCPU_EXIT_NONE) { 2551 break; 2552 } 2553 } 2554 2555 cpudata->vmcs_launched = launched; 2556 2557 cpudata->gtsc = vmx_vmread(VMCS_TSC_OFFSET) + rdtsc(); 2558 2559 vmx_vcpu_guest_misc_leave(vcpu); 2560 vmx_vcpu_guest_dbregs_leave(vcpu); 2561 2562 exit->exitstate.rflags = vmx_vmread(VMCS_GUEST_RFLAGS); 2563 exit->exitstate.cr8 = cpudata->gcr8; 2564 intstate = vmx_vmread(VMCS_GUEST_INTERRUPTIBILITY); 2565 exit->exitstate.int_shadow = 2566 (intstate & (INT_STATE_STI|INT_STATE_MOVSS)) != 0; 2567 exit->exitstate.int_window_exiting = cpudata->int_window_exit; 2568 exit->exitstate.nmi_window_exiting = cpudata->nmi_window_exit; 2569 exit->exitstate.evt_pending = cpudata->evt_pending; 2570 2571 vmx_vmcs_leave(vcpu); 2572 2573 return 0; 2574 } 2575 2576 /* -------------------------------------------------------------------------- */ 2577 2578 static int 2579 vmx_memalloc(paddr_t *pa, vaddr_t *va, size_t npages) 2580 { 2581 struct pglist pglist; 2582 paddr_t _pa; 2583 vaddr_t _va; 2584 size_t i; 2585 int ret; 2586 2587 ret = uvm_pglistalloc(npages * PAGE_SIZE, 0, ~0UL, PAGE_SIZE, 0, 2588 &pglist, 1, 0); 2589 if (ret != 0) 2590 return ENOMEM; 2591 _pa = VM_PAGE_TO_PHYS(TAILQ_FIRST(&pglist)); 2592 _va = uvm_km_alloc(kernel_map, npages * PAGE_SIZE, 0, 2593 UVM_KMF_VAONLY | UVM_KMF_NOWAIT); 2594 if (_va == 0) 2595 goto error; 2596 2597 for (i = 0; i < npages; i++) { 2598 pmap_kenter_pa(_va + i * PAGE_SIZE, _pa + i * PAGE_SIZE, 2599 VM_PROT_READ | VM_PROT_WRITE, PMAP_WRITE_BACK); 2600 } 2601 pmap_update(pmap_kernel()); 2602 2603 memset((void *)_va, 0, npages * PAGE_SIZE); 2604 2605 *pa = _pa; 2606 *va = _va; 2607 return 0; 2608 2609 error: 2610 for (i = 0; i < npages; i++) { 2611 uvm_pagefree(PHYS_TO_VM_PAGE(_pa + i * PAGE_SIZE)); 2612 } 2613 return ENOMEM; 2614 } 2615 2616 static void 2617 vmx_memfree(paddr_t pa, vaddr_t va, size_t npages) 2618 { 2619 size_t i; 2620 2621 pmap_kremove(va, npages * PAGE_SIZE); 2622 pmap_update(pmap_kernel()); 2623 uvm_km_free(kernel_map, va, npages * PAGE_SIZE, UVM_KMF_VAONLY); 2624 for (i = 0; i < npages; i++) { 2625 uvm_pagefree(PHYS_TO_VM_PAGE(pa + i * PAGE_SIZE)); 2626 } 2627 } 2628 2629 /* -------------------------------------------------------------------------- */ 2630 2631 static void 2632 vmx_vcpu_msr_allow(uint8_t *bitmap, uint64_t msr, bool read, bool write) 2633 { 2634 uint64_t byte; 2635 uint8_t bitoff; 2636 2637 if (msr < 0x00002000) { 2638 /* Range 1 */ 2639 byte = ((msr - 0x00000000) / 8) + 0; 2640 } else if (msr >= 0xC0000000 && msr < 0xC0002000) { 2641 /* Range 2 */ 2642 byte = ((msr - 0xC0000000) / 8) + 1024; 2643 } else { 2644 panic("%s: wrong range", __func__); 2645 } 2646 2647 bitoff = (msr & 0x7); 2648 2649 if (read) { 2650 bitmap[byte] &= ~__BIT(bitoff); 2651 } 2652 if (write) { 2653 bitmap[2048 + byte] &= ~__BIT(bitoff); 2654 } 2655 } 2656 2657 #define VMX_SEG_ATTRIB_TYPE __BITS(3,0) 2658 #define VMX_SEG_ATTRIB_S __BIT(4) 2659 #define VMX_SEG_ATTRIB_DPL __BITS(6,5) 2660 #define VMX_SEG_ATTRIB_P __BIT(7) 2661 #define VMX_SEG_ATTRIB_AVL __BIT(12) 2662 #define VMX_SEG_ATTRIB_L __BIT(13) 2663 #define VMX_SEG_ATTRIB_DEF __BIT(14) 2664 #define VMX_SEG_ATTRIB_G __BIT(15) 2665 #define VMX_SEG_ATTRIB_UNUSABLE __BIT(16) 2666 2667 static void 2668 vmx_vcpu_setstate_seg(const struct nvmm_x64_state_seg *segs, int idx) 2669 { 2670 uint64_t attrib; 2671 2672 attrib = 2673 __SHIFTIN(segs[idx].attrib.type, VMX_SEG_ATTRIB_TYPE) | 2674 __SHIFTIN(segs[idx].attrib.s, VMX_SEG_ATTRIB_S) | 2675 __SHIFTIN(segs[idx].attrib.dpl, VMX_SEG_ATTRIB_DPL) | 2676 __SHIFTIN(segs[idx].attrib.p, VMX_SEG_ATTRIB_P) | 2677 __SHIFTIN(segs[idx].attrib.avl, VMX_SEG_ATTRIB_AVL) | 2678 __SHIFTIN(segs[idx].attrib.l, VMX_SEG_ATTRIB_L) | 2679 __SHIFTIN(segs[idx].attrib.def, VMX_SEG_ATTRIB_DEF) | 2680 __SHIFTIN(segs[idx].attrib.g, VMX_SEG_ATTRIB_G) | 2681 (!segs[idx].attrib.p ? VMX_SEG_ATTRIB_UNUSABLE : 0); 2682 2683 if (idx != NVMM_X64_SEG_GDT && idx != NVMM_X64_SEG_IDT) { 2684 vmx_vmwrite(vmx_guest_segs[idx].selector, segs[idx].selector); 2685 vmx_vmwrite(vmx_guest_segs[idx].attrib, attrib); 2686 } 2687 vmx_vmwrite(vmx_guest_segs[idx].limit, segs[idx].limit); 2688 vmx_vmwrite(vmx_guest_segs[idx].base, segs[idx].base); 2689 } 2690 2691 static void 2692 vmx_vcpu_getstate_seg(struct nvmm_x64_state_seg *segs, int idx) 2693 { 2694 uint64_t selector = 0, attrib = 0, base, limit; 2695 2696 if (idx != NVMM_X64_SEG_GDT && idx != NVMM_X64_SEG_IDT) { 2697 selector = vmx_vmread(vmx_guest_segs[idx].selector); 2698 attrib = vmx_vmread(vmx_guest_segs[idx].attrib); 2699 } 2700 limit = vmx_vmread(vmx_guest_segs[idx].limit); 2701 base = vmx_vmread(vmx_guest_segs[idx].base); 2702 2703 segs[idx].selector = selector; 2704 segs[idx].limit = limit; 2705 segs[idx].base = base; 2706 segs[idx].attrib.type = __SHIFTOUT(attrib, VMX_SEG_ATTRIB_TYPE); 2707 segs[idx].attrib.s = __SHIFTOUT(attrib, VMX_SEG_ATTRIB_S); 2708 segs[idx].attrib.dpl = __SHIFTOUT(attrib, VMX_SEG_ATTRIB_DPL); 2709 segs[idx].attrib.p = __SHIFTOUT(attrib, VMX_SEG_ATTRIB_P); 2710 segs[idx].attrib.avl = __SHIFTOUT(attrib, VMX_SEG_ATTRIB_AVL); 2711 segs[idx].attrib.l = __SHIFTOUT(attrib, VMX_SEG_ATTRIB_L); 2712 segs[idx].attrib.def = __SHIFTOUT(attrib, VMX_SEG_ATTRIB_DEF); 2713 segs[idx].attrib.g = __SHIFTOUT(attrib, VMX_SEG_ATTRIB_G); 2714 if (attrib & VMX_SEG_ATTRIB_UNUSABLE) { 2715 segs[idx].attrib.p = 0; 2716 } 2717 } 2718 2719 static inline bool 2720 vmx_state_tlb_flush(const struct nvmm_x64_state *state, uint64_t flags) 2721 { 2722 uint64_t cr0, cr3, cr4, efer; 2723 2724 if (flags & NVMM_X64_STATE_CRS) { 2725 cr0 = vmx_vmread(VMCS_GUEST_CR0); 2726 if ((cr0 ^ state->crs[NVMM_X64_CR_CR0]) & CR0_TLB_FLUSH) { 2727 return true; 2728 } 2729 cr3 = vmx_vmread(VMCS_GUEST_CR3); 2730 if (cr3 != state->crs[NVMM_X64_CR_CR3]) { 2731 return true; 2732 } 2733 cr4 = vmx_vmread(VMCS_GUEST_CR4); 2734 if ((cr4 ^ state->crs[NVMM_X64_CR_CR4]) & CR4_TLB_FLUSH) { 2735 return true; 2736 } 2737 } 2738 2739 if (flags & NVMM_X64_STATE_MSRS) { 2740 efer = vmx_vmread(VMCS_GUEST_IA32_EFER); 2741 if ((efer ^ 2742 state->msrs[NVMM_X64_MSR_EFER]) & EFER_TLB_FLUSH) { 2743 return true; 2744 } 2745 } 2746 2747 return false; 2748 } 2749 2750 static void 2751 vmx_vcpu_setstate(struct nvmm_cpu *vcpu) 2752 { 2753 struct nvmm_comm_page *comm = vcpu->comm; 2754 const struct nvmm_x64_state *state = &comm->state; 2755 struct vmx_cpudata *cpudata = vcpu->cpudata; 2756 struct fxsave *fpustate; 2757 uint64_t ctls1, intstate; 2758 uint64_t flags; 2759 2760 flags = comm->state_wanted; 2761 2762 vmx_vmcs_enter(vcpu); 2763 2764 if (vmx_state_tlb_flush(state, flags)) { 2765 cpudata->gtlb_want_flush = true; 2766 } 2767 2768 if (flags & NVMM_X64_STATE_SEGS) { 2769 vmx_vcpu_setstate_seg(state->segs, NVMM_X64_SEG_CS); 2770 vmx_vcpu_setstate_seg(state->segs, NVMM_X64_SEG_DS); 2771 vmx_vcpu_setstate_seg(state->segs, NVMM_X64_SEG_ES); 2772 vmx_vcpu_setstate_seg(state->segs, NVMM_X64_SEG_FS); 2773 vmx_vcpu_setstate_seg(state->segs, NVMM_X64_SEG_GS); 2774 vmx_vcpu_setstate_seg(state->segs, NVMM_X64_SEG_SS); 2775 vmx_vcpu_setstate_seg(state->segs, NVMM_X64_SEG_GDT); 2776 vmx_vcpu_setstate_seg(state->segs, NVMM_X64_SEG_IDT); 2777 vmx_vcpu_setstate_seg(state->segs, NVMM_X64_SEG_LDT); 2778 vmx_vcpu_setstate_seg(state->segs, NVMM_X64_SEG_TR); 2779 } 2780 2781 CTASSERT(sizeof(cpudata->gprs) == sizeof(state->gprs)); 2782 if (flags & NVMM_X64_STATE_GPRS) { 2783 memcpy(cpudata->gprs, state->gprs, sizeof(state->gprs)); 2784 2785 vmx_vmwrite(VMCS_GUEST_RIP, state->gprs[NVMM_X64_GPR_RIP]); 2786 vmx_vmwrite(VMCS_GUEST_RSP, state->gprs[NVMM_X64_GPR_RSP]); 2787 vmx_vmwrite(VMCS_GUEST_RFLAGS, state->gprs[NVMM_X64_GPR_RFLAGS]); 2788 } 2789 2790 if (flags & NVMM_X64_STATE_CRS) { 2791 /* 2792 * CR0_ET must be 1 both in the shadow and the real register. 2793 * CR0_NE must be 1 in the real register. 2794 * CR0_NW and CR0_CD must be 0 in the real register. 2795 */ 2796 vmx_vmwrite(VMCS_CR0_SHADOW, 2797 (state->crs[NVMM_X64_CR_CR0] & CR0_STATIC_MASK) | 2798 CR0_ET); 2799 vmx_vmwrite(VMCS_GUEST_CR0, 2800 (state->crs[NVMM_X64_CR_CR0] & ~CR0_STATIC_MASK) | 2801 CR0_ET | CR0_NE); 2802 2803 cpudata->gcr2 = state->crs[NVMM_X64_CR_CR2]; 2804 2805 /* XXX We are not handling PDPTE here. */ 2806 vmx_vmwrite(VMCS_GUEST_CR3, state->crs[NVMM_X64_CR_CR3]); 2807 2808 /* CR4_VMXE is mandatory. */ 2809 vmx_vmwrite(VMCS_GUEST_CR4, 2810 (state->crs[NVMM_X64_CR_CR4] & CR4_VALID) | CR4_VMXE); 2811 2812 cpudata->gcr8 = state->crs[NVMM_X64_CR_CR8]; 2813 2814 if (cpudata->xcr0_mask != 0) { 2815 const uint64_t xcr0 = state->crs[NVMM_X64_CR_XCR0]; 2816 2817 cpudata->gxcr0 = nvmm_x86_munge_xcr0(xcr0, 2818 cpudata->xcr0_mask); 2819 } 2820 } 2821 2822 CTASSERT(sizeof(cpudata->drs) == sizeof(state->drs)); 2823 if (flags & NVMM_X64_STATE_DRS) { 2824 memcpy(cpudata->drs, state->drs, sizeof(state->drs)); 2825 2826 cpudata->drs[NVMM_X64_DR_DR6] &= 0xFFFFFFFF; 2827 vmx_vmwrite(VMCS_GUEST_DR7, cpudata->drs[NVMM_X64_DR_DR7]); 2828 } 2829 2830 if (flags & NVMM_X64_STATE_MSRS) { 2831 cpudata->gmsr[VMX_MSRLIST_STAR].val = 2832 state->msrs[NVMM_X64_MSR_STAR]; 2833 cpudata->gmsr[VMX_MSRLIST_LSTAR].val = 2834 state->msrs[NVMM_X64_MSR_LSTAR]; 2835 cpudata->gmsr[VMX_MSRLIST_CSTAR].val = 2836 state->msrs[NVMM_X64_MSR_CSTAR]; 2837 cpudata->gmsr[VMX_MSRLIST_SFMASK].val = 2838 state->msrs[NVMM_X64_MSR_SFMASK]; 2839 cpudata->gmsr[VMX_MSRLIST_KERNELGSBASE].val = 2840 state->msrs[NVMM_X64_MSR_KERNELGSBASE]; 2841 2842 vmx_vmwrite(VMCS_GUEST_IA32_EFER, 2843 state->msrs[NVMM_X64_MSR_EFER]); 2844 vmx_vmwrite(VMCS_GUEST_IA32_PAT, 2845 state->msrs[NVMM_X64_MSR_PAT]); 2846 vmx_vmwrite(VMCS_GUEST_IA32_SYSENTER_CS, 2847 state->msrs[NVMM_X64_MSR_SYSENTER_CS]); 2848 vmx_vmwrite(VMCS_GUEST_IA32_SYSENTER_ESP, 2849 state->msrs[NVMM_X64_MSR_SYSENTER_ESP]); 2850 vmx_vmwrite(VMCS_GUEST_IA32_SYSENTER_EIP, 2851 state->msrs[NVMM_X64_MSR_SYSENTER_EIP]); 2852 2853 cpudata->gtsc = state->msrs[NVMM_X64_MSR_TSC]; 2854 cpudata->gtsc_want_update = true; 2855 2856 /* ENTRY_CTLS_LONG_MODE must match EFER_LMA. */ 2857 ctls1 = vmx_vmread(VMCS_ENTRY_CTLS); 2858 if (state->msrs[NVMM_X64_MSR_EFER] & EFER_LMA) { 2859 ctls1 |= ENTRY_CTLS_LONG_MODE; 2860 } else { 2861 ctls1 &= ~ENTRY_CTLS_LONG_MODE; 2862 } 2863 vmx_vmwrite(VMCS_ENTRY_CTLS, ctls1); 2864 } 2865 2866 if (flags & NVMM_X64_STATE_INTR) { 2867 intstate = vmx_vmread(VMCS_GUEST_INTERRUPTIBILITY); 2868 intstate &= ~(INT_STATE_STI|INT_STATE_MOVSS); 2869 if (state->intr.int_shadow) { 2870 intstate |= INT_STATE_MOVSS; 2871 } 2872 vmx_vmwrite(VMCS_GUEST_INTERRUPTIBILITY, intstate); 2873 2874 if (state->intr.int_window_exiting) { 2875 vmx_event_waitexit_enable(vcpu, false); 2876 } else { 2877 vmx_event_waitexit_disable(vcpu, false); 2878 } 2879 2880 if (state->intr.nmi_window_exiting) { 2881 vmx_event_waitexit_enable(vcpu, true); 2882 } else { 2883 vmx_event_waitexit_disable(vcpu, true); 2884 } 2885 } 2886 2887 CTASSERT(sizeof(cpudata->gfpu.xsh_fxsave) == sizeof(state->fpu)); 2888 if (flags & NVMM_X64_STATE_FPU) { 2889 memcpy(cpudata->gfpu.xsh_fxsave, &state->fpu, 2890 sizeof(state->fpu)); 2891 2892 fpustate = (struct fxsave *)cpudata->gfpu.xsh_fxsave; 2893 fpustate->fx_mxcsr_mask &= x86_fpu_mxcsr_mask; 2894 fpustate->fx_mxcsr &= fpustate->fx_mxcsr_mask; 2895 2896 if (cpudata->xcr0_mask != 0) { 2897 /* Reset XSTATE_BV, to force a reload. */ 2898 cpudata->gfpu.xsh_xstate_bv = cpudata->xcr0_mask; 2899 } 2900 } 2901 /* 2902 * XXX XSAVE area -- need to allocate and map it separately 2903 * since it may exceed the comm page size 2904 */ 2905 2906 vmx_vmcs_leave(vcpu); 2907 2908 comm->state_wanted = 0; 2909 comm->state_cached |= flags; 2910 } 2911 2912 static void 2913 vmx_vcpu_getstate(struct nvmm_cpu *vcpu) 2914 { 2915 struct nvmm_comm_page *comm = vcpu->comm; 2916 struct nvmm_x64_state *state = &comm->state; 2917 struct vmx_cpudata *cpudata = vcpu->cpudata; 2918 uint64_t intstate, flags; 2919 2920 flags = comm->state_wanted; 2921 2922 vmx_vmcs_enter(vcpu); 2923 2924 if (flags & NVMM_X64_STATE_SEGS) { 2925 vmx_vcpu_getstate_seg(state->segs, NVMM_X64_SEG_CS); 2926 vmx_vcpu_getstate_seg(state->segs, NVMM_X64_SEG_DS); 2927 vmx_vcpu_getstate_seg(state->segs, NVMM_X64_SEG_ES); 2928 vmx_vcpu_getstate_seg(state->segs, NVMM_X64_SEG_FS); 2929 vmx_vcpu_getstate_seg(state->segs, NVMM_X64_SEG_GS); 2930 vmx_vcpu_getstate_seg(state->segs, NVMM_X64_SEG_SS); 2931 vmx_vcpu_getstate_seg(state->segs, NVMM_X64_SEG_GDT); 2932 vmx_vcpu_getstate_seg(state->segs, NVMM_X64_SEG_IDT); 2933 vmx_vcpu_getstate_seg(state->segs, NVMM_X64_SEG_LDT); 2934 vmx_vcpu_getstate_seg(state->segs, NVMM_X64_SEG_TR); 2935 } 2936 2937 CTASSERT(sizeof(cpudata->gprs) == sizeof(state->gprs)); 2938 if (flags & NVMM_X64_STATE_GPRS) { 2939 memcpy(state->gprs, cpudata->gprs, sizeof(state->gprs)); 2940 2941 state->gprs[NVMM_X64_GPR_RIP] = vmx_vmread(VMCS_GUEST_RIP); 2942 state->gprs[NVMM_X64_GPR_RSP] = vmx_vmread(VMCS_GUEST_RSP); 2943 state->gprs[NVMM_X64_GPR_RFLAGS] = vmx_vmread(VMCS_GUEST_RFLAGS); 2944 } 2945 2946 if (flags & NVMM_X64_STATE_CRS) { 2947 state->crs[NVMM_X64_CR_CR0] = 2948 (vmx_vmread(VMCS_CR0_SHADOW) & CR0_STATIC_MASK) | 2949 (vmx_vmread(VMCS_GUEST_CR0) & ~CR0_STATIC_MASK); 2950 state->crs[NVMM_X64_CR_CR2] = cpudata->gcr2; 2951 state->crs[NVMM_X64_CR_CR3] = vmx_vmread(VMCS_GUEST_CR3); 2952 state->crs[NVMM_X64_CR_CR4] = vmx_vmread(VMCS_GUEST_CR4); 2953 state->crs[NVMM_X64_CR_CR8] = cpudata->gcr8; 2954 state->crs[NVMM_X64_CR_XCR0] = cpudata->gxcr0; 2955 2956 /* Hide VMXE. */ 2957 state->crs[NVMM_X64_CR_CR4] &= ~CR4_VMXE; 2958 } 2959 2960 CTASSERT(sizeof(cpudata->drs) == sizeof(state->drs)); 2961 if (flags & NVMM_X64_STATE_DRS) { 2962 memcpy(state->drs, cpudata->drs, sizeof(state->drs)); 2963 2964 state->drs[NVMM_X64_DR_DR7] = vmx_vmread(VMCS_GUEST_DR7); 2965 } 2966 2967 if (flags & NVMM_X64_STATE_MSRS) { 2968 state->msrs[NVMM_X64_MSR_STAR] = 2969 cpudata->gmsr[VMX_MSRLIST_STAR].val; 2970 state->msrs[NVMM_X64_MSR_LSTAR] = 2971 cpudata->gmsr[VMX_MSRLIST_LSTAR].val; 2972 state->msrs[NVMM_X64_MSR_CSTAR] = 2973 cpudata->gmsr[VMX_MSRLIST_CSTAR].val; 2974 state->msrs[NVMM_X64_MSR_SFMASK] = 2975 cpudata->gmsr[VMX_MSRLIST_SFMASK].val; 2976 state->msrs[NVMM_X64_MSR_KERNELGSBASE] = 2977 cpudata->gmsr[VMX_MSRLIST_KERNELGSBASE].val; 2978 state->msrs[NVMM_X64_MSR_EFER] = 2979 vmx_vmread(VMCS_GUEST_IA32_EFER); 2980 state->msrs[NVMM_X64_MSR_PAT] = 2981 vmx_vmread(VMCS_GUEST_IA32_PAT); 2982 state->msrs[NVMM_X64_MSR_SYSENTER_CS] = 2983 vmx_vmread(VMCS_GUEST_IA32_SYSENTER_CS); 2984 state->msrs[NVMM_X64_MSR_SYSENTER_ESP] = 2985 vmx_vmread(VMCS_GUEST_IA32_SYSENTER_ESP); 2986 state->msrs[NVMM_X64_MSR_SYSENTER_EIP] = 2987 vmx_vmread(VMCS_GUEST_IA32_SYSENTER_EIP); 2988 state->msrs[NVMM_X64_MSR_TSC] = cpudata->gtsc; 2989 } 2990 2991 if (flags & NVMM_X64_STATE_INTR) { 2992 intstate = vmx_vmread(VMCS_GUEST_INTERRUPTIBILITY); 2993 state->intr.int_shadow = 2994 (intstate & (INT_STATE_STI|INT_STATE_MOVSS)) != 0; 2995 state->intr.int_window_exiting = cpudata->int_window_exit; 2996 state->intr.nmi_window_exiting = cpudata->nmi_window_exit; 2997 state->intr.evt_pending = cpudata->evt_pending; 2998 } 2999 3000 CTASSERT(sizeof(cpudata->gfpu.xsh_fxsave) == sizeof(state->fpu)); 3001 if (flags & NVMM_X64_STATE_FPU) { 3002 memcpy(&state->fpu, cpudata->gfpu.xsh_fxsave, 3003 sizeof(state->fpu)); 3004 } 3005 /* 3006 * XXX XSAVE area -- need to allocate and map it separately 3007 * since it may exceed the comm page size 3008 */ 3009 3010 vmx_vmcs_leave(vcpu); 3011 3012 comm->state_wanted = 0; 3013 comm->state_cached |= flags; 3014 } 3015 3016 static void 3017 vmx_vcpu_state_provide(struct nvmm_cpu *vcpu, uint64_t flags) 3018 { 3019 vcpu->comm->state_wanted = flags; 3020 vmx_vcpu_getstate(vcpu); 3021 } 3022 3023 static void 3024 vmx_vcpu_state_commit(struct nvmm_cpu *vcpu) 3025 { 3026 vcpu->comm->state_wanted = vcpu->comm->state_commit; 3027 vcpu->comm->state_commit = 0; 3028 vmx_vcpu_setstate(vcpu); 3029 } 3030 3031 /* -------------------------------------------------------------------------- */ 3032 3033 static void 3034 vmx_asid_alloc(struct nvmm_cpu *vcpu) 3035 { 3036 struct vmx_cpudata *cpudata = vcpu->cpudata; 3037 size_t i, oct, bit; 3038 3039 mutex_enter(&vmx_asidlock); 3040 3041 for (i = 0; i < vmx_maxasid; i++) { 3042 oct = i / 8; 3043 bit = i % 8; 3044 3045 if (vmx_asidmap[oct] & __BIT(bit)) { 3046 continue; 3047 } 3048 3049 cpudata->asid = i; 3050 3051 vmx_asidmap[oct] |= __BIT(bit); 3052 vmx_vmwrite(VMCS_VPID, i); 3053 mutex_exit(&vmx_asidlock); 3054 return; 3055 } 3056 3057 mutex_exit(&vmx_asidlock); 3058 3059 panic("%s: impossible", __func__); 3060 } 3061 3062 static void 3063 vmx_asid_free(struct nvmm_cpu *vcpu) 3064 { 3065 size_t oct, bit; 3066 uint64_t asid; 3067 3068 asid = vmx_vmread(VMCS_VPID); 3069 3070 oct = asid / 8; 3071 bit = asid % 8; 3072 3073 mutex_enter(&vmx_asidlock); 3074 vmx_asidmap[oct] &= ~__BIT(bit); 3075 mutex_exit(&vmx_asidlock); 3076 } 3077 3078 static void 3079 vmx_vcpu_init(struct nvmm_machine *mach, struct nvmm_cpu *vcpu) 3080 { 3081 struct vmx_cpudata *cpudata = vcpu->cpudata; 3082 struct vmcs *vmcs = cpudata->vmcs; 3083 struct msr_entry *gmsr = cpudata->gmsr; 3084 extern uint8_t vmx_resume_rip; 3085 uint64_t rev, eptp; 3086 3087 rev = vmx_get_revision(); 3088 3089 memset(vmcs, 0, VMCS_SIZE); 3090 vmcs->ident = __SHIFTIN(rev, VMCS_IDENT_REVISION); 3091 vmcs->abort = 0; 3092 3093 vmx_vmcs_enter(vcpu); 3094 3095 /* No link pointer. */ 3096 vmx_vmwrite(VMCS_LINK_POINTER, 0xFFFFFFFFFFFFFFFF); 3097 3098 /* Install the CTLSs. */ 3099 vmx_vmwrite(VMCS_PINBASED_CTLS, vmx_pinbased_ctls); 3100 vmx_vmwrite(VMCS_PROCBASED_CTLS, vmx_procbased_ctls); 3101 vmx_vmwrite(VMCS_PROCBASED_CTLS2, vmx_procbased_ctls2); 3102 vmx_vmwrite(VMCS_ENTRY_CTLS, vmx_entry_ctls); 3103 vmx_vmwrite(VMCS_EXIT_CTLS, vmx_exit_ctls); 3104 3105 /* Allow direct access to certain MSRs. */ 3106 memset(cpudata->msrbm, 0xFF, MSRBM_SIZE); 3107 vmx_vcpu_msr_allow(cpudata->msrbm, MSR_EFER, true, true); 3108 vmx_vcpu_msr_allow(cpudata->msrbm, MSR_STAR, true, true); 3109 vmx_vcpu_msr_allow(cpudata->msrbm, MSR_LSTAR, true, true); 3110 vmx_vcpu_msr_allow(cpudata->msrbm, MSR_CSTAR, true, true); 3111 vmx_vcpu_msr_allow(cpudata->msrbm, MSR_SFMASK, true, true); 3112 vmx_vcpu_msr_allow(cpudata->msrbm, MSR_KERNELGSBASE, true, true); 3113 vmx_vcpu_msr_allow(cpudata->msrbm, MSR_SYSENTER_CS, true, true); 3114 vmx_vcpu_msr_allow(cpudata->msrbm, MSR_SYSENTER_ESP, true, true); 3115 vmx_vcpu_msr_allow(cpudata->msrbm, MSR_SYSENTER_EIP, true, true); 3116 vmx_vcpu_msr_allow(cpudata->msrbm, MSR_FSBASE, true, true); 3117 vmx_vcpu_msr_allow(cpudata->msrbm, MSR_GSBASE, true, true); 3118 vmx_vcpu_msr_allow(cpudata->msrbm, MSR_TSC, true, false); 3119 vmx_vmwrite(VMCS_MSR_BITMAP, (uint64_t)cpudata->msrbm_pa); 3120 3121 /* 3122 * List of Guest MSRs loaded on VMENTRY, saved on VMEXIT. This 3123 * includes the L1D_FLUSH MSR, to mitigate L1TF. 3124 */ 3125 gmsr[VMX_MSRLIST_STAR].msr = MSR_STAR; 3126 gmsr[VMX_MSRLIST_STAR].val = 0; 3127 gmsr[VMX_MSRLIST_LSTAR].msr = MSR_LSTAR; 3128 gmsr[VMX_MSRLIST_LSTAR].val = 0; 3129 gmsr[VMX_MSRLIST_CSTAR].msr = MSR_CSTAR; 3130 gmsr[VMX_MSRLIST_CSTAR].val = 0; 3131 gmsr[VMX_MSRLIST_SFMASK].msr = MSR_SFMASK; 3132 gmsr[VMX_MSRLIST_SFMASK].val = 0; 3133 gmsr[VMX_MSRLIST_KERNELGSBASE].msr = MSR_KERNELGSBASE; 3134 gmsr[VMX_MSRLIST_KERNELGSBASE].val = 0; 3135 gmsr[VMX_MSRLIST_L1DFLUSH].msr = MSR_IA32_FLUSH_CMD; 3136 gmsr[VMX_MSRLIST_L1DFLUSH].val = IA32_FLUSH_CMD_L1D_FLUSH; 3137 vmx_vmwrite(VMCS_ENTRY_MSR_LOAD_ADDRESS, cpudata->gmsr_pa); 3138 vmx_vmwrite(VMCS_EXIT_MSR_STORE_ADDRESS, cpudata->gmsr_pa); 3139 vmx_vmwrite(VMCS_ENTRY_MSR_LOAD_COUNT, vmx_msrlist_entry_nmsr); 3140 vmx_vmwrite(VMCS_EXIT_MSR_STORE_COUNT, VMX_MSRLIST_EXIT_NMSR); 3141 3142 /* Set the CR0 mask. Any change of these bits causes a VMEXIT. */ 3143 vmx_vmwrite(VMCS_CR0_MASK, CR0_STATIC_MASK); 3144 3145 /* Force unsupported CR4 fields to zero. */ 3146 vmx_vmwrite(VMCS_CR4_MASK, CR4_INVALID); 3147 vmx_vmwrite(VMCS_CR4_SHADOW, 0); 3148 3149 /* Set the Host state for resuming. */ 3150 vmx_vmwrite(VMCS_HOST_RIP, (uint64_t)&vmx_resume_rip); 3151 vmx_vmwrite(VMCS_HOST_CS_SELECTOR, GSEL(GCODE_SEL, SEL_KPL)); 3152 vmx_vmwrite(VMCS_HOST_SS_SELECTOR, GSEL(GDATA_SEL, SEL_KPL)); 3153 vmx_vmwrite(VMCS_HOST_DS_SELECTOR, GSEL(GDATA_SEL, SEL_KPL)); 3154 vmx_vmwrite(VMCS_HOST_ES_SELECTOR, GSEL(GDATA_SEL, SEL_KPL)); 3155 vmx_vmwrite(VMCS_HOST_FS_SELECTOR, 0); 3156 vmx_vmwrite(VMCS_HOST_GS_SELECTOR, 0); 3157 vmx_vmwrite(VMCS_HOST_IA32_SYSENTER_CS, 0); 3158 vmx_vmwrite(VMCS_HOST_IA32_SYSENTER_ESP, 0); 3159 vmx_vmwrite(VMCS_HOST_IA32_SYSENTER_EIP, 0); 3160 vmx_vmwrite(VMCS_HOST_IA32_PAT, rdmsr(MSR_CR_PAT)); 3161 vmx_vmwrite(VMCS_HOST_IA32_EFER, rdmsr(MSR_EFER)); 3162 vmx_vmwrite(VMCS_HOST_CR0, rcr0() & ~CR0_TS); 3163 3164 /* Generate ASID. */ 3165 vmx_asid_alloc(vcpu); 3166 3167 /* Enable Extended Paging, 4-Level. */ 3168 eptp = 3169 __SHIFTIN(vmx_eptp_type, EPTP_TYPE) | 3170 __SHIFTIN(4-1, EPTP_WALKLEN) | 3171 (pmap_ept_has_ad ? EPTP_FLAGS_AD : 0) | 3172 mach->vm->vm_map.pmap->pm_pdirpa[0]; 3173 vmx_vmwrite(VMCS_EPTP, eptp); 3174 3175 /* Init IA32_MISC_ENABLE. */ 3176 cpudata->gmsr_misc_enable = rdmsr(MSR_MISC_ENABLE); 3177 cpudata->gmsr_misc_enable &= 3178 ~(IA32_MISC_PERFMON_EN|IA32_MISC_EISST_EN|IA32_MISC_MWAIT_EN); 3179 cpudata->gmsr_misc_enable |= 3180 (IA32_MISC_BTS_UNAVAIL|IA32_MISC_PEBS_UNAVAIL); 3181 3182 /* Init XSAVE header. */ 3183 cpudata->xcr0_mask = vmx_xcr0_mask; 3184 KASSERTMSG(nvmm_x86_xcr0_valid(cpudata->xcr0_mask, vmx_xcr0_mask), 3185 "cpudata->xcr0_mask=0x%"PRIx64" vmx_xcr0_mask=0x%"PRIx64, 3186 cpudata->xcr0_mask, vmx_xcr0_mask); 3187 cpudata->gfpu.xsh_xstate_bv = cpudata->xcr0_mask; 3188 cpudata->gfpu.xsh_xcomp_bv = 0; 3189 3190 /* These MSRs are static. */ 3191 cpudata->star = rdmsr(MSR_STAR); 3192 cpudata->lstar = rdmsr(MSR_LSTAR); 3193 cpudata->cstar = rdmsr(MSR_CSTAR); 3194 cpudata->sfmask = rdmsr(MSR_SFMASK); 3195 3196 /* Install the RESET state. */ 3197 memcpy(&vcpu->comm->state, &nvmm_x86_reset_state, 3198 sizeof(nvmm_x86_reset_state)); 3199 vcpu->comm->state_wanted = NVMM_X64_STATE_ALL; 3200 vcpu->comm->state_cached = 0; 3201 vmx_vcpu_setstate(vcpu); 3202 3203 vmx_vmcs_leave(vcpu); 3204 } 3205 3206 static int 3207 vmx_vcpu_create(struct nvmm_machine *mach, struct nvmm_cpu *vcpu) 3208 { 3209 size_t xsave_size, cpudata_size; 3210 struct vmx_cpudata *cpudata; 3211 int error; 3212 3213 /* 3214 * Compute the size of the VMX cpudata. We put the 3215 * variable-length XSAVE area at the end so if it's small 3216 * enough, it stays within a single page. We size the XSAVE 3217 * area for the maximum set of features supported by the CPU 3218 * which a guest can enable (which may be more than the NetBSD 3219 * host enables for itself -- hence we don't use 3220 * x86_fpu_save_size here!). 3221 */ 3222 xsave_size = nvmm_x86_xsave_size(vmx_xcr0_mask); 3223 KASSERT(xsave_size < SIZE_MAX - offsetof(struct vmx_cpudata, gfpu)); 3224 cpudata_size = MAX(sizeof(*cpudata), 3225 offsetof(struct vmx_cpudata, gfpu) + xsave_size); 3226 3227 /* Allocate the VMX cpudata. */ 3228 cpudata = (struct vmx_cpudata *)uvm_km_alloc(kernel_map, 3229 roundup(cpudata_size, PAGE_SIZE), 0, 3230 UVM_KMF_WIRED|UVM_KMF_ZERO); 3231 vcpu->cpudata = cpudata; 3232 3233 /* VMCS */ 3234 error = vmx_memalloc(&cpudata->vmcs_pa, (vaddr_t *)&cpudata->vmcs, 3235 VMCS_NPAGES); 3236 if (error) 3237 goto error; 3238 3239 /* MSR Bitmap */ 3240 error = vmx_memalloc(&cpudata->msrbm_pa, (vaddr_t *)&cpudata->msrbm, 3241 MSRBM_NPAGES); 3242 if (error) 3243 goto error; 3244 3245 /* Guest MSR List */ 3246 error = vmx_memalloc(&cpudata->gmsr_pa, (vaddr_t *)&cpudata->gmsr, 1); 3247 if (error) 3248 goto error; 3249 3250 kcpuset_create(&cpudata->htlb_want_flush, true); 3251 3252 /* Init the VCPU info. */ 3253 vmx_vcpu_init(mach, vcpu); 3254 3255 return 0; 3256 3257 error: 3258 if (cpudata->vmcs_pa) { 3259 vmx_memfree(cpudata->vmcs_pa, (vaddr_t)cpudata->vmcs, 3260 VMCS_NPAGES); 3261 } 3262 if (cpudata->msrbm_pa) { 3263 vmx_memfree(cpudata->msrbm_pa, (vaddr_t)cpudata->msrbm, 3264 MSRBM_NPAGES); 3265 } 3266 if (cpudata->gmsr_pa) { 3267 vmx_memfree(cpudata->gmsr_pa, (vaddr_t)cpudata->gmsr, 1); 3268 } 3269 3270 kmem_free(cpudata, sizeof(*cpudata)); 3271 return error; 3272 } 3273 3274 static void 3275 vmx_vcpu_destroy(struct nvmm_machine *mach, struct nvmm_cpu *vcpu) 3276 { 3277 struct vmx_cpudata *cpudata = vcpu->cpudata; 3278 3279 vmx_vmcs_enter(vcpu); 3280 vmx_asid_free(vcpu); 3281 vmx_vmcs_destroy(vcpu); 3282 3283 kcpuset_destroy(cpudata->htlb_want_flush); 3284 3285 vmx_memfree(cpudata->vmcs_pa, (vaddr_t)cpudata->vmcs, VMCS_NPAGES); 3286 vmx_memfree(cpudata->msrbm_pa, (vaddr_t)cpudata->msrbm, MSRBM_NPAGES); 3287 vmx_memfree(cpudata->gmsr_pa, (vaddr_t)cpudata->gmsr, 1); 3288 uvm_km_free(kernel_map, (vaddr_t)cpudata, 3289 roundup(sizeof(*cpudata), PAGE_SIZE), UVM_KMF_WIRED); 3290 } 3291 3292 /* -------------------------------------------------------------------------- */ 3293 3294 static int 3295 vmx_vcpu_configure_cpuid(struct vmx_cpudata *cpudata, void *data) 3296 { 3297 struct nvmm_vcpu_conf_cpuid *cpuid = data; 3298 size_t i; 3299 3300 if (__predict_false(cpuid->mask && cpuid->exit)) { 3301 return EINVAL; 3302 } 3303 if (__predict_false(cpuid->mask && 3304 ((cpuid->u.mask.set.eax & cpuid->u.mask.del.eax) || 3305 (cpuid->u.mask.set.ebx & cpuid->u.mask.del.ebx) || 3306 (cpuid->u.mask.set.ecx & cpuid->u.mask.del.ecx) || 3307 (cpuid->u.mask.set.edx & cpuid->u.mask.del.edx)))) { 3308 return EINVAL; 3309 } 3310 3311 /* If unset, delete, to restore the default behavior. */ 3312 if (!cpuid->mask && !cpuid->exit) { 3313 for (i = 0; i < VMX_NCPUIDS; i++) { 3314 if (!cpudata->cpuidpresent[i]) { 3315 continue; 3316 } 3317 if (cpudata->cpuid[i].leaf == cpuid->leaf) { 3318 cpudata->cpuidpresent[i] = false; 3319 } 3320 } 3321 return 0; 3322 } 3323 3324 /* If already here, replace. */ 3325 for (i = 0; i < VMX_NCPUIDS; i++) { 3326 if (!cpudata->cpuidpresent[i]) { 3327 continue; 3328 } 3329 if (cpudata->cpuid[i].leaf == cpuid->leaf) { 3330 memcpy(&cpudata->cpuid[i], cpuid, 3331 sizeof(struct nvmm_vcpu_conf_cpuid)); 3332 return 0; 3333 } 3334 } 3335 3336 /* Not here, insert. */ 3337 for (i = 0; i < VMX_NCPUIDS; i++) { 3338 if (!cpudata->cpuidpresent[i]) { 3339 cpudata->cpuidpresent[i] = true; 3340 memcpy(&cpudata->cpuid[i], cpuid, 3341 sizeof(struct nvmm_vcpu_conf_cpuid)); 3342 return 0; 3343 } 3344 } 3345 3346 return ENOBUFS; 3347 } 3348 3349 static int 3350 vmx_vcpu_configure_tpr(struct vmx_cpudata *cpudata, void *data) 3351 { 3352 struct nvmm_vcpu_conf_tpr *tpr = data; 3353 3354 memcpy(&cpudata->tpr, tpr, sizeof(*tpr)); 3355 return 0; 3356 } 3357 3358 static int 3359 vmx_vcpu_configure_xcr0_mask(struct vmx_cpudata *cpudata, void *data) 3360 { 3361 const uint64_t *xcr0_maskp = data; 3362 3363 /* 3364 * Refuse to enable XCR0 bits (extended CPU state components) 3365 * not supported by this system, or to set up otherwise 3366 * nonsensical masks like AVX (YMM_Hi128) but not SSE (XMM) 3367 * registers. Exception: The mask can be all-zero to disable 3368 * all XSAVE state components. 3369 */ 3370 if (*xcr0_maskp != 0 && 3371 !nvmm_x86_xcr0_valid(*xcr0_maskp, vmx_xcr0_mask)) 3372 return EINVAL; 3373 3374 /* 3375 * Out of paranoia, clear any existing extended CPU state. 3376 * This operation is unlikely to be used before the guest has 3377 * begun execution at all, so the extended CPU state is 3378 * probably all zero. But in case some weird hypervisor 3379 * software tries to change the XCR0 mask dynamically, let's 3380 * avoid accidentally leaking things through any extended CPU 3381 * state. 3382 * 3383 * We could zero only the components that are getting disabled. 3384 * But if the saved state is compated (XSAVEC), we wouldd also 3385 * have to move the remaining components around in order to 3386 * avoid zeroing them. Since no software is likely to try this 3387 * anyway, we'll just zero everything to keep it simple and 3388 * avoid having to test the difficult-and-unused paths. 3389 */ 3390 memset(&cpudata->gfpu, 0, nvmm_x86_xsave_size(vmx_xcr0_mask)); 3391 3392 /* 3393 * Set the XCR0 mask, and limit the guest's XCR0 to this mask. 3394 * Any extended CPU state the guest had previously been using 3395 * will be wiped out. 3396 */ 3397 cpudata->xcr0_mask = *xcr0_maskp; 3398 cpudata->gxcr0 &= cpudata->xcr0_mask; 3399 KASSERTMSG((cpudata->xcr0_mask == 0 || 3400 nvmm_x86_xcr0_valid(cpudata->gxcr0, cpudata->xcr0_mask)), 3401 "gxcr0=0x%"PRIx64" xcr0_mask=0x%"PRIx64, 3402 cpudata->gxcr0, cpudata->xcr0_mask); 3403 return 0; 3404 } 3405 3406 static int 3407 vmx_vcpu_configure(struct nvmm_cpu *vcpu, uint64_t op, void *data) 3408 { 3409 struct vmx_cpudata *cpudata = vcpu->cpudata; 3410 3411 switch (op) { 3412 case NVMM_VCPU_CONF_MD(NVMM_VCPU_CONF_CPUID): 3413 return vmx_vcpu_configure_cpuid(cpudata, data); 3414 case NVMM_VCPU_CONF_MD(NVMM_VCPU_CONF_TPR): 3415 return vmx_vcpu_configure_tpr(cpudata, data); 3416 case NVMM_VCPU_CONF_MD(NVMM_VCPU_CONF_XCR0_MASK): 3417 return vmx_vcpu_configure_xcr0_mask(cpudata, data); 3418 default: 3419 return EINVAL; 3420 } 3421 } 3422 3423 static void 3424 vmx_vcpu_suspend(struct nvmm_machine *mach, struct nvmm_cpu *vcpu) 3425 { 3426 struct vmx_cpudata *cpudata = vcpu->cpudata; 3427 struct cpu_info *vmcs_ci; 3428 3429 KASSERT(cpudata->vmcs_refcnt == 0); 3430 3431 vmcs_ci = cpudata->vmcs_ci; 3432 cpudata->vmcs_ci = (void *)0x00FFFFFFFFFFFFFF; /* clobber */ 3433 3434 kpreempt_disable(); 3435 if (vmcs_ci == NULL) { 3436 /* VMCS is inactive, nothing to do. */ 3437 } else if (vmcs_ci != curcpu()) { 3438 /* VMCS is active on a remote CPU; clear it there. */ 3439 vmx_vmclear_remote(vmcs_ci, cpudata->vmcs_pa); 3440 } else { 3441 /* VMCS is active on this CPU; clear it here. */ 3442 vmx_vmclear(&cpudata->vmcs_pa); 3443 } 3444 kpreempt_enable(); 3445 } 3446 3447 static void 3448 vmx_vcpu_resume(struct nvmm_machine *mach, struct nvmm_cpu *vcpu) 3449 { 3450 struct vmx_cpudata *cpudata = vcpu->cpudata; 3451 3452 KASSERT(cpudata->vmcs_refcnt == 0); 3453 3454 /* Mark VMCS as inactive. */ 3455 cpudata->vmcs_ci = NULL; 3456 } 3457 3458 /* -------------------------------------------------------------------------- */ 3459 3460 static void 3461 vmx_tlb_flush(struct pmap *pm) 3462 { 3463 struct nvmm_machine *mach = pm->pm_data; 3464 struct vmx_machdata *machdata = mach->machdata; 3465 3466 atomic_inc_64(&machdata->mach_htlb_gen); 3467 3468 /* Generates IPIs, which cause #VMEXITs. */ 3469 pmap_tlb_shootdown(pmap_kernel(), -1, PTE_G, TLBSHOOT_NVMM); 3470 } 3471 3472 static void 3473 vmx_machine_create(struct nvmm_machine *mach) 3474 { 3475 struct pmap *pmap = mach->vm->vm_map.pmap; 3476 struct vmx_machdata *machdata; 3477 3478 /* Convert to EPT. */ 3479 pmap_ept_transform(pmap); 3480 3481 /* Fill in pmap info. */ 3482 pmap->pm_data = (void *)mach; 3483 pmap->pm_tlb_flush = vmx_tlb_flush; 3484 3485 machdata = kmem_zalloc(sizeof(struct vmx_machdata), KM_SLEEP); 3486 mach->machdata = machdata; 3487 3488 /* Start with an hTLB flush everywhere. */ 3489 machdata->mach_htlb_gen = 1; 3490 } 3491 3492 static void 3493 vmx_machine_destroy(struct nvmm_machine *mach) 3494 { 3495 struct vmx_machdata *machdata = mach->machdata; 3496 3497 kmem_free(machdata, sizeof(struct vmx_machdata)); 3498 } 3499 3500 static int 3501 vmx_machine_configure(struct nvmm_machine *mach, uint64_t op, void *data) 3502 { 3503 panic("%s: impossible", __func__); 3504 } 3505 3506 /* -------------------------------------------------------------------------- */ 3507 3508 #define CTLS_ONE_ALLOWED(msrval, bitoff) \ 3509 ((msrval & __BIT(32 + bitoff)) != 0) 3510 #define CTLS_ZERO_ALLOWED(msrval, bitoff) \ 3511 ((msrval & __BIT(bitoff)) == 0) 3512 3513 static int 3514 vmx_check_ctls(uint64_t msr_ctls, uint64_t msr_true_ctls, uint64_t set_one) 3515 { 3516 uint64_t basic, val, true_val; 3517 bool has_true; 3518 size_t i; 3519 3520 basic = rdmsr(MSR_IA32_VMX_BASIC); 3521 has_true = (basic & IA32_VMX_BASIC_TRUE_CTLS) != 0; 3522 3523 val = rdmsr(msr_ctls); 3524 if (has_true) { 3525 true_val = rdmsr(msr_true_ctls); 3526 } else { 3527 true_val = val; 3528 } 3529 3530 for (i = 0; i < 32; i++) { 3531 if (!(set_one & __BIT(i))) { 3532 continue; 3533 } 3534 if (!CTLS_ONE_ALLOWED(true_val, i)) { 3535 return -1; 3536 } 3537 } 3538 3539 return 0; 3540 } 3541 3542 static int 3543 vmx_init_ctls(uint64_t msr_ctls, uint64_t msr_true_ctls, 3544 uint64_t set_one, uint64_t set_zero, uint64_t *res) 3545 { 3546 uint64_t basic, val, true_val; 3547 bool one_allowed, zero_allowed, has_true; 3548 size_t i; 3549 3550 basic = rdmsr(MSR_IA32_VMX_BASIC); 3551 has_true = (basic & IA32_VMX_BASIC_TRUE_CTLS) != 0; 3552 3553 val = rdmsr(msr_ctls); 3554 if (has_true) { 3555 true_val = rdmsr(msr_true_ctls); 3556 } else { 3557 true_val = val; 3558 } 3559 3560 for (i = 0; i < 32; i++) { 3561 one_allowed = CTLS_ONE_ALLOWED(true_val, i); 3562 zero_allowed = CTLS_ZERO_ALLOWED(true_val, i); 3563 3564 if (zero_allowed && !one_allowed) { 3565 if (set_one & __BIT(i)) 3566 return -1; 3567 *res &= ~__BIT(i); 3568 } else if (one_allowed && !zero_allowed) { 3569 if (set_zero & __BIT(i)) 3570 return -1; 3571 *res |= __BIT(i); 3572 } else { 3573 if (set_zero & __BIT(i)) { 3574 *res &= ~__BIT(i); 3575 } else if (set_one & __BIT(i)) { 3576 *res |= __BIT(i); 3577 } else if (!has_true) { 3578 *res &= ~__BIT(i); 3579 } else if (CTLS_ZERO_ALLOWED(val, i)) { 3580 *res &= ~__BIT(i); 3581 } else if (CTLS_ONE_ALLOWED(val, i)) { 3582 *res |= __BIT(i); 3583 } else { 3584 return -1; 3585 } 3586 } 3587 } 3588 3589 return 0; 3590 } 3591 3592 static bool 3593 vmx_ident(void) 3594 { 3595 uint64_t msr; 3596 int ret; 3597 3598 if (!(cpu_feature[1] & CPUID2_VMX)) { 3599 return false; 3600 } 3601 3602 msr = rdmsr(MSR_IA32_FEATURE_CONTROL); 3603 if ((msr & IA32_FEATURE_CONTROL_LOCK) != 0 && 3604 (msr & IA32_FEATURE_CONTROL_OUT_SMX) == 0) { 3605 printf("NVMM: VMX disabled in BIOS\n"); 3606 return false; 3607 } 3608 3609 msr = rdmsr(MSR_IA32_VMX_BASIC); 3610 if ((msr & IA32_VMX_BASIC_IO_REPORT) == 0) { 3611 printf("NVMM: I/O reporting not supported\n"); 3612 return false; 3613 } 3614 if (__SHIFTOUT(msr, IA32_VMX_BASIC_MEM_TYPE) != MEM_TYPE_WB) { 3615 printf("NVMM: WB memory not supported\n"); 3616 return false; 3617 } 3618 3619 /* PG and PE are reported, even if Unrestricted Guests is supported. */ 3620 vmx_cr0_fixed0 = rdmsr(MSR_IA32_VMX_CR0_FIXED0) & ~(CR0_PG|CR0_PE); 3621 vmx_cr0_fixed1 = rdmsr(MSR_IA32_VMX_CR0_FIXED1) | (CR0_PG|CR0_PE); 3622 ret = vmx_check_cr(rcr0(), vmx_cr0_fixed0, vmx_cr0_fixed1); 3623 if (ret == -1) { 3624 printf("NVMM: CR0 requirements not satisfied\n"); 3625 return false; 3626 } 3627 3628 vmx_cr4_fixed0 = rdmsr(MSR_IA32_VMX_CR4_FIXED0); 3629 vmx_cr4_fixed1 = rdmsr(MSR_IA32_VMX_CR4_FIXED1); 3630 ret = vmx_check_cr(rcr4() | CR4_VMXE, vmx_cr4_fixed0, vmx_cr4_fixed1); 3631 if (ret == -1) { 3632 printf("NVMM: CR4 requirements not satisfied\n"); 3633 return false; 3634 } 3635 3636 /* Init the CTLSs right now, and check for errors. */ 3637 ret = vmx_init_ctls( 3638 MSR_IA32_VMX_PINBASED_CTLS, MSR_IA32_VMX_TRUE_PINBASED_CTLS, 3639 VMX_PINBASED_CTLS_ONE, VMX_PINBASED_CTLS_ZERO, 3640 &vmx_pinbased_ctls); 3641 if (ret == -1) { 3642 printf("NVMM: pin-based-ctls requirements not satisfied\n"); 3643 return false; 3644 } 3645 ret = vmx_init_ctls( 3646 MSR_IA32_VMX_PROCBASED_CTLS, MSR_IA32_VMX_TRUE_PROCBASED_CTLS, 3647 VMX_PROCBASED_CTLS_ONE, VMX_PROCBASED_CTLS_ZERO, 3648 &vmx_procbased_ctls); 3649 if (ret == -1) { 3650 printf("NVMM: proc-based-ctls requirements not satisfied\n"); 3651 return false; 3652 } 3653 ret = vmx_init_ctls( 3654 MSR_IA32_VMX_PROCBASED_CTLS2, MSR_IA32_VMX_PROCBASED_CTLS2, 3655 VMX_PROCBASED_CTLS2_ONE, VMX_PROCBASED_CTLS2_ZERO, 3656 &vmx_procbased_ctls2); 3657 if (ret == -1) { 3658 printf("NVMM: proc-based-ctls2 requirements not satisfied\n"); 3659 return false; 3660 } 3661 ret = vmx_check_ctls( 3662 MSR_IA32_VMX_PROCBASED_CTLS2, MSR_IA32_VMX_PROCBASED_CTLS2, 3663 PROC_CTLS2_INVPCID_ENABLE); 3664 if (ret != -1) { 3665 vmx_procbased_ctls2 |= PROC_CTLS2_INVPCID_ENABLE; 3666 } 3667 ret = vmx_init_ctls( 3668 MSR_IA32_VMX_ENTRY_CTLS, MSR_IA32_VMX_TRUE_ENTRY_CTLS, 3669 VMX_ENTRY_CTLS_ONE, VMX_ENTRY_CTLS_ZERO, 3670 &vmx_entry_ctls); 3671 if (ret == -1) { 3672 printf("NVMM: entry-ctls requirements not satisfied\n"); 3673 return false; 3674 } 3675 ret = vmx_init_ctls( 3676 MSR_IA32_VMX_EXIT_CTLS, MSR_IA32_VMX_TRUE_EXIT_CTLS, 3677 VMX_EXIT_CTLS_ONE, VMX_EXIT_CTLS_ZERO, 3678 &vmx_exit_ctls); 3679 if (ret == -1) { 3680 printf("NVMM: exit-ctls requirements not satisfied\n"); 3681 return false; 3682 } 3683 3684 msr = rdmsr(MSR_IA32_VMX_EPT_VPID_CAP); 3685 if ((msr & IA32_VMX_EPT_VPID_WALKLENGTH_4) == 0) { 3686 printf("NVMM: 4-level page tree not supported\n"); 3687 return false; 3688 } 3689 if ((msr & IA32_VMX_EPT_VPID_INVEPT) == 0) { 3690 printf("NVMM: INVEPT not supported\n"); 3691 return false; 3692 } 3693 if ((msr & IA32_VMX_EPT_VPID_INVVPID) == 0) { 3694 printf("NVMM: INVVPID not supported\n"); 3695 return false; 3696 } 3697 if ((msr & IA32_VMX_EPT_VPID_FLAGS_AD) != 0) { 3698 pmap_ept_has_ad = true; 3699 } else { 3700 pmap_ept_has_ad = false; 3701 } 3702 if (!(msr & IA32_VMX_EPT_VPID_UC) && !(msr & IA32_VMX_EPT_VPID_WB)) { 3703 printf("NVMM: EPT UC/WB memory types not supported\n"); 3704 return false; 3705 } 3706 3707 return true; 3708 } 3709 3710 static void 3711 vmx_init_asid(uint32_t maxasid) 3712 { 3713 size_t allocsz; 3714 3715 mutex_init(&vmx_asidlock, MUTEX_DEFAULT, IPL_NONE); 3716 3717 vmx_maxasid = maxasid; 3718 allocsz = roundup(maxasid, 8) / 8; 3719 vmx_asidmap = kmem_zalloc(allocsz, KM_SLEEP); 3720 3721 /* ASID 0 is reserved for the host. */ 3722 vmx_asidmap[0] |= __BIT(0); 3723 } 3724 3725 static void 3726 vmx_change_cpu(void *arg1, void *arg2) 3727 { 3728 struct cpu_info *ci = curcpu(); 3729 bool enable = arg1 != NULL; 3730 uint64_t msr, cr4; 3731 3732 if (enable) { 3733 msr = rdmsr(MSR_IA32_FEATURE_CONTROL); 3734 if ((msr & IA32_FEATURE_CONTROL_LOCK) == 0) { 3735 /* Lock now, with VMX-outside-SMX enabled. */ 3736 wrmsr(MSR_IA32_FEATURE_CONTROL, msr | 3737 IA32_FEATURE_CONTROL_LOCK | 3738 IA32_FEATURE_CONTROL_OUT_SMX); 3739 } 3740 } 3741 3742 if (!enable) { 3743 vmx_vmxoff(); 3744 } 3745 3746 cr4 = rcr4(); 3747 if (enable) { 3748 cr4 |= CR4_VMXE; 3749 } else { 3750 cr4 &= ~CR4_VMXE; 3751 } 3752 lcr4(cr4); 3753 3754 if (enable) { 3755 vmx_vmxon(&vmxoncpu[cpu_index(ci)].pa); 3756 } 3757 } 3758 3759 static void 3760 vmx_init_l1tf(void) 3761 { 3762 u_int descs[4]; 3763 uint64_t msr; 3764 3765 if (cpuid_level < 7) { 3766 return; 3767 } 3768 3769 x86_cpuid(7, descs); 3770 3771 if (descs[3] & CPUID_SEF_ARCH_CAP) { 3772 msr = rdmsr(MSR_IA32_ARCH_CAPABILITIES); 3773 if (msr & IA32_ARCH_SKIP_L1DFL_VMENTRY) { 3774 /* No mitigation needed. */ 3775 return; 3776 } 3777 } 3778 3779 if (descs[3] & CPUID_SEF_L1D_FLUSH) { 3780 /* Enable hardware mitigation. */ 3781 vmx_msrlist_entry_nmsr += 1; 3782 } 3783 } 3784 3785 static void 3786 vmx_suspend_interrupt(void) 3787 { 3788 3789 /* 3790 * Generates IPIs, which cause #VMEXITs. No other purpose for 3791 * the TLB business; the #VMEXIT triggered by IPI is the only 3792 * effect that matters here. 3793 */ 3794 pmap_tlb_shootdown(pmap_kernel(), -1, PTE_G, TLBSHOOT_NVMM); 3795 } 3796 3797 static void 3798 vmx_suspend(void) 3799 { 3800 uint64_t xc; 3801 3802 xc = xc_broadcast(0, vmx_change_cpu, (void *)false, NULL); 3803 xc_wait(xc); 3804 } 3805 3806 static void 3807 vmx_resume(void) 3808 { 3809 uint64_t xc; 3810 3811 xc = xc_broadcast(0, vmx_change_cpu, (void *)true, NULL); 3812 xc_wait(xc); 3813 } 3814 3815 static void 3816 vmx_init(void) 3817 { 3818 CPU_INFO_ITERATOR cii; 3819 struct cpu_info *ci; 3820 uint64_t msr; 3821 struct vmxon *vmxon; 3822 uint32_t revision; 3823 u_int descs[4]; 3824 paddr_t pa; 3825 vaddr_t va; 3826 int error; 3827 3828 /* Init the ASID bitmap (VPID). */ 3829 vmx_init_asid(VPID_MAX); 3830 3831 /* 3832 * Init the XCR0 mask. 3833 * 3834 * x86_xsave_features is the cached result of 3835 * CPUID[EAX=0x0000000d,ECX=0].EDX:EAX, the set of all 3836 * supported XCR0 bits for user XSAVE state components on the 3837 * physical CPU. Hypervisor software can use 3838 * nvmm_vcpu_configure(NVMM_VCPU_CONF_XCR0_MASK) to restrict 3839 * the available features on a per-vCPU basis, e.g. in order to 3840 * limit guests to compatible features for migration. 3841 * 3842 * Out of paranoia, we mask off bit 63 which is reserved for 3843 * future extension which we don't understand because it's not 3844 * yet defined. 3845 */ 3846 vmx_xcr0_mask = x86_xsave_features & __BITS(62, 0); 3847 KASSERTMSG((vmx_xcr0_mask == 0 || 3848 nvmm_x86_xcr0_valid(vmx_xcr0_mask, vmx_xcr0_mask)), 3849 "vmx_xcr0_mask=0x%"PRIx64, vmx_xcr0_mask); 3850 3851 /* Init the max basic CPUID leaf. */ 3852 vmx_cpuid_max_basic = uimin(cpuid_level, VMX_CPUID_MAX_BASIC); 3853 3854 /* Init the max extended CPUID leaf. */ 3855 x86_cpuid(0x80000000, descs); 3856 vmx_cpuid_max_extended = uimin(descs[0], VMX_CPUID_MAX_EXTENDED); 3857 3858 /* Init the TLB flush op, the EPT flush op and the EPTP type. */ 3859 msr = rdmsr(MSR_IA32_VMX_EPT_VPID_CAP); 3860 if ((msr & IA32_VMX_EPT_VPID_INVVPID_CONTEXT) != 0) { 3861 vmx_tlb_flush_op = VMX_INVVPID_CONTEXT; 3862 } else { 3863 vmx_tlb_flush_op = VMX_INVVPID_ALL; 3864 } 3865 if ((msr & IA32_VMX_EPT_VPID_INVEPT_CONTEXT) != 0) { 3866 vmx_ept_flush_op = VMX_INVEPT_CONTEXT; 3867 } else { 3868 vmx_ept_flush_op = VMX_INVEPT_ALL; 3869 } 3870 if ((msr & IA32_VMX_EPT_VPID_WB) != 0) { 3871 vmx_eptp_type = EPTP_TYPE_WB; 3872 } else { 3873 vmx_eptp_type = EPTP_TYPE_UC; 3874 } 3875 3876 /* Init the L1TF mitigation. */ 3877 vmx_init_l1tf(); 3878 3879 memset(vmxoncpu, 0, sizeof(vmxoncpu)); 3880 revision = vmx_get_revision(); 3881 3882 for (CPU_INFO_FOREACH(cii, ci)) { 3883 error = vmx_memalloc(&pa, &va, 1); 3884 if (error) { 3885 panic("%s: out of memory", __func__); 3886 } 3887 vmxoncpu[cpu_index(ci)].pa = pa; 3888 vmxoncpu[cpu_index(ci)].va = va; 3889 3890 vmxon = (struct vmxon *)vmxoncpu[cpu_index(ci)].va; 3891 vmxon->ident = __SHIFTIN(revision, VMXON_IDENT_REVISION); 3892 } 3893 3894 vmx_resume(); 3895 } 3896 3897 static void 3898 vmx_fini_asid(void) 3899 { 3900 size_t allocsz; 3901 3902 allocsz = roundup(vmx_maxasid, 8) / 8; 3903 kmem_free(vmx_asidmap, allocsz); 3904 3905 mutex_destroy(&vmx_asidlock); 3906 } 3907 3908 static void 3909 vmx_fini(void) 3910 { 3911 size_t i; 3912 3913 vmx_suspend(); 3914 3915 for (i = 0; i < MAXCPUS; i++) { 3916 if (vmxoncpu[i].pa != 0) 3917 vmx_memfree(vmxoncpu[i].pa, vmxoncpu[i].va, 1); 3918 } 3919 3920 vmx_fini_asid(); 3921 } 3922 3923 static void 3924 vmx_capability(struct nvmm_capability *cap) 3925 { 3926 cap->arch.mach_conf_support = 0; 3927 cap->arch.vcpu_conf_support = 3928 NVMM_CAP_ARCH_VCPU_CONF_CPUID | 3929 NVMM_CAP_ARCH_VCPU_CONF_TPR; 3930 cap->arch.xcr0_mask = vmx_xcr0_mask; 3931 cap->arch.mxcsr_mask = x86_fpu_mxcsr_mask; 3932 cap->arch.conf_cpuid_maxops = VMX_NCPUIDS; 3933 } 3934 3935 const struct nvmm_impl nvmm_x86_vmx = { 3936 .name = "x86-vmx", 3937 .ident = vmx_ident, 3938 .init = vmx_init, 3939 .fini = vmx_fini, 3940 .suspend_interrupt = vmx_suspend_interrupt, 3941 .suspend = vmx_suspend, 3942 .resume = vmx_resume, 3943 .capability = vmx_capability, 3944 .mach_conf_max = NVMM_X86_MACH_NCONF, 3945 .mach_conf_sizes = NULL, 3946 .vcpu_conf_max = NVMM_X86_VCPU_NCONF, 3947 .vcpu_conf_sizes = vmx_vcpu_conf_sizes, 3948 .state_size = sizeof(struct nvmm_x64_state), 3949 .machine_create = vmx_machine_create, 3950 .machine_destroy = vmx_machine_destroy, 3951 .machine_configure = vmx_machine_configure, 3952 .vcpu_create = vmx_vcpu_create, 3953 .vcpu_destroy = vmx_vcpu_destroy, 3954 .vcpu_configure = vmx_vcpu_configure, 3955 .vcpu_setstate = vmx_vcpu_setstate, 3956 .vcpu_getstate = vmx_vcpu_getstate, 3957 .vcpu_inject = vmx_vcpu_inject, 3958 .vcpu_run = vmx_vcpu_run, 3959 .vcpu_suspend = vmx_vcpu_suspend, 3960 .vcpu_resume = vmx_vcpu_resume, 3961 }; 3962