Skip to content

Add generic ISA DMA support to chipset resources#3117

Draft
moor-coding wants to merge 77 commits intomicrosoft:mainfrom
moor-coding:isa-dma-resourcify
Draft

Add generic ISA DMA support to chipset resources#3117
moor-coding wants to merge 77 commits intomicrosoft:mainfrom
moor-coding:isa-dma-resourcify

Conversation

@moor-coding
Copy link
Copy Markdown
Contributor

This PR:

  • Adds a generic ISA DMA resource handle and resolver registration.
  • Adds ISA DMA controller capability plumbing in the chipset device abstraction layer.
  • Updates base chipset wiring to resolve DMA before floppy wiring, preventing runtime NoDmaForFloppy failures.
  • Normalizes DMA module layout with a dedicated resolver module.

jstarks and others added 18 commits March 19, 2026 13:37
- Introduced a new `PitDeviceHandle` struct in `chipset_resources` for resource identification.
- Updated `vm_manifest_builder` to attach the PIT device during VM build.
- Removed deprecated generic PIT dependencies from `base_chipset`.
- Implemented the PIT device functionality in `pit/mod.rs`, including timer management and I/O operations.
- Created a resource resolver for the PIT device in `pit/resolver.rs` to handle IRQ configuration and instantiation.
- Added tests for the PIT device to ensure correct behavior in both binary and BCD modes.
- Introduced a new  struct in  for resource identification and bus attachment metadata.
- Updated  to attach the PIIX4 UHCI stub device during Hyper-V Gen1 VM manifest construction.
- Removed deprecated legacy  dependencies and direct instantiation from .
- Implemented a UHCI resource resolver in  to instantiate the device and register fixed PCI BDF .
- Registered the resolver in both OpenVMM and OpenHCL static resource registries and added required crate dependencies.
- Added tests to verify manifest attachment behavior and resolver PCI registration semantics.
Copilot AI review requested due to automatic review settings March 24, 2026 17:47
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds resource-level support for ISA DMA (and normalizes PIT/UHCI stub to resources) so the base chipset can resolve DMA early enough for floppy wiring, while also carrying optional static PCI placement metadata in chipset device handles.

Changes:

  • Introduces GenericIsaDmaDeviceHandle (+ resolver) and exposes ISA DMA controller access via ChipsetDevice::supports_isa_dma_controller.
  • Reworks base chipset wiring to resolve ISA DMA handles before floppy setup; shifts PIT and PIIX4 UHCI stub instantiation to resource resolvers and manifest handles (with optional fixed PCI placement).
  • Plumbs a new with_pit boolean through config/worker paths for ACPI table generation and adds manifest-builder tests around PIT attachment.

Reviewed changes

