aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Grehan <grehan@FreeBSD.org>2014-04-25 17:35:34 +0000
committerPeter Grehan <grehan@FreeBSD.org>2014-04-25 17:35:34 +0000
commitfcbec69157575bd6b7d4157c31c97a63ea6e367f (patch)
tree02608926dfc94712f787b40a44f5354b38f5e875
parent459d6434a83b364916c3018fe59ee1a7c472a70c (diff)
downloadsrc-fcbec69157575bd6b7d4157c31c97a63ea6e367f.tar.gz
src-fcbec69157575bd6b7d4157c31c97a63ea6e367f.zip
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
Notes
Notes: svn path=/head/; revision=264921
-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 c403233208cb..15f2fad53485 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);