xref: /openbsd/sys/dev/vmm/vmm.h (revision 3bef86f7)
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