Skip to content

feat: Refine virtio and support msix - #180

Merged
junyu0312 merged 1 commit into
mainfrom
msi
Jun 21, 2026
Merged

junyu0312 merged 1 commit into
mainfrom
msi

Conversation

@junyu0312

@junyu0312 junyu0312 commented Jun 21, 2026 •

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Added MSI-X interrupt support for PCI virtio devices.
    • Enhanced virtio device architecture with improved async virtqueue handling.
  • Refactor

    • Restructured virtio transport layers (MMIO and PCI) for better modularity and interrupt management.
    • Simplified virtio device initialization with cleaner API contracts.
    • Redesigned interrupt controller interface for message signaling.
  • Chores

    • Added tokio-util workspace dependency.

@coderabbitai

coderabbitai Bot commented Jun 21, 2026 •

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

This PR replaces the monolithic VirtioDev<D> virtio transport with a split architecture: a new VirtioTransportCommon<D> holds shared register/queue state, while MMIO and PCI transports each own runtime dependencies. Async virtqueue workers with cancellation tokens replace synchronous handler loops. MSI-X interrupt dispatch is added to the PCI transport alongside legacy INTx support. All virtio device implementations (blk, entropy, balloon) are updated to the new VirtioDevice trait and async VirtqueueHandler interfaces. The InterruptController::send_msi API is changed to accept raw address/data fields instead of an interrupt ID.

Changes

Virtio Transport Refactor

