Skip to content

Commit 9cc82d9

Browse files
Marc ZyngierKAGA-KOKO
authored andcommitted
PCI/MSI: Size device MSI domain with the maximum number of vectors
Zenghui reports that since 1396e89 ("genirq/msi: Move prepare() call to per-device allocation"), his Multi-MSI capable device isn't working anymore. This is a consequence of 15c72f8 ("PCI/MSI: Add support for per device MSI[X] domains"), which always creates a MSI domain of size 1, even in the presence of Multi-MSI. While this was somehow working until then, moving the .prepare() call ends up sizing the ITS table with a tiny value for this device, and making the endpoint driver unhappy. Instead, always create the domain and call the .prepare() helper with the maximum expected size. Fixes: 1396e89 ("genirq/msi: Move prepare() call to per-device allocation") Fixes: 15c72f8 ("PCI/MSI: Add support for per device MSI[X] domains") Reported-by: Zenghui Yu <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Tested-by: Zenghui Yu <[email protected]> Reviewed-by: Lorenzo Pieralisi <[email protected]> Link: https://lore.kernel.org/all/[email protected] Closes: https://lore.kernel.org/r/[email protected]
1 parent 5abc743 commit 9cc82d9

File tree

3 files changed

+8
-7
lines changed

3 files changed

+8
-7
lines changed

drivers/pci/msi/irqdomain.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ static bool pci_create_device_domain(struct pci_dev *pdev, const struct msi_doma
271271
/**
272272
* pci_setup_msi_device_domain - Setup a device MSI interrupt domain
273273
* @pdev: The PCI device to create the domain on
274+
* @hwsize: The maximum number of MSI vectors
274275
*
275276
* Return:
276277
* True when:
@@ -287,7 +288,7 @@ static bool pci_create_device_domain(struct pci_dev *pdev, const struct msi_doma
287288
* - The device is removed
288289
* - MSI is disabled and a MSI-X domain is created
289290
*/
290-
bool pci_setup_msi_device_domain(struct pci_dev *pdev)
291+
bool pci_setup_msi_device_domain(struct pci_dev *pdev, unsigned int hwsize)
291292
{
292293
if (WARN_ON_ONCE(pdev->msix_enabled))
293294
return false;
@@ -297,7 +298,7 @@ bool pci_setup_msi_device_domain(struct pci_dev *pdev)
297298
if (pci_match_device_domain(pdev, DOMAIN_BUS_PCI_DEVICE_MSIX))
298299
msi_remove_device_irq_domain(&pdev->dev, MSI_DEFAULT_DOMAIN);
299300

300-
return pci_create_device_domain(pdev, &pci_msi_template, 1);
301+
return pci_create_device_domain(pdev, &pci_msi_template, hwsize);
301302
}
302303

303304
/**

drivers/pci/msi/msi.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -439,16 +439,16 @@ int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec,
439439
if (nvec < minvec)
440440
return -ENOSPC;
441441

442-
if (nvec > maxvec)
443-
nvec = maxvec;
444-
445442
rc = pci_setup_msi_context(dev);
446443
if (rc)
447444
return rc;
448445

449-
if (!pci_setup_msi_device_domain(dev))
446+
if (!pci_setup_msi_device_domain(dev, nvec))
450447
return -ENODEV;
451448

449+
if (nvec > maxvec)
450+
nvec = maxvec;
451+
452452
for (;;) {
453453
if (affd) {
454454
nvec = irq_calc_affinity_vectors(minvec, nvec, affd);

drivers/pci/msi/msi.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ enum support_mode {
107107
};
108108

109109
bool pci_msi_domain_supports(struct pci_dev *dev, unsigned int feature_mask, enum support_mode mode);
110-
bool pci_setup_msi_device_domain(struct pci_dev *pdev);
110+
bool pci_setup_msi_device_domain(struct pci_dev *pdev, unsigned int hwsize);
111111
bool pci_setup_msix_device_domain(struct pci_dev *pdev, unsigned int hwsize);
112112

113113
/* Legacy (!IRQDOMAIN) fallbacks */

0 commit comments

Comments
 (0)