summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Zeller <mike@mikezeller.net>2020-03-24 14:18:54 -0400
committerGitHub <noreply@github.com>2020-03-24 14:18:54 -0400
commit83d6c1c819dce16c1f12a8ae9f0d8319900f4695 (patch)
tree6cde4b61225154f034ab77d9ab0a03b1737104ea
parent6fc9a8917bb40c1476c23626baae1fc359df05c1 (diff)
downloadillumos-joyent-83d6c1c819dce16c1f12a8ae9f0d8319900f4695.tar.gz
OS-8143 Keep the shadow PCIR_COMMAND synced with the real one for pass through.
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: Jason King <jason.king@joyent.com>
-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);
}