diff options
author | Michael Zeller <mike@mikezeller.net> | 2020-03-24 14:18:54 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-24 14:18:54 -0400 |
commit | 83d6c1c819dce16c1f12a8ae9f0d8319900f4695 (patch) | |
tree | 6cde4b61225154f034ab77d9ab0a03b1737104ea | |
parent | 6fc9a8917bb40c1476c23626baae1fc359df05c1 (diff) | |
download | illumos-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.c | 26 |
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); } |