Page MenuHomeFreeBSD

D29698.id87231.diff
No OneTemporary

D29698.id87231.diff

Index: usr.sbin/bhyve/pci_emul.c
===================================================================
--- usr.sbin/bhyve/pci_emul.c
+++ usr.sbin/bhyve/pci_emul.c
@@ -590,23 +590,47 @@
return (cmd & PCIM_CMD_MEMEN);
}
+/* Is the registration actually just all 'f's? */
+static bool
+addr_is_probe(uint64_t addr, uint64_t size, int type)
+{
+ switch (type) {
+ case PCIBAR_IO:
+ return (addr + size - 1 == 0xffffUL);
+ case PCIBAR_MEM32:
+ case PCIBAR_MEM64:
+ return ((addr & 0xffffffffUL) + size - 1 == 0xffffffffUL);
+ case PCIBAR_MEMHI64:
+ return ((addr >> 32) + size - 1 == 0xffffffffUL);
+ default:
+ assert(0);
+ }
+}
+
/*
* Update the MMIO or I/O address that is decoded by the BAR register.
*
* If the pci device has enabled the address space decoding then intercept
* the address range decoded by the BAR register.
+ *
+ * However, do not intercept the address if we are writing all '1's to the
+ * BAR register, since that is an attempt to probe the capabilities of
+ * the device.
*/
static void
update_bar_address(struct pci_devinst *pi, uint64_t addr, int idx, int type)
{
int decode;
+ uint64_t size;
+
+ size = pi->pi_bar[idx].size;
if (pi->pi_bar[idx].type == PCIBAR_IO)
decode = porten(pi);
else
decode = memen(pi);
- if (decode)
+ if (decode && !addr_is_probe(pi->pi_bar[idx].addr, size, type))
unregister_bar(pi, idx);
switch (type) {
@@ -619,14 +643,14 @@
pi->pi_bar[idx].addr |= addr;
break;
case PCIBAR_MEMHI64:
- pi->pi_bar[idx].addr &= 0xffffffff;
+ pi->pi_bar[idx].addr &= 0xffffffffUL;
pi->pi_bar[idx].addr |= addr;
break;
default:
assert(0);
}
- if (decode)
+ if (decode && !addr_is_probe(pi->pi_bar[idx].addr, size, type))
register_bar(pi, idx);
}

File Metadata

Mime Type
text/plain
Expires
Wed, Sep 25, 8:36 AM (11 h, 10 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
12747851
Default Alt Text
D29698.id87231.diff (1 KB)

Event Timeline