mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-19 04:02:05 +00:00
hv: fix bug in sizing MSI-X Table Base Address Register
To sizing a 64-bit BAR, need to form the two 32-bit registers as a 64-bit words, before doing the calculation: inverting all bits and incrementing by 1. Tracked-On: #1568 Signed-off-by: dongshen <dongsheng.x.zhang@intel.com> Signed-off-by: Zide Chen <zide.chen@intel.com> Acked-by: Anthony Xu <anthony.xu@intel.com>
This commit is contained in:
parent
51977a6d2c
commit
5555a2f85d
@ -261,7 +261,7 @@ static void decode_msix_table_bar(struct pci_vdev *vdev)
|
|||||||
uint32_t bir = vdev->msix.table_bar;
|
uint32_t bir = vdev->msix.table_bar;
|
||||||
union pci_bdf pbdf = vdev->pdev.bdf;
|
union pci_bdf pbdf = vdev->pdev.bdf;
|
||||||
uint64_t base, size;
|
uint64_t base, size;
|
||||||
uint32_t bar_lo, bar_hi;
|
uint32_t bar_lo, bar_hi, val32;
|
||||||
|
|
||||||
bar_lo = pci_pdev_read_cfg(pbdf, pci_bar_offset(bir), 4U);
|
bar_lo = pci_pdev_read_cfg(pbdf, pci_bar_offset(bir), 4U);
|
||||||
if ((bar_lo & PCIM_BAR_SPACE) == PCIM_BAR_IO_SPACE) {
|
if ((bar_lo & PCIM_BAR_SPACE) == PCIM_BAR_IO_SPACE) {
|
||||||
@ -281,16 +281,19 @@ static void decode_msix_table_bar(struct pci_vdev *vdev)
|
|||||||
vdev->msix.mmio_gpa = vm0_hpa2gpa(base);
|
vdev->msix.mmio_gpa = vm0_hpa2gpa(base);
|
||||||
|
|
||||||
/* Sizing the BAR */
|
/* Sizing the BAR */
|
||||||
pci_pdev_write_cfg(pbdf, pci_bar_offset(bir), 4U, ~0U);
|
size = 0U;
|
||||||
size = pci_pdev_read_cfg(pbdf, pci_bar_offset(bir), 4U);
|
if (((bar_lo & PCIM_BAR_MEM_TYPE) == PCIM_BAR_MEM_64) && (bir < (PCI_BAR_COUNT - 1U))) {
|
||||||
vdev->msix.mmio_size = (size & ~(size - 1U));
|
|
||||||
|
|
||||||
if ((bar_lo & PCIM_BAR_MEM_TYPE) == PCIM_BAR_MEM_64) {
|
|
||||||
pci_pdev_write_cfg(pbdf, pci_bar_offset(bir + 1U), 4U, ~0U);
|
pci_pdev_write_cfg(pbdf, pci_bar_offset(bir + 1U), 4U, ~0U);
|
||||||
size = (uint64_t)pci_pdev_read_cfg(pbdf, pci_bar_offset(bir + 1U), 4U);
|
size = (uint64_t)pci_pdev_read_cfg(pbdf, pci_bar_offset(bir + 1U), 4U);
|
||||||
vdev->msix.mmio_size |= (size << 32U);
|
size <<= 32U;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pci_pdev_write_cfg(pbdf, pci_bar_offset(bir), 4U, ~0U);
|
||||||
|
val32 = pci_pdev_read_cfg(pbdf, pci_bar_offset(bir), 4U);
|
||||||
|
size |= ((uint64_t)val32 & PCIM_BAR_MEM_BASE);
|
||||||
|
|
||||||
|
vdev->msix.mmio_size = size & ~(size - 1U);
|
||||||
|
|
||||||
/* Restore the BAR */
|
/* Restore the BAR */
|
||||||
pci_pdev_write_cfg(pbdf, pci_bar_offset(bir), 4U, bar_lo);
|
pci_pdev_write_cfg(pbdf, pci_bar_offset(bir), 4U, bar_lo);
|
||||||
|
|
||||||
@ -314,6 +317,12 @@ static int vmsix_init(struct pci_vdev *vdev)
|
|||||||
msix->table_offset = table_info & ~PCIM_MSIX_BIR_MASK;
|
msix->table_offset = table_info & ~PCIM_MSIX_BIR_MASK;
|
||||||
msix->table_count = (msgctrl & PCIM_MSIXCTRL_TABLE_SIZE) + 1U;
|
msix->table_count = (msgctrl & PCIM_MSIXCTRL_TABLE_SIZE) + 1U;
|
||||||
|
|
||||||
|
if (msix->table_bar >= (PCI_BAR_COUNT - 1U)) {
|
||||||
|
pr_err("%s, MSI-X device (%x) invalid table BIR %d", __func__, vdev->pdev.bdf.value, msix->table_bar);
|
||||||
|
vdev->msix.capoff = 0U;
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
/* Mask all table entries */
|
/* Mask all table entries */
|
||||||
for (i = 0U; i < msix->table_count; i++) {
|
for (i = 0U; i < msix->table_count; i++) {
|
||||||
msix->tables[i].vector_control |= PCIM_MSIX_VCTRL_MASK;
|
msix->tables[i].vector_control |= PCIM_MSIX_VCTRL_MASK;
|
||||||
|
Loading…
Reference in New Issue
Block a user