Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | /* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ACRN_HSM_DRV_H #define __ACRN_HSM_DRV_H #include <linux/acrn.h> #include <linux/dev_printk.h> #include <linux/miscdevice.h> #include <linux/types.h> #include "hypercall.h" extern struct miscdevice acrn_dev; #define ACRN_NAME_LEN 16 #define ACRN_MEM_MAPPING_MAX 256 #define ACRN_MEM_REGION_ADD 0 #define ACRN_MEM_REGION_DEL 2 struct acrn_vm; struct acrn_ioreq_client; /** * struct vm_memory_region_op - Hypervisor memory operation * @type: Operation type (ACRN_MEM_REGION_*) * @attr: Memory attribute (ACRN_MEM_TYPE_* | ACRN_MEM_ACCESS_*) * @user_vm_pa: Physical address of User VM to be mapped. * @service_vm_pa: Physical address of Service VM to be mapped. * @size: Size of this region. * * Structure containing needed information that is provided to ACRN Hypervisor * to manage the EPT mappings of a single memory region of the User VM. Several * &struct vm_memory_region_op can be batched to ACRN Hypervisor, see &struct * vm_memory_region_batch. */ struct vm_memory_region_op { u32 type; u32 attr; u64 user_vm_pa; u64 service_vm_pa; u64 size; }; /** * struct vm_memory_region_batch - A batch of vm_memory_region_op. * @vmid: A User VM ID. * @reserved: Reserved. * @regions_num: The number of vm_memory_region_op. * @regions_gpa: Physical address of a vm_memory_region_op array. * @regions_op: Flexible array of vm_memory_region_op. * * HC_VM_SET_MEMORY_REGIONS uses this structure to manage EPT mappings of * multiple memory regions of a User VM. A &struct vm_memory_region_batch * contains multiple &struct vm_memory_region_op for batch processing in the * ACRN Hypervisor. */ struct vm_memory_region_batch { u16 vmid; u16 reserved[3]; u32 regions_num; u64 regions_gpa; struct vm_memory_region_op regions_op[]; }; /** * struct vm_memory_mapping - Memory map between a User VM and the Service VM * @pages: Pages in Service VM kernel. * @npages: Number of pages. * @service_vm_va: Virtual address in Service VM kernel. * @user_vm_pa: Physical address in User VM. * @size: Size of this memory region. * * HSM maintains memory mappings between a User VM GPA and the Service VM * kernel VA for accelerating the User VM GPA translation. */ struct vm_memory_mapping { struct page **pages; int npages; void *service_vm_va; u64 user_vm_pa; size_t size; }; /** * struct acrn_ioreq_buffer - Data for setting the ioreq buffer of User VM * @ioreq_buf: The GPA of the IO request shared buffer of a VM * * The parameter for the HC_SET_IOREQ_BUFFER hypercall used to set up * the shared I/O request buffer between Service VM and ACRN hypervisor. */ struct acrn_ioreq_buffer { u64 ioreq_buf; }; struct acrn_ioreq_range { struct list_head list; u32 type; u64 start; u64 end; }; #define ACRN_IOREQ_CLIENT_DESTROYING 0U typedef int (*ioreq_handler_t)(struct acrn_ioreq_client *client, struct acrn_io_request *req); /** * struct acrn_ioreq_client - Structure of I/O client. * @name: Client name * @vm: The VM that the client belongs to * @list: List node for this acrn_ioreq_client * @is_default: If this client is the default one * @flags: Flags (ACRN_IOREQ_CLIENT_*) * @range_list: I/O ranges * @range_lock: Lock to protect range_list * @ioreqs_map: The pending I/O requests bitmap. * @handler: I/O requests handler of this client * @thread: The thread which executes the handler * @wq: The wait queue for the handler thread parking * @priv: Data for the thread */ struct acrn_ioreq_client { char name[ACRN_NAME_LEN]; struct acrn_vm *vm; struct list_head list; bool is_default; unsigned long flags; struct list_head range_list; rwlock_t range_lock; DECLARE_BITMAP(ioreqs_map, ACRN_IO_REQUEST_MAX); ioreq_handler_t handler; struct task_struct *thread; wait_queue_head_t wq; void *priv; }; #define ACRN_INVALID_VMID (0xffffU) #define ACRN_VM_FLAG_DESTROYED 0U #define ACRN_VM_FLAG_CLEARING_IOREQ 1U extern struct list_head acrn_vm_list; extern rwlock_t acrn_vm_list_lock; /** * struct acrn_vm - Properties of ACRN User VM. * @list: Entry within global list of all VMs. * @vmid: User VM ID. * @vcpu_num: Number of virtual CPUs in the VM. * @flags: Flags (ACRN_VM_FLAG_*) of the VM. This is VM * flag management in HSM which is different * from the &acrn_vm_creation.vm_flag. * @regions_mapping_lock: Lock to protect &acrn_vm.regions_mapping and * &acrn_vm.regions_mapping_count. * @regions_mapping: Memory mappings of this VM. * @regions_mapping_count: Number of memory mapping of this VM. * @ioreq_clients_lock: Lock to protect ioreq_clients and default_client * @ioreq_clients: The I/O request clients list of this VM * @default_client: The default I/O request client * @ioreq_buf: I/O request shared buffer * @ioreq_page: The page of the I/O request shared buffer * @pci_conf_addr: Address of a PCI configuration access emulation * @monitor_page: Page of interrupt statistics of User VM * @ioeventfds_lock: Lock to protect ioeventfds list * @ioeventfds: List to link all hsm_ioeventfd * @ioeventfd_client: I/O client for ioeventfds of the VM * @irqfds_lock: Lock to protect irqfds list * @irqfds: List to link all hsm_irqfd * @irqfd_wq: Workqueue for irqfd async shutdown */ struct acrn_vm { struct list_head list; u16 vmid; int vcpu_num; unsigned long flags; struct mutex regions_mapping_lock; struct vm_memory_mapping regions_mapping[ACRN_MEM_MAPPING_MAX]; int regions_mapping_count; spinlock_t ioreq_clients_lock; struct list_head ioreq_clients; struct acrn_ioreq_client *default_client; struct acrn_io_request_buffer *ioreq_buf; struct page *ioreq_page; u32 pci_conf_addr; struct page *monitor_page; struct mutex ioeventfds_lock; struct list_head ioeventfds; struct acrn_ioreq_client *ioeventfd_client; struct mutex irqfds_lock; struct list_head irqfds; struct workqueue_struct *irqfd_wq; }; struct acrn_vm *acrn_vm_create(struct acrn_vm *vm, struct acrn_vm_creation *vm_param); int acrn_vm_destroy(struct acrn_vm *vm); int acrn_mm_region_add(struct acrn_vm *vm, u64 user_gpa, u64 service_gpa, u64 size, u32 mem_type, u32 mem_access_right); int acrn_mm_region_del(struct acrn_vm *vm, u64 user_gpa, u64 size); int acrn_vm_memseg_map(struct acrn_vm *vm, struct acrn_vm_memmap *memmap); int acrn_vm_memseg_unmap(struct acrn_vm *vm, struct acrn_vm_memmap *memmap); int acrn_vm_ram_map(struct acrn_vm *vm, struct acrn_vm_memmap *memmap); void acrn_vm_all_ram_unmap(struct acrn_vm *vm); int acrn_ioreq_init(struct acrn_vm *vm, u64 buf_vma); void acrn_ioreq_deinit(struct acrn_vm *vm); int acrn_ioreq_intr_setup(void); void acrn_ioreq_intr_remove(void); void acrn_ioreq_request_clear(struct acrn_vm *vm); int acrn_ioreq_client_wait(struct acrn_ioreq_client *client); int acrn_ioreq_request_default_complete(struct acrn_vm *vm, u16 vcpu); struct acrn_ioreq_client *acrn_ioreq_client_create(struct acrn_vm *vm, ioreq_handler_t handler, void *data, bool is_default, const char *name); void acrn_ioreq_client_destroy(struct acrn_ioreq_client *client); int acrn_ioreq_range_add(struct acrn_ioreq_client *client, u32 type, u64 start, u64 end); void acrn_ioreq_range_del(struct acrn_ioreq_client *client, u32 type, u64 start, u64 end); int acrn_msi_inject(struct acrn_vm *vm, u64 msi_addr, u64 msi_data); int acrn_ioeventfd_init(struct acrn_vm *vm); int acrn_ioeventfd_config(struct acrn_vm *vm, struct acrn_ioeventfd *args); void acrn_ioeventfd_deinit(struct acrn_vm *vm); int acrn_irqfd_init(struct acrn_vm *vm); int acrn_irqfd_config(struct acrn_vm *vm, struct acrn_irqfd *args); void acrn_irqfd_deinit(struct acrn_vm *vm); #endif /* __ACRN_HSM_DRV_H */ |