Skip to content

arm64: enable MSHV VFIO PCI passthrough#3900

Merged
souradeep100 merged 2 commits into
microsoft:mainfrom
souradeep100:schakrabarti/arm64-mshv-passthrough
Jul 14, 2026
Merged

arm64: enable MSHV VFIO PCI passthrough#3900
souradeep100 merged 2 commits into
microsoft:mainfrom
souradeep100:schakrabarti/arm64-mshv-passthrough

Conversation

@souradeep100

Copy link
Copy Markdown
Contributor

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.

Copilot AI review requested due to automatic review settings July 9, 2026 09:01
@souradeep100 souradeep100 requested a review from a team as a code owner July 9, 2026 09:01
@github-actions github-actions Bot added the unsafe Related to unsafe code label Jul 9, 2026
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

⚠️ Unsafe Code Detected

This PR modifies files containing unsafe Rust code. Extra scrutiny is required during review.

For more on why we check whole files, instead of just diffs, check out the Rustonomicon

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 SignalMsi support 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.

Comment thread vm/devices/pci/vfio_assigned_device/src/lib.rs Outdated
Comment thread vmm_core/virt_mshv/src/irqfd.rs
Comment thread openvmm/openvmm_defs/src/config.rs Outdated
Copilot AI review requested due to automatic review settings July 9, 2026 09:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Comment thread vm/devices/pci/vfio_assigned_device/src/lib.rs Outdated
@souradeep100

Copy link
Copy Markdown
Contributor Author

@microsoft-github-policy-service agree company="Microsoft"

@souradeep100

Copy link
Copy Markdown
Contributor Author

@souradeep100 please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.

@microsoft-github-policy-service agree [company="{your company}"]

Options:

  • (default - no company specified) I have sole ownership of intellectual property rights to my Submissions and I am not making Submissions in the course of work for my employer.
@microsoft-github-policy-service agree
  • (when company given) I am making Submissions in the course of work for my employer (or my employer has intellectual property rights in my Submissions by contract or applicable law). I have permission from my employer to make Submissions and enter into this Agreement on behalf of my employer. By signing below, the defined term “You” includes me and my employer.
@microsoft-github-policy-service agree company="Microsoft"

Contributor License Agreement

@microsoft-github-policy-service agree company="Microsoft"

Copilot AI review requested due to automatic review settings July 9, 2026 10:06
@souradeep100 souradeep100 force-pushed the schakrabarti/arm64-mshv-passthrough branch from 8b72cb5 to 8e33614 Compare July 9, 2026 10:06
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.
@souradeep100 souradeep100 force-pushed the schakrabarti/arm64-mshv-passthrough branch from 8e33614 to 70cc9ff Compare July 9, 2026 10:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Comment thread vm/devices/pci/vfio_assigned_device/src/lib.rs Outdated
Comment thread vm/devices/user_driver/vfio_sys/src/lib.rs Outdated
Copilot AI review requested due to automatic review settings July 9, 2026 10:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Comment thread vmm_core/virt_mshv/src/irqfd.rs
Comment thread vm/devices/pci/vfio_assigned_device/src/lib.rs Outdated
Comment thread vmm_core/virt_mshv/src/irqfd.rs
Comment thread vm/devices/user_driver/vfio_sys/src/lib.rs Outdated
Comment thread vmm_core/virt_mshv/src/aarch64/mod.rs Outdated

@jstarks jstarks left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some feedback.

Copilot AI review requested due to automatic review settings July 9, 2026 12:10
@souradeep100 souradeep100 force-pushed the schakrabarti/arm64-mshv-passthrough branch from 650d2e4 to 79bcffb Compare July 9, 2026 12:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Comment thread vm/devices/user_driver/vfio_sys/src/lib.rs
@souradeep100 souradeep100 requested a review from jstarks July 14, 2026 06:09
/// 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,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
Copilot AI review requested due to automatic review settings July 14, 2026 08:20
@souradeep100 souradeep100 force-pushed the schakrabarti/arm64-mshv-passthrough branch from 79bcffb to e3b63e2 Compare July 14, 2026 08:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Comment thread openvmm/openvmm_defs/src/config.rs
@souradeep100 souradeep100 merged commit c4b5510 into microsoft:main Jul 14, 2026
69 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

unsafe Related to unsafe code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants