Author: jhb
Date: Wed Aug 14 23:31:53 2019
New Revision: 351060
URL: https://svnweb.freebsd.org/changeset/base/351060

Log:
  MFC 348695: Support MSI-X for passthrough devices with a separate PBA BAR.
  
  pci_alloc_msix() requires both the table and PBA BARs to be allocated
  by the driver.  ppt was only allocating the table BAR so would fail
  for devices with the PBA in a separate BAR.  Fix this by allocating
  the PBA BAR before pci_alloc_msix() if it is stored in a separate BAR.
  
  While here, release BARs after calling pci_release_msi() instead of
  before.  Also, don't call bus_teardown_intr() in error handling code
  if bus_setup_intr() has just failed.

Modified:
  stable/12/sys/amd64/vmm/io/ppt.c
Directory Properties:
  stable/12/   (props changed)

Changes in other areas also in this revision:
Modified:
  stable/11/sys/amd64/vmm/io/ppt.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/12/sys/amd64/vmm/io/ppt.c
==============================================================================
--- stable/12/sys/amd64/vmm/io/ppt.c    Wed Aug 14 23:28:43 2019        
(r351059)
+++ stable/12/sys/amd64/vmm/io/ppt.c    Wed Aug 14 23:31:53 2019        
(r351060)
@@ -102,7 +102,9 @@ struct pptdev {
                int num_msgs;
                int startrid;
                int msix_table_rid;
+               int msix_pba_rid;
                struct resource *msix_table_res;
+               struct resource *msix_pba_res;
                struct resource **res;
                void **cookie;
                struct pptintr_arg *arg;
@@ -292,6 +294,12 @@ ppt_teardown_msix(struct pptdev *ppt)
        for (i = 0; i < ppt->msix.num_msgs; i++) 
                ppt_teardown_msix_intr(ppt, i);
 
+       free(ppt->msix.res, M_PPTMSIX);
+       free(ppt->msix.cookie, M_PPTMSIX);
+       free(ppt->msix.arg, M_PPTMSIX);
+
+       pci_release_msi(ppt->dev);
+
        if (ppt->msix.msix_table_res) {
                bus_release_resource(ppt->dev, SYS_RES_MEMORY, 
                                     ppt->msix.msix_table_rid,
@@ -299,13 +307,14 @@ ppt_teardown_msix(struct pptdev *ppt)
                ppt->msix.msix_table_res = NULL;
                ppt->msix.msix_table_rid = 0;
        }
+       if (ppt->msix.msix_pba_res) {
+               bus_release_resource(ppt->dev, SYS_RES_MEMORY, 
+                                    ppt->msix.msix_pba_rid,
+                                    ppt->msix.msix_pba_res);
+               ppt->msix.msix_pba_res = NULL;
+               ppt->msix.msix_pba_rid = 0;
+       }
 
-       free(ppt->msix.res, M_PPTMSIX);
-       free(ppt->msix.cookie, M_PPTMSIX);
-       free(ppt->msix.arg, M_PPTMSIX);
-
-       pci_release_msi(ppt->dev);
-
        ppt->msix.num_msgs = 0;
 }
 
@@ -634,6 +643,19 @@ ppt_setup_msix(struct vm *vm, int vcpu, int bus, int s
                }
                ppt->msix.msix_table_rid = rid;
 
+               if (dinfo->cfg.msix.msix_table_bar !=
+                   dinfo->cfg.msix.msix_pba_bar) {
+                       rid = dinfo->cfg.msix.msix_pba_bar;
+                       ppt->msix.msix_pba_res = bus_alloc_resource_any(
+                           ppt->dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+
+                       if (ppt->msix.msix_pba_res == NULL) {
+                               ppt_teardown_msix(ppt);
+                               return (ENOSPC);
+                       }
+                       ppt->msix.msix_pba_rid = rid;
+               }
+
                alloced = numvec;
                error = pci_alloc_msix(ppt->dev, &alloced);
                if (error || alloced != numvec) {
@@ -665,7 +687,6 @@ ppt_setup_msix(struct vm *vm, int vcpu, int bus, int s
                                       &ppt->msix.cookie[idx]);
        
                if (error != 0) {
-                       bus_teardown_intr(ppt->dev, ppt->msix.res[idx], 
ppt->msix.cookie[idx]);
                        bus_release_resource(ppt->dev, SYS_RES_IRQ, rid, 
ppt->msix.res[idx]);
                        ppt->msix.cookie[idx] = NULL;
                        ppt->msix.res[idx] = NULL;
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to