Emulate reads of the PCI command register for passthrough devices.

VFs return zero for the memory enable bit even if it has been set by a
prior write.  After r348779 this caused the annoying behavior that a
guest OS would unintentionally disable memory decoding on a future
read-modify-write operation on the command register.  Instead, return
the shadow value of the command register for reads.  This ensures that
the guest will only toggle the state of the memory enable bit when it
specifically intends to do so.

MFC after:	2 weeks
Sponsored by:	Chelsio Communications
This commit is contained in:
John Baldwin 2019-12-11 23:41:39 +00:00
parent c8b29d1212
commit c7ba149dba

View File

@ -803,6 +803,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->psc_sel, PCIR_STATUS, 2);
return (0);
}
/* Everything else just read from the device's config space */
*rv = read_config(&sc->psc_sel, coff, bytes);