1 /* $NetBSD: nvmm_x86.h,v 1.22 2026/07/15 01:22:21 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 #ifndef _NVMM_X86_H_ 32 #define _NVMM_X86_H_ 33 34 /* -------------------------------------------------------------------------- */ 35 36 #ifndef ASM_NVMM 37 38 struct nvmm_x86_exit_memory { 39 int prot; 40 gpaddr_t gpa; 41 uint8_t inst_len; 42 uint8_t inst_bytes[15]; 43 }; 44 45 struct nvmm_x86_exit_io { 46 bool in; 47 uint16_t port; 48 int8_t seg; 49 uint8_t address_size; 50 uint8_t operand_size; 51 bool rep; 52 bool str; 53 uint64_t npc; 54 }; 55 56 struct nvmm_x86_exit_rdmsr { 57 uint32_t msr; 58 uint64_t npc; 59 }; 60 61 struct nvmm_x86_exit_wrmsr { 62 uint32_t msr; 63 uint64_t val; 64 uint64_t npc; 65 }; 66 67 struct nvmm_x86_exit_insn { 68 uint64_t npc; 69 }; 70 71 struct nvmm_x86_exit_invalid { 72 uint64_t hwcode; 73 }; 74 75 /* Generic. */ 76 #define NVMM_VCPU_EXIT_NONE 0x0000000000000000ULL 77 #define NVMM_VCPU_EXIT_STOPPED 0xFFFFFFFFFFFFFFFEULL 78 #define NVMM_VCPU_EXIT_INVALID 0xFFFFFFFFFFFFFFFFULL 79 /* x86: operations. */ 80 #define NVMM_VCPU_EXIT_MEMORY 0x0000000000000001ULL 81 #define NVMM_VCPU_EXIT_IO 0x0000000000000002ULL 82 /* x86: changes in VCPU state. */ 83 #define NVMM_VCPU_EXIT_SHUTDOWN 0x0000000000001000ULL 84 #define NVMM_VCPU_EXIT_INT_READY 0x0000000000001001ULL 85 #define NVMM_VCPU_EXIT_NMI_READY 0x0000000000001002ULL 86 #define NVMM_VCPU_EXIT_HALTED 0x0000000000001003ULL 87 #define NVMM_VCPU_EXIT_TPR_CHANGED 0x0000000000001004ULL 88 /* x86: instructions. */ 89 #define NVMM_VCPU_EXIT_RDMSR 0x0000000000002000ULL 90 #define NVMM_VCPU_EXIT_WRMSR 0x0000000000002001ULL 91 #define NVMM_VCPU_EXIT_MONITOR 0x0000000000002002ULL 92 #define NVMM_VCPU_EXIT_MWAIT 0x0000000000002003ULL 93 #define NVMM_VCPU_EXIT_CPUID 0x0000000000002004ULL 94 95 struct nvmm_x86_exit { 96 uint64_t reason; 97 union { 98 struct nvmm_x86_exit_memory mem; 99 struct nvmm_x86_exit_io io; 100 struct nvmm_x86_exit_rdmsr rdmsr; 101 struct nvmm_x86_exit_wrmsr wrmsr; 102 struct nvmm_x86_exit_insn insn; 103 struct nvmm_x86_exit_invalid inv; 104 } u; 105 struct { 106 uint64_t rflags; 107 uint64_t cr8; 108 uint64_t int_shadow:1; 109 uint64_t int_window_exiting:1; 110 uint64_t nmi_window_exiting:1; 111 uint64_t evt_pending:1; 112 uint64_t rsvd:60; 113 } exitstate; 114 }; 115 116 #define NVMM_VCPU_EVENT_EXCP 0 117 #define NVMM_VCPU_EVENT_INTR 1 118 119 struct nvmm_x86_event { 120 u_int type; 121 uint8_t vector; 122 union { 123 struct { 124 uint64_t error; 125 } excp; 126 } u; 127 }; 128 129 struct nvmm_cap_md { 130 uint64_t mach_conf_support; 131 132 uint64_t vcpu_conf_support; 133 #define NVMM_CAP_ARCH_VCPU_CONF_CPUID __BIT(0) 134 #define NVMM_CAP_ARCH_VCPU_CONF_TPR __BIT(1) 135 #define NVMM_CAP_ARCH_VCPU_CONF_XCR0_MASK __BIT(2) 136 137 uint64_t xcr0_mask; 138 uint32_t mxcsr_mask; 139 uint32_t conf_cpuid_maxops; 140 uint64_t rsvd[6]; 141 }; 142 143 #endif 144 145 /* -------------------------------------------------------------------------- */ 146 147 /* 148 * Segment state indexes. We use X64 as naming convention, not to confuse with 149 * X86 which originally implied 32bit. 150 */ 151 152 /* Segments. */ 153 #define NVMM_X64_SEG_ES 0 154 #define NVMM_X64_SEG_CS 1 155 #define NVMM_X64_SEG_SS 2 156 #define NVMM_X64_SEG_DS 3 157 #define NVMM_X64_SEG_FS 4 158 #define NVMM_X64_SEG_GS 5 159 #define NVMM_X64_SEG_GDT 6 160 #define NVMM_X64_SEG_IDT 7 161 #define NVMM_X64_SEG_LDT 8 162 #define NVMM_X64_SEG_TR 9 163 #define NVMM_X64_NSEG 10 164 165 /* General Purpose Registers. */ 166 #define NVMM_X64_GPR_RAX 0 167 #define NVMM_X64_GPR_RCX 1 168 #define NVMM_X64_GPR_RDX 2 169 #define NVMM_X64_GPR_RBX 3 170 #define NVMM_X64_GPR_RSP 4 171 #define NVMM_X64_GPR_RBP 5 172 #define NVMM_X64_GPR_RSI 6 173 #define NVMM_X64_GPR_RDI 7 174 #define NVMM_X64_GPR_R8 8 175 #define NVMM_X64_GPR_R9 9 176 #define NVMM_X64_GPR_R10 10 177 #define NVMM_X64_GPR_R11 11 178 #define NVMM_X64_GPR_R12 12 179 #define NVMM_X64_GPR_R13 13 180 #define NVMM_X64_GPR_R14 14 181 #define NVMM_X64_GPR_R15 15 182 #define NVMM_X64_GPR_RIP 16 183 #define NVMM_X64_GPR_RFLAGS 17 184 #define NVMM_X64_NGPR 18 185 186 /* Control Registers. */ 187 #define NVMM_X64_CR_CR0 0 188 #define NVMM_X64_CR_CR2 1 189 #define NVMM_X64_CR_CR3 2 190 #define NVMM_X64_CR_CR4 3 191 #define NVMM_X64_CR_CR8 4 192 #define NVMM_X64_CR_XCR0 5 193 #define NVMM_X64_NCR 6 194 195 /* Debug Registers. */ 196 #define NVMM_X64_DR_DR0 0 197 #define NVMM_X64_DR_DR1 1 198 #define NVMM_X64_DR_DR2 2 199 #define NVMM_X64_DR_DR3 3 200 #define NVMM_X64_DR_DR6 4 201 #define NVMM_X64_DR_DR7 5 202 #define NVMM_X64_NDR 6 203 204 /* MSRs. */ 205 #define NVMM_X64_MSR_EFER 0 206 #define NVMM_X64_MSR_STAR 1 207 #define NVMM_X64_MSR_LSTAR 2 208 #define NVMM_X64_MSR_CSTAR 3 209 #define NVMM_X64_MSR_SFMASK 4 210 #define NVMM_X64_MSR_KERNELGSBASE 5 211 #define NVMM_X64_MSR_SYSENTER_CS 6 212 #define NVMM_X64_MSR_SYSENTER_ESP 7 213 #define NVMM_X64_MSR_SYSENTER_EIP 8 214 #define NVMM_X64_MSR_PAT 9 215 #define NVMM_X64_MSR_TSC 10 216 #define NVMM_X64_NMSR 11 217 218 #ifndef ASM_NVMM 219 220 #include <sys/types.h> 221 #include <x86/cpu_extended_state.h> 222 223 struct nvmm_x64_state_seg { 224 uint16_t selector; 225 struct { /* hidden */ 226 uint16_t type:4; 227 uint16_t s:1; 228 uint16_t dpl:2; 229 uint16_t p:1; 230 uint16_t avl:1; 231 uint16_t l:1; 232 uint16_t def:1; 233 uint16_t g:1; 234 uint16_t rsvd:4; 235 } attrib; 236 uint32_t limit; /* hidden */ 237 uint64_t base; /* hidden */ 238 }; 239 240 struct nvmm_x64_state_intr { 241 uint64_t int_shadow:1; 242 uint64_t int_window_exiting:1; 243 uint64_t nmi_window_exiting:1; 244 uint64_t evt_pending:1; 245 uint64_t rsvd:60; 246 }; 247 248 /* Flags. */ 249 #define NVMM_X64_STATE_SEGS 0x01 250 #define NVMM_X64_STATE_GPRS 0x02 251 #define NVMM_X64_STATE_CRS 0x04 252 #define NVMM_X64_STATE_DRS 0x08 253 #define NVMM_X64_STATE_MSRS 0x10 254 #define NVMM_X64_STATE_INTR 0x20 255 #define NVMM_X64_STATE_FPU 0x40 256 #define NVMM_X64_STATE_ALL \ 257 (NVMM_X64_STATE_SEGS | NVMM_X64_STATE_GPRS | NVMM_X64_STATE_CRS | \ 258 NVMM_X64_STATE_DRS | NVMM_X64_STATE_MSRS | NVMM_X64_STATE_INTR | \ 259 NVMM_X64_STATE_FPU) 260 261 struct nvmm_x64_state { 262 struct nvmm_x64_state_seg segs[NVMM_X64_NSEG]; 263 uint64_t gprs[NVMM_X64_NGPR]; 264 uint64_t crs[NVMM_X64_NCR]; 265 uint64_t drs[NVMM_X64_NDR]; 266 uint64_t msrs[NVMM_X64_NMSR]; 267 struct nvmm_x64_state_intr intr; 268 struct fxsave fpu; 269 }; 270 271 #define NVMM_VCPU_CONF_CPUID NVMM_VCPU_CONF_MD_BEGIN 272 #define NVMM_VCPU_CONF_TPR (NVMM_VCPU_CONF_MD_BEGIN + 1) 273 #define NVMM_VCPU_CONF_XCR0_MASK (NVMM_VCPU_CONF_MD_BEGIN + 2) 274 275 struct nvmm_vcpu_conf_cpuid { 276 /* The options. */ 277 uint32_t mask:1; 278 uint32_t exit:1; 279 uint32_t rsvd:30; 280 281 /* The leaf. */ 282 uint32_t leaf; 283 284 /* The params. */ 285 union { 286 struct { 287 struct { 288 uint32_t eax; 289 uint32_t ebx; 290 uint32_t ecx; 291 uint32_t edx; 292 } set; 293 struct { 294 uint32_t eax; 295 uint32_t ebx; 296 uint32_t ecx; 297 uint32_t edx; 298 } del; 299 } mask; 300 } u; 301 }; 302 303 struct nvmm_vcpu_conf_tpr { 304 uint32_t exit_changed:1; 305 uint32_t rsvd:31; 306 }; 307 308 #define nvmm_vcpu_exit nvmm_x86_exit 309 #define nvmm_vcpu_event nvmm_x86_event 310 #define nvmm_vcpu_state nvmm_x64_state 311 312 #ifdef _KERNEL 313 #define NVMM_X86_MACH_NCONF 0 314 #define NVMM_X86_VCPU_NCONF 3 315 struct nvmm_x86_cpuid_mask { 316 uint32_t eax; 317 uint32_t ebx; 318 uint32_t ecx; 319 uint32_t edx; 320 }; 321 extern const struct nvmm_x64_state nvmm_x86_reset_state; 322 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_00000001; 323 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_00000007; 324 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_80000001; 325 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_80000007; 326 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_80000008; 327 bool nvmm_x86_pat_validate(uint64_t); 328 uint32_t nvmm_x86_xsave_size(uint64_t); 329 bool nvmm_x86_xcr0_valid(uint64_t, uint64_t); 330 uint64_t nvmm_x86_munge_xcr0(uint64_t, uint64_t); 331 #endif 332 333 #endif /* ASM_NVMM */ 334 335 #endif /* _NVMM_X86_H_ */ 336