summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Zeller <mike@mikezeller.net>2020-03-24 14:18:54 -0400
committerPatrick Mooney <pmooney@pfmooney.com>2020-05-23 16:38:23 +0000
commite43213726a6068355df89cb553a223328af375f4 (patch)
treec9031827f42f7d15a133932e89777e59fcbf3534
parentc376fe93141769de29a07813de2dfb2c8c4b8481 (diff)
downloadillumos-joyent-e43213726a6068355df89cb553a223328af375f4.tar.gz
12737 sync shadow PCIR_COMMAND with real one for bhyve pass-thru
Reviewed by: Hans Rosenfeld <hans.rosenfeld@joyent.com> Reviewed by: Jason King <jason.king@joyent.com> Reviewed by: Jorge Schrauwen <jorge@blackdot.be> Approved by: Robert Mustacchi <rm@fingolfin.org>
-rw-r--r--usr/src/cmd/bhyve/pci_passthru.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/usr/src/cmd/bhyve/pci_passthru.c b/usr/src/cmd/bhyve/pci_passthru.c
index 3782914cd5..7dff426253 100644
--- a/usr/src/cmd/bhyve/pci_passthru.c
+++ b/usr/src/cmd/bhyve/pci_passthru.c
@@ -654,6 +654,8 @@ cfginitbar(struct vmctx *ctx, struct passthru_softc *sc)
static int
cfginit(struct vmctx *ctx, struct passthru_softc *sc)
{
+ struct pci_devinst *pi = sc->psc_pi;
+
if (cfginitmsi(sc) != 0) {
warnx("failed to initialize MSI for PCI %d", sc->pptfd);
return (-1);
@@ -664,6 +666,8 @@ cfginit(struct vmctx *ctx, struct passthru_softc *sc)
return (-1);
}
+ pci_set_cfgdata16(pi, PCIR_COMMAND, read_config(sc, PCIR_COMMAND, 2));
+
return (0);
}
@@ -782,6 +786,19 @@ passthru_cfgread(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
}
#endif
+ /*
+ * Emulate the command register. If a single read reads both the
+ * command and status registers, read the status register from the
+ * device's config space.
+ */
+ if (coff == PCIR_COMMAND) {
+ if (bytes <= 2)
+ return (-1);
+ *rv = pci_get_cfgdata16(pi, PCIR_COMMAND) << 16 |
+ read_config(sc, PCIR_STATUS, 2);
+ return (0);
+ }
+
/* Everything else just read from the device's config space */
*rv = read_config(sc, coff, bytes);
@@ -794,6 +811,7 @@ passthru_cfgwrite(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
{
int error, msix_table_entries, i;
struct passthru_softc *sc;
+ uint16_t cmd_old;
sc = pi->pi_arg;
@@ -847,6 +865,14 @@ passthru_cfgwrite(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
#endif
write_config(sc, 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);
}