From 30b77aba5ddc1b50b09ddd662bcc4294d61b6c72 Mon Sep 17 00:00:00 2001 From: Edwin Zhai Date: Wed, 29 Aug 2018 14:42:35 +0800 Subject: [PATCH] DM: unmap ptdev BAR when deinit Unmap ptdev BAR when deinit to comply with native system, who zap out all pre-allocated BARs. Tracked-On: #1146 Signed-off-by: Edwin Zhai Acked-by: Yin Fengwei Acked-by: Eddie Dong --- devicemodel/core/vmmapi.c | 16 ++++++++++++++++ devicemodel/hw/pci/passthrough.c | 18 +++++++++++++++++- devicemodel/include/public/vhm_ioctl_defs.h | 1 + devicemodel/include/vmmapi.h | 2 ++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/devicemodel/core/vmmapi.c b/devicemodel/core/vmmapi.c index 6a1310acf..a7103f88c 100644 --- a/devicemodel/core/vmmapi.c +++ b/devicemodel/core/vmmapi.c @@ -549,6 +549,22 @@ vm_map_ptdev_mmio(struct vmctx *ctx, int bus, int slot, int func, return ioctl(ctx->fd, IC_SET_MEMSEG, &memmap); } +int +vm_unmap_ptdev_mmio(struct vmctx *ctx, int bus, int slot, int func, + vm_paddr_t gpa, size_t len, vm_paddr_t hpa) +{ + struct vm_memmap memmap; + + bzero(&memmap, sizeof(struct vm_memmap)); + memmap.type = VM_MMIO; + memmap.len = len; + memmap.gpa = gpa; + memmap.hpa = hpa; + memmap.prot = PROT_ALL; + + return ioctl(ctx->fd, IC_UNSET_MEMSEG, &memmap); +} + int vm_setup_ptdev_msi(struct vmctx *ctx, struct acrn_vm_pci_msix_remap *msi_remap) { diff --git a/devicemodel/hw/pci/passthrough.c b/devicemodel/hw/pci/passthrough.c index ac059451e..e2829b138 100644 --- a/devicemodel/hw/pci/passthrough.c +++ b/devicemodel/hw/pci/passthrough.c @@ -672,6 +672,7 @@ init_msix_table(struct vmctx *ctx, struct passthru_dev *ptdev, uint64_t base) /* Map everything before the MSI-X table */ if (table_offset > 0) { len = table_offset; + warnx("Map part of MSI-X BAR!\n"); error = vm_map_ptdev_mmio(ctx, b, s, f, start, len, base); if (error) return error; @@ -703,6 +704,7 @@ init_msix_table(struct vmctx *ctx, struct passthru_dev *ptdev, uint64_t base) /* Map everything beyond the end of the MSI-X table */ if (remaining > 0) { len = remaining; + warnx("Map remaining of MSI-X BAR!\n"); error = vm_map_ptdev_mmio(ctx, b, s, f, start, len, base); if (error) return error; @@ -1064,7 +1066,7 @@ passthru_deinit(struct vmctx *ctx, struct pci_vdev *dev, char *opts) struct passthru_dev *ptdev; uint8_t bus, slot, func; uint16_t virt_bdf = PCI_BDF(dev->bus, dev->slot, dev->func); - int vector_cnt = 0; + int i, vector_cnt = 0; if (!dev->arg) { warnx("%s: passthru_dev is NULL", __func__); @@ -1095,6 +1097,20 @@ passthru_deinit(struct vmctx *ctx, struct pci_vdev *dev, char *opts) free(dev->msix.table); } + /* unmap the physical BAR in guest MMIO space */ + for (i = 0; i <= PCI_BARMAX; i++) { + + if (ptdev->bar[i].size == 0 || + i == pci_msix_table_bar(dev) || + ptdev->bar[i].type == PCIBAR_IO) + continue; + + vm_unmap_ptdev_mmio(ctx, ptdev->sel.bus, + ptdev->sel.dev, ptdev->sel.func, + dev->bar[i].addr, ptdev->bar[i].size, + ptdev->bar[i].addr); + } + free(ptdev); vm_unassign_ptdev(ctx, bus, slot, func); } diff --git a/devicemodel/include/public/vhm_ioctl_defs.h b/devicemodel/include/public/vhm_ioctl_defs.h index 43cc6899c..a7fd941fb 100644 --- a/devicemodel/include/public/vhm_ioctl_defs.h +++ b/devicemodel/include/public/vhm_ioctl_defs.h @@ -94,6 +94,7 @@ /* IC_ALLOC_MEMSEG not used */ #define IC_ALLOC_MEMSEG _IC_ID(IC_ID, IC_ID_MEM_BASE + 0x00) #define IC_SET_MEMSEG _IC_ID(IC_ID, IC_ID_MEM_BASE + 0x01) +#define IC_UNSET_MEMSEG _IC_ID(IC_ID, IC_ID_MEM_BASE + 0x02) /* PCI assignment*/ #define IC_ID_PCI_BASE 0x50UL diff --git a/devicemodel/include/vmmapi.h b/devicemodel/include/vmmapi.h index 2de0da5a2..4931d8a39 100644 --- a/devicemodel/include/vmmapi.h +++ b/devicemodel/include/vmmapi.h @@ -138,6 +138,8 @@ int vm_assign_ptdev(struct vmctx *ctx, int bus, int slot, int func); int vm_unassign_ptdev(struct vmctx *ctx, int bus, int slot, int func); int vm_map_ptdev_mmio(struct vmctx *ctx, int bus, int slot, int func, vm_paddr_t gpa, size_t len, vm_paddr_t hpa); +int vm_unmap_ptdev_mmio(struct vmctx *ctx, int bus, int slot, int func, + vm_paddr_t gpa, size_t len, vm_paddr_t hpa); int vm_setup_ptdev_msi(struct vmctx *ctx, struct acrn_vm_pci_msix_remap *msi_remap); int vm_set_ptdev_msix_info(struct vmctx *ctx, struct ic_ptdev_irq *ptirq);