From ed1bdcbbdf158d72f6a19eecc851391a52e52459 Mon Sep 17 00:00:00 2001 From: dongshen Date: Thu, 27 Jun 2019 16:42:29 -0700 Subject: [PATCH] HV: add uint64_t bar_base_mapped[PCI_BAR_COUNT] to struct pci_vdev To remember the previously mapped/registered vbar base For the following reasons: register_mmio_emulation_handler() will throw an error if the the same addr_lo is alreayd registered before We are going to remove the base member from struct pci_bar, so we cannot use vdev->bar[idx].base in the code any more In subsequent commits, we will assume vdev_pt_remap_generic_mem_vbar() is called after a new vbar base is set, mainly because of 64-bit mmio bar handling, so we need a separate bar_base_mapped[] array to track the previously mapped vbar bases. Tracked-On: #3241 Signed-off-by: dongshen Reviewed-by: Eddie Dong --- hypervisor/dm/vpci/pci_pt.c | 18 +++++++++++++----- hypervisor/include/dm/vpci.h | 3 +++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/hypervisor/dm/vpci/pci_pt.c b/hypervisor/dm/vpci/pci_pt.c index a56115d5d..c37ab727b 100644 --- a/hypervisor/dm/vpci/pci_pt.c +++ b/hypervisor/dm/vpci/pci_pt.c @@ -245,8 +245,12 @@ void vdev_pt_remap_msix_table_bar(struct pci_vdev *vdev) addr_lo = round_page_down(msix->mmio_gpa + msix->table_offset); } - register_mmio_emulation_handler(vdev->vpci->vm, vmsix_table_mmio_access_handler, - addr_lo, addr_hi, vdev); + if (vdev->bar_base_mapped[msix->table_bar] != addr_lo) { + register_mmio_emulation_handler(vdev->vpci->vm, vmsix_table_mmio_access_handler, + addr_lo, addr_hi, vdev); + /* Remember the previously registered MMIO vbar base */ + vdev->bar_base_mapped[msix->table_bar] = addr_lo; + } } } @@ -258,15 +262,16 @@ void vdev_pt_remap_msix_table_bar(struct pci_vdev *vdev) * @pre vdev->vpci != NULL * @pre vdev->vpci->vm != NULL */ -static void vdev_pt_remap_generic_mem_vbar(const struct pci_vdev *vdev, uint32_t idx, uint32_t new_base) +static void vdev_pt_remap_generic_mem_vbar(struct pci_vdev *vdev, uint32_t idx, uint32_t new_base) { struct acrn_vm *vm = vdev->vpci->vm; /* If the old vbar is mapped before, unmap it first */ - if (vdev->bar[idx].base != 0UL) { + if (vdev->bar_base_mapped[idx] != 0UL) { ept_del_mr(vm, (uint64_t *)vm->arch_vm.nworld_eptp, - vdev->bar[idx].base, /* GPA (old vbar) */ + vdev->bar_base_mapped[idx], /* GPA (old vbar) */ vdev->bar[idx].size); + vdev->bar_base_mapped[idx] = 0UL; } if (new_base != 0U) { @@ -278,6 +283,9 @@ static void vdev_pt_remap_generic_mem_vbar(const struct pci_vdev *vdev, uint32_t new_base, /*GPA*/ vdev->bar[idx].size, EPT_WR | EPT_RD | EPT_UNCACHED); + + /* Remember the previously mapped MMIO vbar */ + vdev->bar_base_mapped[idx] = (uint64_t)new_base; } } diff --git a/hypervisor/include/dm/vpci.h b/hypervisor/include/dm/vpci.h index b36226d79..a1770904c 100644 --- a/hypervisor/include/dm/vpci.h +++ b/hypervisor/include/dm/vpci.h @@ -77,6 +77,9 @@ struct pci_vdev { uint32_t nr_bars; /* 6 for normal device, 2 for bridge, 1 for cardbus */ struct pci_bar bar[PCI_BAR_COUNT]; + /* Remember the previously mapped/registered vbar base for undo purpose */ + uint64_t bar_base_mapped[PCI_BAR_COUNT]; + struct pci_msi msi; struct pci_msix msix;