diff --git a/hypervisor/dm/vpci/pci_pt.c b/hypervisor/dm/vpci/pci_pt.c index af7d9ef5b3..3a6b636d24 100644 --- a/hypervisor/dm/vpci/pci_pt.c +++ b/hypervisor/dm/vpci/pci_pt.c @@ -47,8 +47,7 @@ int32_t vdev_pt_read_cfg(const struct pci_vdev *vdev, uint32_t offset, uint32_t { int32_t ret = -ENODEV; - /* PCI BARs is emulated */ - if (is_prelaunched_vm(vdev->vpci->vm) && pci_bar_access(offset)) { + if (is_prelaunched_vm(vdev->vpci->vm) && is_bar_offset(vdev->nr_bars, offset)) { *val = pci_vdev_read_cfg(vdev, offset, bytes); ret = 0; } @@ -61,7 +60,7 @@ int32_t vdev_pt_read_cfg(const struct pci_vdev *vdev, uint32_t offset, uint32_t * @pre vdev->vpci != NULL * @pre vdev->vpci->vm != NULL * @pre vdev->pdev != NULL -* @pre vdev->pdev->msix.table_bar < (PCI_BAR_COUNT - 1U) +* @pre vdev->pdev->msix.table_bar < vdev->nr_bars */ void vdev_pt_remap_msix_table_bar(struct pci_vdev *vdev) { @@ -71,7 +70,7 @@ void vdev_pt_remap_msix_table_bar(struct pci_vdev *vdev) struct pci_pdev *pdev = vdev->pdev; struct pci_bar *bar; - ASSERT(vdev->pdev->msix.table_bar < (PCI_BAR_COUNT - 1U), "msix->table_bar is out of range"); + ASSERT(vdev->pdev->msix.table_bar < vdev->nr_bars, "msix->table_bar is out of range"); /* Mask all table entries */ for (i = 0U; i < msix->table_count; i++) { @@ -246,7 +245,8 @@ int32_t vdev_pt_write_cfg(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes int32_t ret = -ENODEV; /* bar write access must be 4 bytes and offset must also be 4 bytes aligned */ - if (is_prelaunched_vm(vdev->vpci->vm) && pci_bar_access(offset) && (bytes == 4U) && ((offset & 0x3U) == 0U)) { + if (is_prelaunched_vm(vdev->vpci->vm) && is_bar_offset(vdev->nr_bars, offset) + && (bytes == 4U) && ((offset & 0x3U) == 0U)) { vdev_pt_write_vbar(vdev, offset, val); ret = 0; } @@ -294,8 +294,12 @@ void init_vdev_pt(struct pci_vdev *vdev) struct pci_bar *pbar, *vbar; uint16_t pci_command; + vdev->nr_bars = vdev->pdev->nr_bars; + + ASSERT(vdev->nr_bars > 0U, "vdev->nr_bars should be greater than 0!"); + if (is_prelaunched_vm(vdev->vpci->vm)) { - for (idx = 0U; idx < (uint32_t)PCI_BAR_COUNT; idx++) { + for (idx = 0U; idx < vdev->nr_bars; idx++) { pbar = &vdev->pdev->bar[idx]; vbar = &vdev->bar[idx]; diff --git a/hypervisor/dm/vpci/vhostbridge.c b/hypervisor/dm/vpci/vhostbridge.c index b68ae5923d..9de9b2badb 100644 --- a/hypervisor/dm/vpci/vhostbridge.c +++ b/hypervisor/dm/vpci/vhostbridge.c @@ -127,7 +127,7 @@ int32_t vhostbridge_write_cfg(struct pci_vdev *vdev, uint32_t offset, int32_t ret = -ENODEV; if (is_hostbridge(vdev) && is_prelaunched_vm(vdev->vpci->vm)) { - if (!pci_bar_access(offset)) { + if (!is_bar_offset(PCI_BAR_COUNT, offset)) { pci_vdev_write_cfg(vdev, offset, bytes, val); } diff --git a/hypervisor/include/dm/vpci.h b/hypervisor/include/dm/vpci.h index af337867d2..b36226d79e 100644 --- a/hypervisor/include/dm/vpci.h +++ b/hypervisor/include/dm/vpci.h @@ -74,6 +74,7 @@ struct pci_vdev { union pci_cfgdata cfgdata; /* The bar info of the virtual PCI device. */ + uint32_t nr_bars; /* 6 for normal device, 2 for bridge, 1 for cardbus */ struct pci_bar bar[PCI_BAR_COUNT]; struct pci_msi msi; diff --git a/hypervisor/include/hw/pci.h b/hypervisor/include/hw/pci.h index 2bbab45635..a879e46616 100644 --- a/hypervisor/include/hw/pci.h +++ b/hypervisor/include/hw/pci.h @@ -227,12 +227,12 @@ static inline uint32_t pci_bar_offset(uint32_t idx) return PCIR_BARS + (idx << 2U); } -static inline bool pci_bar_access(uint32_t offset) +static inline bool is_bar_offset(uint32_t nr_bars, uint32_t offset) { bool ret; if ((offset >= pci_bar_offset(0U)) - && (offset < pci_bar_offset(PCI_BAR_COUNT))) { + && (offset < pci_bar_offset(nr_bars))) { ret = true; } else { ret = false;