diff --git a/xen/arch/x86/msi.c b/xen/arch/x86/msi.c index ff2e3d8687..677fd83218 100644 --- a/xen/arch/x86/msi.c +++ b/xen/arch/x86/msi.c @@ -278,23 +278,21 @@ void __msi_set_enable(u16 seg, u8 bus, u8 slot, u8 func, int pos, int enable) static void msi_set_enable(struct pci_dev *dev, int enable) { - int pos; + unsigned int pos = dev->msi_pos; u16 seg = dev->seg; u8 bus = dev->bus; u8 slot = PCI_SLOT(dev->devfn); u8 func = PCI_FUNC(dev->devfn); - pos = pci_find_cap_offset(dev->sbdf, PCI_CAP_ID_MSI); if ( pos ) __msi_set_enable(seg, bus, slot, func, pos, enable); } static void msix_set_enable(struct pci_dev *dev, int enable) { - int pos; + unsigned int pos = dev->msix_pos; uint16_t control; - pos = pci_find_cap_offset(dev->sbdf, PCI_CAP_ID_MSIX); if ( pos ) { control = pci_conf_read16(dev->sbdf, msix_control_reg(pos)); @@ -601,7 +599,7 @@ static int msi_capability_init(struct pci_dev *dev, uint16_t control; ASSERT_PDEV_LIST_IS_READ_LOCKED(dev->domain); - pos = pci_find_cap_offset(dev->sbdf, PCI_CAP_ID_MSI); + pos = dev->msi_pos; if ( !pos ) return -ENODEV; control = pci_conf_read16(dev->sbdf, msi_control_reg(pos)); @@ -764,7 +762,7 @@ static int msix_capability_init(struct pci_dev *dev, u8 slot = PCI_SLOT(dev->devfn); u8 func = PCI_FUNC(dev->devfn); bool maskall = msix->host_maskall, zap_on_error = false; - unsigned int pos = pci_find_cap_offset(dev->sbdf, PCI_CAP_ID_MSIX); + unsigned int pos = dev->msix_pos; if ( !pos ) return -ENODEV; @@ -1133,11 +1131,13 @@ static void _pci_cleanup_msix(struct arch_msix *msix) static void __pci_disable_msix(struct msi_desc *entry) { struct pci_dev *dev = entry->dev; - unsigned int pos = pci_find_cap_offset(dev->sbdf, PCI_CAP_ID_MSIX); + unsigned int pos = dev->msix_pos; u16 control = pci_conf_read16(dev->sbdf, msix_control_reg(entry->msi_attrib.pos)); bool maskall = dev->msix->host_maskall; + ASSERT(pos); + if ( unlikely(!(control & PCI_MSIX_FLAGS_ENABLE)) ) { dev->msix->host_maskall = 1; @@ -1241,7 +1241,7 @@ void pci_cleanup_msi(struct pci_dev *pdev) int pci_reset_msix_state(struct pci_dev *pdev) { - unsigned int pos = pci_find_cap_offset(pdev->sbdf, PCI_CAP_ID_MSIX); + unsigned int pos = pdev->msix_pos; ASSERT(pos); /* @@ -1269,8 +1269,7 @@ int pci_msi_conf_write_intercept(struct pci_dev *pdev, unsigned int reg, if ( pdev->msix ) { entry = find_msi_entry(pdev, -1, PCI_CAP_ID_MSIX); - pos = entry ? entry->msi_attrib.pos - : pci_find_cap_offset(pdev->sbdf, PCI_CAP_ID_MSIX); + pos = entry ? entry->msi_attrib.pos : pdev->msix_pos; ASSERT(pos); if ( reg >= pos && reg < msix_pba_offset_reg(pos) + 4 ) diff --git a/xen/drivers/passthrough/msi.c b/xen/drivers/passthrough/msi.c index 13d904692e..ed2bc7ebe6 100644 --- a/xen/drivers/passthrough/msi.c +++ b/xen/drivers/passthrough/msi.c @@ -29,6 +29,7 @@ int pdev_msi_init(struct pci_dev *pdev) { uint16_t ctrl = pci_conf_read16(pdev->sbdf, msi_control_reg(pos)); + pdev->msi_pos = pos; pdev->msi_maxvec = multi_msi_capable(ctrl); } @@ -41,6 +42,8 @@ int pdev_msi_init(struct pci_dev *pdev) if ( !msix ) return -ENOMEM; + pdev->msix_pos = pos; + spin_lock_init(&msix->table_lock); ctrl = pci_conf_read16(pdev->sbdf, msix_control_reg(pos)); diff --git a/xen/drivers/vpci/msi.c b/xen/drivers/vpci/msi.c index dd6620ec56..66e5a8a116 100644 --- a/xen/drivers/vpci/msi.c +++ b/xen/drivers/vpci/msi.c @@ -195,7 +195,7 @@ static void cf_check mask_write( static int cf_check init_msi(struct pci_dev *pdev) { - unsigned int pos = pci_find_cap_offset(pdev->sbdf, PCI_CAP_ID_MSI); + unsigned int pos = pdev->msi_pos; uint16_t control; int ret; diff --git a/xen/drivers/vpci/msix.c b/xen/drivers/vpci/msix.c index 5bb4444ce2..6bd8c55bb4 100644 --- a/xen/drivers/vpci/msix.c +++ b/xen/drivers/vpci/msix.c @@ -711,7 +711,7 @@ static int cf_check init_msix(struct pci_dev *pdev) struct vpci_msix *msix; int rc; - msix_offset = pci_find_cap_offset(pdev->sbdf, PCI_CAP_ID_MSIX); + msix_offset = pdev->msix_pos; if ( !msix_offset ) return 0; diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h index 63e49f0117..1e4fe68c60 100644 --- a/xen/include/xen/pci.h +++ b/xen/include/xen/pci.h @@ -113,6 +113,9 @@ struct pci_dev { pci_sbdf_t sbdf; }; + uint8_t msi_pos; + uint8_t msix_pos; + uint8_t msi_maxvec; uint8_t phantom_stride;