Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 7 Jun 2019 15:53:27 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r348779 - head/usr.sbin/bhyve
Message-ID:  <201906071553.x57FrRDe019503@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Fri Jun  7 15:53:27 2019
New Revision: 348779
URL: https://svnweb.freebsd.org/changeset/base/348779

Log:
  Keep the shadow PCIR_COMMAND synced with the real one for pass through.
  
  This ensures that bhyve properly recognizes when decoding is disabled
  for BARs on passthru devices.  To properly handle writes to the
  register, export a pci_emul_cmd_changed function from pci_emul.c that
  the pass through device model invokes for config writes that change
  PCIR_COMMAND.
  
  Reviewed by:	rgrimes
  MFC after:	2 weeks
  Differential Revision:	https://reviews.freebsd.org/D20531

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

Modified: head/usr.sbin/bhyve/pci_emul.c
==============================================================================
--- head/usr.sbin/bhyve/pci_emul.c	Fri Jun  7 15:48:12 2019	(r348778)
+++ head/usr.sbin/bhyve/pci_emul.c	Fri Jun  7 15:53:27 2019	(r348779)
@@ -1679,33 +1679,20 @@ pci_emul_hdrtype_fixup(int bus, int slot, int off, int
 	}
 }
 
-static void
-pci_emul_cmdsts_write(struct pci_devinst *pi, int coff, uint32_t new, int bytes)
+/*
+ * Update device state in response to changes to the PCI command
+ * register.
+ */
+void
+pci_emul_cmd_changed(struct pci_devinst *pi, uint16_t old)
 {
-	int i, rshift;
-	uint32_t cmd, cmd2, changed, old, readonly;
+	int i;
+	uint16_t changed, new;
 
-	cmd = pci_get_cfgdata16(pi, PCIR_COMMAND);	/* stash old value */
+	new = pci_get_cfgdata16(pi, PCIR_COMMAND);
+	changed = old ^ new;
 
 	/*
-	 * From PCI Local Bus Specification 3.0 sections 6.2.2 and 6.2.3.
-	 *
-	 * XXX Bits 8, 11, 12, 13, 14 and 15 in the status register are
-	 * 'write 1 to clear'. However these bits are not set to '1' by
-	 * any device emulation so it is simpler to treat them as readonly.
-	 */
-	rshift = (coff & 0x3) * 8;
-	readonly = 0xFFFFF880 >> rshift;
-
-	old = CFGREAD(pi, coff, bytes);
-	new &= ~readonly;
-	new |= (old & readonly);
-	CFGWRITE(pi, coff, new, bytes);			/* update config */
-
-	cmd2 = pci_get_cfgdata16(pi, PCIR_COMMAND);	/* get updated value */
-	changed = cmd ^ cmd2;
-
-	/*
 	 * If the MMIO or I/O address space decoding has changed then
 	 * register/unregister all BARs that decode that address space.
 	 */
@@ -1717,7 +1704,7 @@ pci_emul_cmdsts_write(struct pci_devinst *pi, int coff
 			case PCIBAR_IO:
 				/* I/O address space decoding changed? */
 				if (changed & PCIM_CMD_PORTEN) {
-					if (porten(pi))
+					if (new & PCIM_CMD_PORTEN)
 						register_bar(pi, i);
 					else
 						unregister_bar(pi, i);
@@ -1727,7 +1714,7 @@ pci_emul_cmdsts_write(struct pci_devinst *pi, int coff
 			case PCIBAR_MEM64:
 				/* MMIO address space decoding changed? */
 				if (changed & PCIM_CMD_MEMEN) {
-					if (memen(pi))
+					if (new & PCIM_CMD_MEMEN)
 						register_bar(pi, i);
 					else
 						unregister_bar(pi, i);
@@ -1743,6 +1730,32 @@ pci_emul_cmdsts_write(struct pci_devinst *pi, int coff
 	 * interrupt.
 	 */
 	pci_lintr_update(pi);
+}
+
+static void
+pci_emul_cmdsts_write(struct pci_devinst *pi, int coff, uint32_t new, int bytes)
+{
+	int rshift;
+	uint32_t cmd, old, readonly;
+
+	cmd = pci_get_cfgdata16(pi, PCIR_COMMAND);	/* stash old value */
+
+	/*
+	 * From PCI Local Bus Specification 3.0 sections 6.2.2 and 6.2.3.
+	 *
+	 * XXX Bits 8, 11, 12, 13, 14 and 15 in the status register are
+	 * 'write 1 to clear'. However these bits are not set to '1' by
+	 * any device emulation so it is simpler to treat them as readonly.
+	 */
+	rshift = (coff & 0x3) * 8;
+	readonly = 0xFFFFF880 >> rshift;
+
+	old = CFGREAD(pi, coff, bytes);
+	new &= ~readonly;
+	new |= (old & readonly);
+	CFGWRITE(pi, coff, new, bytes);			/* update config */
+
+	pci_emul_cmd_changed(pi, cmd);
 }
 
 static void

Modified: head/usr.sbin/bhyve/pci_emul.h
==============================================================================
--- head/usr.sbin/bhyve/pci_emul.h	Fri Jun  7 15:48:12 2019	(r348778)
+++ head/usr.sbin/bhyve/pci_emul.h	Fri Jun  7 15:53:27 2019	(r348779)
@@ -223,6 +223,7 @@ 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_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);
 void	pci_lintr_assert(struct pci_devinst *pi);

Modified: head/usr.sbin/bhyve/pci_passthru.c
==============================================================================
--- head/usr.sbin/bhyve/pci_passthru.c	Fri Jun  7 15:48:12 2019	(r348778)
+++ head/usr.sbin/bhyve/pci_passthru.c	Fri Jun  7 15:53:27 2019	(r348779)
@@ -639,6 +639,9 @@ cfginit(struct vmctx *ctx, struct pci_devinst *pi, int
 		goto done;
 	}
 
+	pci_set_cfgdata16(pi, PCIR_COMMAND, read_config(&sc->psc_sel,
+	    PCIR_COMMAND, 2));
+
 	error = 0;				/* success */
 done:
 	return (error);
@@ -815,6 +818,7 @@ passthru_cfgwrite(struct vmctx *ctx, int vcpu, struct 
 {
 	int error, msix_table_entries, i;
 	struct passthru_softc *sc;
+	uint16_t cmd_old;
 
 	sc = pi->pi_arg;
 
@@ -871,6 +875,14 @@ passthru_cfgwrite(struct vmctx *ctx, int vcpu, struct 
 #endif
 
 	write_config(&sc->psc_sel, coff, bytes, val);
+	if (coff == PCIR_COMMAND) {
+		cmd_old = pci_get_cfgdata16(pi, PCIR_COMMAND);
+		if (bytes == 1)
+			pci_set_cfgdata8(pi, PCIR_COMMAND, val);
+		else if (bytes == 2)
+			pci_set_cfgdata16(pi, PCIR_COMMAND, val);
+		pci_emul_cmd_changed(pi, cmd_old);
+	}
 
 	return (0);
 }



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