From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jason Chen CJ Date: Fri, 31 Aug 2018 10:59:00 +0800 Subject: [PATCH] vhm: add set_memmaps hypercall support This new added hypercall is to support multi regions memmap in one time, which improve the performance. 1 API is added to support set_memmaps hypercall: - int set_memmaps(struct set_memmaps *memmaps) struct set_memmaps is added to present multi region memmap info, which include a page buffer to fill the memmaps array. Signed-off-by: Jason Chen CJ --- drivers/vhm/vhm_hypercall.c | 5 +++++ drivers/vhm/vhm_mm.c | 14 ++++++++++++++ include/linux/vhm/acrn_hv_defs.h | 32 +++++++++++++++++++++++++++++++ include/linux/vhm/acrn_vhm_mm.h | 12 +++++++++++- include/linux/vhm/vhm_hypercall.h | 1 + 5 files changed, 63 insertions(+), 1 deletion(-) diff --git a/drivers/vhm/vhm_hypercall.c b/drivers/vhm/vhm_hypercall.c index 463cd71d4b93..bbdbea8d623c 100644 --- a/drivers/vhm/vhm_hypercall.c +++ b/drivers/vhm/vhm_hypercall.c @@ -97,6 +97,11 @@ inline long hcall_set_memmap(unsigned long vmid, unsigned long memmap) return acrn_hypercall2(HC_VM_SET_MEMMAP, vmid, memmap); } +inline long hcall_set_memmaps(unsigned long pa_memmaps) +{ + return acrn_hypercall1(HC_VM_SET_MEMMAPS, pa_memmaps); +} + inline long hcall_set_ioreq_buffer(unsigned long vmid, unsigned long buffer) { return acrn_hypercall2(HC_SET_IOREQ_BUFFER, vmid, buffer); diff --git a/drivers/vhm/vhm_mm.c b/drivers/vhm/vhm_mm.c index 070327e616d6..75ccd3f09a4e 100644 --- a/drivers/vhm/vhm_mm.c +++ b/drivers/vhm/vhm_mm.c @@ -199,6 +199,20 @@ int unset_mmio_map(unsigned long vmid, unsigned long guest_gpa, 0, 0, MAP_UNMAP); } +int set_memmaps(struct set_memmaps *memmaps) +{ + if (memmaps == NULL) + return -EINVAL; + if (memmaps->memmaps_num > 0) { + if (hcall_set_memmaps(virt_to_phys(memmaps)) < 0) { + pr_err("vhm: failed to set memmaps!\n"); + return -EFAULT; + } + } + + return 0; +} + int update_memmap_attr(unsigned long vmid, unsigned long guest_gpa, unsigned long host_gpa, unsigned long len, unsigned int mem_type, unsigned int mem_access_right) diff --git a/include/linux/vhm/acrn_hv_defs.h b/include/linux/vhm/acrn_hv_defs.h index 8dc5b37510bb..cd0147f732bc 100644 --- a/include/linux/vhm/acrn_hv_defs.h +++ b/include/linux/vhm/acrn_hv_defs.h @@ -94,6 +94,7 @@ #define HC_ID_MEM_BASE 0x40UL #define HC_VM_SET_MEMMAP _HC_ID(HC_ID, HC_ID_MEM_BASE + 0x00) #define HC_VM_GPA2HPA _HC_ID(HC_ID, HC_ID_MEM_BASE + 0x01) +#define HC_VM_SET_MEMMAPS _HC_ID(HC_ID, HC_ID_MEM_BASE + 0x02) /* PCI assignment*/ #define HC_ID_PCI_BASE 0x50UL @@ -149,6 +150,37 @@ struct vm_set_memmap { uint32_t prot; } __attribute__((aligned(8))); +struct memory_map { + uint32_t type; + + /* IN: mem attr */ + uint32_t prot; + + /* IN: beginning guest GPA to map */ + uint64_t remote_gpa; + + /* IN: VM0's GPA which foreign gpa will be mapped to */ + uint64_t vm0_gpa; + + /* IN: length of the range */ + uint64_t length; +} __attribute__((aligned(8))); + +struct set_memmaps { + /*IN: vmid for this hypercall */ + uint64_t vmid; + + /* IN: multi memmaps numbers */ + uint32_t memmaps_num; + + /* IN: + * the gpa of memmaps buffer, point to the memmaps array: + * struct memory_map memmap_array[memmaps_num] + * the max buffer size is one page. + */ + uint64_t memmaps_gpa; +} __attribute__((aligned(8))); + struct sbuf_setup_param { uint32_t pcpu_id; uint32_t sbuf_id; diff --git a/include/linux/vhm/acrn_vhm_mm.h b/include/linux/vhm/acrn_vhm_mm.h index 9be6749d12e2..712860b5f5af 100644 --- a/include/linux/vhm/acrn_vhm_mm.h +++ b/include/linux/vhm/acrn_vhm_mm.h @@ -62,6 +62,7 @@ #include #include +#include /** * acrn_hpa2gpa - physical address conversion @@ -189,7 +190,7 @@ void free_guest_mem(struct vhm_vm *vm); int alloc_guest_memseg(struct vhm_vm *vm, struct vm_memseg *memseg); /** - * map_guest_memseg - map EPT mmapping of memory of guest according to + * map_guest_memseg - set guest mmapping of memory according to * pre-defined memory mapping info * * @vm: pointer to guest vm @@ -207,4 +208,13 @@ int hugepage_map_guest(struct vhm_vm *vm, struct vm_memmap *memmap); void hugepage_free_guest(struct vhm_vm *vm); void *hugepage_map_guest_phys(struct vhm_vm *vm, u64 guest_phys, size_t size); int hugepage_unmap_guest_phys(struct vhm_vm *vm, u64 guest_phys); + +/** + * set_memmaps - set guest mapping for multi regions + * + * @memmaps: pointer to set_memmaps + * + * Return: 0 on success, <0 for error. + */ +int set_memmaps(struct set_memmaps *memmaps); #endif diff --git a/include/linux/vhm/vhm_hypercall.h b/include/linux/vhm/vhm_hypercall.h index 38a9cb9e8487..ea4c3c2e416d 100644 --- a/include/linux/vhm/vhm_hypercall.h +++ b/include/linux/vhm/vhm_hypercall.h @@ -148,6 +148,7 @@ inline long hcall_setup_sbuf(unsigned long sbuf_head); inline long hcall_get_cpu_state(unsigned long cmd, unsigned long state_pa); inline long hcall_set_memmap(unsigned long vmid, unsigned long memmap); +inline long hcall_set_memmaps(unsigned long pa_memmaps); inline long hcall_set_ioreq_buffer(unsigned long vmid, unsigned long buffer); inline long hcall_notify_req_finish(unsigned long vmid, unsigned long vcpu); -- https://clearlinux.org