clear-pkgs-linux-iot-lts2018/0517-vhm-add-set_memmaps-hy...

165 lines
5.4 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Chen CJ <jason.cj.chen@intel.com>
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 <jason.cj.chen@intel.com>
---
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 <linux/vhm/vhm_ioctl_defs.h>
#include <linux/vhm/vhm_vm_mngt.h>
+#include <linux/vhm/acrn_hv_defs.h>
/**
* 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