1 /* $NetBSD: nvmm_x86.h,v 1.15.4.2 2020/08/26 17:55:49 martin Exp $ */ 2 3 /* 4 * Copyright (c) 2018-2020 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Maxime Villard. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #ifndef _NVMM_X86_H_ 33 #define _NVMM_X86_H_ 34 35 /* -------------------------------------------------------------------------- */ 36 37 #ifndef ASM_NVMM 38 39 struct nvmm_x86_exit_memory { 40 int prot; 41 gpaddr_t gpa; 42 uint8_t inst_len; 43 uint8_t inst_bytes[15]; 44 }; 45 46 struct nvmm_x86_exit_io { 47 bool in; 48 uint16_t port; 49 int8_t seg; 50 uint8_t address_size; 51 uint8_t operand_size; 52 bool rep; 53 bool str; 54 uint64_t npc; 55 }; 56 57 struct nvmm_x86_exit_rdmsr { 58 uint32_t msr; 59 uint64_t npc; 60 }; 61 62 struct nvmm_x86_exit_wrmsr { 63 uint32_t msr; 64 uint64_t val; 65 uint64_t npc; 66 }; 67 68 struct nvmm_x86_exit_insn { 69 uint64_t npc; 70 }; 71 72 struct nvmm_x86_exit_invalid { 73 uint64_t hwcode; 74 }; 75 76 /* Generic. */ 77 #define NVMM_VCPU_EXIT_NONE 0x0000000000000000ULL 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 136 uint64_t xcr0_mask; 137 uint32_t mxcsr_mask; 138 uint32_t conf_cpuid_maxops; 139 uint64_t rsvd[6]; 140 }; 141 142 #endif 143 144 /* -------------------------------------------------------------------------- */ 145 146 /* 147 * Segment state indexes. We use X64 as naming convention, not to confuse with 148 * X86 which originally implied 32bit. 149 */ 150 151 /* Segments. */ 152 #define NVMM_X64_SEG_ES 0 153 #define NVMM_X64_SEG_CS 1 154 #define NVMM_X64_SEG_SS 2 155 #define NVMM_X64_SEG_DS 3 156 #define NVMM_X64_SEG_FS 4 157 #define NVMM_X64_SEG_GS 5 158 #define NVMM_X64_SEG_GDT 6 159 #define NVMM_X64_SEG_IDT 7 160 #define NVMM_X64_SEG_LDT 8 161 #define NVMM_X64_SEG_TR 9 162 #define NVMM_X64_NSEG 10 163 164 /* General Purpose Registers. */ 165 #define NVMM_X64_GPR_RAX 0 166 #define NVMM_X64_GPR_RCX 1 167 #define NVMM_X64_GPR_RDX 2 168 #define NVMM_X64_GPR_RBX 3 169 #define NVMM_X64_GPR_RSP 4 170 #define NVMM_X64_GPR_RBP 5 171 #define NVMM_X64_GPR_RSI 6 172 #define NVMM_X64_GPR_RDI 7 173 #define NVMM_X64_GPR_R8 8 174 #define NVMM_X64_GPR_R9 9 175 #define NVMM_X64_GPR_R10 10 176 #define NVMM_X64_GPR_R11 11 177 #define NVMM_X64_GPR_R12 12 178 #define NVMM_X64_GPR_R13 13 179 #define NVMM_X64_GPR_R14 14 180 #define NVMM_X64_GPR_R15 15 181 #define NVMM_X64_GPR_RIP 16 182 #define NVMM_X64_GPR_RFLAGS 17 183 #define NVMM_X64_NGPR 18 184 185 /* Control Registers. */ 186 #define NVMM_X64_CR_CR0 0 187 #define NVMM_X64_CR_CR2 1 188 #define NVMM_X64_CR_CR3 2 189 #define NVMM_X64_CR_CR4 3 190 #define NVMM_X64_CR_CR8 4 191 #define NVMM_X64_CR_XCR0 5 192 #define NVMM_X64_NCR 6 193 194 /* Debug Registers. */ 195 #define NVMM_X64_DR_DR0 0 196 #define NVMM_X64_DR_DR1 1 197 #define NVMM_X64_DR_DR2 2 198 #define NVMM_X64_DR_DR3 3 199 #define NVMM_X64_DR_DR6 4 200 #define NVMM_X64_DR_DR7 5 201 #define NVMM_X64_NDR 6 202 203 /* MSRs. */ 204 #define NVMM_X64_MSR_EFER 0 205 #define NVMM_X64_MSR_STAR 1 206 #define NVMM_X64_MSR_LSTAR 2 207 #define NVMM_X64_MSR_CSTAR 3 208 #define NVMM_X64_MSR_SFMASK 4 209 #define NVMM_X64_MSR_KERNELGSBASE 5 210 #define NVMM_X64_MSR_SYSENTER_CS 6 211 #define NVMM_X64_MSR_SYSENTER_ESP 7 212 #define NVMM_X64_MSR_SYSENTER_EIP 8 213 #define NVMM_X64_MSR_PAT 9 214 #define NVMM_X64_MSR_TSC 10 215 #define NVMM_X64_NMSR 11 216 217 #ifndef ASM_NVMM 218 219 #include <sys/types.h> 220 #include <machine/npx.h> 221 222 struct nvmm_x64_state_seg { 223 uint16_t selector; 224 struct { /* hidden */ 225 uint16_t type:4; 226 uint16_t s:1; 227 uint16_t dpl:2; 228 uint16_t p:1; 229 uint16_t avl:1; 230 uint16_t l:1; 231 uint16_t def:1; 232 uint16_t g:1; 233 uint16_t rsvd:4; 234 } attrib; 235 uint32_t limit; /* hidden */ 236 uint64_t base; /* hidden */ 237 }; 238 239 struct nvmm_x64_state_intr { 240 uint64_t int_shadow:1; 241 uint64_t int_window_exiting:1; 242 uint64_t nmi_window_exiting:1; 243 uint64_t evt_pending:1; 244 uint64_t rsvd:60; 245 }; 246 247 /* Flags. */ 248 #define NVMM_X64_STATE_SEGS 0x01 249 #define NVMM_X64_STATE_GPRS 0x02 250 #define NVMM_X64_STATE_CRS 0x04 251 #define NVMM_X64_STATE_DRS 0x08 252 #define NVMM_X64_STATE_MSRS 0x10 253 #define NVMM_X64_STATE_INTR 0x20 254 #define NVMM_X64_STATE_FPU 0x40 255 #define NVMM_X64_STATE_ALL \ 256 (NVMM_X64_STATE_SEGS | NVMM_X64_STATE_GPRS | NVMM_X64_STATE_CRS | \ 257 NVMM_X64_STATE_DRS | NVMM_X64_STATE_MSRS | NVMM_X64_STATE_INTR | \ 258 NVMM_X64_STATE_FPU) 259 260 struct nvmm_x64_state { 261 struct nvmm_x64_state_seg segs[NVMM_X64_NSEG]; 262 uint64_t gprs[NVMM_X64_NGPR]; 263 uint64_t crs[NVMM_X64_NCR]; 264 uint64_t drs[NVMM_X64_NDR]; 265 uint64_t msrs[NVMM_X64_NMSR]; 266 struct nvmm_x64_state_intr intr; 267 union savefpu fpu; 268 }; 269 270 #define NVMM_VCPU_CONF_CPUID NVMM_VCPU_CONF_MD_BEGIN 271 #define NVMM_VCPU_CONF_TPR (NVMM_VCPU_CONF_MD_BEGIN + 1) 272 273 struct nvmm_vcpu_conf_cpuid { 274 /* The options. */ 275 uint32_t mask:1; 276 uint32_t exit:1; 277 uint32_t rsvd:30; 278 279 /* The leaf. */ 280 uint32_t leaf; 281 282 /* The params. */ 283 union { 284 struct { 285 struct { 286 uint32_t eax; 287 uint32_t ebx; 288 uint32_t ecx; 289 uint32_t edx; 290 } set; 291 struct { 292 uint32_t eax; 293 uint32_t ebx; 294 uint32_t ecx; 295 uint32_t edx; 296 } del; 297 } mask; 298 } u; 299 }; 300 301 struct nvmm_vcpu_conf_tpr { 302 uint32_t exit_changed:1; 303 uint32_t rsvd:31; 304 }; 305 306 #define nvmm_vcpu_exit nvmm_x86_exit 307 #define nvmm_vcpu_event nvmm_x86_event 308 #define nvmm_vcpu_state nvmm_x64_state 309 310 #ifdef _KERNEL 311 #define NVMM_X86_MACH_NCONF 0 312 #define NVMM_X86_VCPU_NCONF 2 313 struct nvmm_x86_cpuid_mask { 314 uint32_t eax; 315 uint32_t ebx; 316 uint32_t ecx; 317 uint32_t edx; 318 }; 319 extern const struct nvmm_x64_state nvmm_x86_reset_state; 320 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_00000001; 321 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_00000007; 322 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_80000001; 323 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_80000007; 324 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_80000008; 325 bool nvmm_x86_pat_validate(uint64_t); 326 #endif 327 328 #endif /* ASM_NVMM */ 329 330 #endif /* _NVMM_X86_H_ */ 331