162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci#ifndef __ACRN_HSM_DRV_H
462306a36Sopenharmony_ci#define __ACRN_HSM_DRV_H
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include <linux/acrn.h>
762306a36Sopenharmony_ci#include <linux/dev_printk.h>
862306a36Sopenharmony_ci#include <linux/miscdevice.h>
962306a36Sopenharmony_ci#include <linux/types.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include "hypercall.h"
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ciextern struct miscdevice acrn_dev;
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#define ACRN_NAME_LEN		16
1662306a36Sopenharmony_ci#define ACRN_MEM_MAPPING_MAX	256
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#define ACRN_MEM_REGION_ADD	0
1962306a36Sopenharmony_ci#define ACRN_MEM_REGION_DEL	2
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_cistruct acrn_vm;
2262306a36Sopenharmony_cistruct acrn_ioreq_client;
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci/**
2562306a36Sopenharmony_ci * struct vm_memory_region_op - Hypervisor memory operation
2662306a36Sopenharmony_ci * @type:		Operation type (ACRN_MEM_REGION_*)
2762306a36Sopenharmony_ci * @attr:		Memory attribute (ACRN_MEM_TYPE_* | ACRN_MEM_ACCESS_*)
2862306a36Sopenharmony_ci * @user_vm_pa:		Physical address of User VM to be mapped.
2962306a36Sopenharmony_ci * @service_vm_pa:	Physical address of Service VM to be mapped.
3062306a36Sopenharmony_ci * @size:		Size of this region.
3162306a36Sopenharmony_ci *
3262306a36Sopenharmony_ci * Structure containing needed information that is provided to ACRN Hypervisor
3362306a36Sopenharmony_ci * to manage the EPT mappings of a single memory region of the User VM. Several
3462306a36Sopenharmony_ci * &struct vm_memory_region_op can be batched to ACRN Hypervisor, see &struct
3562306a36Sopenharmony_ci * vm_memory_region_batch.
3662306a36Sopenharmony_ci */
3762306a36Sopenharmony_cistruct vm_memory_region_op {
3862306a36Sopenharmony_ci	u32	type;
3962306a36Sopenharmony_ci	u32	attr;
4062306a36Sopenharmony_ci	u64	user_vm_pa;
4162306a36Sopenharmony_ci	u64	service_vm_pa;
4262306a36Sopenharmony_ci	u64	size;
4362306a36Sopenharmony_ci};
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci/**
4662306a36Sopenharmony_ci * struct vm_memory_region_batch - A batch of vm_memory_region_op.
4762306a36Sopenharmony_ci * @vmid:		A User VM ID.
4862306a36Sopenharmony_ci * @reserved:		Reserved.
4962306a36Sopenharmony_ci * @regions_num:	The number of vm_memory_region_op.
5062306a36Sopenharmony_ci * @regions_gpa:	Physical address of a vm_memory_region_op array.
5162306a36Sopenharmony_ci * @regions_op:		Flexible array of vm_memory_region_op.
5262306a36Sopenharmony_ci *
5362306a36Sopenharmony_ci * HC_VM_SET_MEMORY_REGIONS uses this structure to manage EPT mappings of
5462306a36Sopenharmony_ci * multiple memory regions of a User VM. A &struct vm_memory_region_batch
5562306a36Sopenharmony_ci * contains multiple &struct vm_memory_region_op for batch processing in the
5662306a36Sopenharmony_ci * ACRN Hypervisor.
5762306a36Sopenharmony_ci */
5862306a36Sopenharmony_cistruct vm_memory_region_batch {
5962306a36Sopenharmony_ci	u16			   vmid;
6062306a36Sopenharmony_ci	u16			   reserved[3];
6162306a36Sopenharmony_ci	u32			   regions_num;
6262306a36Sopenharmony_ci	u64			   regions_gpa;
6362306a36Sopenharmony_ci	struct vm_memory_region_op regions_op[];
6462306a36Sopenharmony_ci};
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci/**
6762306a36Sopenharmony_ci * struct vm_memory_mapping - Memory map between a User VM and the Service VM
6862306a36Sopenharmony_ci * @pages:		Pages in Service VM kernel.
6962306a36Sopenharmony_ci * @npages:		Number of pages.
7062306a36Sopenharmony_ci * @service_vm_va:	Virtual address in Service VM kernel.
7162306a36Sopenharmony_ci * @user_vm_pa:		Physical address in User VM.
7262306a36Sopenharmony_ci * @size:		Size of this memory region.
7362306a36Sopenharmony_ci *
7462306a36Sopenharmony_ci * HSM maintains memory mappings between a User VM GPA and the Service VM
7562306a36Sopenharmony_ci * kernel VA for accelerating the User VM GPA translation.
7662306a36Sopenharmony_ci */
7762306a36Sopenharmony_cistruct vm_memory_mapping {
7862306a36Sopenharmony_ci	struct page	**pages;
7962306a36Sopenharmony_ci	int		npages;
8062306a36Sopenharmony_ci	void		*service_vm_va;
8162306a36Sopenharmony_ci	u64		user_vm_pa;
8262306a36Sopenharmony_ci	size_t		size;
8362306a36Sopenharmony_ci};
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci/**
8662306a36Sopenharmony_ci * struct acrn_ioreq_buffer - Data for setting the ioreq buffer of User VM
8762306a36Sopenharmony_ci * @ioreq_buf:	The GPA of the IO request shared buffer of a VM
8862306a36Sopenharmony_ci *
8962306a36Sopenharmony_ci * The parameter for the HC_SET_IOREQ_BUFFER hypercall used to set up
9062306a36Sopenharmony_ci * the shared I/O request buffer between Service VM and ACRN hypervisor.
9162306a36Sopenharmony_ci */
9262306a36Sopenharmony_cistruct acrn_ioreq_buffer {
9362306a36Sopenharmony_ci	u64	ioreq_buf;
9462306a36Sopenharmony_ci};
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_cistruct acrn_ioreq_range {
9762306a36Sopenharmony_ci	struct list_head	list;
9862306a36Sopenharmony_ci	u32			type;
9962306a36Sopenharmony_ci	u64			start;
10062306a36Sopenharmony_ci	u64			end;
10162306a36Sopenharmony_ci};
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci#define ACRN_IOREQ_CLIENT_DESTROYING	0U
10462306a36Sopenharmony_citypedef	int (*ioreq_handler_t)(struct acrn_ioreq_client *client,
10562306a36Sopenharmony_ci			       struct acrn_io_request *req);
10662306a36Sopenharmony_ci/**
10762306a36Sopenharmony_ci * struct acrn_ioreq_client - Structure of I/O client.
10862306a36Sopenharmony_ci * @name:	Client name
10962306a36Sopenharmony_ci * @vm:		The VM that the client belongs to
11062306a36Sopenharmony_ci * @list:	List node for this acrn_ioreq_client
11162306a36Sopenharmony_ci * @is_default:	If this client is the default one
11262306a36Sopenharmony_ci * @flags:	Flags (ACRN_IOREQ_CLIENT_*)
11362306a36Sopenharmony_ci * @range_list:	I/O ranges
11462306a36Sopenharmony_ci * @range_lock:	Lock to protect range_list
11562306a36Sopenharmony_ci * @ioreqs_map:	The pending I/O requests bitmap.
11662306a36Sopenharmony_ci * @handler:	I/O requests handler of this client
11762306a36Sopenharmony_ci * @thread:	The thread which executes the handler
11862306a36Sopenharmony_ci * @wq:		The wait queue for the handler thread parking
11962306a36Sopenharmony_ci * @priv:	Data for the thread
12062306a36Sopenharmony_ci */
12162306a36Sopenharmony_cistruct acrn_ioreq_client {
12262306a36Sopenharmony_ci	char			name[ACRN_NAME_LEN];
12362306a36Sopenharmony_ci	struct acrn_vm		*vm;
12462306a36Sopenharmony_ci	struct list_head	list;
12562306a36Sopenharmony_ci	bool			is_default;
12662306a36Sopenharmony_ci	unsigned long		flags;
12762306a36Sopenharmony_ci	struct list_head	range_list;
12862306a36Sopenharmony_ci	rwlock_t		range_lock;
12962306a36Sopenharmony_ci	DECLARE_BITMAP(ioreqs_map, ACRN_IO_REQUEST_MAX);
13062306a36Sopenharmony_ci	ioreq_handler_t		handler;
13162306a36Sopenharmony_ci	struct task_struct	*thread;
13262306a36Sopenharmony_ci	wait_queue_head_t	wq;
13362306a36Sopenharmony_ci	void			*priv;
13462306a36Sopenharmony_ci};
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci#define ACRN_INVALID_VMID (0xffffU)
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci#define ACRN_VM_FLAG_DESTROYED		0U
13962306a36Sopenharmony_ci#define ACRN_VM_FLAG_CLEARING_IOREQ	1U
14062306a36Sopenharmony_ciextern struct list_head acrn_vm_list;
14162306a36Sopenharmony_ciextern rwlock_t acrn_vm_list_lock;
14262306a36Sopenharmony_ci/**
14362306a36Sopenharmony_ci * struct acrn_vm - Properties of ACRN User VM.
14462306a36Sopenharmony_ci * @list:			Entry within global list of all VMs.
14562306a36Sopenharmony_ci * @vmid:			User VM ID.
14662306a36Sopenharmony_ci * @vcpu_num:			Number of virtual CPUs in the VM.
14762306a36Sopenharmony_ci * @flags:			Flags (ACRN_VM_FLAG_*) of the VM. This is VM
14862306a36Sopenharmony_ci *				flag management in HSM which is different
14962306a36Sopenharmony_ci *				from the &acrn_vm_creation.vm_flag.
15062306a36Sopenharmony_ci * @regions_mapping_lock:	Lock to protect &acrn_vm.regions_mapping and
15162306a36Sopenharmony_ci *				&acrn_vm.regions_mapping_count.
15262306a36Sopenharmony_ci * @regions_mapping:		Memory mappings of this VM.
15362306a36Sopenharmony_ci * @regions_mapping_count:	Number of memory mapping of this VM.
15462306a36Sopenharmony_ci * @ioreq_clients_lock:		Lock to protect ioreq_clients and default_client
15562306a36Sopenharmony_ci * @ioreq_clients:		The I/O request clients list of this VM
15662306a36Sopenharmony_ci * @default_client:		The default I/O request client
15762306a36Sopenharmony_ci * @ioreq_buf:			I/O request shared buffer
15862306a36Sopenharmony_ci * @ioreq_page:			The page of the I/O request shared buffer
15962306a36Sopenharmony_ci * @pci_conf_addr:		Address of a PCI configuration access emulation
16062306a36Sopenharmony_ci * @monitor_page:		Page of interrupt statistics of User VM
16162306a36Sopenharmony_ci * @ioeventfds_lock:		Lock to protect ioeventfds list
16262306a36Sopenharmony_ci * @ioeventfds:			List to link all hsm_ioeventfd
16362306a36Sopenharmony_ci * @ioeventfd_client:		I/O client for ioeventfds of the VM
16462306a36Sopenharmony_ci * @irqfds_lock:		Lock to protect irqfds list
16562306a36Sopenharmony_ci * @irqfds:			List to link all hsm_irqfd
16662306a36Sopenharmony_ci * @irqfd_wq:			Workqueue for irqfd async shutdown
16762306a36Sopenharmony_ci */
16862306a36Sopenharmony_cistruct acrn_vm {
16962306a36Sopenharmony_ci	struct list_head		list;
17062306a36Sopenharmony_ci	u16				vmid;
17162306a36Sopenharmony_ci	int				vcpu_num;
17262306a36Sopenharmony_ci	unsigned long			flags;
17362306a36Sopenharmony_ci	struct mutex			regions_mapping_lock;
17462306a36Sopenharmony_ci	struct vm_memory_mapping	regions_mapping[ACRN_MEM_MAPPING_MAX];
17562306a36Sopenharmony_ci	int				regions_mapping_count;
17662306a36Sopenharmony_ci	spinlock_t			ioreq_clients_lock;
17762306a36Sopenharmony_ci	struct list_head		ioreq_clients;
17862306a36Sopenharmony_ci	struct acrn_ioreq_client	*default_client;
17962306a36Sopenharmony_ci	struct acrn_io_request_buffer	*ioreq_buf;
18062306a36Sopenharmony_ci	struct page			*ioreq_page;
18162306a36Sopenharmony_ci	u32				pci_conf_addr;
18262306a36Sopenharmony_ci	struct page			*monitor_page;
18362306a36Sopenharmony_ci	struct mutex			ioeventfds_lock;
18462306a36Sopenharmony_ci	struct list_head		ioeventfds;
18562306a36Sopenharmony_ci	struct acrn_ioreq_client	*ioeventfd_client;
18662306a36Sopenharmony_ci	struct mutex			irqfds_lock;
18762306a36Sopenharmony_ci	struct list_head		irqfds;
18862306a36Sopenharmony_ci	struct workqueue_struct		*irqfd_wq;
18962306a36Sopenharmony_ci};
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_cistruct acrn_vm *acrn_vm_create(struct acrn_vm *vm,
19262306a36Sopenharmony_ci			       struct acrn_vm_creation *vm_param);
19362306a36Sopenharmony_ciint acrn_vm_destroy(struct acrn_vm *vm);
19462306a36Sopenharmony_ciint acrn_mm_region_add(struct acrn_vm *vm, u64 user_gpa, u64 service_gpa,
19562306a36Sopenharmony_ci		       u64 size, u32 mem_type, u32 mem_access_right);
19662306a36Sopenharmony_ciint acrn_mm_region_del(struct acrn_vm *vm, u64 user_gpa, u64 size);
19762306a36Sopenharmony_ciint acrn_vm_memseg_map(struct acrn_vm *vm, struct acrn_vm_memmap *memmap);
19862306a36Sopenharmony_ciint acrn_vm_memseg_unmap(struct acrn_vm *vm, struct acrn_vm_memmap *memmap);
19962306a36Sopenharmony_ciint acrn_vm_ram_map(struct acrn_vm *vm, struct acrn_vm_memmap *memmap);
20062306a36Sopenharmony_civoid acrn_vm_all_ram_unmap(struct acrn_vm *vm);
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ciint acrn_ioreq_init(struct acrn_vm *vm, u64 buf_vma);
20362306a36Sopenharmony_civoid acrn_ioreq_deinit(struct acrn_vm *vm);
20462306a36Sopenharmony_ciint acrn_ioreq_intr_setup(void);
20562306a36Sopenharmony_civoid acrn_ioreq_intr_remove(void);
20662306a36Sopenharmony_civoid acrn_ioreq_request_clear(struct acrn_vm *vm);
20762306a36Sopenharmony_ciint acrn_ioreq_client_wait(struct acrn_ioreq_client *client);
20862306a36Sopenharmony_ciint acrn_ioreq_request_default_complete(struct acrn_vm *vm, u16 vcpu);
20962306a36Sopenharmony_cistruct acrn_ioreq_client *acrn_ioreq_client_create(struct acrn_vm *vm,
21062306a36Sopenharmony_ci						   ioreq_handler_t handler,
21162306a36Sopenharmony_ci						   void *data, bool is_default,
21262306a36Sopenharmony_ci						   const char *name);
21362306a36Sopenharmony_civoid acrn_ioreq_client_destroy(struct acrn_ioreq_client *client);
21462306a36Sopenharmony_ciint acrn_ioreq_range_add(struct acrn_ioreq_client *client,
21562306a36Sopenharmony_ci			 u32 type, u64 start, u64 end);
21662306a36Sopenharmony_civoid acrn_ioreq_range_del(struct acrn_ioreq_client *client,
21762306a36Sopenharmony_ci			  u32 type, u64 start, u64 end);
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ciint acrn_msi_inject(struct acrn_vm *vm, u64 msi_addr, u64 msi_data);
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ciint acrn_ioeventfd_init(struct acrn_vm *vm);
22262306a36Sopenharmony_ciint acrn_ioeventfd_config(struct acrn_vm *vm, struct acrn_ioeventfd *args);
22362306a36Sopenharmony_civoid acrn_ioeventfd_deinit(struct acrn_vm *vm);
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ciint acrn_irqfd_init(struct acrn_vm *vm);
22662306a36Sopenharmony_ciint acrn_irqfd_config(struct acrn_vm *vm, struct acrn_irqfd *args);
22762306a36Sopenharmony_civoid acrn_irqfd_deinit(struct acrn_vm *vm);
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ci#endif /* __ACRN_HSM_DRV_H */
230