xref: /openbsd-src/sys/dev/vmm/vmm.h (revision ebaf145fc214b20f93a59c0f55728a6db3a03c40)
1*ebaf145fSbluhm /* $OpenBSD: vmm.h,v 1.7 2024/08/27 09:16:03 bluhm Exp $ */
23a0db596Smlarkin /*
33a0db596Smlarkin  * Copyright (c) 2014-2023 Mike Larkin <mlarkin@openbsd.org>
43a0db596Smlarkin  *
53a0db596Smlarkin  * Permission to use, copy, modify, and distribute this software for any
63a0db596Smlarkin  * purpose with or without fee is hereby granted, provided that the above
73a0db596Smlarkin  * copyright notice and this permission notice appear in all copies.
83a0db596Smlarkin  *
93a0db596Smlarkin  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
103a0db596Smlarkin  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
113a0db596Smlarkin  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
123a0db596Smlarkin  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
133a0db596Smlarkin  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
143a0db596Smlarkin  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
153a0db596Smlarkin  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
163a0db596Smlarkin  */
173a0db596Smlarkin 
183a0db596Smlarkin #include <sys/rwlock.h>
193a0db596Smlarkin #include <sys/refcnt.h>
203a0db596Smlarkin 
213a0db596Smlarkin #include <uvm/uvm_extern.h>
223a0db596Smlarkin 
23ba66f564Sdv #include <machine/vmmvar.h>
24ba66f564Sdv 
2525f7c0b5Smlarkin #ifndef DEV_VMM_H
2625f7c0b5Smlarkin #define DEV_VMM_H
2725f7c0b5Smlarkin 
28ba66f564Sdv #define VMM_MAX_MEM_RANGES	16
29ba66f564Sdv #define VMM_MAX_DISKS_PER_VM	4
30ba66f564Sdv #define VMM_MAX_NAME_LEN	64
31ba66f564Sdv #define VMM_MAX_VCPUS		512
32ba66f564Sdv #define VMM_MAX_VCPUS_PER_VM	64
33ba66f564Sdv #define VMM_MAX_VM_MEM_SIZE	128L * 1024 * 1024 * 1024
34ba66f564Sdv #define VMM_MAX_NICS_PER_VM	4
35ba66f564Sdv 
3625f7c0b5Smlarkin struct vm_mem_range {
3725f7c0b5Smlarkin 	paddr_t vmr_gpa;
3825f7c0b5Smlarkin 	vaddr_t vmr_va;
3925f7c0b5Smlarkin 	size_t  vmr_size;
4025f7c0b5Smlarkin 	int     vmr_type;
4125f7c0b5Smlarkin #define VM_MEM_RAM		0	/* Presented as usable system memory. */
4225f7c0b5Smlarkin #define VM_MEM_RESERVED		1	/* Reserved for BIOS, etc. */
4325f7c0b5Smlarkin #define VM_MEM_MMIO		2	/* Special region for device mmio. */
4425f7c0b5Smlarkin };
4525f7c0b5Smlarkin 
4625f7c0b5Smlarkin struct vm_create_params {
4725f7c0b5Smlarkin /* Input parameters to VMM_IOC_CREATE */
4825f7c0b5Smlarkin 	size_t			vcp_nmemranges;
4925f7c0b5Smlarkin 	size_t			vcp_ncpus;
5025f7c0b5Smlarkin 	struct vm_mem_range	vcp_memranges[VMM_MAX_MEM_RANGES];
5125f7c0b5Smlarkin 	char			vcp_name[VMM_MAX_NAME_LEN];
52*ebaf145fSbluhm 	int			vcp_sev;
5325f7c0b5Smlarkin 
5425f7c0b5Smlarkin         /* Output parameter from VMM_IOC_CREATE */
5525f7c0b5Smlarkin         uint32_t		vcp_id;
56*ebaf145fSbluhm         uint32_t		vcp_poscbit;
57*ebaf145fSbluhm         uint32_t		vcp_asid[VMM_MAX_VCPUS];
5825f7c0b5Smlarkin };
5925f7c0b5Smlarkin 
6025f7c0b5Smlarkin struct vm_info_result {
6125f7c0b5Smlarkin 	/* Output parameters from VMM_IOC_INFO */
6225f7c0b5Smlarkin 	size_t		vir_memory_size;
6325f7c0b5Smlarkin 	size_t		vir_used_size;
6425f7c0b5Smlarkin 	size_t		vir_ncpus;
6525f7c0b5Smlarkin 	uint8_t		vir_vcpu_state[VMM_MAX_VCPUS_PER_VM];
6625f7c0b5Smlarkin 	pid_t		vir_creator_pid;
6725f7c0b5Smlarkin 	uint32_t	vir_id;
6825f7c0b5Smlarkin 	char		vir_name[VMM_MAX_NAME_LEN];
6925f7c0b5Smlarkin };
7025f7c0b5Smlarkin 
7125f7c0b5Smlarkin struct vm_info_params {
7225f7c0b5Smlarkin 	/* Input parameters to VMM_IOC_INFO */
7325f7c0b5Smlarkin 	size_t			 vip_size;	/* Output buffer size */
7425f7c0b5Smlarkin 
7525f7c0b5Smlarkin 	/* Output Parameters from VMM_IOC_INFO */
7625f7c0b5Smlarkin 	size_t			 vip_info_ct;	/* # of entries returned */
7725f7c0b5Smlarkin 	struct vm_info_result	*vip_info;	/* Output buffer */
7825f7c0b5Smlarkin };
7925f7c0b5Smlarkin 
8025f7c0b5Smlarkin struct vm_terminate_params {
8125f7c0b5Smlarkin 	/* Input parameters to VMM_IOC_TERM */
8225f7c0b5Smlarkin 	uint32_t		vtp_vm_id;
8325f7c0b5Smlarkin };
8425f7c0b5Smlarkin 
8525f7c0b5Smlarkin struct vm_resetcpu_params {
8625f7c0b5Smlarkin 	/* Input parameters to VMM_IOC_RESETCPU */
8725f7c0b5Smlarkin 	uint32_t		vrp_vm_id;
8825f7c0b5Smlarkin 	uint32_t		vrp_vcpu_id;
8925f7c0b5Smlarkin 	struct vcpu_reg_state	vrp_init_state;
9025f7c0b5Smlarkin };
9125f7c0b5Smlarkin 
923c817da7Sdv struct vm_sharemem_params {
933c817da7Sdv 	/* Input parameters to VMM_IOC_SHAREMEM */
943c817da7Sdv 	uint32_t		vsp_vm_id;
953c817da7Sdv 	size_t			vsp_nmemranges;
963c817da7Sdv 	struct vm_mem_range	vsp_memranges[VMM_MAX_MEM_RANGES];
973c817da7Sdv };
983c817da7Sdv 
99ba66f564Sdv struct vm_run_params {
100ba66f564Sdv 	/* Input parameters to VMM_IOC_RUN */
101ba66f564Sdv 	uint32_t	vrp_vm_id;
102ba66f564Sdv 	uint32_t	vrp_vcpu_id;
103ba66f564Sdv 	struct vcpu_inject_event	vrp_inject;
104ba66f564Sdv 	uint8_t		vrp_intr_pending;	/* Additional intrs pending? */
105ba66f564Sdv 
106ba66f564Sdv 	/* Input/output parameter to VMM_IOC_RUN */
107ba66f564Sdv 	struct vm_exit	*vrp_exit;		/* updated exit data */
108ba66f564Sdv 
109ba66f564Sdv 	/* Output parameter from VMM_IOC_RUN */
110ba66f564Sdv 	uint16_t	vrp_exit_reason;	/* exit reason */
111ba66f564Sdv 	uint8_t		vrp_irqready;		/* ready for IRQ on entry */
112ba66f564Sdv };
113ba66f564Sdv 
114234ee546Sdv #define VM_RWVMPARAMS_PVCLOCK_SYSTEM_GPA 0x1	/* read/write pvclock gpa */
115234ee546Sdv #define VM_RWVMPARAMS_PVCLOCK_VERSION	 0x2	/* read/write pvclock version */
116234ee546Sdv #define VM_RWVMPARAMS_ALL	(VM_RWVMPARAMS_PVCLOCK_SYSTEM_GPA | \
117234ee546Sdv     VM_RWVMPARAMS_PVCLOCK_VERSION)
118234ee546Sdv 
119234ee546Sdv struct vm_rwvmparams_params {
120234ee546Sdv 	/* Input parameters to VMM_IOC_READVMPARAMS/VMM_IOC_WRITEVMPARAMS */
121234ee546Sdv 	uint32_t		vpp_vm_id;
122234ee546Sdv 	uint32_t		vpp_vcpu_id;
123234ee546Sdv 	uint32_t		vpp_mask;
124234ee546Sdv 	paddr_t			vpp_pvclock_system_gpa;
125234ee546Sdv 	uint32_t		vpp_pvclock_version;
126234ee546Sdv };
127234ee546Sdv 
12825f7c0b5Smlarkin /* IOCTL definitions */
12925f7c0b5Smlarkin #define VMM_IOC_CREATE _IOWR('V', 1, struct vm_create_params) /* Create VM */
13025f7c0b5Smlarkin #define VMM_IOC_RUN _IOWR('V', 2, struct vm_run_params) /* Run VCPU */
13125f7c0b5Smlarkin #define VMM_IOC_INFO _IOWR('V', 3, struct vm_info_params) /* Get VM Info */
13225f7c0b5Smlarkin #define VMM_IOC_TERM _IOW('V', 4, struct vm_terminate_params) /* Terminate VM */
13325f7c0b5Smlarkin #define VMM_IOC_RESETCPU _IOW('V', 5, struct vm_resetcpu_params) /* Reset */
13425f7c0b5Smlarkin #define VMM_IOC_READREGS _IOWR('V', 7, struct vm_rwregs_params) /* Get regs */
13525f7c0b5Smlarkin #define VMM_IOC_WRITEREGS _IOW('V', 8, struct vm_rwregs_params) /* Set regs */
13625f7c0b5Smlarkin /* Get VM params */
13725f7c0b5Smlarkin #define VMM_IOC_READVMPARAMS _IOWR('V', 9, struct vm_rwvmparams_params)
13825f7c0b5Smlarkin /* Set VM params */
13925f7c0b5Smlarkin #define VMM_IOC_WRITEVMPARAMS _IOW('V', 10, struct vm_rwvmparams_params)
1403c817da7Sdv #define VMM_IOC_SHAREMEM _IOW('V', 11, struct vm_sharemem_params)
14125f7c0b5Smlarkin 
14225f7c0b5Smlarkin #ifdef _KERNEL
14325f7c0b5Smlarkin 
1443a0db596Smlarkin /* #define VMM_DEBUG */
1453a0db596Smlarkin 
1463a0db596Smlarkin #ifdef VMM_DEBUG
1473a0db596Smlarkin #define DPRINTF(x...)   do { printf(x); } while(0)
1483a0db596Smlarkin #else
1493a0db596Smlarkin #define DPRINTF(x...)
1503a0db596Smlarkin #endif /* VMM_DEBUG */
1513a0db596Smlarkin enum {
1523a0db596Smlarkin 	VCPU_STATE_STOPPED,
1533a0db596Smlarkin 	VCPU_STATE_RUNNING,
1543a0db596Smlarkin 	VCPU_STATE_REQTERM,
1553a0db596Smlarkin 	VCPU_STATE_TERMINATED,
1563a0db596Smlarkin 	VCPU_STATE_UNKNOWN,
1573a0db596Smlarkin };
1583a0db596Smlarkin 
1593a0db596Smlarkin /*
1603a0db596Smlarkin  * Virtual Machine
1613a0db596Smlarkin  *
1623a0db596Smlarkin  * Methods used to protect vm struct members:
1633a0db596Smlarkin  *	a	atomic operations
1643a0db596Smlarkin  *	I	immutable after create
1653a0db596Smlarkin  *	K	kernel lock
1663a0db596Smlarkin  *	r	reference count
1673a0db596Smlarkin  *	v	vcpu list rwlock (vm_vcpu_list)
1683a0db596Smlarkin  *	V	vmm_softc's vm_lock
1693a0db596Smlarkin  */
1703a0db596Smlarkin struct vm {
1713a0db596Smlarkin 	struct vmspace		 *vm_vmspace;		/* [K] */
1723a0db596Smlarkin 	vm_map_t		 vm_map;		/* [K] */
1733a0db596Smlarkin 	uint32_t		 vm_id;			/* [I] */
1743a0db596Smlarkin 	pid_t			 vm_creator_pid;	/* [I] */
1753a0db596Smlarkin 	size_t			 vm_nmemranges;		/* [I] */
1763a0db596Smlarkin 	size_t			 vm_memory_size;	/* [I] */
1773a0db596Smlarkin 	char			 vm_name[VMM_MAX_NAME_LEN];
1783a0db596Smlarkin 	struct vm_mem_range	 vm_memranges[VMM_MAX_MEM_RANGES];
1793a0db596Smlarkin 	struct refcnt		 vm_refcnt;		/* [a] */
1803a0db596Smlarkin 
1813a0db596Smlarkin 	struct vcpu_head	 vm_vcpu_list;		/* [v] */
1823a0db596Smlarkin 	uint32_t		 vm_vcpu_ct;		/* [v] */
1833a0db596Smlarkin 	struct rwlock		 vm_vcpu_lock;
1843a0db596Smlarkin 
1853a0db596Smlarkin 	SLIST_ENTRY(vm)		 vm_link;		/* [V] */
1863a0db596Smlarkin };
1873a0db596Smlarkin 
1883a0db596Smlarkin SLIST_HEAD(vmlist_head, vm);
1893a0db596Smlarkin 
1903a0db596Smlarkin /*
1913a0db596Smlarkin  * Virtual Machine Monitor
1923a0db596Smlarkin  *
1933a0db596Smlarkin  * Methods used to protect struct members in the global vmm device:
1943a0db596Smlarkin  *	a	atomic opererations
1953a0db596Smlarkin  *	I	immutable operations
1963a0db596Smlarkin  *	K	kernel lock
1973a0db596Smlarkin  *	p	virtual process id (vpid/asid) rwlock
1983a0db596Smlarkin  *	r	reference count
1993a0db596Smlarkin  *	v	vm list rwlock (vm_lock)
2003a0db596Smlarkin  */
2013a0db596Smlarkin struct vmm_softc {
2023a0db596Smlarkin 	struct device		sc_dev;		/* [r] */
2033a0db596Smlarkin 
2043a0db596Smlarkin 	/* Suspend/Resume Synchronization */
2053a0db596Smlarkin 	struct rwlock		sc_slock;
2063a0db596Smlarkin 	struct refcnt		sc_refcnt;
2073a0db596Smlarkin 	volatile unsigned int	sc_status;	/* [a] */
2083a0db596Smlarkin #define VMM_SUSPENDED		(unsigned int) 0
2093a0db596Smlarkin #define VMM_ACTIVE		(unsigned int) 1
2103a0db596Smlarkin 
2113a0db596Smlarkin 	struct vmm_softc_md	sc_md;
2123a0db596Smlarkin 
2133a0db596Smlarkin 	/* Managed VMs */
2143a0db596Smlarkin 	struct vmlist_head	vm_list;	/* [v] */
2153a0db596Smlarkin 
2163a0db596Smlarkin 	int			mode;		/* [I] */
2173a0db596Smlarkin 
2183a0db596Smlarkin 	size_t			vcpu_ct;	/* [v] */
2193a0db596Smlarkin 	size_t			vcpu_max;	/* [I] */
2203a0db596Smlarkin 
2213a0db596Smlarkin 	struct rwlock		vm_lock;
2223a0db596Smlarkin 	size_t			vm_ct;		/* [v] no. of in-memory VMs */
2233a0db596Smlarkin 	size_t			vm_idx;		/* [a] next unique VM index */
2243a0db596Smlarkin 
2253a0db596Smlarkin 	struct rwlock		vpid_lock;
2263a0db596Smlarkin 	uint16_t		max_vpid;	/* [I] */
2273a0db596Smlarkin 	uint8_t			vpids[512];	/* [p] bitmap of VPID/ASIDs */
2283a0db596Smlarkin };
2293a0db596Smlarkin 
2303a0db596Smlarkin int vmm_probe(struct device *, void *, void *);
2313a0db596Smlarkin int vmm_activate(struct device *, int);
2323a0db596Smlarkin void vmm_attach(struct device *, struct device *,  void *);
2333a0db596Smlarkin int vmmopen(dev_t, int, int, struct proc *);
2343a0db596Smlarkin int vmmclose(dev_t, int, int, struct proc *);
2353a0db596Smlarkin int vm_find(uint32_t, struct vm **);
2363a0db596Smlarkin int vmmioctl_machdep(dev_t, u_long, caddr_t, int, struct proc *);
2373a0db596Smlarkin int pledge_ioctl_vmm(struct proc *, long);
2383a0db596Smlarkin struct vcpu *vm_find_vcpu(struct vm *, uint32_t);
2393a0db596Smlarkin int vm_create(struct vm_create_params *, struct proc *);
2403a0db596Smlarkin size_t vm_create_check_mem_ranges(struct vm_create_params *);
2413a0db596Smlarkin void vm_teardown(struct vm **);
2423a0db596Smlarkin int vm_get_info(struct vm_info_params *);
2433a0db596Smlarkin int vm_terminate(struct vm_terminate_params *);
2443a0db596Smlarkin int vm_resetcpu(struct vm_resetcpu_params *);
245234ee546Sdv int vm_rwvmparams(struct vm_rwvmparams_params *, int);
2463a0db596Smlarkin int vcpu_must_stop(struct vcpu *);
2473c817da7Sdv int vm_share_mem(struct vm_sharemem_params *, struct proc *);
248ba66f564Sdv int vm_run(struct vm_run_params *);
2493a0db596Smlarkin 
2503aa75afeSjan #ifdef VMM_DEBUG
2513aa75afeSjan void dump_vcpu(struct vcpu *);
2523aa75afeSjan #endif
2533aa75afeSjan 
25425f7c0b5Smlarkin #endif /* _KERNEL */
25525f7c0b5Smlarkin #endif /* DEV_VMM_H */
256