Repository navigation
vfio-pci: mmap the BARs into the guest - #337
Merged
Merged
Conversation
This was referenced Oct 14, 2026
tamnd
added a commit
that referenced
this pull request
Oct 14, 2026
…#339) Part of #9. QEMU realizes a `-device` with the option's location current, so a warning or error that vfio-pci prints during realize starts with "-device vfio-pci,...: ". ruvm printed the dma-buf warning from #337 without it. `realize_x86()` now pushes the plug's location for the length of realize, like `qdev_device_add()` does, so the dma-buf warnings and "Failed to mmap NAME BAR n. Performance may be slow" carry the same prefix as in QEMU. Errors that realize returns were already printed with the location and do not change. Checked: - On 220ceef, this branch with main (debd8d2) merged in, on server2: clippy with `-D warnings` and `--all-targets` for ruvm-mem, ruvm-hw-iommu, ruvm-sys, ruvm-hw-pci, ruvm-hw-vfio, ruvm-machine-x86, ruvm-machine-arm and ruvm-system, the same clippy for x86_64-pc-windows-gnu and aarch64-apple-darwin, the tests of ruvm-mem, ruvm-hw-iommu, ruvm-sys, ruvm-hw-pci and ruvm-hw-vfio and of the ruvm-machine-x86, ruvm-machine-arm and ruvm-system libs, and xtask unsafe-audit, provenance, layers and style. All passed, with 113 tests in the ruvm-system lib, 43 in ruvm-machine-x86 and 35 in ruvm-machine-arm. ruvm-machine-x86 has 3 fewer than before because #338 moved its PCI vmstate tests to ruvm-hw-pci. - On the release build of 19fd2c7, the change before the merge, an L1 run with the same setup as #337: QEMU 11.1 as L1 with an e1000e at 00:04.0 bound to vfio-pci, and L2 run as QEMU 11.1 and as ruvm with `-device vfio-pci,host=0000:00:04.0,addr=2` under `-S` and qtest. Both print the same line, byte for byte: ``` qemu-system-x86_64: -device vfio-pci,host=0000:00:04.0,addr=2: warning: VFIO dma-buf not supported in kernel, using mmap fallback, P2P DMA will not work ``` Both also got all 778 of 778 answers with the same 71 distinct ones, and the same three mmaps of the device fd.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #9.
vfio-pci now maps the BARs of the device into the guest, like
vfio_region_mmap()in QEMU. Reads and writes to a mapped BAR go to the device memory without a pread or pwrite per access. While INTx is pending the mmaps are off, so the guest's next BAR access traps and serves as the EOI, and a timer on the virtual clock turns them back on once INTx is quiet, asvfio_intx_mmap_enable()does.What is in it:
memory_region_init_ram_device_ptr(), that the vfio listener maps for DMA like RAM.MSIX_MAPPABLE),VFIO_DEVICE_FEATURE_DMA_BUF, andHostMemory::map_device(), which reserves the whole region and maps each area into it.vfio_setup_region_sparse_mmaps()reads them, with size 0 areas dropped, the areas sorted, and QEMU's error for overlapping areas. Each area becomes a "NAME BAR n mmaps[i]" subregion of the trapped BAR, then the dma-buf probe runs with QEMU's two warnings. A failed mmap prints "Failed to mmap NAME BAR n. Performance may be slow" and the BAR stays trapped. WithoutMSIX_MAPPABLEthe pages of the MSI-X table are cut out of the mmaps, asvfio_pci_fixup_msix_region()does. INTx turns the mmaps off and arms the timer, the timer rearms while INTx is pending, and turning INTx off deletes the timer and turns the mmaps on. The container maps the RAM device sections for DMA, and a failure there is a warning with QEMU's peer to peer hint instead of an error.x-no-mmapandx-intx-mmap-timeout-msnow do what they do in QEMU, and the virtual clock is passed to realize for the timer.Where it differs from QEMU:
vfio_sub_page_bar_update_mapping()is not ported, so a BAR smaller than a host page stays trapped.VFIO_IOMMU_GET_INFOis not ported.x-msix-relocationis not ported.Checked:
On server2, on 9596e67, the branch with main up to #336 merged in:
-D warningsand--all-targetsfor ruvm-mem, ruvm-hw-iommu, ruvm-sys, ruvm-hw-pci, ruvm-hw-vfio, ruvm-machine-x86, ruvm-system and ruvm-machine-arm.The same checks without ruvm-machine-arm, the release build and the L1 compare below ran on 7b2159e, the commit before that merge. The merge brings in #335 and #336, which touch only Arm files.
intel-iommu,caching-mode=onand an e1000e at 00:04.0 bound to vfio-pci. L2 is run with-device vfio-pci,host=0000:00:04.0,addr=2under qtest, as QEMU 11.1 and ruvm, each with and withoutx-no-mmap=on, and then withx-intx-mmap-timeout-ms=0. Each batch waits for all of its answers, and the syscall counts are the syscr deltas of the L2 process from /proc.Part A, with
-S, where the virtual clock does not move. qtest places the BARs, reads and writes BAR0, BAR1, the IO BAR and the MSI-X BAR, sends a frame by DMA, programs the IOAPIC and raises INTx.All 71 answers are the same in the four runs. Both print "VFIO dma-buf not supported in kernel, using mmap fallback, P2P DMA will not work", as the L1 kernel has no dma-buf for vfio. ruvm prints it without QEMU's
-device vfio-pci,host=0000:00:04.0,addr=2:prefix. The MSI-X BAR is mapped whole in both, since the kernel reportsMSIX_MAPPABLE.Part B, in a guest that runs, so the timer can fire. SeaBIOS places BAR0 at 0xfeba0000 in all four runs. qtest raises INTx, waits 3 seconds, does one STATUS read, then reads ICR, masks the interrupt and does 300 reads, waits 3 seconds and does 300 reads more.
The INTx step itself is two writes at 4, 2, 3 and 2, so the one read adds a pread in every run. ICR reads 0x80000001 in all four. The mmaps are off while INTx is pending, back on after the timeout, and stay off with a timeout of 0, in QEMU and in ruvm. How many of the 300 reads right after the EOI trap depends on when the next timer tick lands, and was between 74 and 319 over the debug runs for both.