Layer / File(s) Summary
Core interrupt and error contracts
Cargo.toml, crates/vm-virtio/Cargo.toml, crates/vm-core/src/arch/irq.rs, crates/vm-core/src/device/error.rs, crates/vm-core/src/lib.rs, crates/vm-core/src/virtualization/*/irq_chip.rs, crates/vm-device/src/device/mod.rs, crates/vm-vmm/src/device/error.rs
InterruptController::send_msi changes from intid: u32 to address_lo/address_hi/data; KVM implementation wires kvm_msi; HVP stub updated to todo!(); adds tokio-util and async-trait workspace dependencies; adds DeviceError::Device and InitDeviceError::Virtio; adds #![deny(warnings)]; removes GicV3 stub module.
Virtqueue data model and thread-safety
crates/vm-virtio/src/virtqueue.rs, crates/vm-virtio/src/virtqueue/virtq_avail_ring.rs, crates/vm-virtio/src/virtqueue/virtq_desc_table.rs
Virtqueue ring address fields change from Option<u32> to u32; queue_size_max becomes u16; last_available_idx removed; snapshot serialization updated to unconditional u32; unsafe impl Send/Sync added for VirtqAvail, VirtqDesc, and VirtqDescTableRef.
VirtioDevice trait and VirtioError expansion
crates/vm-virtio/src/device.rs, crates/vm-virtio/src/device/virtqueue.rs, crates/vm-virtio/src/result.rs, crates/vm-virtio/src/transport.rs, crates/vm-virtio/src/transport/common/control_register.rs, crates/vm-virtio/src/types/device/balloon_tranditional.rs, crates/vm-virtio/src/types/pci.rs
VirtioDevice drops irq/irq_chip methods, changes virtqueues_size_max to Vec<u16>, replaces closure-based virtqueue_handler with queue_sel:u16 → Option<Box<dyn VirtqueueHandler>>, adds into_mmio_device; VirtioError gains MMIO/IRQ allocation and queue lookup variants; VirtioUsedBufferNotifier/VirtioConfigurationChangeNotifier traits and VirtqueueWorkerController added; async virtqueue_worker replaces old run() loop; QueueNotify removed from ControlRegister; VIRTIO_MSI_NO_VECTOR added.
VirtioTransportCommon: shared state and register I/O
crates/vm-virtio/src/transport/common.rs
New VirtioTransportCommon<D> stores device, feature bits, queue selection, Virtqueue list, and shared Arc<Mutex<>> interrupt/config-generation state; read_reg/write_reg implement the full VirtIO control register protocol; save/load serialize all transport state.
MMIO transport: struct, interrupt notifier, and register handler
crates/vm-virtio/src/transport/mmio.rs, crates/vm-virtio/src/transport/mmio/interrupt.rs, crates/vm-virtio/src/transport/mmio/mmio_handler.rs
VirtioMmioTransport gains tokio runtime, memory, irq_chip, and event-notifier fields; VirtioMmioEventNotifier implements both notifier traits and triggers IRQ on VRING/CONFIG events; MMIO read/write now return Result<()> with typed error variants; QueueReady write spawns async virtqueue workers; ACPI/device-tree IRQ generation uses transport's own irq field; VirtioDeviceOps impl added.
PCI MSI-X capability, table, and BAR infrastructure
crates/vm-pci/src/device/capability/msix.rs, crates/vm-pci/src/types/configuration_space/header.rs, crates/vm-virtio/src/transport/pci/msix.rs, crates/vm-virtio/src/transport/pci/msix_handler.rs
MsixEntry packed struct added with zerocopy derives; PCI_MSIX_FLAGS_ENABLE/MASKALL constants added; From<PciMsixCap> for StandardCapability implemented; VirtioPciMsixInfo manages MSI-X vector table with PBA offset and BAR size computation; read_msix/write_msix dispatch between table and PBA regions; PCI_COMMAND_INTX_DISABLE/PCI_STATUS_INTERRUPT constants added.
PCI configuration space Arc<Mutex<>> threading
crates/vm-pci/src/device/function/type0.rs, crates/vm-pci/src/types/function/type0.rs
Type0FunctionInternal.configuration_space changes from a plain value to Arc<Mutex<ConfigurationSpace>>; new_with_configuration_space locks on init; Bar gains Clone/Copy; write_bar, write_command, ecam_read, and ecam_write explicitly lock the configuration space before header/register access.
VirtioPciTransport: IRQ dispatch, MSI-X wiring, and config handlers
crates/vm-virtio/src/transport/pci.rs, crates/vm-virtio/src/transport/pci/interrupt.rs, crates/vm-virtio/src/transport/pci/common_config_handler.rs, crates/vm-virtio/src/transport/pci/device_handler.rs, crates/vm-virtio/src/transport/pci/isr_handler.rs, crates/vm-virtio/src/transport/pci/notify_handler.rs
VirtioPciTransport holds configuration space, VirtioTransportCommon behind Mutex, VirtioPciIrqDispatcher selecting MSI-X vs legacy INT# per notification; VirtioPciEventUsedBufferNotifier/VirtioPciConfigurationChangeNotifier implemented; write_common_config wires MSI-X vector reads/writes and spawns workers on QueueEnable; read_isr clears status and conditionally triggers legacy interrupt; write_notify triggers per-queue worker via queue_notify; TryFrom<VirtioPciTransport<D>> for VirtioPciDev<D> added; VirtioPciDevice conversion APIs made fallible.
Virtio device implementations: blk, entropy, balloon
crates/vm-device/src/device/virtio/virtio_blk.rs, crates/vm-device/src/device/virtio/virtio_entropy.rs, crates/vm-device/src/device/virtio/virtio_balloon_traditional/device.rs, crates/vm-device/src/device/virtio/virtio_balloon_traditional/monitor.rs
Device structs drop irq/irq_chip fields; constructors accept memory: Arc<MemoryAddressSpace> only; closure-based handlers replaced with async VirtqueueHandler struct impls; read_config/write_config lock Arc<Mutex<config>>; balloon snapshot inserts into existing HashSet instead of replacing; VirtioBalloonMonitor stores Arc<Mutex<config>> and VirtioConfigurationChangeNotifier; VirtioBalloonApi/VirtioBalloonDev removed; entropy CLASS_CODE fixed.
VMM device builder wiring
crates/vm-vmm/src/vm/device_builder.rs, crates/vm-vmm/src/vm/device_builder/arch/aarch64.rs
DeviceManagerBuilder::init_device constructs virtio devices with memory only, then calls into_mmio_device/into_pci_device with IRQ allocator, MMIO index allocator, tokio runtime, and IRQ controller; balloon monitor built from config + notifier extracted from transport; alloc_irq helper removed; AArch64 PL011 IRQ allocation inlined with explicit error mapping.

Sequence Diagram(s)

sequenceDiagram
  participant Builder as DeviceManagerBuilder
  participant Device as VirtioDevice (blk/entropy/balloon)
  participant Common as VirtioTransportCommon
  participant Transport as VirtioMmioTransport / VirtioPciTransport
  participant Worker as virtqueue_worker (tokio task)
  participant IrqChip as InterruptController

  Builder->>Device: new(memory)
  Builder->>Device: into_mmio_device(irq_alloc, mmio_alloc, runtime, irq_chip)
  Device->>Common: VirtioTransportCommon::new(device)
  Device->>Transport: VirtioMmioTransport::new(runtime, memory, irq_chip, index, range, irq, common)
  note over Transport: or VirtioPciTransport::new(...)

  Builder->>Transport: register with device manager

  Note over Transport: Guest writes QueueReady=1
  Transport->>Common: write_reg(QueueReady, 1)
  Common->>Worker: tokio::spawn(virtqueue_worker(controller, notifier, virtqueue))

  Note over Worker: Guest posts buffer to avail ring
  Worker->>Worker: queue_notify.notified().await
  Worker->>Device: handle_desc(desc_ring, desc_id)
  Worker->>IrqChip: notify_used_buffer() → trigger_irq / send_msi
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

  • junyu0312/rust-vm#74: Introduces the Tokio-based async virtqueue task model that this PR refactors into virtqueue_worker with VirtqueueWorkerController and cancellation tokens.
  • junyu0312/rust-vm#156: Modifies KvmIrqChip's InterruptController implementation in the same file updated by this PR's send_msi API change.
  • junyu0312/rust-vm#170: Refactors DeviceManagerBuilder initialization flow in device_builder.rs, directly overlapping with this PR's updated virtio device construction and transport wiring.

Poem

🐇 Hop, hop through virtqueues at last,
MSI-X vectors fly fast!
Arc<Mutex<>> guards every ring,
Async workers dance on a string.
No more intid — address and data reign,
The transport refactor soothes all the pain! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.65% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: Refine virtio and support msix' directly reflects the main changes: comprehensive virtio architecture refactoring and MSI-X interrupt support implementation across multiple device types.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch msi

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@junyu0312
junyu0312 merged commit 0a6d72b into main Jun 21, 2026
11 of 12 checks passed
@junyu0312
junyu0312 deleted the msi branch June 21, 2026 19:00
@coderabbitai coderabbitai Bot mentioned this pull request Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant