diff options
author | Michael Zeller <mike@mikezeller.net> | 2020-03-24 14:18:54 -0400 |
---|---|---|
committer | Patrick Mooney <pmooney@pfmooney.com> | 2020-05-23 16:38:23 +0000 |
commit | e43213726a6068355df89cb553a223328af375f4 (patch) | |
tree | c9031827f42f7d15a133932e89777e59fcbf3534 | |
parent | c376fe93141769de29a07813de2dfb2c8c4b8481 (diff) | |
download | illumos-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.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); } |