Copilot reviewed 25 out of 26 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
vmm_core/vmotherboard/src/lib.rs Adds ChipsetDevicePciPlacement and extends ChipsetDeviceHandle with optional PCI placement metadata.
vmm_core/vmotherboard/src/base_chipset.rs Resolves ISA DMA device handle early (before floppy wiring), applies optional PCI placement when resolving handles, and adapts DMA channel wiring to erased devices.
vmm_core/vm_manifest_builder/src/lib.rs Adds DMA/PIT/UHCI stub handles to manifests, provides with_pit() helper, and adds unit tests for PIT attachment matrix/idempotency.
vm/devices/chipset_resources/src/lib.rs Adds resource IDs for PIT, generic ISA DMA, and PIIX4 UHCI stub.
vm/devices/chipset_legacy/src/piix4_uhci/resolver.rs New async resolver for the PIIX4 UHCI stub device.
vm/devices/chipset_legacy/src/piix4_uhci.rs Exposes the new UHCI resolver module.
vm/devices/chipset_legacy/Cargo.toml Adds dependencies needed for chipset-device resource resolving (and async resolver).
vm/devices/chipset/src/pit/resolver.rs New PIT resolver that wires IRQ2 and vmtime access.
vm/devices/chipset/src/pit/mod.rs Exposes PIT resolver module.
vm/devices/chipset/src/dma/resolver.rs New resolver for the generic ISA DMA controller.
vm/devices/chipset/src/dma/mod.rs Adds ISA DMA controller capability plumbing to the DMA device.
vm/chipset_device_resources/src/lib.rs Extends erased chipset device wrapper to forward ISA DMA controller capability.
vm/chipset_device/src/lib.rs Adds supports_isa_dma_controller() capability hook and exports new isa_dma module.
vm/chipset_device/src/isa_dma.rs Introduces the ISA DMA controller capability trait and transfer types.
petri/src/vm/openvmm/modify.rs Updates chipset device handle construction for the new pci_placement field.
petri/src/vm/openvmm/construct.rs Captures manifest with_pit() and propagates it into OpenVMM config; updates handle construction.
openvmm/openvmm_resources/src/lib.rs Registers new chipset resolvers (DMA, PIT, UHCI stub) for OpenVMM.
openvmm/openvmm_resources/Cargo.toml Adds chipset_legacy dependency to support UHCI stub resolver registration.
openvmm/openvmm_entry/src/ttrpc/mod.rs Propagates with_pit from manifest into worker config.
openvmm/openvmm_entry/src/lib.rs Propagates with_pit from manifest into worker config; updates handle construction.
openvmm/openvmm_defs/src/config.rs Adds with_pit: bool to worker Config.
openvmm/openvmm_core/src/worker/dispatch.rs Uses with_pit (plus manifest flags) for ACPI table generation and carries capabilities through VM lifecycle.
openhcl/underhill_core/src/worker.rs Removes PIT/UHCI deps plumbing and updates handle construction for pci_placement.
openhcl/openvmm_hcl_resources/src/lib.rs Registers PIT and UHCI stub resolvers for OpenVMM-HCL (but currently missing DMA resolver).
openhcl/openvmm_hcl_resources/Cargo.toml Adds chipset_legacy dependency for UHCI stub resolver registration.
Cargo.lock Lockfile updates for new/changed dependencies.
Comments suppressed due to low confidence (1)

vm/devices/chipset/src/dma/mod.rs:225

  • impl IsaDmaController for DmaController currently calls self.check_transfer_size(...) inside check_transfer_size, which resolves back to the same trait method and will recurse until stack overflow. Disambiguate the call to the inherent method (or rename one of the methods) so the trait implementation delegates to the existing controller logic instead of recursing.

moor-coding and others added 9 commits March 24, 2026 21:14
…icrosoft#2944)

ContiguousBufferMemory works by having a rolling `len`-sized window of
valid offsets across all `u32` values. The only safe window sizes are
therefore powers of 2, otherwise you can potentially have multiple
buffers assigned the same offset near the end of the `u32` space, due to
how modular arithmetic rolls over values.

---------

Co-authored-by: Ben Lewis <Ben.Lewis@microsoft.com>
Previously, consomme dropped out-of-order TCP segments and relied on the
sender to retransmit all data after a gap. This is correct but slow when
segments arrive out of order — every gap causes a full retransmission
cycle.

Add a small assembler that tracks up to 4 non-contiguous received byte
ranges, allowing out-of-order segments to be buffered in the ring and
delivered once the gaps are filled. FIN handling is integrated: a FIN is
latched when received but only delivered to the state machine once all
preceding data is contiguous.

- assembler.rs: new Assembler type with add/clear/try_fin, extensive
unit tests covering merges, overlaps, table-full rejection, and FIN
ordering
- ring.rs: add write_at() for arbitrary-offset writes into the ring
buffer (used for both in-order and OOO segments), support zero- capacity
rings, fix wrapping mask computation
- tcp.rs: replace VecDeque rx_buffer with Ring, integrate 3-stage
reassembly (write to ring, record in assembler, advance frontier), add
Inspect support to Assembler, fix DNS TCP backend for Ring API
- tests.rs: end-to-end TCP test harness with real loopback sockets,
covering in-order data, OOO reassembly, FIN in/out of order, host-
to-guest data, host FIN, duplicate segments, and overlapping
retransmissions
…rosoft#3080)

External device backends (vhost-user) need access to the backing fds and
region layout of guest RAM so they can mmap the same physical memory in
their own process. This adds the plumbing to expose that information
through GuestMemory without requiring direct knowledge of membacking.

The MappingManager already tracks all active mappings. Rather than
maintaining a separate snapshot, a new dma_target flag on regions marks
which mappings are guest RAM (vs device MMIO). A DmaRegionProvider
queries the MappingManager asynchronously and translates the results
into ShareableRegions exposed through the GuestMemorySharing trait
object, accessible via GuestMemory::sharing().

