arm64: enable MSHV VFIO PCI passthrough#3900
Conversation
|
This PR modifies files containing For more on why we check whole files, instead of just diffs, check out the Rustonomicon |
There was a problem hiding this comment.
Pull request overview
This PR enables VFIO PCI passthrough on the aarch64 MSHV backend by adding the missing interrupt plumbing needed for MSI/MSI-X delivery, aligning the arm64 path with the existing x86_64 irqfd/MSI routing model.
Changes:
- Enable irqfd support on aarch64 MSHV and implement
Partition::irqfd()so VFIO eventfds can drive direct interrupt injection. - Add GICv2m-based
SignalMsisupport on aarch64 and set MSHV partition properties to route PCIe MSIs via the v2m frame (SPI-based) rather than ITS/LPIs. - Raise the per-device MSI-X vector cap from 256 to 2048 in the VFIO stack to support devices with large MSI-X tables.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| vmm_core/virt_mshv/src/lib.rs | Makes irqfd module available on both x86_64 and aarch64; adds aarch64 GIC MSI config storage in partition state. |
| vmm_core/virt_mshv/src/irqfd.rs | Defers MSHV irqfd registration until routing is installed via enable(), supporting aarch64’s assign-time mapping semantics. |
| vmm_core/virt_mshv/src/aarch64/mod.rs | Configures MSI-related GIC partition properties and exposes a GICv2m SignalMsi plus irqfd() for VFIO passthrough. |
| vm/devices/user_driver/vfio_sys/src/lib.rs | Increases VFIO map_msix per-device eventfd array limit to 2048. |
| vm/devices/pci/vfio_assigned_device/src/lib.rs | Raises assigned-device MSI-X vector limit to 2048 to match the new VFIO cap. |
| openvmm/openvmm_defs/src/config.rs | Moves the default GICv2m MSI frame base to 0xEFF6_8000 and updates associated documentation. |
|
@microsoft-github-policy-service agree company="Microsoft" |
@microsoft-github-policy-service agree company="Microsoft" |
8b72cb5 to
8e33614
Compare
Enable assigning physical PCI devices (via Linux VFIO) to guests on the aarch64 Microsoft Hypervisor (MSHV) backend. Previously this path was x86_64-only; the arm64 backend had no guest MSI controller and no irqfd, so assigned-device interrupts could not be delivered. Changes: - virt_mshv (aarch64): provide a GICv2m SignalMsi via as_signal_msi, and register the partition GIC properties needed for MSI delivery - GicLpiIntIdBits=0 (so Linux uses the v2m frame rather than an ITS) and GitsTranslaterBaseAddress = v2m frame base, so a passthrough device's DMA MSI-X write to the doorbell is trapped by the hypervisor and injected as a guest SPI. - virt_mshv: un-gate the irqfd module (MSI routing + MSHV_IRQFD) for aarch64 and implement Partition::irqfd(). The route is armed after its MSI routing is installed, matching the arm64 assign-time mapping model. - spi_layout: allocate the GICv2m SPI block top-down from the high SPI range to avoid conflicting with the guest vPCI (pci-hyperv) MSI allocator, which allocates bottom-up from INTID 64. - config: place the GICv2m MSI frame at the Hyper-V convention base 0xEFF6_8000, clear of the emulated PL011 UARTs, GIC dist/redist, ITS, and VMBus MMIO (the hypervisor shadows a ~64 KiB region at this base). - vfio: raise the per-device MSI-X vector limit from 256 to 2048 so devices with large MSI-X tables (e.g. NVMe controllers with 513 vectors) can be assigned. Verified end-to-end by assigning an NVMe controller to an aarch64 guest: the device enumerates, MSI-X interrupts are delivered, and I/O works.
8e33614 to
70cc9ff
Compare
650d2e4 to
79bcffb
Compare
| /// hypervisor for PCI passthrough (GITS translater base). May differ from | ||
| /// `frame_base`; consumed only by the MSHV root/arm64 backend. | ||
| #[cfg_attr(feature = "inspect", inspect(hex))] | ||
| pub doorbell_base: u64, |
There was a problem hiding this comment.
This isn't quite right--this should apply for ITS, too. But let's just leave it for now, since we don't currently support ITS anywhere that this is configurable. We can clean it up later.
| /// GITS_TRANSLATER_BASE_ADDRESS. | ||
| /// The hypervisor shadows a ~64 KiB region at this base, | ||
| /// so it uses the Hyper-V convention address 0xEFF6_8000. | ||
| pub const DEFAULT_GIC_V2M_DOORBELL_BASE: u64 = 0xEFF6_8000; |
There was a problem hiding this comment.
I want to move this stuff out of openvmm_defs. But I'll figure this out in a followup change. This is OK for now.
Doorbell decoupled ( frame 0xEFFE_8000 / doorbell 0xEFF6_8000 , plumbed through config) HeaderVec MSI-X request (no compile-time max) + obsolete cap removed.
79bcffb to
e3b63e2
Compare
Enable assigning physical PCI devices (via Linux VFIO) to guests on the aarch64 Microsoft Hypervisor (MSHV) backend. Previously this path was x86_64-only; the arm64 backend had no guest MSI controller and no irqfd, so assigned-device interrupts could not be delivered.
Changes:
Verified end-to-end by assigning an NVMe controller to an aarch64 guest: the device enumerates, MSI-X interrupts are delivered, and I/O works.