diff --git a/hypervisor/dm/vpci/hostbridge.c b/hypervisor/dm/vpci/hostbridge.c index 2a8c0c2e7..a6ade24aa 100644 --- a/hypervisor/dm/vpci/hostbridge.c +++ b/hypervisor/dm/vpci/hostbridge.c @@ -115,7 +115,9 @@ static int vdev_hostbridge_cfgwrite(struct pci_vdev *vdev, uint32_t offset, return -EINVAL; } - pci_vdev_write_cfg(vdev, offset, bytes, val); + if (!pci_bar_access(offset)) { + pci_vdev_write_cfg(vdev, offset, bytes, val); + } return 0; } diff --git a/hypervisor/dm/vpci/pci_priv.h b/hypervisor/dm/vpci/pci_priv.h index 87d562bc0..380925511 100644 --- a/hypervisor/dm/vpci/pci_priv.h +++ b/hypervisor/dm/vpci/pci_priv.h @@ -42,7 +42,6 @@ #define PCIR_VENDOR 0x00U #define PCIR_DEVICE 0x02U #define PCIR_COMMAND 0x04U -#define PCIM_CMD_MEMEN 0x0002U #define PCIR_REVID 0x08U #define PCIR_SUBCLASS 0x0AU #define PCIR_CLASS 0x0BU diff --git a/hypervisor/dm/vpci/pci_pt.c b/hypervisor/dm/vpci/pci_pt.c index d920532ac..6a26a82e5 100644 --- a/hypervisor/dm/vpci/pci_pt.c +++ b/hypervisor/dm/vpci/pci_pt.c @@ -131,6 +131,7 @@ static int vdev_pt_init(struct pci_vdev *vdev) { int ret; struct vm *vm = vdev->vpci->vm; + uint16_t pci_command; ret = vdev_pt_init_validate(vdev); if (ret != 0) { @@ -150,6 +151,11 @@ static int vdev_pt_init(struct pci_vdev *vdev) ret = assign_iommu_device(vm->iommu, vdev->pdev.bdf.bits.b, (uint8_t)(vdev->pdev.bdf.value & 0xFFU)); + pci_command = pci_pdev_read_cfg(&vdev->pdev, PCIR_COMMAND, 2U); + /* Disable INTX */ + pci_command |= 0x400U; + pci_pdev_write_cfg(&vdev->pdev, PCIR_COMMAND, 2U, pci_command); + return ret; } @@ -212,44 +218,47 @@ static int vdev_pt_remap_bar(struct pci_vdev *vdev, uint32_t idx, return error; } -static uint32_t memen(struct pci_vdev *vdev) -{ - return pci_pdev_read_cfg(&vdev->pdev, PCIR_COMMAND, 2U) - & PCIM_CMD_MEMEN; -} - static void vdev_pt_cfgwrite_bar(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t new_bar_uos) { uint32_t idx; uint32_t new_bar, mask; - bool bar_update_normal = 1; - bool do_map; + bool bar_update_normal; int error; if ((bytes != 4U) || ((offset & 0x3U) != 0U)) { return; } + new_bar = 0U; idx = (offset - pci_bar_offset(0U)) >> 2U; mask = ~(vdev->bar[idx].size - 1U); - bar_update_normal = (new_bar_uos != (uint32_t)~0U); - new_bar = new_bar_uos & mask; - if (pci_bar_base(new_bar) == vdev->bar[idx].base) { - return; - } + switch (vdev->bar[idx].type) { + case PCIBAR_NONE: + vdev->bar[idx].base = 0UL; + break; - do_map = (memen(vdev)) && bar_update_normal; - if (do_map) { - error = vdev_pt_remap_bar(vdev, idx, pci_bar_base(new_bar)); - if (error != 0) { - pr_err("vdev_pt_remap_bar failed: %d", idx); + case PCIBAR_MEM32: + bar_update_normal = (new_bar_uos != (uint32_t)~0U); + new_bar = new_bar_uos & mask; + if (bar_update_normal) { + error = vdev_pt_remap_bar(vdev, idx, + pci_bar_base(new_bar)); + if (error != 0) { + pr_err("vdev_pt_remap_bar failed: %d", idx); + } + + vdev->bar[idx].base = pci_bar_base(new_bar); } + break; + + default: + pr_err("Unknown bar type, idx=%d", idx); + break; } pci_vdev_write_cfg_u32(vdev, offset, new_bar); - vdev->bar[idx].base = pci_bar_base(new_bar); } static int vdev_pt_cfgwrite(struct pci_vdev *vdev, uint32_t offset,