The guestmem crate defines the abstraction boundary: ShareableRegion,
GuestMemorySharing, and the ProvideShareableRegions trait. The
membacking crate provides the implementation. Consumers like vhost-user
only depend on guestmem.
…microsoft#3084)

Move GuestMemory from virtio device construction time to queue start
time. This allows the transport to provide the correct GuestMemory at
the point where it's actually needed (when queues are activated), rather
than requiring it up front.

This is useful in particular for vhost-user, where the memory cannot be
provided until the VMM actually attaches.
Move the virtio specification constants and types (VirtioDeviceType,
VirtioDeviceFeatures, VirtioDeviceStatus, PCI/MMIO register offsets,
queue structures) into a new virtio_spec crate.

Re-export as 'pub use virtio_spec as spec' from the virtio crate so all
existing virtio::spec::* paths continue to work.

Also change DeviceTraits::device_id from u16 to VirtioDeviceType for
type safety.
)

Adds the ability to mark individual vmm test variants as unstable.
Includes changes to petri and the vmm tests macros to make this
possible.
…ft#3099)

Add .github/workflows/copilot-setup-steps.yml to give the Copilot coding
agent a working Rust toolchain, cargo-nextest, and restore-packages
(protoc + build deps) so it can validate changes locally before pushing.
moor-coding and others added 26 commits March 25, 2026 16:41
- Add a generic ISA DMA resource handle and resolver registration.
- Add ISA DMA controller capability plumbing to chipset_device and erased wrappers.
- Resolve DMA before floppy wiring in base chipset to avoid NoDmaForFloppy at runtime.
- register generic ISA DMA resolver for HCL resources

- ratelimit ISA DMA mismatch logging and warn on duplicate DMA handles

- switch vm_manifest_builder tests to test_with_tracing
Copilot AI review requested due to automatic review settings March 27, 2026 17:57
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 29 out of 30 changed files in this pull request and generated 3 comments.

Comment on lines +11 to +17
pub struct PciPlacementHint {
/// Name of the PCI bus this device should attach to.
pub bus_name: &'static str,
/// Optional static BDF for this device.
///
/// If absent, the VMM may use `PciConfigSpace::suggested_bdf`.
pub bdf: Option<(u8, u8, u8)>,
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

PciPlacementHint::bus_name is typed as &'static str, which forces callers without truly-static bus names (e.g. remote device proxies) to leak memory or otherwise manufacture a 'static reference. Since BusId::new only needs &str (it clones into Arc<str>), consider making bus_name owned (e.g. Arc<str>/Box<str>/String) or lifetime-parameterized so implementations can return borrowed data without leaks.

Copilot uses AI. Check for mistakes.
Comment on lines +137 to +139
// The transport payload is owned String; leak once to satisfy the
// static lifetime required by PciPlacementHint.
bus_name: Box::leak(placement.bus_name.into_boxed_str()),
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

Using Box::leak here permanently leaks the bus name string for every proxied device instance, which can accumulate across VM create/destroy cycles. If the goal is only to pass a placement hint through, consider adjusting the PciPlacementHint API to avoid requiring a 'static bus name (or store the owned string in the proxy and return a borrowed reference tied to self).

Suggested change
// The transport payload is owned String; leak once to satisfy the
// static lifetime required by PciPlacementHint.
bus_name: Box::leak(placement.bus_name.into_boxed_str()),
// The transport payload is an owned String; store it directly to avoid leaks.
bus_name: placement.bus_name,

Copilot uses AI. Check for mistakes.
Comment on lines +470 to +475
fn attach_piix4_pci_usb_uhci_stub(&mut self) -> &mut Self {
self.chipset_devices.push(ChipsetDeviceHandle {
name: "piix4-usb-uhci-stub".to_string(),
resource: Piix4PciUsbUhciStubDeviceHandle.into_resource(),
});
self
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

attach_piix4_pci_usb_uhci_stub is not idempotent (unlike attach_generic_isa_dma/attach_pit), so callers that already provided a Piix4PciUsbUhciStubDeviceHandle can end up with duplicate UHCI stub devices in chipset_devices. Consider checking for an existing handle (by resource.id()) and returning early if present.

Copilot uses AI. Check for mistakes.
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.

8 participants