Skip site navigation (1)Skip section navigation (2)


| raw e-mail | index | archive | help
Suppose I configure a VM with a virtio-blk and virtio-net device.  Both
register BAR 0 as an I/O BAR with sizes of 128 and 64, respectively, and
bhyve puts them at 0xdf000000 and 0xdf000080.  If the network device is
PCI device 2 and the block device is device 3, which happens
automatically when using vmrun.sh, then for some reason u-boot suffles
them around: it unmaps the network device BAR at 0xdf000080, then maps
it at 0xdf000000, and then it unmaps the block device BAR at 0xdf000000,
and puts it at 0xdf000080.  I don't know yet why it does this; if the
PCI device numbers are swapped then the BARs aren't moved around.

This behaviour interacts with an oddity of bhyve's register_mem_init():
when u-boot maps the network device BAR at 0xdf000000,
register_mem_init() does a lookup, finds that a MMIO region is there,
and silently succeeds without inserting an entry into the MMIO RB tree.
Later, u-boot moves the block device BAR, so nothing is mapped at
0xdf000000, and then when FreeBSD reprograms BARs it triggers an
assertion failure because unregister_mem() isn't allowed to fail.

What's the right solution?  At a glance, QEMU appears to permit
overlapping mappings and has a priority-based scheme for deciding which
mapping a given access corresponds to.  I verified that u-boot doesn't
actually access the mappings in the window that the overlap, so it seems
pretty safe to allow overlapping mappings and handle access conflicts
with an assertion failure or so.  Is there some context I'm missing?
Should I look further into what u-boot is doing instead?  Thanks in
advance for any pointers.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?>