summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authorgrehan <grehan@FreeBSD.org>2014-04-25 17:35:34 +0000
committergrehan <grehan@FreeBSD.org>2014-04-25 17:35:34 +0000
commit24057041971ae5c28d980e04d07e97ded0f7423a (patch)
tree02608926dfc94712f787b40a44f5354b38f5e875 /usr.sbin
parente199bfd4cc86cd6611379d224cabdf55faaba28c (diff)
downloadFreeBSD-src-24057041971ae5c28d980e04d07e97ded0f7423a.zip
FreeBSD-src-24057041971ae5c28d980e04d07e97ded0f7423a.tar.gz
Respect and track the enable bit in the PCI configuration address word.
Ignore writes, and return 0xff's, on config accesses when not set. Behaviour now matches that seen on h/w. Found with a NetBSD/amd64 guest. Reviewed by: tychon MFC after: 3 weeks
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/bhyve/pci_emul.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/usr.sbin/bhyve/pci_emul.c b/usr.sbin/bhyve/pci_emul.c
index c403233..15f2fad 100644
--- a/usr.sbin/bhyve/pci_emul.c
+++ b/usr.sbin/bhyve/pci_emul.c
@@ -1508,7 +1508,7 @@ pci_emul_hdrtype_fixup(int bus, int slot, int off, int bytes, uint32_t *rv)
}
}
-static int cfgbus, cfgslot, cfgfunc, cfgoff;
+static int cfgenable, cfgbus, cfgslot, cfgfunc, cfgoff;
static int
pci_emul_cfgaddr(struct vmctx *ctx, int vcpu, int in, int port, int bytes,
@@ -1527,9 +1527,12 @@ pci_emul_cfgaddr(struct vmctx *ctx, int vcpu, int in, int port, int bytes,
(cfgslot << 11) |
(cfgfunc << 8) |
cfgoff;
- *eax = x | CONF1_ENABLE;
+ if (cfgenable)
+ x |= CONF1_ENABLE;
+ *eax = x;
} else {
x = *eax;
+ cfgenable = (x & CONF1_ENABLE) == CONF1_ENABLE;
cfgoff = x & PCI_REGMAX;
cfgfunc = (x >> 8) & PCI_FUNCMAX;
cfgslot = (x >> 11) & PCI_SLOTMAX;
@@ -1629,10 +1632,11 @@ pci_emul_cfgdata(struct vmctx *ctx, int vcpu, int in, int port, int bytes,
#endif
/*
- * Just return if there is no device at this cfgslot:cfgfunc or
- * if the guest is doing an un-aligned access
+ * Just return if there is no device at this cfgslot:cfgfunc,
+ * if the guest is doing an un-aligned access, or if the config
+ * address word isn't enabled.
*/
- if (pi == NULL || (coff & (bytes - 1)) != 0) {
+ if (!cfgenable || pi == NULL || (coff & (bytes - 1)) != 0) {
if (in)
*eax = 0xffffffff;
return (0);
OpenPOWER on IntegriCloud