Author: neel
Date: Fri Feb  1 02:41:47 2013
New Revision: 246190
URL: http://svnweb.freebsd.org/changeset/base/246190

Log:
  Fix a bug in the passthru implementation where it would assume that all
  devices are MSI-X capable. This in turn would lead it to treat bar 0 as
  the MSI-X table bar even if the underlying device did not support MSI-X.
  
  Fix this by providing an API to query the MSI-X table index of the emulated
  device. If the underlying device does not support MSI-X then this API will
  return -1.
  
  Obtained from:        NetApp

Modified:
  head/usr.sbin/bhyve/pci_emul.c
  head/usr.sbin/bhyve/pci_emul.h
  head/usr.sbin/bhyve/pci_passthru.c
  head/usr.sbin/bhyve/pci_virtio_net.c

Modified: head/usr.sbin/bhyve/pci_emul.c
==============================================================================
--- head/usr.sbin/bhyve/pci_emul.c      Fri Feb  1 01:34:59 2013        
(r246189)
+++ head/usr.sbin/bhyve/pci_emul.c      Fri Feb  1 02:41:47 2013        
(r246190)
@@ -254,6 +254,26 @@ pci_emul_msix_tread(struct pci_devinst *
        return (retval);
 }
 
+int
+pci_msix_table_bar(struct pci_devinst *pi)
+{
+
+       if (pi->pi_msix.table != NULL)
+               return (pi->pi_msix.table_bar);
+       else
+               return (-1);
+}
+
+int
+pci_msix_pba_bar(struct pci_devinst *pi)
+{
+
+       if (pi->pi_msix.table != NULL)
+               return (pi->pi_msix.pba_bar);
+       else
+               return (-1);
+}
+
 static int
 pci_emul_io_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes,
                    uint32_t *eax, void *arg)

Modified: head/usr.sbin/bhyve/pci_emul.h
==============================================================================
--- head/usr.sbin/bhyve/pci_emul.h      Fri Feb  1 01:34:59 2013        
(r246189)
+++ head/usr.sbin/bhyve/pci_emul.h      Fri Feb  1 02:41:47 2013        
(r246190)
@@ -169,6 +169,8 @@ void        pci_lintr_deassert(struct pci_devin
 int    pci_lintr_request(struct pci_devinst *pi, int ivec);
 int    pci_msi_enabled(struct pci_devinst *pi);
 int    pci_msix_enabled(struct pci_devinst *pi);
+int    pci_msix_table_bar(struct pci_devinst *pi);
+int    pci_msix_pba_bar(struct pci_devinst *pi);
 int    pci_msi_msgnum(struct pci_devinst *pi);
 void   pci_parse_slot(char *opt, int legacy);
 void   pci_populate_msicap(struct msicap *cap, int msgs, int nextptr);

Modified: head/usr.sbin/bhyve/pci_passthru.c
==============================================================================
--- head/usr.sbin/bhyve/pci_passthru.c  Fri Feb  1 01:34:59 2013        
(r246189)
+++ head/usr.sbin/bhyve/pci_passthru.c  Fri Feb  1 02:41:47 2013        
(r246190)
@@ -361,6 +361,8 @@ init_msix_table(struct vmctx *ctx, struc
        size_t len;
        struct pci_devinst *pi = sc->psc_pi;
 
+       assert(pci_msix_table_bar(pi) >= 0 && pci_msix_pba_bar(pi) >= 0);
+
        /* 
         * If the MSI-X table BAR maps memory intended for
         * other uses, it is at least assured that the table 
@@ -370,7 +372,9 @@ init_msix_table(struct vmctx *ctx, struc
        if (pi->pi_msix.pba_bar == pi->pi_msix.table_bar && 
            ((pi->pi_msix.pba_offset - pi->pi_msix.table_offset) < 4096)) {
                /* Need to also emulate the PBA, not supported yet */
-               printf("Unsupported MSI-X table and PBA in same page\n");
+               printf("Unsupported MSI-X configuration: %d/%d/%d\n",
+                      sc->psc_sel.pc_bus, sc->psc_sel.pc_dev,
+                      sc->psc_sel.pc_func);
                return (-1);
        }
 
@@ -447,7 +451,7 @@ cfginitbar(struct vmctx *ctx, struct pas
                        return (-1);
 
                /* The MSI-X table needs special handling */
-               if (i == pi->pi_msix.table_bar) {
+               if (i == pci_msix_table_bar(pi)) {
                        error = init_msix_table(ctx, sc, base);
                        if (error) 
                                return (-1);
@@ -688,7 +692,7 @@ passthru_write(struct vmctx *ctx, int vc
 
        sc = pi->pi_arg;
 
-       if (pi->pi_msix.table_bar == baridx) {
+       if (baridx == pci_msix_table_bar(pi)) {
                msix_table_write(ctx, vcpu, sc, offset, size, value);
        } else {
                assert(pi->pi_bar[baridx].type == PCIBAR_IO);
@@ -712,7 +716,7 @@ passthru_read(struct vmctx *ctx, int vcp
 
        sc = pi->pi_arg;
 
-       if (pi->pi_msix.table_bar == baridx) {
+       if (baridx == pci_msix_table_bar(pi)) {
                val = msix_table_read(sc, offset, size);
        } else {
                assert(pi->pi_bar[baridx].type == PCIBAR_IO);

Modified: head/usr.sbin/bhyve/pci_virtio_net.c
==============================================================================
--- head/usr.sbin/bhyve/pci_virtio_net.c        Fri Feb  1 01:34:59 2013        
(r246189)
+++ head/usr.sbin/bhyve/pci_virtio_net.c        Fri Feb  1 02:41:47 2013        
(r246190)
@@ -685,8 +685,8 @@ pci_vtnet_write(struct vmctx *ctx, int v
        void *ptr;
 
        if (use_msix) {
-               if (baridx == pi->pi_msix.table_bar ||
-                   baridx == pi->pi_msix.pba_bar) {
+               if (baridx == pci_msix_table_bar(pi) ||
+                   baridx == pci_msix_pba_bar(pi)) {
                        pci_emul_msix_twrite(pi, offset, size, value);
                        return;
                }
@@ -781,8 +781,8 @@ pci_vtnet_read(struct vmctx *ctx, int vc
        uint64_t value;
 
        if (use_msix) {
-               if (baridx == pi->pi_msix.table_bar ||
-                   baridx == pi->pi_msix.pba_bar) {
+               if (baridx == pci_msix_table_bar(pi) ||
+                   baridx == pci_msix_pba_bar(pi)) {
                        return (pci_emul_msix_tread(pi, offset, size));
                }
        }
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to