xref: /openbsd/sys/dev/vmm/vmm.h (revision ebaf145f)
1 /* $OpenBSD: vmm.h,v 1.7 2024/08/27 09:16:03 bluhm 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 #include <machine/vmmvar.h>
24 
25 #ifndef DEV_VMM_H
26 #define DEV_VMM_H
27 
28 #define VMM_MAX_MEM_RANGES	16
29 #define VMM_MAX_DISKS_PER_VM	4
30 #define VMM_MAX_NAME_LEN	64
31 #define VMM_MAX_VCPUS		512
32 #define VMM_MAX_VCPUS_PER_VM	64
33 #define VMM_MAX_VM_MEM_SIZE	128L * 1024 * 1024 * 1024
34 #define VMM_MAX_NICS_PER_VM	4
35 
36 struct vm_mem_range {
37 	paddr_t vmr_gpa;
38 	vaddr_t vmr_va;
39 	size_t  vmr_size;
40 	int     vmr_type;
41 #define VM_MEM_RAM		0	/* Presented as usable system memory. */
42 #define VM_MEM_RESERVED		1	/* Reserved for BIOS, etc. */
43 #define VM_MEM_MMIO		2	/* Special region for device mmio. */
44 };
45 
46 struct vm_create_params {
47 /* Input parameters to VMM_IOC_CREATE */
48 	size_t			vcp_nmemranges;
49 	size_t			vcp_ncpus;
50 	struct vm_mem_range	vcp_memranges[VMM_MAX_MEM_RANGES];
51 	char			vcp_name[VMM_MAX_NAME_LEN];
52 	int			vcp_sev;
53 
54         /* Output parameter from VMM_IOC_CREATE */
55         uint32_t		vcp_id;
56         uint32_t		vcp_poscbit;
57         uint32_t		vcp_asid[VMM_MAX_VCPUS];
58 };
59 
60 struct vm_info_result {
61 	/* Output parameters from VMM_IOC_INFO */
62 	size_t		vir_memory_size;
63 	size_t		vir_used_size;
64 	size_t		vir_ncpus;
65 	uint8_t		vir_vcpu_state[VMM_MAX_VCPUS_PER_VM];
66 	pid_t		vir_creator_pid;
67 	uint32_t	vir_id;
68 	char		vir_name[VMM_MAX_NAME_LEN];
69 };
70 
71 struct vm_info_params {
72 	/* Input parameters to VMM_IOC_INFO */
73 	size_t			 vip_size;	/* Output buffer size */
74 
75 	/* Output Parameters from VMM_IOC_INFO */
76 	size_t			 vip_info_ct;	/* # of entries returned */
77 	struct vm_info_result	*vip_info;	/* Output buffer */
78 };
79 
80 struct vm_terminate_params {
81 	/* Input parameters to VMM_IOC_TERM */
82 	uint32_t		vtp_vm_id;
83 };
84 
85 struct vm_resetcpu_params {
86 	/* Input parameters to VMM_IOC_RESETCPU */
87 	uint32_t		vrp_vm_id;
88 	uint32_t		vrp_vcpu_id;
89 	struct vcpu_reg_state	vrp_init_state;
90 };
91 
92 struct vm_sharemem_params {
93 	/* Input parameters to VMM_IOC_SHAREMEM */
94 	uint32_t		vsp_vm_id;
95 	size_t			vsp_nmemranges;
96 	struct vm_mem_range	vsp_memranges[VMM_MAX_MEM_RANGES];
97 };
98 
99 struct vm_run_params {
100 	/* Input parameters to VMM_IOC_RUN */
101 	uint32_t	vrp_vm_id;
102 	uint32_t	vrp_vcpu_id;
103 	struct vcpu_inject_event	vrp_inject;
104 	uint8_t		vrp_intr_pending;	/* Additional intrs pending? */
105 
106 	/* Input/output parameter to VMM_IOC_RUN */
107 	struct vm_exit	*vrp_exit;		/* updated exit data */
108 
109 	/* Output parameter from VMM_IOC_RUN */
110 	uint16_t	vrp_exit_reason;	/* exit reason */
111 	uint8_t		vrp_irqready;		/* ready for IRQ on entry */
112 };
113 
114 #define VM_RWVMPARAMS_PVCLOCK_SYSTEM_GPA 0x1	/* read/write pvclock gpa */
115 #define VM_RWVMPARAMS_PVCLOCK_VERSION	 0x2	/* read/write pvclock version */
116 #define VM_RWVMPARAMS_ALL	(VM_RWVMPARAMS_PVCLOCK_SYSTEM_GPA | \
117     VM_RWVMPARAMS_PVCLOCK_VERSION)
118 
119 struct vm_rwvmparams_params {
120 	/* Input parameters to VMM_IOC_READVMPARAMS/VMM_IOC_WRITEVMPARAMS */
121 	uint32_t		vpp_vm_id;
122 	uint32_t		vpp_vcpu_id;
123 	uint32_t		vpp_mask;
124 	paddr_t			vpp_pvclock_system_gpa;
125 	uint32_t		vpp_pvclock_version;
126 };
127 
128 /* IOCTL definitions */
129 #define VMM_IOC_CREATE _IOWR('V', 1, struct vm_create_params) /* Create VM */
130 #define VMM_IOC_RUN _IOWR('V', 2, struct vm_run_params) /* Run VCPU */
131 #define VMM_IOC_INFO _IOWR('V', 3, struct vm_info_params) /* Get VM Info */
132 #define VMM_IOC_TERM _IOW('V', 4, struct vm_terminate_params) /* Terminate VM */
133 #define VMM_IOC_RESETCPU _IOW('V', 5, struct vm_resetcpu_params) /* Reset */
134 #define VMM_IOC_READREGS _IOWR('V', 7, struct vm_rwregs_params) /* Get regs */
135 #define VMM_IOC_WRITEREGS _IOW('V', 8, struct vm_rwregs_params) /* Set regs */
136 /* Get VM params */
137 #define VMM_IOC_READVMPARAMS _IOWR('V', 9, struct vm_rwvmparams_params)
138 /* Set VM params */
139 #define VMM_IOC_WRITEVMPARAMS _IOW('V', 10, struct vm_rwvmparams_params)
140 #define VMM_IOC_SHAREMEM _IOW('V', 11, struct vm_sharemem_params)
141 
142 #ifdef _KERNEL
143 
144 /* #define VMM_DEBUG */
145 
146 #ifdef VMM_DEBUG
147 #define DPRINTF(x...)   do { printf(x); } while(0)
148 #else
149 #define DPRINTF(x...)
150 #endif /* VMM_DEBUG */
151 enum {
152 	VCPU_STATE_STOPPED,
153 	VCPU_STATE_RUNNING,
154 	VCPU_STATE_REQTERM,
155 	VCPU_STATE_TERMINATED,
156 	VCPU_STATE_UNKNOWN,
157 };
158 
159 /*
160  * Virtual Machine
161  *
162  * Methods used to protect vm struct members:
163  *	a	atomic operations
164  *	I	immutable after create
165  *	K	kernel lock
166  *	r	reference count
167  *	v	vcpu list rwlock (vm_vcpu_list)
168  *	V	vmm_softc's vm_lock
169  */
170 struct vm {
171 	struct vmspace		 *vm_vmspace;		/* [K] */
172 	vm_map_t		 vm_map;		/* [K] */
173 	uint32_t		 vm_id;			/* [I] */
174 	pid_t			 vm_creator_pid;	/* [I] */
175 	size_t			 vm_nmemranges;		/* [I] */
176 	size_t			 vm_memory_size;	/* [I] */
177 	char			 vm_name[VMM_MAX_NAME_LEN];
178 	struct vm_mem_range	 vm_memranges[VMM_MAX_MEM_RANGES];
179 	struct refcnt		 vm_refcnt;		/* [a] */
180 
181 	struct vcpu_head	 vm_vcpu_list;		/* [v] */
182 	uint32_t		 vm_vcpu_ct;		/* [v] */
183 	struct rwlock		 vm_vcpu_lock;
184 
185 	SLIST_ENTRY(vm)		 vm_link;		/* [V] */
186 };
187 
188 SLIST_HEAD(vmlist_head, vm);
189 
190 /*
191  * Virtual Machine Monitor
192  *
193  * Methods used to protect struct members in the global vmm device:
194  *	a	atomic opererations
195  *	I	immutable operations
196  *	K	kernel lock
197  *	p	virtual process id (vpid/asid) rwlock
198  *	r	reference count
199  *	v	vm list rwlock (vm_lock)
200  */
201 struct vmm_softc {
202 	struct device		sc_dev;		/* [r] */
203 
204 	/* Suspend/Resume Synchronization */
205 	struct rwlock		sc_slock;
206 	struct refcnt		sc_refcnt;
207 	volatile unsigned int	sc_status;	/* [a] */
208 #define VMM_SUSPENDED		(unsigned int) 0
209 #define VMM_ACTIVE		(unsigned int) 1
210 
211 	struct vmm_softc_md	sc_md;
212 
213 	/* Managed VMs */
214 	struct vmlist_head	vm_list;	/* [v] */
215 
216 	int			mode;		/* [I] */
217 
218 	size_t			vcpu_ct;	/* [v] */
219 	size_t			vcpu_max;	/* [I] */
220 
221 	struct rwlock		vm_lock;
222 	size_t			vm_ct;		/* [v] no. of in-memory VMs */
223 	size_t			vm_idx;		/* [a] next unique VM index */
224 
225 	struct rwlock		vpid_lock;
226 	uint16_t		max_vpid;	/* [I] */
227 	uint8_t			vpids[512];	/* [p] bitmap of VPID/ASIDs */
228 };
229 
230 int vmm_probe(struct device *, void *, void *);
231 int vmm_activate(struct device *, int);
232 void vmm_attach(struct device *, struct device *,  void *);
233 int vmmopen(dev_t, int, int, struct proc *);
234 int vmmclose(dev_t, int, int, struct proc *);
235 int vm_find(uint32_t, struct vm **);
236 int vmmioctl_machdep(dev_t, u_long, caddr_t, int, struct proc *);
237 int pledge_ioctl_vmm(struct proc *, long);
238 struct vcpu *vm_find_vcpu(struct vm *, uint32_t);
239 int vm_create(struct vm_create_params *, struct proc *);
240 size_t vm_create_check_mem_ranges(struct vm_create_params *);
241 void vm_teardown(struct vm **);
242 int vm_get_info(struct vm_info_params *);
243 int vm_terminate(struct vm_terminate_params *);
244 int vm_resetcpu(struct vm_resetcpu_params *);
245 int vm_rwvmparams(struct vm_rwvmparams_params *, int);
246 int vcpu_must_stop(struct vcpu *);
247 int vm_share_mem(struct vm_sharemem_params *, struct proc *);
248 int vm_run(struct vm_run_params *);
249 
250 #ifdef VMM_DEBUG
251 void dump_vcpu(struct vcpu *);
252 #endif
253 
254 #endif /* _KERNEL */
255 #endif /* DEV_VMM_H */
256