Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 1 Jun 2020 05:14:02 +0000 (UTC)
From:      Peter Grehan <grehan@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r361686 - stable/12/usr.sbin/bhyve
Message-ID:  <202006010514.0515E2cL086486@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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++) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202006010514.0515E2cL086486>