git: e9715b1c4474 - main - LinuxKPI: fix pci_alloc_irq_vectors() for MSI

From: Bjoern A. Zeeb <bz_at_FreeBSD.org>
Date: Fri, 13 Jan 2023 00:40:38 UTC
The branch main has been updated by bz:

URL: https://cgit.FreeBSD.org/src/commit/?id=e9715b1c4474333ff119aba3a9a74bff91f72372

commit e9715b1c4474333ff119aba3a9a74bff91f72372
Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2022-11-28 18:05:48 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2023-01-13 00:39:24 +0000

    LinuxKPI: fix pci_alloc_irq_vectors() for MSI
    
    pci_alloc_irq_vectors() is given a min and max vector value.
    pci_enable_msi() will always succeed independent of these arguments as
    it does not know about them.  Further it will only ever allocate
    1 "vector" not supporting any other amount.
    So upfront check that (a) the available pci_msi_count() can satisfy the
    requested minv and (b) given the pci_enable_msi() hard coded limit check
    that minv is not larger than 1.
    If we cannot satisfy either requirement return an error.
    
    This fixes problems with drivers which check that the returned value
    of allocated "vectors" will match their requests and only otherwise try
    to fall back to ask for 1 or deal otherwise.
    
    Sponsored by:   The FreeBSD Foundation
    MFC after:      3 days
    Reviewed by:    hselasky (earlier version)
    Differential Revision: https://reviews.freebsd.org/D37522
---
 sys/compat/linuxkpi/common/src/linux_pci.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/sys/compat/linuxkpi/common/src/linux_pci.c b/sys/compat/linuxkpi/common/src/linux_pci.c
index aab4bfb6650d..9e79ec80b74f 100644
--- a/sys/compat/linuxkpi/common/src/linux_pci.c
+++ b/sys/compat/linuxkpi/common/src/linux_pci.c
@@ -931,6 +931,11 @@ out:
 			return (pdev->dev.irq_end - pdev->dev.irq_start);
 	}
 	if (flags & PCI_IRQ_MSI) {
+		if (pci_msi_count(pdev->dev.bsddev) < minv)
+			return (-ENOSPC);
+		/* We only support 1 vector in pci_enable_msi() */
+		if (minv != 1)
+			return (-ENOSPC);
 		error = pci_enable_msi(pdev);
 		if (error == 0 && pdev->msi_enabled)
 			return (pdev->dev.irq_end - pdev->dev.irq_start);