464 lines
15 KiB
Diff
464 lines
15 KiB
Diff
From ee49ed77634d48e6c901996b3f20c99f6a50689f Mon Sep 17 00:00:00 2001
|
|
From: "Li, Fei1" <fei1.li@intel.com>
|
|
Date: Fri, 31 Aug 2018 10:59:02 +0800
|
|
Subject: [PATCH 551/743] sos: vhm: refine set memory region API
|
|
|
|
1. rename set_mmio_map to add_memory_region;
|
|
unset_mmio_map to del_memory_region.
|
|
2. rename set_memmap to set_memory_region;
|
|
set_memmaps to set_memory_region;
|
|
3. remove HV_VM_SET_MEMORY_REGION hypercall
|
|
|
|
Signed-off-by: Li, Fei1 <fei1.li@intel.com>
|
|
Acked-by: Eddie Dong <eddie.dong@intel.com>
|
|
---
|
|
drivers/vhm/vhm_hugetlb.c | 61 +++++++++++----------
|
|
drivers/vhm/vhm_hypercall.c | 9 +---
|
|
drivers/vhm/vhm_mm.c | 89 +++++++++++++++----------------
|
|
include/linux/vhm/acrn_hv_defs.h | 39 ++++----------
|
|
include/linux/vhm/acrn_vhm_mm.h | 31 +++++------
|
|
include/linux/vhm/vhm_hypercall.h | 4 +-
|
|
6 files changed, 98 insertions(+), 135 deletions(-)
|
|
|
|
diff --git a/drivers/vhm/vhm_hugetlb.c b/drivers/vhm/vhm_hugetlb.c
|
|
index a83f00ad2e9d..34ebbd90acea 100644
|
|
--- a/drivers/vhm/vhm_hugetlb.c
|
|
+++ b/drivers/vhm/vhm_hugetlb.c
|
|
@@ -120,11 +120,11 @@ static int add_guest_map(struct vhm_vm *vm, unsigned long vm0_gpa,
|
|
|
|
int hugepage_map_guest(struct vhm_vm *vm, struct vm_memmap *memmap)
|
|
{
|
|
- struct page *page = NULL, *memmaps_buf_pg = NULL;
|
|
+ struct page *page = NULL, *regions_buf_pg = NULL;
|
|
unsigned long len, guest_gpa, vma;
|
|
- struct memory_map *memmap_array;
|
|
- struct set_memmaps memmaps;
|
|
- int max_size = PAGE_SIZE/sizeof(struct memory_map);
|
|
+ struct vm_memory_region *region_array;
|
|
+ struct set_regions regions;
|
|
+ int max_size = PAGE_SIZE/sizeof(struct vm_memory_region);
|
|
int ret;
|
|
|
|
if (vm == NULL || memmap == NULL)
|
|
@@ -134,14 +134,14 @@ int hugepage_map_guest(struct vhm_vm *vm, struct vm_memmap *memmap)
|
|
vma = memmap->vma_base;
|
|
guest_gpa = memmap->gpa;
|
|
|
|
- /* prepare set_memmaps info */
|
|
- memmaps_buf_pg = alloc_page(GFP_KERNEL);
|
|
- if (memmaps_buf_pg == NULL)
|
|
+ /* prepare set_memory_regions info */
|
|
+ regions_buf_pg = alloc_page(GFP_KERNEL);
|
|
+ if (regions_buf_pg == NULL)
|
|
return -ENOMEM;
|
|
- memmaps.memmaps_num = 0;
|
|
- memmaps.vmid = vm->vmid;
|
|
- memmaps.memmaps_gpa = page_to_phys(memmaps_buf_pg);
|
|
- memmap_array = page_to_virt(memmaps_buf_pg);
|
|
+ regions.mr_num = 0;
|
|
+ regions.vmid = vm->vmid;
|
|
+ regions.regions_gpa = page_to_phys(regions_buf_pg);
|
|
+ region_array = page_to_virt(regions_buf_pg);
|
|
|
|
while (len > 0) {
|
|
unsigned long vm0_gpa, pagesize;
|
|
@@ -162,24 +162,23 @@ int hugepage_map_guest(struct vhm_vm *vm, struct vm_memmap *memmap)
|
|
goto err;
|
|
}
|
|
|
|
- /* fill each memmap region into memmap_array */
|
|
- memmap_array[memmaps.memmaps_num].type = MAP_MEM;
|
|
- memmap_array[memmaps.memmaps_num].remote_gpa = guest_gpa;
|
|
- memmap_array[memmaps.memmaps_num].vm0_gpa = vm0_gpa;
|
|
- memmap_array[memmaps.memmaps_num].length = pagesize;
|
|
- memmap_array[memmaps.memmaps_num].prot =
|
|
- MEM_TYPE_WB & MEM_TYPE_MASK;
|
|
- memmap_array[memmaps.memmaps_num].prot |=
|
|
- memmap->prot & MEM_ACCESS_RIGHT_MASK;
|
|
- memmaps.memmaps_num++;
|
|
- if (memmaps.memmaps_num == max_size) {
|
|
- pr_info("region buffer full, set & renew memmaps!\n");
|
|
- ret = set_memmaps(&memmaps);
|
|
+ /* fill each memory region into region_array */
|
|
+ region_array[regions.mr_num].type = MR_ADD;
|
|
+ region_array[regions.mr_num].gpa = guest_gpa;
|
|
+ region_array[regions.mr_num].vm0_gpa = vm0_gpa;
|
|
+ region_array[regions.mr_num].size = pagesize;
|
|
+ region_array[regions.mr_num].prot =
|
|
+ (MEM_TYPE_WB & MEM_TYPE_MASK) |
|
|
+ (memmap->prot & MEM_ACCESS_RIGHT_MASK);
|
|
+ regions.mr_num++;
|
|
+ if (regions.mr_num == max_size) {
|
|
+ pr_info("region buffer full, set & renew regions!\n");
|
|
+ ret = set_memory_regions(®ions);
|
|
if (ret < 0) {
|
|
- pr_err("failed to set memmaps,ret=%d!\n", ret);
|
|
+ pr_err("failed to set regions,ret=%d!\n", ret);
|
|
goto err;
|
|
}
|
|
- memmaps.memmaps_num = 0;
|
|
+ regions.mr_num = 0;
|
|
}
|
|
|
|
len -= pagesize;
|
|
@@ -187,18 +186,18 @@ int hugepage_map_guest(struct vhm_vm *vm, struct vm_memmap *memmap)
|
|
guest_gpa += pagesize;
|
|
}
|
|
|
|
- ret = set_memmaps(&memmaps);
|
|
+ ret = set_memory_regions(®ions);
|
|
if (ret < 0) {
|
|
- pr_err("failed to set memmaps, ret=%d!\n", ret);
|
|
+ pr_err("failed to set regions, ret=%d!\n", ret);
|
|
goto err;
|
|
}
|
|
|
|
- __free_page(memmaps_buf_pg);
|
|
+ __free_page(regions_buf_pg);
|
|
|
|
return 0;
|
|
err:
|
|
- if (memmaps_buf_pg)
|
|
- __free_page(memmaps_buf_pg);
|
|
+ if (regions_buf_pg)
|
|
+ __free_page(regions_buf_pg);
|
|
if (page)
|
|
put_page(page);
|
|
return ret;
|
|
diff --git a/drivers/vhm/vhm_hypercall.c b/drivers/vhm/vhm_hypercall.c
|
|
index 8611bb1819d4..9a92d6888b90 100644
|
|
--- a/drivers/vhm/vhm_hypercall.c
|
|
+++ b/drivers/vhm/vhm_hypercall.c
|
|
@@ -102,14 +102,9 @@ inline long hcall_get_cpu_state(unsigned long cmd, unsigned long state_pa)
|
|
return acrn_hypercall2(HC_PM_GET_CPU_STATE, cmd, state_pa);
|
|
}
|
|
|
|
-inline long hcall_set_memmap(unsigned long vmid, unsigned long memmap)
|
|
+inline long hcall_set_memory_regions(unsigned long pa_regions)
|
|
{
|
|
- 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);
|
|
+ return acrn_hypercall1(HC_VM_SET_MEMORY_REGIONS, pa_regions);
|
|
}
|
|
|
|
inline long hcall_write_protect_page(unsigned long vmid, unsigned long wp)
|
|
diff --git a/drivers/vhm/vhm_mm.c b/drivers/vhm/vhm_mm.c
|
|
index c7ca8e99612d..4d5854d0c139 100644
|
|
--- a/drivers/vhm/vhm_mm.c
|
|
+++ b/drivers/vhm/vhm_mm.c
|
|
@@ -102,56 +102,59 @@ static bool _free_memblk(struct device *dev, u64 vm0_gpa, size_t len)
|
|
return dma_release_from_contiguous(dev, page, count);
|
|
}
|
|
|
|
-int _mem_set_memmap(unsigned long vmid, unsigned long guest_gpa,
|
|
- unsigned long host_gpa, unsigned long len,
|
|
- unsigned int mem_type, unsigned int mem_access_right,
|
|
- unsigned int type)
|
|
+static int set_memory_region(unsigned long vmid,
|
|
+ struct vm_memory_region *region)
|
|
{
|
|
- struct vm_set_memmap set_memmap;
|
|
+ struct set_regions regions;
|
|
|
|
- set_memmap.type = type;
|
|
- set_memmap.remote_gpa = guest_gpa;
|
|
- set_memmap.vm0_gpa = host_gpa;
|
|
- set_memmap.length = len;
|
|
- set_memmap.prot = set_memmap.prot_2 = ((mem_type & MEM_TYPE_MASK) |
|
|
- (mem_access_right & MEM_ACCESS_RIGHT_MASK));
|
|
+ regions.vmid = vmid;
|
|
+ regions.mr_num = 1;
|
|
+ regions.regions_gpa = virt_to_phys(region);
|
|
|
|
- /* hypercall to notify hv the guest EPT setting*/
|
|
- if (hcall_set_memmap(vmid,
|
|
- virt_to_phys(&set_memmap)) < 0) {
|
|
- pr_err("vhm: failed to set memmap %ld!\n", vmid);
|
|
+ if (set_memory_regions(®ions) < 0) {
|
|
+ pr_err("vhm: failed to set memory region for vm[%ld]!\n", vmid);
|
|
return -EFAULT;
|
|
}
|
|
|
|
- pr_debug("VHM: set ept for mem map[type=0x%x, host_gpa=0x%lx,"
|
|
- "guest_gpa=0x%lx,len=0x%lx, prot=0x%x]\n",
|
|
- type, host_gpa, guest_gpa, len, set_memmap.prot);
|
|
-
|
|
return 0;
|
|
}
|
|
|
|
-int set_mmio_map(unsigned long vmid, unsigned long guest_gpa,
|
|
- unsigned long host_gpa, unsigned long len,
|
|
+int add_memory_region(unsigned long vmid, unsigned long gpa,
|
|
+ unsigned long host_gpa, unsigned long size,
|
|
unsigned int mem_type, unsigned mem_access_right)
|
|
{
|
|
- return _mem_set_memmap(vmid, guest_gpa, host_gpa, len,
|
|
- mem_type, mem_access_right, MAP_MEM);
|
|
+ struct vm_memory_region region;
|
|
+
|
|
+ region.type = MR_ADD;
|
|
+ region.gpa = gpa;
|
|
+ region.vm0_gpa = host_gpa;
|
|
+ region.size = size;
|
|
+ region.prot = ((mem_type & MEM_TYPE_MASK) |
|
|
+ (mem_access_right & MEM_ACCESS_RIGHT_MASK));
|
|
+ return set_memory_region(vmid, ®ion);
|
|
}
|
|
|
|
-int unset_mmio_map(unsigned long vmid, unsigned long guest_gpa,
|
|
- unsigned long host_gpa, unsigned long len)
|
|
+int del_memory_region(unsigned long vmid, unsigned long gpa,
|
|
+ unsigned long size)
|
|
{
|
|
- return _mem_set_memmap(vmid, guest_gpa, host_gpa, len,
|
|
- 0, 0, MAP_UNMAP);
|
|
+ struct vm_memory_region region;
|
|
+
|
|
+ region.type = MR_DEL;
|
|
+ region.gpa = gpa;
|
|
+ region.vm0_gpa = 0;
|
|
+ region.size = size;
|
|
+ region.prot = 0;
|
|
+
|
|
+ return set_memory_region(vmid, ®ion);
|
|
}
|
|
|
|
-int set_memmaps(struct set_memmaps *memmaps)
|
|
+int set_memory_regions(struct set_regions *regions)
|
|
{
|
|
- if (memmaps == NULL)
|
|
+ if (regions == 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");
|
|
+ if (regions->mr_num > 0) {
|
|
+ if (hcall_set_memory_regions(virt_to_phys(regions)) < 0) {
|
|
+ pr_err("vhm: failed to set memory regions!\n");
|
|
return -EFAULT;
|
|
}
|
|
}
|
|
@@ -184,10 +187,6 @@ int write_protect_page(unsigned long vmid,
|
|
|
|
int map_guest_memseg(struct vhm_vm *vm, struct vm_memmap *memmap)
|
|
{
|
|
- unsigned int type;
|
|
- unsigned int mem_type, mem_access_right;
|
|
- unsigned long guest_gpa, host_gpa;
|
|
-
|
|
/* hugetlb use vma to do the mapping */
|
|
if (memmap->type == VM_MEMMAP_SYSMEM && memmap->using_vma)
|
|
return hugepage_map_guest(vm, memmap);
|
|
@@ -198,15 +197,11 @@ int map_guest_memseg(struct vhm_vm *vm, struct vm_memmap *memmap)
|
|
__func__, memmap->type);
|
|
return -EINVAL;
|
|
}
|
|
- guest_gpa = memmap->gpa;
|
|
- host_gpa = acrn_hpa2gpa(memmap->hpa);
|
|
- mem_type = MEM_TYPE_UC;
|
|
- mem_access_right = (memmap->prot & MEM_ACCESS_RIGHT_MASK);
|
|
- type = MAP_MEM;
|
|
-
|
|
- if (_mem_set_memmap(vm->vmid, guest_gpa, host_gpa, memmap->len,
|
|
- mem_type, mem_access_right, type) < 0) {
|
|
- pr_err("vhm: failed to set memmap %ld!\n", vm->vmid);
|
|
+
|
|
+ if (add_memory_region(vm->vmid, memmap->gpa,
|
|
+ acrn_hpa2gpa(memmap->hpa), memmap->len,
|
|
+ MEM_TYPE_UC, memmap->prot) < 0){
|
|
+ pr_err("vhm: failed to set memory region %ld!\n", vm->vmid);
|
|
return -EFAULT;
|
|
}
|
|
|
|
@@ -233,8 +228,8 @@ int init_trusty(struct vhm_vm *vm)
|
|
|
|
pr_info("VHM: set ept for trusty memory [host_gpa=0x%lx, "
|
|
"guest_gpa=0x%lx, len=0x%lx]", host_gpa, guest_gpa, len);
|
|
- return _mem_set_memmap(vm->vmid, guest_gpa, host_gpa, len,
|
|
- MEM_TYPE_WB, MEM_ACCESS_RWX, MAP_MEM);
|
|
+ return add_memory_region(vm->vmid, guest_gpa, host_gpa, len,
|
|
+ MEM_TYPE_WB, MEM_ACCESS_RWX);
|
|
}
|
|
|
|
void deinit_trusty(struct vhm_vm *vm)
|
|
diff --git a/include/linux/vhm/acrn_hv_defs.h b/include/linux/vhm/acrn_hv_defs.h
|
|
index 74f8a137206d..223702c0330c 100644
|
|
--- a/include/linux/vhm/acrn_hv_defs.h
|
|
+++ b/include/linux/vhm/acrn_hv_defs.h
|
|
@@ -93,9 +93,8 @@
|
|
|
|
/* Guest memory management */
|
|
#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)
|
|
+#define HC_VM_SET_MEMORY_REGIONS _HC_ID(HC_ID, HC_ID_MEM_BASE + 0x02)
|
|
#define HC_VM_WRITE_PROTECT_PAGE _HC_ID(HC_ID, HC_ID_MEM_BASE + 0x03)
|
|
|
|
/* PCI assignment*/
|
|
@@ -133,43 +132,25 @@
|
|
#define MEM_TYPE_WP 0x00000400
|
|
#define MEM_TYPE_MASK 0x000007C0
|
|
|
|
-struct vm_set_memmap {
|
|
-#define MAP_MEM 0
|
|
-#define MAP_UNMAP 2
|
|
+struct vm_memory_region {
|
|
+#define MR_ADD 0
|
|
+#define MR_DEL 2
|
|
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;
|
|
-
|
|
- uint32_t prot_2;
|
|
-} __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;
|
|
+ uint64_t gpa;
|
|
|
|
/* IN: VM0's GPA which foreign gpa will be mapped to */
|
|
uint64_t vm0_gpa;
|
|
|
|
- /* IN: length of the range */
|
|
- uint64_t length;
|
|
+ /* IN: size of the region */
|
|
+ uint64_t size;
|
|
} __attribute__((aligned(8)));
|
|
|
|
-struct set_memmaps {
|
|
+struct set_regions {
|
|
/*IN: vmid for this hypercall */
|
|
uint16_t vmid;
|
|
|
|
@@ -177,14 +158,14 @@ struct set_memmaps {
|
|
uint16_t reserved[3];
|
|
|
|
/* IN: multi memmaps numbers */
|
|
- uint32_t memmaps_num;
|
|
+ uint32_t mr_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;
|
|
+ uint64_t regions_gpa;
|
|
} __attribute__((aligned(8)));
|
|
|
|
struct wp_data {
|
|
diff --git a/include/linux/vhm/acrn_vhm_mm.h b/include/linux/vhm/acrn_vhm_mm.h
|
|
index 0769200ea3bf..62aed3466e9f 100644
|
|
--- a/include/linux/vhm/acrn_vhm_mm.h
|
|
+++ b/include/linux/vhm/acrn_vhm_mm.h
|
|
@@ -99,12 +99,12 @@ void *map_guest_phys(unsigned long vmid, u64 uos_phys, size_t size);
|
|
int unmap_guest_phys(unsigned long vmid, u64 uos_phys);
|
|
|
|
/**
|
|
- * set_mmio_map - map mmio EPT mapping between UOS gpa and SOS gpa
|
|
+ * add_memory_region - add a guest memory region
|
|
*
|
|
* @vmid: guest vmid
|
|
- * @guest_gpa: gpa of UOS
|
|
+ * @gpa: gpa of UOS
|
|
* @host_gpa: gpa of SOS
|
|
- * @len: memory mapped length
|
|
+ * @size: memory region size
|
|
* @mem_type: memory mapping type. Possible value could be:
|
|
* MEM_TYPE_WB
|
|
* MEM_TYPE_WT
|
|
@@ -119,22 +119,21 @@ int unmap_guest_phys(unsigned long vmid, u64 uos_phys);
|
|
*
|
|
* Return: 0 on success, <0 for error.
|
|
*/
|
|
-int set_mmio_map(unsigned long vmid, unsigned long guest_gpa,
|
|
- unsigned long host_gpa, unsigned long len,
|
|
+int add_memory_region(unsigned long vmid, unsigned long gpa,
|
|
+ unsigned long host_gpa, unsigned long size,
|
|
unsigned int mem_type, unsigned int mem_access_right);
|
|
|
|
/**
|
|
- * unset_mmio_map - unmap mmio mapping between UOS gpa and SOS gpa
|
|
+ * del_memory_region - delete a guest memory region
|
|
*
|
|
* @vmid: guest vmid
|
|
- * @guest_gpa: gpa of UOS
|
|
- * @host_gpa: gpa of SOS
|
|
- * @len: memory mapped length
|
|
+ * @gpa: gpa of UOS
|
|
+ * @size: memory region size
|
|
*
|
|
* Return: 0 on success, <0 for error.
|
|
*/
|
|
-int unset_mmio_map(unsigned long vmid, unsigned long guest_gpa,
|
|
- unsigned long host_gpa, unsigned long len);
|
|
+int del_memory_region(unsigned long vmid, unsigned long gpa,
|
|
+ unsigned long size);
|
|
|
|
/**
|
|
* write_protect_page - change one page write protection
|
|
@@ -173,21 +172,17 @@ int map_guest_memseg(struct vhm_vm *vm, struct vm_memmap *memmap);
|
|
int init_trusty(struct vhm_vm *vm);
|
|
void deinit_trusty(struct vhm_vm *vm);
|
|
|
|
-int _mem_set_memmap(unsigned long vmid, unsigned long guest_gpa,
|
|
- unsigned long host_gpa, unsigned long len,
|
|
- unsigned int mem_type, unsigned int mem_access_right,
|
|
- unsigned int type);
|
|
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
|
|
+ * set_memory_regions - set guest mapping for multi regions
|
|
*
|
|
- * @memmaps: pointer to set_memmaps
|
|
+ * @regions: pointer to set_regions
|
|
*
|
|
* Return: 0 on success, <0 for error.
|
|
*/
|
|
-int set_memmaps(struct set_memmaps *memmaps);
|
|
+int set_memory_regions(struct set_regions *regions);
|
|
#endif
|
|
diff --git a/include/linux/vhm/vhm_hypercall.h b/include/linux/vhm/vhm_hypercall.h
|
|
index 87a34fec8d90..0a3869b356b8 100644
|
|
--- a/include/linux/vhm/vhm_hypercall.h
|
|
+++ b/include/linux/vhm/vhm_hypercall.h
|
|
@@ -148,9 +148,7 @@ inline long hcall_query_vm_state(unsigned long vmid);
|
|
inline long hcall_setup_sbuf(unsigned long sbuf_head);
|
|
inline long hcall_set_sstate_data(unsigned long sx_data_addr);
|
|
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_memory_regions(unsigned long pa_regions);
|
|
inline long hcall_write_protect_page(unsigned long vmid,
|
|
unsigned long wp);
|
|
inline long hcall_set_ioreq_buffer(unsigned long vmid,
|
|
--
|
|
2.19.2
|
|
|