Author: grehan
Date: Mon Jun  1 05:14:01 2020
New Revision: 361686
URL: https://svnweb.freebsd.org/changeset/base/361686

Log:
  MFC r361442
  Fix pci-passthru MSI issues with OpenBSD guests
  
  PR:   245392

Modified:
  stable/12/usr.sbin/bhyve/pci_emul.c
  stable/12/usr.sbin/bhyve/pci_emul.h
  stable/12/usr.sbin/bhyve/pci_passthru.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/usr.sbin/bhyve/pci_emul.c
==============================================================================
--- stable/12/usr.sbin/bhyve/pci_emul.c Mon Jun  1 03:37:58 2020        
(r361685)
+++ stable/12/usr.sbin/bhyve/pci_emul.c Mon Jun  1 05:14:01 2020        
(r361686)
@@ -874,7 +874,7 @@ pci_emul_add_msixcap(struct pci_devinst *pi, int msgnu
                                        sizeof(msixcap)));
 }
 
-void
+static void
 msixcap_cfgwrite(struct pci_devinst *pi, int capoff, int offset,
                 int bytes, uint32_t val)
 {
@@ -898,7 +898,7 @@ msixcap_cfgwrite(struct pci_devinst *pi, int capoff, i
        CFGWRITE(pi, offset, val, bytes);
 }
 
-void
+static void
 msicap_cfgwrite(struct pci_devinst *pi, int capoff, int offset,
                int bytes, uint32_t val)
 {
@@ -977,30 +977,34 @@ pci_emul_add_pciecap(struct pci_devinst *pi, int type)
 
 /*
  * This function assumes that 'coff' is in the capabilities region of the
- * config space.
+ * config space. A capoff parameter of zero will force a search for the
+ * offset and type.
  */
-static void
-pci_emul_capwrite(struct pci_devinst *pi, int offset, int bytes, uint32_t val)
+void
+pci_emul_capwrite(struct pci_devinst *pi, int offset, int bytes, uint32_t val,
+    uint8_t capoff, int capid)
 {
-       int capid;
-       uint8_t capoff, nextoff;
+       uint8_t nextoff;
 
        /* Do not allow un-aligned writes */
        if ((offset & (bytes - 1)) != 0)
                return;
 
-       /* Find the capability that we want to update */
-       capoff = CAP_START_OFFSET;
-       while (1) {
-               nextoff = pci_get_cfgdata8(pi, capoff + 1);
-               if (nextoff == 0)
-                       break;
-               if (offset >= capoff && offset < nextoff)
-                       break;
+       if (capoff == 0) {
+               /* Find the capability that we want to update */
+               capoff = CAP_START_OFFSET;
+               while (1) {
+                       nextoff = pci_get_cfgdata8(pi, capoff + 1);
+                       if (nextoff == 0)
+                               break;
+                       if (offset >= capoff && offset < nextoff)
+                               break;
 
-               capoff = nextoff;
+                       capoff = nextoff;
+               }
+               assert(offset >= capoff);
+               capid = pci_get_cfgdata8(pi, capoff);
        }
-       assert(offset >= capoff);
 
        /*
         * Capability ID and Next Capability Pointer are readonly.
@@ -1017,7 +1021,6 @@ pci_emul_capwrite(struct pci_devinst *pi, int offset, 
                        return;
        }
 
-       capid = pci_get_cfgdata8(pi, capoff);
        switch (capid) {
        case PCIY_MSI:
                msicap_cfgwrite(pi, capoff, offset, bytes, val);
@@ -1896,7 +1899,7 @@ pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus
                        pci_set_cfgdata32(pi, coff, bar);
 
                } else if (pci_emul_iscap(pi, coff)) {
-                       pci_emul_capwrite(pi, coff, bytes, *eax);
+                       pci_emul_capwrite(pi, coff, bytes, *eax, 0, 0);
                } else if (coff >= PCIR_COMMAND && coff < PCIR_REVID) {
                        pci_emul_cmdsts_write(pi, coff, *eax, bytes);
                } else {

Modified: stable/12/usr.sbin/bhyve/pci_emul.h
==============================================================================
--- stable/12/usr.sbin/bhyve/pci_emul.h Mon Jun  1 03:37:58 2020        
(r361685)
+++ stable/12/usr.sbin/bhyve/pci_emul.h Mon Jun  1 05:14:01 2020        
(r361686)
@@ -212,10 +212,6 @@ typedef void (*pci_lintr_cb)(int b, int s, int pin, in
     int ioapic_irq, void *arg);
 
 int    init_pci(struct vmctx *ctx);
-void   msicap_cfgwrite(struct pci_devinst *pi, int capoff, int offset,
-           int bytes, uint32_t val);
-void   msixcap_cfgwrite(struct pci_devinst *pi, int capoff, int offset,
-           int bytes, uint32_t val);
 void   pci_callback(void);
 int    pci_emul_alloc_bar(struct pci_devinst *pdi, int idx,
            enum pcibar_type type, uint64_t size);
@@ -223,6 +219,8 @@ int pci_emul_alloc_pbar(struct pci_devinst *pdi, int i
            uint64_t hostbase, enum pcibar_type type, uint64_t size);
 int    pci_emul_add_msicap(struct pci_devinst *pi, int msgnum);
 int    pci_emul_add_pciecap(struct pci_devinst *pi, int pcie_device_type);
+void   pci_emul_capwrite(struct pci_devinst *pi, int offset, int bytes,
+           uint32_t val, uint8_t capoff, int capid);
 void   pci_emul_cmd_changed(struct pci_devinst *pi, uint16_t old);
 void   pci_generate_msi(struct pci_devinst *pi, int msgnum);
 void   pci_generate_msix(struct pci_devinst *pi, int msgnum);

Modified: stable/12/usr.sbin/bhyve/pci_passthru.c
==============================================================================
--- stable/12/usr.sbin/bhyve/pci_passthru.c     Mon Jun  1 03:37:58 2020        
(r361685)
+++ stable/12/usr.sbin/bhyve/pci_passthru.c     Mon Jun  1 05:14:01 2020        
(r361686)
@@ -814,8 +814,8 @@ passthru_cfgread(struct vmctx *ctx, int vcpu, struct p
        if (coff == PCIR_COMMAND) {
                if (bytes <= 2)
                        return (-1);
-               *rv = pci_get_cfgdata16(pi, PCIR_COMMAND) << 16 |
-                   read_config(&sc->psc_sel, PCIR_STATUS, 2);
+               *rv = read_config(&sc->psc_sel, PCIR_STATUS, 2) << 16 |
+                   pci_get_cfgdata16(pi, PCIR_COMMAND);
                return (0);
        }
 
@@ -845,8 +845,8 @@ passthru_cfgwrite(struct vmctx *ctx, int vcpu, struct 
         * MSI capability is emulated
         */
        if (msicap_access(sc, coff)) {
-               msicap_cfgwrite(pi, sc->psc_msi.capoff, coff, bytes, val);
-
+               pci_emul_capwrite(pi, coff, bytes, val, sc->psc_msi.capoff,
+                   PCIY_MSI);
                error = vm_setup_pptdev_msi(ctx, vcpu, sc->psc_sel.pc_bus,
                        sc->psc_sel.pc_dev, sc->psc_sel.pc_func,
                        pi->pi_msi.addr, pi->pi_msi.msg_data,
@@ -857,7 +857,8 @@ passthru_cfgwrite(struct vmctx *ctx, int vcpu, struct 
        }
 
        if (msixcap_access(sc, coff)) {
-               msixcap_cfgwrite(pi, sc->psc_msix.capoff, coff, bytes, val);
+               pci_emul_capwrite(pi, coff, bytes, val, sc->psc_msix.capoff,
+                   PCIY_MSIX);
                if (pi->pi_msix.enabled) {
                        msix_table_entries = pi->pi_msix.table_count;
                        for (i = 0; i < msix_table_entries; i++) {
_______________________________________________
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