1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 /* This file is dual-licensed; see usr/src/contrib/bhyve/LICENSE */ 12 13 /* 14 * Copyright 2023 Oxide Computer Company 15 */ 16 17 #ifndef _VMM_DATA_H_ 18 #define _VMM_DATA_H_ 19 20 /* VMM Data Classes */ 21 #define VDC_VERSION 1 /* Version information for each data class */ 22 23 /* Classes bearing per-CPU data */ 24 #define VDC_REGISTER 2 /* Registers (GPR, segment, etc) */ 25 #define VDC_MSR 3 /* Model-specific registers */ 26 #define VDC_FPU 4 /* FPU (and associated SIMD) */ 27 #define VDC_LAPIC 5 /* Local APIC */ 28 #define VDC_VMM_ARCH 6 /* Arch-specific VMM state (VMX/SVM) */ 29 30 /* Classes for system-wide devices */ 31 #define VDC_IOAPIC 7 /* bhyve IO-APIC */ 32 #define VDC_ATPIT 8 /* i8254 PIT */ 33 #define VDC_ATPIC 9 /* i8259 PIC */ 34 #define VDC_HPET 10 /* HPET */ 35 #define VDC_PM_TIMER 11 /* ACPI Power Management Timer */ 36 #define VDC_RTC 12 /* IBM PC Real Time Clock */ 37 38 #define VDC_VMM_TIME 13 /* Time-related VMM data */ 39 40 /* Indicates top of VMM Data Class range, updated as classes are added */ 41 #define VDC_MAX (VDC_VMM_TIME + 1) 42 43 44 /* VMM Data Identifiers */ 45 46 /* 47 * Generic field encoding for 64-bit (or smaller) data which are identified by a 48 * 32-bit (or smaller) name. 49 * 50 * Used by the following classes/version: 51 * - VDC_REGISTER v1: `vm_reg_name` identifiers 52 * - VDC_MSR v1: MSR identifiers 53 * - VDC_VMM_ARCH v1: Identifiers described below 54 */ 55 struct vdi_field_entry_v1 { 56 uint32_t vfe_ident; 57 uint32_t _pad; 58 uint64_t vfe_value; 59 }; 60 61 /* VDC_VERSION */ 62 struct vdi_version_entry_v1 { 63 uint16_t vve_class; 64 uint16_t vve_version; 65 uint16_t vve_len_expect; 66 uint16_t vve_len_per_item; 67 }; 68 69 /* 70 * VDC_FPU: 71 * 72 * Unimplemented for now. Use VM_GET_FPU/VM_SET_FPU ioctls. 73 */ 74 75 /* VDC_LAPIC: */ 76 77 struct vdi_lapic_page_v1 { 78 uint32_t vlp_id; 79 uint32_t vlp_version; 80 uint32_t vlp_tpr; 81 uint32_t vlp_apr; 82 uint32_t vlp_ldr; 83 uint32_t vlp_dfr; 84 uint32_t vlp_svr; 85 uint32_t vlp_isr[8]; 86 uint32_t vlp_tmr[8]; 87 uint32_t vlp_irr[8]; 88 uint32_t vlp_esr; 89 uint32_t vlp_lvt_cmci; 90 uint64_t vlp_icr; 91 uint32_t vlp_lvt_timer; 92 uint32_t vlp_lvt_thermal; 93 uint32_t vlp_lvt_pcint; 94 uint32_t vlp_lvt_lint0; 95 uint32_t vlp_lvt_lint1; 96 uint32_t vlp_lvt_error; 97 uint32_t vlp_icr_timer; 98 uint32_t vlp_dcr_timer; 99 }; 100 101 struct vdi_lapic_v1 { 102 struct vdi_lapic_page_v1 vl_lapic; 103 uint64_t vl_msr_apicbase; 104 int64_t vl_timer_target; 105 uint32_t vl_esr_pending; 106 }; 107 108 /* 109 * VDC_VMM_ARCH: 110 */ 111 112 /* 113 * Version 1 identifiers: 114 */ 115 116 /* 117 * VM-wide: 118 */ 119 120 /* Is the VM currently in the "paused" state? (0 or 1) */ 121 #define VAI_VM_IS_PAUSED 4 122 123 /* 124 * per-vCPU: 125 * 126 * Note: While these are currently defined with values disjoint from those in 127 * the VM-wide category, it is not required that they be. The VM-wide and 128 * per-vCPU identifiers are distinguished by vm_data_xfer`vdx_vcpuid. 129 */ 130 131 /* NMI pending injection for vCPU (0 or 1) */ 132 #define VAI_PEND_NMI 10 133 /* extint pending injection for vCPU (0 or 1) */ 134 #define VAI_PEND_EXTINT 11 135 /* HW exception pending injection for vCPU */ 136 #define VAI_PEND_EXCP 12 137 /* exception/interrupt pending injection for vCPU */ 138 #define VAI_PEND_INTINFO 13 139 140 /* VDC_IOAPIC: */ 141 142 struct vdi_ioapic_v1 { 143 uint64_t vi_pin_reg[32]; 144 uint32_t vi_pin_level[32]; 145 uint32_t vi_id; 146 uint32_t vi_reg_sel; 147 }; 148 149 /* VDC_ATPIT: */ 150 151 struct vdi_atpit_channel_v1 { 152 uint16_t vac_initial; 153 uint16_t vac_reg_cr; 154 uint16_t vac_reg_ol; 155 uint8_t vac_reg_status; 156 uint8_t vac_mode; 157 /* 158 * vac_status bits: 159 * - 0b00001 status latched 160 * - 0b00010 output latched 161 * - 0b00100 control register sel 162 * - 0b01000 output latch sel 163 * - 0b10000 free-running timer 164 */ 165 uint8_t vac_status; 166 167 int64_t vac_time_target; 168 }; 169 170 struct vdi_atpit_v1 { 171 struct vdi_atpit_channel_v1 va_channel[3]; 172 }; 173 174 /* VDC_ATPIC: */ 175 176 struct vdi_atpic_chip_v1 { 177 uint8_t vac_icw_state; 178 /* 179 * vac_status bits: 180 * - 0b00000001 ready 181 * - 0b00000010 auto EOI 182 * - 0b00000100 poll 183 * - 0b00001000 rotate 184 * - 0b00010000 special full nested 185 * - 0b00100000 read isr next 186 * - 0b01000000 intr raised 187 * - 0b10000000 special mask mode 188 */ 189 uint8_t vac_status; 190 uint8_t vac_reg_irr; 191 uint8_t vac_reg_isr; 192 uint8_t vac_reg_imr; 193 uint8_t vac_irq_base; 194 uint8_t vac_lowprio; 195 uint8_t vac_elc; 196 uint32_t vac_level[8]; 197 }; 198 199 struct vdi_atpic_v1 { 200 struct vdi_atpic_chip_v1 va_chip[2]; 201 }; 202 203 /* VDC_HPET: */ 204 205 struct vdi_hpet_timer_v1 { 206 uint64_t vht_config; 207 uint64_t vht_msi; 208 uint32_t vht_comp_val; 209 uint32_t vht_comp_rate; 210 int64_t vht_time_target; 211 }; 212 213 struct vdi_hpet_v1 { 214 uint64_t vh_config; 215 uint64_t vh_isr; 216 uint32_t vh_count_base; 217 int64_t vh_time_base; 218 219 struct vdi_hpet_timer_v1 vh_timers[8]; 220 }; 221 222 /* VDC_PM_TIMER: */ 223 224 struct vdi_pm_timer_v1 { 225 int64_t vpt_time_base; 226 /* 227 * Since the PM-timer IO port registration can be set by a dedicated 228 * ioctl today, it is considered a read-only field in the vmm data 229 * interface and its contents will be ignored when writing state data to 230 * the timer. 231 */ 232 uint16_t vpt_ioport; 233 }; 234 235 /* VDC_RTC: */ 236 237 struct vdi_rtc_v2 { 238 int64_t vr_base_clock; 239 int64_t vr_last_period; 240 uint8_t vr_content[128]; 241 uint8_t vr_addr; 242 }; 243 244 /* VDC_VMM_TIME: */ 245 246 /* 247 * Interface for modifying time-related data of a guest, allowing the guest's 248 * TSC and device timers to continue working across inter-machine live 249 * migrations. 250 * 251 * Reads of this data will populate all fields, including: 252 * - current guest TSC (a calculated value) 253 * - guest TSC frequency 254 * - guest boot_time, which tracks the offset of the guest boot based on host 255 * hrtime 256 * - current host hrtime and wall clock time (hrestime) at the time of read 257 * 258 * Callers writing this data may want to make adjustments to the guest TSC based 259 * on the time between read and write, such as in the case of a migration. 260 * For migrations between machines, the boot_hrtime must also be updated based 261 * on the hrtime of the target system. Callers should populate the host time 262 * fields for the host the write is performed on. These fields are used by the 263 * write interface to make additional adjustments to the guest fields to account 264 * for latency between the userspace adjustment and kernel receipt of those 265 * values. 266 */ 267 struct vdi_time_info_v1 { 268 /* guest-related fields */ 269 uint64_t vt_guest_freq; /* guest TSC frequency (hz) */ 270 uint64_t vt_guest_tsc; /* current guest TSC */ 271 int64_t vt_boot_hrtime; /* guest boot_hrtime */ 272 273 /* host time fields */ 274 int64_t vt_hrtime; /* host hrtime (ns) */ 275 uint64_t vt_hres_sec; /* host hrestime (sec) */ 276 uint64_t vt_hres_ns; /* host hrestime (ns) */ 277 }; 278 279 #endif /* _VMM_DATA_H_ */ 280