From 150ad30b09c3065f1cff0c5f4e8f40597d49228f Mon Sep 17 00:00:00 2001 From: Jian Jun Chen Date: Fri, 10 Aug 2018 15:06:05 +0800 Subject: [PATCH] dm: virtio: implement vhost_set_mem_table vhost kernel driver needs the information of memory mapping between GPA and the virtual addresses in device model process. This is required for virtqueue related operations. This patch gets memory mapping information from vmctx then conveys to vhost. Tracked-On: #1329 Signed-off-by: Jian Jun Chen Acked-by: Yu Wang --- devicemodel/hw/pci/virtio/vhost.c | 65 ++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/devicemodel/hw/pci/virtio/vhost.c b/devicemodel/hw/pci/virtio/vhost.c index 44c3b5a70..8dfc59d47 100644 --- a/devicemodel/hw/pci/virtio/vhost.c +++ b/devicemodel/hw/pci/virtio/vhost.c @@ -44,6 +44,14 @@ vhost_kernel_deinit(struct vhost_dev *vdev) /* to be implemented */ } +static int +vhost_kernel_set_mem_table(struct vhost_dev *vdev, + struct vhost_memory *mem) +{ + /* to be implemented */ + return -1; +} + static int vhost_kernel_set_vring_addr(struct vhost_dev *vdev, struct vhost_vring_addr *addr) @@ -370,8 +378,61 @@ vhost_vq_stop(struct vhost_dev *vdev, int idx) static int vhost_set_mem_table(struct vhost_dev *vdev) { - /* to be implemented */ - return -1; + struct vmctx *ctx; + struct vhost_memory *mem; + uint32_t nregions = 0; + int rc; + + ctx = vdev->base->dev->vmctx; + if (ctx->lowmem > 0) + nregions++; + if (ctx->highmem > 0) + nregions++; + + mem = calloc(1, sizeof(struct vhost_memory) + + sizeof(struct vhost_memory_region) * nregions); + if (!mem) { + WPRINTF("out of memory\n"); + return -1; + } + + nregions = 0; + if (ctx->lowmem > 0) { + mem->regions[nregions].guest_phys_addr = (uintptr_t)0; + mem->regions[nregions].memory_size = ctx->lowmem; + mem->regions[nregions].userspace_addr = + (uintptr_t)ctx->baseaddr; + DPRINTF("[%d][0x%llx -> 0x%llx, 0x%llx]\n", + nregions, + mem->regions[nregions].guest_phys_addr, + mem->regions[nregions].userspace_addr, + mem->regions[nregions].memory_size); + nregions++; + } + + if (ctx->highmem > 0) { + mem->regions[nregions].guest_phys_addr = 4*GB; + mem->regions[nregions].memory_size = ctx->highmem; + mem->regions[nregions].userspace_addr = + (uintptr_t)(ctx->baseaddr + 4*GB); + DPRINTF("[%d][0x%llx -> 0x%llx, 0x%llx]\n", + nregions, + mem->regions[nregions].guest_phys_addr, + mem->regions[nregions].userspace_addr, + mem->regions[nregions].memory_size); + nregions++; + } + + mem->nregions = nregions; + mem->padding = 0; + rc = vhost_kernel_set_mem_table(vdev, mem); + free(mem); + if (rc < 0) { + WPRINTF("set_mem_table failed\n"); + return -1; + } + + return 0; } int