1 1.23 msaitoh /* $NetBSD: nvmm_x86.c,v 1.23 2022/10/06 00:22:16 msaitoh Exp $ */ 2 1.1 maxv 3 1.1 maxv /* 4 1.17 maxv * Copyright (c) 2018-2020 Maxime Villard, m00nbsd.net 5 1.1 maxv * All rights reserved. 6 1.1 maxv * 7 1.17 maxv * This code is part of the NVMM hypervisor. 8 1.1 maxv * 9 1.1 maxv * Redistribution and use in source and binary forms, with or without 10 1.1 maxv * modification, are permitted provided that the following conditions 11 1.1 maxv * are met: 12 1.1 maxv * 1. Redistributions of source code must retain the above copyright 13 1.1 maxv * notice, this list of conditions and the following disclaimer. 14 1.1 maxv * 2. Redistributions in binary form must reproduce the above copyright 15 1.1 maxv * notice, this list of conditions and the following disclaimer in the 16 1.1 maxv * documentation and/or other materials provided with the distribution. 17 1.1 maxv * 18 1.17 maxv * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 1.17 maxv * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 1.17 maxv * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 1.17 maxv * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 1.17 maxv * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 23 1.17 maxv * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 1.17 maxv * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 25 1.17 maxv * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 1.17 maxv * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 1.17 maxv * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 1.17 maxv * SUCH DAMAGE. 29 1.1 maxv */ 30 1.1 maxv 31 1.1 maxv #include <sys/cdefs.h> 32 1.23 msaitoh __KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.23 2022/10/06 00:22:16 msaitoh Exp $"); 33 1.1 maxv 34 1.1 maxv #include <sys/param.h> 35 1.1 maxv #include <sys/systm.h> 36 1.1 maxv #include <sys/kernel.h> 37 1.1 maxv #include <sys/cpu.h> 38 1.1 maxv 39 1.20 riastrad #include <uvm/uvm_extern.h> 40 1.20 riastrad 41 1.1 maxv #include <x86/cputypes.h> 42 1.22 riastrad #include <x86/pat.h> 43 1.1 maxv #include <x86/specialreg.h> 44 1.1 maxv 45 1.1 maxv #include <dev/nvmm/nvmm.h> 46 1.1 maxv #include <dev/nvmm/nvmm_internal.h> 47 1.1 maxv #include <dev/nvmm/x86/nvmm_x86.h> 48 1.1 maxv 49 1.1 maxv /* 50 1.1 maxv * Code shared between x86-SVM and x86-VMX. 51 1.1 maxv */ 52 1.1 maxv 53 1.1 maxv const struct nvmm_x64_state nvmm_x86_reset_state = { 54 1.1 maxv .segs = { 55 1.2 maxv [NVMM_X64_SEG_ES] = { 56 1.2 maxv .selector = 0x0000, 57 1.2 maxv .base = 0x00000000, 58 1.2 maxv .limit = 0xFFFF, 59 1.2 maxv .attrib = { 60 1.2 maxv .type = 3, 61 1.2 maxv .s = 1, 62 1.2 maxv .p = 1, 63 1.2 maxv } 64 1.2 maxv }, 65 1.1 maxv [NVMM_X64_SEG_CS] = { 66 1.1 maxv .selector = 0xF000, 67 1.1 maxv .base = 0xFFFF0000, 68 1.1 maxv .limit = 0xFFFF, 69 1.1 maxv .attrib = { 70 1.2 maxv .type = 3, 71 1.2 maxv .s = 1, 72 1.1 maxv .p = 1, 73 1.1 maxv } 74 1.1 maxv }, 75 1.2 maxv [NVMM_X64_SEG_SS] = { 76 1.1 maxv .selector = 0x0000, 77 1.1 maxv .base = 0x00000000, 78 1.1 maxv .limit = 0xFFFF, 79 1.1 maxv .attrib = { 80 1.2 maxv .type = 3, 81 1.2 maxv .s = 1, 82 1.1 maxv .p = 1, 83 1.1 maxv } 84 1.1 maxv }, 85 1.2 maxv [NVMM_X64_SEG_DS] = { 86 1.1 maxv .selector = 0x0000, 87 1.1 maxv .base = 0x00000000, 88 1.1 maxv .limit = 0xFFFF, 89 1.1 maxv .attrib = { 90 1.2 maxv .type = 3, 91 1.2 maxv .s = 1, 92 1.1 maxv .p = 1, 93 1.1 maxv } 94 1.1 maxv }, 95 1.1 maxv [NVMM_X64_SEG_FS] = { 96 1.1 maxv .selector = 0x0000, 97 1.1 maxv .base = 0x00000000, 98 1.1 maxv .limit = 0xFFFF, 99 1.1 maxv .attrib = { 100 1.2 maxv .type = 3, 101 1.2 maxv .s = 1, 102 1.1 maxv .p = 1, 103 1.1 maxv } 104 1.1 maxv }, 105 1.1 maxv [NVMM_X64_SEG_GS] = { 106 1.1 maxv .selector = 0x0000, 107 1.1 maxv .base = 0x00000000, 108 1.1 maxv .limit = 0xFFFF, 109 1.1 maxv .attrib = { 110 1.2 maxv .type = 3, 111 1.2 maxv .s = 1, 112 1.1 maxv .p = 1, 113 1.1 maxv } 114 1.1 maxv }, 115 1.1 maxv [NVMM_X64_SEG_GDT] = { 116 1.1 maxv .selector = 0x0000, 117 1.1 maxv .base = 0x00000000, 118 1.1 maxv .limit = 0xFFFF, 119 1.1 maxv .attrib = { 120 1.2 maxv .type = 2, 121 1.2 maxv .s = 1, 122 1.1 maxv .p = 1, 123 1.1 maxv } 124 1.1 maxv }, 125 1.1 maxv [NVMM_X64_SEG_IDT] = { 126 1.1 maxv .selector = 0x0000, 127 1.1 maxv .base = 0x00000000, 128 1.1 maxv .limit = 0xFFFF, 129 1.1 maxv .attrib = { 130 1.2 maxv .type = 2, 131 1.2 maxv .s = 1, 132 1.1 maxv .p = 1, 133 1.1 maxv } 134 1.1 maxv }, 135 1.1 maxv [NVMM_X64_SEG_LDT] = { 136 1.1 maxv .selector = 0x0000, 137 1.1 maxv .base = 0x00000000, 138 1.1 maxv .limit = 0xFFFF, 139 1.1 maxv .attrib = { 140 1.1 maxv .type = SDT_SYSLDT, 141 1.2 maxv .s = 0, 142 1.1 maxv .p = 1, 143 1.1 maxv } 144 1.1 maxv }, 145 1.1 maxv [NVMM_X64_SEG_TR] = { 146 1.1 maxv .selector = 0x0000, 147 1.1 maxv .base = 0x00000000, 148 1.1 maxv .limit = 0xFFFF, 149 1.1 maxv .attrib = { 150 1.1 maxv .type = SDT_SYS286BSY, 151 1.2 maxv .s = 0, 152 1.1 maxv .p = 1, 153 1.1 maxv } 154 1.1 maxv }, 155 1.1 maxv }, 156 1.1 maxv 157 1.1 maxv .gprs = { 158 1.1 maxv [NVMM_X64_GPR_RAX] = 0x00000000, 159 1.1 maxv [NVMM_X64_GPR_RCX] = 0x00000000, 160 1.1 maxv [NVMM_X64_GPR_RDX] = 0x00000600, 161 1.1 maxv [NVMM_X64_GPR_RBX] = 0x00000000, 162 1.1 maxv [NVMM_X64_GPR_RSP] = 0x00000000, 163 1.1 maxv [NVMM_X64_GPR_RBP] = 0x00000000, 164 1.1 maxv [NVMM_X64_GPR_RSI] = 0x00000000, 165 1.1 maxv [NVMM_X64_GPR_RDI] = 0x00000000, 166 1.1 maxv [NVMM_X64_GPR_R8] = 0x00000000, 167 1.1 maxv [NVMM_X64_GPR_R9] = 0x00000000, 168 1.1 maxv [NVMM_X64_GPR_R10] = 0x00000000, 169 1.1 maxv [NVMM_X64_GPR_R11] = 0x00000000, 170 1.1 maxv [NVMM_X64_GPR_R12] = 0x00000000, 171 1.1 maxv [NVMM_X64_GPR_R13] = 0x00000000, 172 1.1 maxv [NVMM_X64_GPR_R14] = 0x00000000, 173 1.1 maxv [NVMM_X64_GPR_R15] = 0x00000000, 174 1.1 maxv [NVMM_X64_GPR_RIP] = 0x0000FFF0, 175 1.1 maxv [NVMM_X64_GPR_RFLAGS] = 0x00000002, 176 1.1 maxv }, 177 1.1 maxv 178 1.1 maxv .crs = { 179 1.1 maxv [NVMM_X64_CR_CR0] = 0x60000010, 180 1.1 maxv [NVMM_X64_CR_CR2] = 0x00000000, 181 1.1 maxv [NVMM_X64_CR_CR3] = 0x00000000, 182 1.1 maxv [NVMM_X64_CR_CR4] = 0x00000000, 183 1.1 maxv [NVMM_X64_CR_CR8] = 0x00000000, 184 1.1 maxv [NVMM_X64_CR_XCR0] = 0x00000001, 185 1.1 maxv }, 186 1.1 maxv 187 1.1 maxv .drs = { 188 1.1 maxv [NVMM_X64_DR_DR0] = 0x00000000, 189 1.1 maxv [NVMM_X64_DR_DR1] = 0x00000000, 190 1.1 maxv [NVMM_X64_DR_DR2] = 0x00000000, 191 1.1 maxv [NVMM_X64_DR_DR3] = 0x00000000, 192 1.1 maxv [NVMM_X64_DR_DR6] = 0xFFFF0FF0, 193 1.1 maxv [NVMM_X64_DR_DR7] = 0x00000400, 194 1.1 maxv }, 195 1.1 maxv 196 1.1 maxv .msrs = { 197 1.1 maxv [NVMM_X64_MSR_EFER] = 0x00000000, 198 1.1 maxv [NVMM_X64_MSR_STAR] = 0x00000000, 199 1.1 maxv [NVMM_X64_MSR_LSTAR] = 0x00000000, 200 1.1 maxv [NVMM_X64_MSR_CSTAR] = 0x00000000, 201 1.1 maxv [NVMM_X64_MSR_SFMASK] = 0x00000000, 202 1.1 maxv [NVMM_X64_MSR_KERNELGSBASE] = 0x00000000, 203 1.1 maxv [NVMM_X64_MSR_SYSENTER_CS] = 0x00000000, 204 1.1 maxv [NVMM_X64_MSR_SYSENTER_ESP] = 0x00000000, 205 1.1 maxv [NVMM_X64_MSR_SYSENTER_EIP] = 0x00000000, 206 1.1 maxv [NVMM_X64_MSR_PAT] = 207 1.1 maxv PATENTRY(0, PAT_WB) | PATENTRY(1, PAT_WT) | 208 1.1 maxv PATENTRY(2, PAT_UCMINUS) | PATENTRY(3, PAT_UC) | 209 1.1 maxv PATENTRY(4, PAT_WB) | PATENTRY(5, PAT_WT) | 210 1.1 maxv PATENTRY(6, PAT_UCMINUS) | PATENTRY(7, PAT_UC), 211 1.4 maxv [NVMM_X64_MSR_TSC] = 0, 212 1.1 maxv }, 213 1.1 maxv 214 1.6 maxv .intr = { 215 1.6 maxv .int_shadow = 0, 216 1.6 maxv .int_window_exiting = 0, 217 1.6 maxv .nmi_window_exiting = 0, 218 1.6 maxv .evt_pending = 0, 219 1.1 maxv }, 220 1.1 maxv 221 1.1 maxv .fpu = { 222 1.1 maxv .fx_cw = 0x0040, 223 1.1 maxv .fx_sw = 0x0000, 224 1.1 maxv .fx_tw = 0x55, 225 1.1 maxv .fx_zero = 0x55, 226 1.1 maxv .fx_mxcsr = 0x1F80, 227 1.1 maxv } 228 1.1 maxv }; 229 1.3 maxv 230 1.3 maxv const struct nvmm_x86_cpuid_mask nvmm_cpuid_00000001 = { 231 1.3 maxv .eax = ~0, 232 1.3 maxv .ebx = ~0, 233 1.3 maxv .ecx = 234 1.10 maxv CPUID2_SSE3 | 235 1.18 maxv CPUID2_PCLMULQDQ | 236 1.16 maxv /* CPUID2_DTES64 excluded */ 237 1.10 maxv /* CPUID2_MONITOR excluded */ 238 1.16 maxv /* CPUID2_DS_CPL excluded */ 239 1.10 maxv /* CPUID2_VMX excluded */ 240 1.10 maxv /* CPUID2_SMX excluded */ 241 1.10 maxv /* CPUID2_EST excluded */ 242 1.10 maxv /* CPUID2_TM2 excluded */ 243 1.10 maxv CPUID2_SSSE3 | 244 1.18 maxv /* CPUID2_CNXTID excluded */ 245 1.16 maxv /* CPUID2_SDBG excluded */ 246 1.10 maxv CPUID2_FMA | 247 1.10 maxv CPUID2_CX16 | 248 1.18 maxv /* CPUID2_XTPR excluded */ 249 1.10 maxv /* CPUID2_PDCM excluded */ 250 1.10 maxv /* CPUID2_PCID excluded, but re-included in VMX */ 251 1.10 maxv /* CPUID2_DCA excluded */ 252 1.10 maxv CPUID2_SSE41 | 253 1.10 maxv CPUID2_SSE42 | 254 1.10 maxv /* CPUID2_X2APIC excluded */ 255 1.10 maxv CPUID2_MOVBE | 256 1.10 maxv CPUID2_POPCNT | 257 1.10 maxv /* CPUID2_DEADLINE excluded */ 258 1.18 maxv CPUID2_AESNI | 259 1.10 maxv CPUID2_XSAVE | 260 1.10 maxv CPUID2_OSXSAVE | 261 1.10 maxv /* CPUID2_AVX excluded */ 262 1.10 maxv CPUID2_F16C | 263 1.9 maxv CPUID2_RDRAND, 264 1.10 maxv /* CPUID2_RAZ excluded */ 265 1.3 maxv .edx = 266 1.10 maxv CPUID_FPU | 267 1.10 maxv CPUID_VME | 268 1.10 maxv CPUID_DE | 269 1.10 maxv CPUID_PSE | 270 1.10 maxv CPUID_TSC | 271 1.10 maxv CPUID_MSR | 272 1.10 maxv CPUID_PAE | 273 1.10 maxv /* CPUID_MCE excluded */ 274 1.10 maxv CPUID_CX8 | 275 1.10 maxv CPUID_APIC | 276 1.10 maxv CPUID_SEP | 277 1.10 maxv /* CPUID_MTRR excluded */ 278 1.10 maxv CPUID_PGE | 279 1.10 maxv /* CPUID_MCA excluded */ 280 1.10 maxv CPUID_CMOV | 281 1.10 maxv CPUID_PAT | 282 1.10 maxv CPUID_PSE36 | 283 1.18 maxv /* CPUID_PSN excluded */ 284 1.18 maxv CPUID_CLFSH | 285 1.10 maxv /* CPUID_DS excluded */ 286 1.10 maxv /* CPUID_ACPI excluded */ 287 1.10 maxv CPUID_MMX | 288 1.10 maxv CPUID_FXSR | 289 1.10 maxv CPUID_SSE | 290 1.10 maxv CPUID_SSE2 | 291 1.10 maxv CPUID_SS | 292 1.10 maxv CPUID_HTT | 293 1.10 maxv /* CPUID_TM excluded */ 294 1.18 maxv CPUID_PBE 295 1.3 maxv }; 296 1.3 maxv 297 1.3 maxv const struct nvmm_x86_cpuid_mask nvmm_cpuid_00000007 = { 298 1.3 maxv .eax = ~0, 299 1.3 maxv .ebx = 300 1.3 maxv CPUID_SEF_FSGSBASE | 301 1.10 maxv /* CPUID_SEF_TSC_ADJUST excluded */ 302 1.11 maxv /* CPUID_SEF_SGX excluded */ 303 1.10 maxv CPUID_SEF_BMI1 | 304 1.11 maxv /* CPUID_SEF_HLE excluded */ 305 1.10 maxv /* CPUID_SEF_AVX2 excluded */ 306 1.10 maxv CPUID_SEF_FDPEXONLY | 307 1.10 maxv CPUID_SEF_SMEP | 308 1.10 maxv CPUID_SEF_BMI2 | 309 1.10 maxv CPUID_SEF_ERMS | 310 1.10 maxv /* CPUID_SEF_INVPCID excluded, but re-included in VMX */ 311 1.11 maxv /* CPUID_SEF_RTM excluded */ 312 1.10 maxv /* CPUID_SEF_QM excluded */ 313 1.10 maxv CPUID_SEF_FPUCSDS | 314 1.10 maxv /* CPUID_SEF_MPX excluded */ 315 1.10 maxv CPUID_SEF_PQE | 316 1.10 maxv /* CPUID_SEF_AVX512F excluded */ 317 1.10 maxv /* CPUID_SEF_AVX512DQ excluded */ 318 1.10 maxv CPUID_SEF_RDSEED | 319 1.10 maxv CPUID_SEF_ADX | 320 1.10 maxv CPUID_SEF_SMAP | 321 1.10 maxv /* CPUID_SEF_AVX512_IFMA excluded */ 322 1.10 maxv CPUID_SEF_CLFLUSHOPT | 323 1.9 maxv CPUID_SEF_CLWB, 324 1.10 maxv /* CPUID_SEF_PT excluded */ 325 1.10 maxv /* CPUID_SEF_AVX512PF excluded */ 326 1.10 maxv /* CPUID_SEF_AVX512ER excluded */ 327 1.10 maxv /* CPUID_SEF_AVX512CD excluded */ 328 1.10 maxv /* CPUID_SEF_SHA excluded */ 329 1.10 maxv /* CPUID_SEF_AVX512BW excluded */ 330 1.10 maxv /* CPUID_SEF_AVX512VL excluded */ 331 1.3 maxv .ecx = 332 1.10 maxv CPUID_SEF_PREFETCHWT1 | 333 1.10 maxv /* CPUID_SEF_AVX512_VBMI excluded */ 334 1.10 maxv CPUID_SEF_UMIP | 335 1.11 maxv /* CPUID_SEF_PKU excluded */ 336 1.12 maxv /* CPUID_SEF_OSPKE excluded */ 337 1.11 maxv /* CPUID_SEF_WAITPKG excluded */ 338 1.10 maxv /* CPUID_SEF_AVX512_VBMI2 excluded */ 339 1.10 maxv /* CPUID_SEF_CET_SS excluded */ 340 1.10 maxv CPUID_SEF_GFNI | 341 1.10 maxv CPUID_SEF_VAES | 342 1.10 maxv CPUID_SEF_VPCLMULQDQ | 343 1.10 maxv /* CPUID_SEF_AVX512_VNNI excluded */ 344 1.10 maxv /* CPUID_SEF_AVX512_BITALG excluded */ 345 1.10 maxv /* CPUID_SEF_AVX512_VPOPCNTDQ excluded */ 346 1.10 maxv /* CPUID_SEF_MAWAU excluded */ 347 1.10 maxv /* CPUID_SEF_RDPID excluded */ 348 1.10 maxv CPUID_SEF_CLDEMOTE | 349 1.10 maxv CPUID_SEF_MOVDIRI | 350 1.11 maxv CPUID_SEF_MOVDIR64B, 351 1.11 maxv /* CPUID_SEF_SGXLC excluded */ 352 1.10 maxv /* CPUID_SEF_PKS excluded */ 353 1.3 maxv .edx = 354 1.10 maxv /* CPUID_SEF_AVX512_4VNNIW excluded */ 355 1.10 maxv /* CPUID_SEF_AVX512_4FMAPS excluded */ 356 1.23 msaitoh CPUID_SEF_FSRM | 357 1.10 maxv /* CPUID_SEF_AVX512_VP2INTERSECT excluded */ 358 1.10 maxv /* CPUID_SEF_SRBDS_CTRL excluded */ 359 1.10 maxv CPUID_SEF_MD_CLEAR | 360 1.10 maxv /* CPUID_SEF_TSX_FORCE_ABORT excluded */ 361 1.13 maxv CPUID_SEF_SERIALIZE | 362 1.10 maxv /* CPUID_SEF_HYBRID excluded */ 363 1.10 maxv /* CPUID_SEF_TSXLDTRK excluded */ 364 1.10 maxv /* CPUID_SEF_CET_IBT excluded */ 365 1.10 maxv /* CPUID_SEF_IBRS excluded */ 366 1.10 maxv /* CPUID_SEF_STIBP excluded */ 367 1.10 maxv /* CPUID_SEF_L1D_FLUSH excluded */ 368 1.10 maxv CPUID_SEF_ARCH_CAP 369 1.10 maxv /* CPUID_SEF_CORE_CAP excluded */ 370 1.10 maxv /* CPUID_SEF_SSBD excluded */ 371 1.3 maxv }; 372 1.3 maxv 373 1.3 maxv const struct nvmm_x86_cpuid_mask nvmm_cpuid_80000001 = { 374 1.3 maxv .eax = ~0, 375 1.3 maxv .ebx = ~0, 376 1.3 maxv .ecx = 377 1.10 maxv CPUID_LAHF | 378 1.10 maxv CPUID_CMPLEGACY | 379 1.10 maxv /* CPUID_SVM excluded */ 380 1.10 maxv /* CPUID_EAPIC excluded */ 381 1.10 maxv CPUID_ALTMOVCR0 | 382 1.18 maxv CPUID_ABM | 383 1.10 maxv CPUID_SSE4A | 384 1.10 maxv CPUID_MISALIGNSSE | 385 1.10 maxv CPUID_3DNOWPF | 386 1.10 maxv /* CPUID_OSVW excluded */ 387 1.15 maxv /* CPUID_IBS excluded */ 388 1.10 maxv CPUID_XOP | 389 1.11 maxv /* CPUID_SKINIT excluded */ 390 1.15 maxv /* CPUID_WDT excluded */ 391 1.15 maxv /* CPUID_LWP excluded */ 392 1.10 maxv CPUID_FMA4 | 393 1.10 maxv CPUID_TCE | 394 1.15 maxv /* CPUID_NODEID excluded */ 395 1.10 maxv CPUID_TBM | 396 1.15 maxv CPUID_TOPOEXT, 397 1.15 maxv /* CPUID_PCEC excluded */ 398 1.15 maxv /* CPUID_PCENB excluded */ 399 1.15 maxv /* CPUID_SPM excluded */ 400 1.15 maxv /* CPUID_DBE excluded */ 401 1.15 maxv /* CPUID_PTSC excluded */ 402 1.15 maxv /* CPUID_L2IPERFC excluded */ 403 1.10 maxv /* CPUID_MWAITX excluded */ 404 1.3 maxv .edx = 405 1.10 maxv CPUID_SYSCALL | 406 1.10 maxv CPUID_MPC | 407 1.10 maxv CPUID_XD | 408 1.10 maxv CPUID_MMXX | 409 1.21 maxv CPUID_MMX | 410 1.10 maxv CPUID_FXSR | 411 1.10 maxv CPUID_FFXSR | 412 1.18 maxv CPUID_PAGE1GB | 413 1.10 maxv /* CPUID_RDTSCP excluded */ 414 1.10 maxv CPUID_EM64T | 415 1.10 maxv CPUID_3DNOW2 | 416 1.3 maxv CPUID_3DNOW 417 1.3 maxv }; 418 1.5 maxv 419 1.14 maxv const struct nvmm_x86_cpuid_mask nvmm_cpuid_80000007 = { 420 1.14 maxv .eax = 0, 421 1.14 maxv .ebx = 0, 422 1.14 maxv .ecx = 0, 423 1.14 maxv .edx = CPUID_APM_ITSC 424 1.14 maxv }; 425 1.14 maxv 426 1.14 maxv const struct nvmm_x86_cpuid_mask nvmm_cpuid_80000008 = { 427 1.14 maxv .eax = ~0, 428 1.14 maxv .ebx = 429 1.14 maxv CPUID_CAPEX_CLZERO | 430 1.14 maxv /* CPUID_CAPEX_IRPERF excluded */ 431 1.14 maxv CPUID_CAPEX_XSAVEERPTR | 432 1.14 maxv /* CPUID_CAPEX_RDPRU excluded */ 433 1.14 maxv /* CPUID_CAPEX_MCOMMIT excluded */ 434 1.14 maxv CPUID_CAPEX_WBNOINVD, 435 1.14 maxv .ecx = ~0, /* TODO? */ 436 1.14 maxv .edx = 0 437 1.14 maxv }; 438 1.14 maxv 439 1.5 maxv bool 440 1.5 maxv nvmm_x86_pat_validate(uint64_t val) 441 1.5 maxv { 442 1.5 maxv uint8_t *pat = (uint8_t *)&val; 443 1.5 maxv size_t i; 444 1.5 maxv 445 1.5 maxv for (i = 0; i < 8; i++) { 446 1.5 maxv if (__predict_false(pat[i] & ~__BITS(2,0))) 447 1.5 maxv return false; 448 1.5 maxv if (__predict_false(pat[i] == 2 || pat[i] == 3)) 449 1.5 maxv return false; 450 1.5 maxv } 451 1.5 maxv 452 1.5 maxv return true; 453 1.5 maxv } 454