xref: /linux/drivers/virt/acrn/acrn_drv.h (revision 0ea5c948cb64bab5bc7a5516774eb8536f05aa0d)
1666834c4SShuo Liu /* SPDX-License-Identifier: GPL-2.0 */
2666834c4SShuo Liu 
3666834c4SShuo Liu #ifndef __ACRN_HSM_DRV_H
4666834c4SShuo Liu #define __ACRN_HSM_DRV_H
5666834c4SShuo Liu 
69c5137aeSShuo Liu #include <linux/acrn.h>
79c5137aeSShuo Liu #include <linux/dev_printk.h>
89c5137aeSShuo Liu #include <linux/miscdevice.h>
9666834c4SShuo Liu #include <linux/types.h>
10666834c4SShuo Liu 
119c5137aeSShuo Liu #include "hypercall.h"
129c5137aeSShuo Liu 
139c5137aeSShuo Liu extern struct miscdevice acrn_dev;
149c5137aeSShuo Liu 
1572f293deSShuo Liu #define ACRN_NAME_LEN		16
1688f537d5SShuo Liu #define ACRN_MEM_MAPPING_MAX	256
1788f537d5SShuo Liu 
1888f537d5SShuo Liu #define ACRN_MEM_REGION_ADD	0
1988f537d5SShuo Liu #define ACRN_MEM_REGION_DEL	2
2072f293deSShuo Liu 
2172f293deSShuo Liu struct acrn_vm;
2272f293deSShuo Liu struct acrn_ioreq_client;
2372f293deSShuo Liu 
2488f537d5SShuo Liu /**
2588f537d5SShuo Liu  * struct vm_memory_region_op - Hypervisor memory operation
2688f537d5SShuo Liu  * @type:		Operation type (ACRN_MEM_REGION_*)
2788f537d5SShuo Liu  * @attr:		Memory attribute (ACRN_MEM_TYPE_* | ACRN_MEM_ACCESS_*)
2888f537d5SShuo Liu  * @user_vm_pa:		Physical address of User VM to be mapped.
2988f537d5SShuo Liu  * @service_vm_pa:	Physical address of Service VM to be mapped.
3088f537d5SShuo Liu  * @size:		Size of this region.
3188f537d5SShuo Liu  *
3288f537d5SShuo Liu  * Structure containing needed information that is provided to ACRN Hypervisor
3388f537d5SShuo Liu  * to manage the EPT mappings of a single memory region of the User VM. Several
3488f537d5SShuo Liu  * &struct vm_memory_region_op can be batched to ACRN Hypervisor, see &struct
3588f537d5SShuo Liu  * vm_memory_region_batch.
3688f537d5SShuo Liu  */
3788f537d5SShuo Liu struct vm_memory_region_op {
3888f537d5SShuo Liu 	u32	type;
3988f537d5SShuo Liu 	u32	attr;
4088f537d5SShuo Liu 	u64	user_vm_pa;
4188f537d5SShuo Liu 	u64	service_vm_pa;
4288f537d5SShuo Liu 	u64	size;
4388f537d5SShuo Liu };
4488f537d5SShuo Liu 
4588f537d5SShuo Liu /**
4688f537d5SShuo Liu  * struct vm_memory_region_batch - A batch of vm_memory_region_op.
4788f537d5SShuo Liu  * @vmid:		A User VM ID.
4888f537d5SShuo Liu  * @reserved:		Reserved.
4988f537d5SShuo Liu  * @regions_num:	The number of vm_memory_region_op.
5088f537d5SShuo Liu  * @regions_gpa:	Physical address of a vm_memory_region_op array.
51746f1b0aSLen Baker  * @regions_op:		Flexible array of vm_memory_region_op.
5288f537d5SShuo Liu  *
5388f537d5SShuo Liu  * HC_VM_SET_MEMORY_REGIONS uses this structure to manage EPT mappings of
5488f537d5SShuo Liu  * multiple memory regions of a User VM. A &struct vm_memory_region_batch
5588f537d5SShuo Liu  * contains multiple &struct vm_memory_region_op for batch processing in the
5688f537d5SShuo Liu  * ACRN Hypervisor.
5788f537d5SShuo Liu  */
5888f537d5SShuo Liu struct vm_memory_region_batch {
5988f537d5SShuo Liu 	u16			   vmid;
6088f537d5SShuo Liu 	u16			   reserved[3];
6188f537d5SShuo Liu 	u32			   regions_num;
6288f537d5SShuo Liu 	u64			   regions_gpa;
63*51a71ab2SKees Cook 	struct vm_memory_region_op regions_op[] __counted_by(regions_num);
6488f537d5SShuo Liu };
6588f537d5SShuo Liu 
6688f537d5SShuo Liu /**
6788f537d5SShuo Liu  * struct vm_memory_mapping - Memory map between a User VM and the Service VM
6888f537d5SShuo Liu  * @pages:		Pages in Service VM kernel.
6988f537d5SShuo Liu  * @npages:		Number of pages.
7088f537d5SShuo Liu  * @service_vm_va:	Virtual address in Service VM kernel.
7188f537d5SShuo Liu  * @user_vm_pa:		Physical address in User VM.
7288f537d5SShuo Liu  * @size:		Size of this memory region.
7388f537d5SShuo Liu  *
7488f537d5SShuo Liu  * HSM maintains memory mappings between a User VM GPA and the Service VM
7588f537d5SShuo Liu  * kernel VA for accelerating the User VM GPA translation.
7688f537d5SShuo Liu  */
7788f537d5SShuo Liu struct vm_memory_mapping {
7888f537d5SShuo Liu 	struct page	**pages;
7988f537d5SShuo Liu 	int		npages;
8088f537d5SShuo Liu 	void		*service_vm_va;
8188f537d5SShuo Liu 	u64		user_vm_pa;
8288f537d5SShuo Liu 	size_t		size;
8388f537d5SShuo Liu };
8488f537d5SShuo Liu 
8572f293deSShuo Liu /**
8672f293deSShuo Liu  * struct acrn_ioreq_buffer - Data for setting the ioreq buffer of User VM
8772f293deSShuo Liu  * @ioreq_buf:	The GPA of the IO request shared buffer of a VM
8872f293deSShuo Liu  *
8972f293deSShuo Liu  * The parameter for the HC_SET_IOREQ_BUFFER hypercall used to set up
9072f293deSShuo Liu  * the shared I/O request buffer between Service VM and ACRN hypervisor.
9172f293deSShuo Liu  */
9272f293deSShuo Liu struct acrn_ioreq_buffer {
9372f293deSShuo Liu 	u64	ioreq_buf;
9472f293deSShuo Liu };
9572f293deSShuo Liu 
9672f293deSShuo Liu struct acrn_ioreq_range {
9772f293deSShuo Liu 	struct list_head	list;
9872f293deSShuo Liu 	u32			type;
9972f293deSShuo Liu 	u64			start;
10072f293deSShuo Liu 	u64			end;
10172f293deSShuo Liu };
10272f293deSShuo Liu 
10372f293deSShuo Liu #define ACRN_IOREQ_CLIENT_DESTROYING	0U
10472f293deSShuo Liu typedef	int (*ioreq_handler_t)(struct acrn_ioreq_client *client,
10572f293deSShuo Liu 			       struct acrn_io_request *req);
10672f293deSShuo Liu /**
10772f293deSShuo Liu  * struct acrn_ioreq_client - Structure of I/O client.
10872f293deSShuo Liu  * @name:	Client name
10972f293deSShuo Liu  * @vm:		The VM that the client belongs to
11072f293deSShuo Liu  * @list:	List node for this acrn_ioreq_client
11172f293deSShuo Liu  * @is_default:	If this client is the default one
11272f293deSShuo Liu  * @flags:	Flags (ACRN_IOREQ_CLIENT_*)
11372f293deSShuo Liu  * @range_list:	I/O ranges
11472f293deSShuo Liu  * @range_lock:	Lock to protect range_list
11572f293deSShuo Liu  * @ioreqs_map:	The pending I/O requests bitmap.
11672f293deSShuo Liu  * @handler:	I/O requests handler of this client
11772f293deSShuo Liu  * @thread:	The thread which executes the handler
11872f293deSShuo Liu  * @wq:		The wait queue for the handler thread parking
11972f293deSShuo Liu  * @priv:	Data for the thread
12072f293deSShuo Liu  */
12172f293deSShuo Liu struct acrn_ioreq_client {
12272f293deSShuo Liu 	char			name[ACRN_NAME_LEN];
12372f293deSShuo Liu 	struct acrn_vm		*vm;
12472f293deSShuo Liu 	struct list_head	list;
12572f293deSShuo Liu 	bool			is_default;
12672f293deSShuo Liu 	unsigned long		flags;
12772f293deSShuo Liu 	struct list_head	range_list;
12872f293deSShuo Liu 	rwlock_t		range_lock;
12972f293deSShuo Liu 	DECLARE_BITMAP(ioreqs_map, ACRN_IO_REQUEST_MAX);
13072f293deSShuo Liu 	ioreq_handler_t		handler;
13172f293deSShuo Liu 	struct task_struct	*thread;
13272f293deSShuo Liu 	wait_queue_head_t	wq;
13372f293deSShuo Liu 	void			*priv;
13472f293deSShuo Liu };
13572f293deSShuo Liu 
136666834c4SShuo Liu #define ACRN_INVALID_VMID (0xffffU)
137666834c4SShuo Liu 
1389c5137aeSShuo Liu #define ACRN_VM_FLAG_DESTROYED		0U
13972f293deSShuo Liu #define ACRN_VM_FLAG_CLEARING_IOREQ	1U
14072f293deSShuo Liu extern struct list_head acrn_vm_list;
14172f293deSShuo Liu extern rwlock_t acrn_vm_list_lock;
142666834c4SShuo Liu /**
143666834c4SShuo Liu  * struct acrn_vm - Properties of ACRN User VM.
14488f537d5SShuo Liu  * @list:			Entry within global list of all VMs.
14588f537d5SShuo Liu  * @vmid:			User VM ID.
14688f537d5SShuo Liu  * @vcpu_num:			Number of virtual CPUs in the VM.
14788f537d5SShuo Liu  * @flags:			Flags (ACRN_VM_FLAG_*) of the VM. This is VM
14888f537d5SShuo Liu  *				flag management in HSM which is different
14988f537d5SShuo Liu  *				from the &acrn_vm_creation.vm_flag.
15088f537d5SShuo Liu  * @regions_mapping_lock:	Lock to protect &acrn_vm.regions_mapping and
15188f537d5SShuo Liu  *				&acrn_vm.regions_mapping_count.
15288f537d5SShuo Liu  * @regions_mapping:		Memory mappings of this VM.
15388f537d5SShuo Liu  * @regions_mapping_count:	Number of memory mapping of this VM.
15472f293deSShuo Liu  * @ioreq_clients_lock:		Lock to protect ioreq_clients and default_client
15572f293deSShuo Liu  * @ioreq_clients:		The I/O request clients list of this VM
15672f293deSShuo Liu  * @default_client:		The default I/O request client
15772f293deSShuo Liu  * @ioreq_buf:			I/O request shared buffer
15872f293deSShuo Liu  * @ioreq_page:			The page of the I/O request shared buffer
1593c4c3316SShuo Liu  * @pci_conf_addr:		Address of a PCI configuration access emulation
160c7cf8d27SShuo Liu  * @monitor_page:		Page of interrupt statistics of User VM
161d8ad5151SShuo Liu  * @ioeventfds_lock:		Lock to protect ioeventfds list
162d8ad5151SShuo Liu  * @ioeventfds:			List to link all hsm_ioeventfd
163d8ad5151SShuo Liu  * @ioeventfd_client:		I/O client for ioeventfds of the VM
164aa3b483fSShuo Liu  * @irqfds_lock:		Lock to protect irqfds list
165aa3b483fSShuo Liu  * @irqfds:			List to link all hsm_irqfd
166aa3b483fSShuo Liu  * @irqfd_wq:			Workqueue for irqfd async shutdown
167666834c4SShuo Liu  */
168666834c4SShuo Liu struct acrn_vm {
1699c5137aeSShuo Liu 	struct list_head		list;
170666834c4SShuo Liu 	u16				vmid;
1719c5137aeSShuo Liu 	int				vcpu_num;
1729c5137aeSShuo Liu 	unsigned long			flags;
17388f537d5SShuo Liu 	struct mutex			regions_mapping_lock;
17488f537d5SShuo Liu 	struct vm_memory_mapping	regions_mapping[ACRN_MEM_MAPPING_MAX];
17588f537d5SShuo Liu 	int				regions_mapping_count;
17672f293deSShuo Liu 	spinlock_t			ioreq_clients_lock;
17772f293deSShuo Liu 	struct list_head		ioreq_clients;
17872f293deSShuo Liu 	struct acrn_ioreq_client	*default_client;
17972f293deSShuo Liu 	struct acrn_io_request_buffer	*ioreq_buf;
18072f293deSShuo Liu 	struct page			*ioreq_page;
1813c4c3316SShuo Liu 	u32				pci_conf_addr;
182c7cf8d27SShuo Liu 	struct page			*monitor_page;
183d8ad5151SShuo Liu 	struct mutex			ioeventfds_lock;
184d8ad5151SShuo Liu 	struct list_head		ioeventfds;
185d8ad5151SShuo Liu 	struct acrn_ioreq_client	*ioeventfd_client;
186aa3b483fSShuo Liu 	struct mutex			irqfds_lock;
187aa3b483fSShuo Liu 	struct list_head		irqfds;
188aa3b483fSShuo Liu 	struct workqueue_struct		*irqfd_wq;
189666834c4SShuo Liu };
190666834c4SShuo Liu 
1919c5137aeSShuo Liu struct acrn_vm *acrn_vm_create(struct acrn_vm *vm,
1929c5137aeSShuo Liu 			       struct acrn_vm_creation *vm_param);
1939c5137aeSShuo Liu int acrn_vm_destroy(struct acrn_vm *vm);
19488f537d5SShuo Liu int acrn_mm_region_add(struct acrn_vm *vm, u64 user_gpa, u64 service_gpa,
19588f537d5SShuo Liu 		       u64 size, u32 mem_type, u32 mem_access_right);
19688f537d5SShuo Liu int acrn_mm_region_del(struct acrn_vm *vm, u64 user_gpa, u64 size);
19788f537d5SShuo Liu int acrn_vm_memseg_map(struct acrn_vm *vm, struct acrn_vm_memmap *memmap);
19888f537d5SShuo Liu int acrn_vm_memseg_unmap(struct acrn_vm *vm, struct acrn_vm_memmap *memmap);
19988f537d5SShuo Liu int acrn_vm_ram_map(struct acrn_vm *vm, struct acrn_vm_memmap *memmap);
20088f537d5SShuo Liu void acrn_vm_all_ram_unmap(struct acrn_vm *vm);
2019c5137aeSShuo Liu 
20272f293deSShuo Liu int acrn_ioreq_init(struct acrn_vm *vm, u64 buf_vma);
20372f293deSShuo Liu void acrn_ioreq_deinit(struct acrn_vm *vm);
20472f293deSShuo Liu int acrn_ioreq_intr_setup(void);
20572f293deSShuo Liu void acrn_ioreq_intr_remove(void);
20672f293deSShuo Liu void acrn_ioreq_request_clear(struct acrn_vm *vm);
20772f293deSShuo Liu int acrn_ioreq_client_wait(struct acrn_ioreq_client *client);
20872f293deSShuo Liu int acrn_ioreq_request_default_complete(struct acrn_vm *vm, u16 vcpu);
20972f293deSShuo Liu struct acrn_ioreq_client *acrn_ioreq_client_create(struct acrn_vm *vm,
21072f293deSShuo Liu 						   ioreq_handler_t handler,
21172f293deSShuo Liu 						   void *data, bool is_default,
21272f293deSShuo Liu 						   const char *name);
21372f293deSShuo Liu void acrn_ioreq_client_destroy(struct acrn_ioreq_client *client);
2145a0c9f17SShuo Liu int acrn_ioreq_range_add(struct acrn_ioreq_client *client,
2155a0c9f17SShuo Liu 			 u32 type, u64 start, u64 end);
2165a0c9f17SShuo Liu void acrn_ioreq_range_del(struct acrn_ioreq_client *client,
2175a0c9f17SShuo Liu 			  u32 type, u64 start, u64 end);
21872f293deSShuo Liu 
219c7cf8d27SShuo Liu int acrn_msi_inject(struct acrn_vm *vm, u64 msi_addr, u64 msi_data);
220c7cf8d27SShuo Liu 
221d8ad5151SShuo Liu int acrn_ioeventfd_init(struct acrn_vm *vm);
222d8ad5151SShuo Liu int acrn_ioeventfd_config(struct acrn_vm *vm, struct acrn_ioeventfd *args);
223d8ad5151SShuo Liu void acrn_ioeventfd_deinit(struct acrn_vm *vm);
224d8ad5151SShuo Liu 
225aa3b483fSShuo Liu int acrn_irqfd_init(struct acrn_vm *vm);
226aa3b483fSShuo Liu int acrn_irqfd_config(struct acrn_vm *vm, struct acrn_irqfd *args);
227aa3b483fSShuo Liu void acrn_irqfd_deinit(struct acrn_vm *vm);
228aa3b483fSShuo Liu 
229666834c4SShuo Liu #endif /* __ACRN_HSM_DRV_H */
230