virtio: Add VirtIO PCI modern (V1) support Use the existing legacy PCI driver as the basis for shared code between the legacy and modern PCI drivers. Changes to the virtqueue and each device driver (network, block, etc) for V1 support, and hooking them in as child devices will come in later commits.
- R10:9da9560c4dd3: virtio: Add VirtIO PCI modern (V1) support
This predates 046096d, but when I was rebasing this change, I was a little confused as to what was going on in this driver but forgot to circle back to it. I was unsure how the V1 support was working, at least against a V1 (mmio-v2) compliant device. 50a6b28 had since fixed one of my major questions, but there's still various spec compliance issues remaining:
And a few older bugs or code issues:
We should strive to get as close as possible to the spec, since neither the transport or device drivers are going to run against just one VMM.
I'll add a >1 check here to keep the status quo going.
I've looked at all the non-vtnet phab changes, and looked at the diff of the cumulative vtnet changes.
Also built and run the cumulative change set as a guest on CURRENT bhyve with net/block/random devices, and no issues found.
I'm going to accept this and all follow-on changes.
Rebasing this on top of D28073 would help to reduce the diff (provided you're still happy with the concept, but if so it'd be good to land the cleanup first IMO before all the new code comes in).
D28070 fixes the first couple of points. I intend to revisit the others once modern PCI has landed, either by copying the code or (better) pushing as much of the generic negotiation stuff into virtio.c itself (maybe even introducing a common parent class to all the transports if common softc state is needed) so it can be shared between MMIO and PCI (there is currently far too much duplication between the two...).
I haven't taken a look at the other old code quality issues (except for the 046096d-related one, I should just have deleted that debug printf rather than copy it, will do so tomorrow because it's a waste of space) but those are lower priority, at least for me (others are welcome to jump in and clean it up!).
This is no longer going to be applicable with a common virtio_pci device name (and the problem needs solving for virtio_mmio given they're the same driver). I think it's best to just have each device's feature flags include it if supported? Or at least that's about the only sensible way I can think of.
style(9) doesn't explicitly state it, but has several examples where the casts don't have a space after them.
Some of feature negotiation can be combined, like
features = virtio_negotiate_features(host_features, child_features)
and add the the features sysctl to virtio_mmio, but I'm not sure if there is too much opportunity to further share code without impacting readability.
It is though because we've attached via PCI modern by this point.
Ideally, the device (network, block, etc) drivers should not control the transport features. F_INDIRECT_DESC may be an exception because we do pre-alloc those chains. For both PCI and MMIO, we can improve this by just reflecting our supported transport features, and tighten things by checking that both PCI modern or MMIO version > 1 advertises F_VERSION_1. I don't think what is added is necessarily wrong though.
To clarify, my concern is the following:
My instinct is/was that each device should be putting VIRTIO_F_VERSION_1 in its features, not the transport (and the queue makes sure to not filter it out).