1 /* $OpenBSD: vmm.h,v 1.4 2024/01/11 17:13:48 jan Exp $ */ 2 /* 3 * Copyright (c) 2014-2023 Mike Larkin <mlarkin@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <sys/rwlock.h> 19 #include <sys/refcnt.h> 20 21 #include <uvm/uvm_extern.h> 22 23 #ifndef DEV_VMM_H 24 #define DEV_VMM_H 25 26 struct vm_mem_range { 27 paddr_t vmr_gpa; 28 vaddr_t vmr_va; 29 size_t vmr_size; 30 int vmr_type; 31 #define VM_MEM_RAM 0 /* Presented as usable system memory. */ 32 #define VM_MEM_RESERVED 1 /* Reserved for BIOS, etc. */ 33 #define VM_MEM_MMIO 2 /* Special region for device mmio. */ 34 }; 35 36 struct vm_create_params { 37 /* Input parameters to VMM_IOC_CREATE */ 38 size_t vcp_nmemranges; 39 size_t vcp_ncpus; 40 struct vm_mem_range vcp_memranges[VMM_MAX_MEM_RANGES]; 41 char vcp_name[VMM_MAX_NAME_LEN]; 42 43 /* Output parameter from VMM_IOC_CREATE */ 44 uint32_t vcp_id; 45 }; 46 47 struct vm_info_result { 48 /* Output parameters from VMM_IOC_INFO */ 49 size_t vir_memory_size; 50 size_t vir_used_size; 51 size_t vir_ncpus; 52 uint8_t vir_vcpu_state[VMM_MAX_VCPUS_PER_VM]; 53 pid_t vir_creator_pid; 54 uint32_t vir_id; 55 char vir_name[VMM_MAX_NAME_LEN]; 56 }; 57 58 struct vm_info_params { 59 /* Input parameters to VMM_IOC_INFO */ 60 size_t vip_size; /* Output buffer size */ 61 62 /* Output Parameters from VMM_IOC_INFO */ 63 size_t vip_info_ct; /* # of entries returned */ 64 struct vm_info_result *vip_info; /* Output buffer */ 65 }; 66 67 struct vm_terminate_params { 68 /* Input parameters to VMM_IOC_TERM */ 69 uint32_t vtp_vm_id; 70 }; 71 72 struct vm_resetcpu_params { 73 /* Input parameters to VMM_IOC_RESETCPU */ 74 uint32_t vrp_vm_id; 75 uint32_t vrp_vcpu_id; 76 struct vcpu_reg_state vrp_init_state; 77 }; 78 79 struct vm_sharemem_params { 80 /* Input parameters to VMM_IOC_SHAREMEM */ 81 uint32_t vsp_vm_id; 82 size_t vsp_nmemranges; 83 struct vm_mem_range vsp_memranges[VMM_MAX_MEM_RANGES]; 84 }; 85 86 /* IOCTL definitions */ 87 #define VMM_IOC_CREATE _IOWR('V', 1, struct vm_create_params) /* Create VM */ 88 #define VMM_IOC_RUN _IOWR('V', 2, struct vm_run_params) /* Run VCPU */ 89 #define VMM_IOC_INFO _IOWR('V', 3, struct vm_info_params) /* Get VM Info */ 90 #define VMM_IOC_TERM _IOW('V', 4, struct vm_terminate_params) /* Terminate VM */ 91 #define VMM_IOC_RESETCPU _IOW('V', 5, struct vm_resetcpu_params) /* Reset */ 92 #define VMM_IOC_READREGS _IOWR('V', 7, struct vm_rwregs_params) /* Get regs */ 93 #define VMM_IOC_WRITEREGS _IOW('V', 8, struct vm_rwregs_params) /* Set regs */ 94 /* Get VM params */ 95 #define VMM_IOC_READVMPARAMS _IOWR('V', 9, struct vm_rwvmparams_params) 96 /* Set VM params */ 97 #define VMM_IOC_WRITEVMPARAMS _IOW('V', 10, struct vm_rwvmparams_params) 98 #define VMM_IOC_SHAREMEM _IOW('V', 11, struct vm_sharemem_params) 99 100 #ifdef _KERNEL 101 102 /* #define VMM_DEBUG */ 103 104 #ifdef VMM_DEBUG 105 #define DPRINTF(x...) do { printf(x); } while(0) 106 #else 107 #define DPRINTF(x...) 108 #endif /* VMM_DEBUG */ 109 enum { 110 VCPU_STATE_STOPPED, 111 VCPU_STATE_RUNNING, 112 VCPU_STATE_REQTERM, 113 VCPU_STATE_TERMINATED, 114 VCPU_STATE_UNKNOWN, 115 }; 116 117 /* 118 * Virtual Machine 119 * 120 * Methods used to protect vm struct members: 121 * a atomic operations 122 * I immutable after create 123 * K kernel lock 124 * r reference count 125 * v vcpu list rwlock (vm_vcpu_list) 126 * V vmm_softc's vm_lock 127 */ 128 struct vm { 129 struct vmspace *vm_vmspace; /* [K] */ 130 vm_map_t vm_map; /* [K] */ 131 uint32_t vm_id; /* [I] */ 132 pid_t vm_creator_pid; /* [I] */ 133 size_t vm_nmemranges; /* [I] */ 134 size_t vm_memory_size; /* [I] */ 135 char vm_name[VMM_MAX_NAME_LEN]; 136 struct vm_mem_range vm_memranges[VMM_MAX_MEM_RANGES]; 137 struct refcnt vm_refcnt; /* [a] */ 138 139 struct vcpu_head vm_vcpu_list; /* [v] */ 140 uint32_t vm_vcpu_ct; /* [v] */ 141 struct rwlock vm_vcpu_lock; 142 143 SLIST_ENTRY(vm) vm_link; /* [V] */ 144 }; 145 146 SLIST_HEAD(vmlist_head, vm); 147 148 /* 149 * Virtual Machine Monitor 150 * 151 * Methods used to protect struct members in the global vmm device: 152 * a atomic opererations 153 * I immutable operations 154 * K kernel lock 155 * p virtual process id (vpid/asid) rwlock 156 * r reference count 157 * v vm list rwlock (vm_lock) 158 */ 159 struct vmm_softc { 160 struct device sc_dev; /* [r] */ 161 162 /* Suspend/Resume Synchronization */ 163 struct rwlock sc_slock; 164 struct refcnt sc_refcnt; 165 volatile unsigned int sc_status; /* [a] */ 166 #define VMM_SUSPENDED (unsigned int) 0 167 #define VMM_ACTIVE (unsigned int) 1 168 169 struct vmm_softc_md sc_md; 170 171 /* Managed VMs */ 172 struct vmlist_head vm_list; /* [v] */ 173 174 int mode; /* [I] */ 175 176 size_t vcpu_ct; /* [v] */ 177 size_t vcpu_max; /* [I] */ 178 179 struct rwlock vm_lock; 180 size_t vm_ct; /* [v] no. of in-memory VMs */ 181 size_t vm_idx; /* [a] next unique VM index */ 182 183 struct rwlock vpid_lock; 184 uint16_t max_vpid; /* [I] */ 185 uint8_t vpids[512]; /* [p] bitmap of VPID/ASIDs */ 186 }; 187 188 int vmm_probe(struct device *, void *, void *); 189 int vmm_activate(struct device *, int); 190 void vmm_attach(struct device *, struct device *, void *); 191 int vmmopen(dev_t, int, int, struct proc *); 192 int vmmclose(dev_t, int, int, struct proc *); 193 int vm_find(uint32_t, struct vm **); 194 int vmmioctl_machdep(dev_t, u_long, caddr_t, int, struct proc *); 195 int pledge_ioctl_vmm(struct proc *, long); 196 struct vcpu *vm_find_vcpu(struct vm *, uint32_t); 197 int vm_create(struct vm_create_params *, struct proc *); 198 size_t vm_create_check_mem_ranges(struct vm_create_params *); 199 void vm_teardown(struct vm **); 200 int vm_get_info(struct vm_info_params *); 201 int vm_terminate(struct vm_terminate_params *); 202 int vm_resetcpu(struct vm_resetcpu_params *); 203 int vcpu_must_stop(struct vcpu *); 204 int vm_share_mem(struct vm_sharemem_params *, struct proc *); 205 206 #ifdef VMM_DEBUG 207 void dump_vcpu(struct vcpu *); 208 #endif 209 210 #endif /* _KERNEL */ 211 #endif /* DEV_VMM_H */ 212