git: 6615aa8e1b3d - releng/13.1 - linuxkpi: Restore the KBI for struct pci_driver

From: Warner Losh <imp_at_FreeBSD.org>
Date: Wed, 06 Apr 2022 17:46:01 UTC
The branch releng/13.1 has been updated by imp:

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

commit 6615aa8e1b3de544772f6bd40d791cfe468fa15c
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2022-04-02 19:52:53 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2022-04-06 17:44:54 +0000

    linuxkpi: Restore the KBI for struct pci_driver
    
    The size of the 13.0 version of struct pci_driver was 92 or 184 bytes on
    32- or 64-bit systems respectively. We recently added bsd_probe_return
    at the end of this struct, breaking the KBI on the stable/13 branch.
    
    Fix this by removing the isdrm member. We don't need it because we can
    do a strcmp in the few places that need it as they aren't performance
    critical. Move the newly added bsd_probe_return to that slot. It's the
    same size in all our supported KBIs as bool and fits into that slot due
    to padding rules.
    
    Direct commit to stable/13 because this is not relevant to main.
    
    Approved by:            re@ (gjb)
    Sponsored by:           Netflix
    Reviewed by:            bz
    Differential Revision:  https://reviews.freebsd.org/D34754
    
    (cherry picked from commit aa61c28b4242ce3f86f1ae7807ae95887cbe9d11)
---
 sys/compat/linuxkpi/common/include/linux/pci.h |  3 +--
 sys/compat/linuxkpi/common/src/linux_pci.c     | 14 +++++++++-----
 2 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/sys/compat/linuxkpi/common/include/linux/pci.h b/sys/compat/linuxkpi/common/include/linux/pci.h
index eb5f46a4879c..7afe426d6b52 100644
--- a/sys/compat/linuxkpi/common/include/linux/pci.h
+++ b/sys/compat/linuxkpi/common/include/linux/pci.h
@@ -229,13 +229,12 @@ struct pci_driver {
 	devclass_t			bsdclass;
 	struct device_driver		driver;
 	const struct pci_error_handlers       *err_handler;
-	bool				isdrm;
+	int				bsd_probe_return;
 	int  (*bsd_iov_init)(device_t dev, uint16_t num_vfs,
 	    const nvlist_t *pf_config);
 	void  (*bsd_iov_uninit)(device_t dev);
 	int  (*bsd_iov_add_vf)(device_t dev, uint16_t vfnum,
 	    const nvlist_t *vf_config);
-	int				bsd_probe_return;
 };
 
 struct pci_bus {
diff --git a/sys/compat/linuxkpi/common/src/linux_pci.c b/sys/compat/linuxkpi/common/src/linux_pci.c
index 0734acac60ac..0e952c17d7f7 100644
--- a/sys/compat/linuxkpi/common/src/linux_pci.c
+++ b/sys/compat/linuxkpi/common/src/linux_pci.c
@@ -119,6 +119,12 @@ struct linux_dma_priv {
 #define	DMA_PRIV_LOCK(priv) mtx_lock(&(priv)->lock)
 #define	DMA_PRIV_UNLOCK(priv) mtx_unlock(&(priv)->lock)
 
+static bool
+linux_is_drm(struct pci_driver *pdrv)
+{
+	return (pdrv->name != NULL && strcmp(pdrv->name, "drmn") == 0);
+}
+
 static int
 linux_pdev_dma_uninit(struct pci_dev *pdev)
 {
@@ -405,7 +411,7 @@ linux_pci_attach_device(device_t dev, struct pci_driver *pdrv,
 	linux_set_current(curthread);
 
 	parent = device_get_parent(dev);
-	isdrm = pdrv != NULL && pdrv->isdrm;
+	isdrm = pdrv != NULL && linux_is_drm(pdrv);
 
 	if (isdrm) {
 		struct pci_devinfo *dinfo;
@@ -674,7 +680,6 @@ linux_pci_register_driver(struct pci_driver *pdrv)
 	dc = devclass_find("pci");
 	if (dc == NULL)
 		return (-ENXIO);
-	pdrv->isdrm = false;
 	return (_linux_pci_register_driver(pdrv, dc));
 }
 
@@ -688,7 +693,7 @@ linux_pci_reserve_bar(struct pci_dev *pdev, struct resource_list *rl,
 	KASSERT(type == SYS_RES_IOPORT || type == SYS_RES_MEMORY,
 	    ("trying to reserve non-BAR type %d", type));
 
-	dev = pdev->pdrv != NULL && pdev->pdrv->isdrm ?
+	dev = pdev->pdrv != NULL && linux_is_drm(pdev->pdrv) ?
 	    device_get_parent(pdev->dev.bsddev) : pdev->dev.bsddev;
 	res = pci_reserve_map(device_get_parent(dev), dev, type, &rid, 0, ~0,
 	    1, 1, 0);
@@ -706,7 +711,7 @@ pci_resource_start(struct pci_dev *pdev, int bar)
 
 	if ((rle = linux_pci_get_bar(pdev, bar, true)) == NULL)
 		return (0);
-	dev = pdev->pdrv != NULL && pdev->pdrv->isdrm ?
+	dev = pdev->pdrv != NULL && linux_is_drm(pdev->pdrv) ?
 	    device_get_parent(pdev->dev.bsddev) : pdev->dev.bsddev;
 	if (BUS_TRANSLATE_RESOURCE(dev, rle->type, rle->start, &newstart)) {
 		device_printf(pdev->dev.bsddev, "translate of %#jx failed\n",
@@ -734,7 +739,6 @@ linux_pci_register_drm_driver(struct pci_driver *pdrv)
 	dc = devclass_create("vgapci");
 	if (dc == NULL)
 		return (-ENXIO);
-	pdrv->isdrm = true;
 	pdrv->name = "drmn";
 	return (_linux_pci_register_driver(pdrv, dc));
 }