Skip to content

pcie, virtio, nvme: preserve and quiesce emulated PCIe devices across guest reset#3915

Open
bitranox wants to merge 1 commit into
microsoft:mainfrom
bitranox:fix-pcie-device-reset
Open

pcie, virtio, nvme: preserve and quiesce emulated PCIe devices across guest reset#3915
bitranox wants to merge 1 commit into
microsoft:mainfrom
bitranox:fix-pcie-device-reset

Conversation

@bitranox

Copy link
Copy Markdown
Contributor

On a guest reboot, emulated PCIe devices either vanished from the guest or corrupted the rebooted guest's memory. Three independent fixes here:

PCIe presence detect. A VM reset resets device config space, which clears the downstream-port slot-status Presence Detect bit. The connected device (the port's link) survives the reset, so the slot is still occupied, but the guest's pciehp driver reads the port after reboot, sees no presence, and removes the still-attached device: an emulated disk or NIC disappears on every reboot until a manual PCI rescan. Re-derive presence from the link on reset, for both root-complex root ports and switch downstream ports.

virtio-blk in-flight I/O. The reset/disable teardown drained the queue and posted completions to the used ring. A disk read submitted before the reset completes asynchronously and writes into guest memory the rebooted guest has already reused. Await the in-flight I/O to completion (so it finishes while the guest is stopped) but discard the completion rather than posting it. The suspend/resume path is unchanged and still posts.

nvme shadow doorbell. A shadow-doorbell mapping installed by Doorbell Buffer Config survived controller reset, so after a reboot the controller wrote shadow event_idx into the stale guest address the rebooted guest had reused. Reset the doorbell store to its power-on host-backed state on controller reset.

Tested by rebooting a Linux guest with virtio-blk, nvme, and virtio-net attached in a loop: before, guest memory was corrupted on the first reboot (random anon_vma / slab / rbtree oopses); after, it survives repeated reboots with the devices intact.

@bitranox
bitranox requested review from a team as code owners July 10, 2026 11:15
Copilot AI review requested due to automatic review settings July 10, 2026 11:15

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 hardens device reset behavior so emulated PCIe and storage devices remain present and do not corrupt guest memory across guest reboot/reset cycles.

Changes:

  • Virtio: introduce abort_queue() and switch reset/disable teardown to use it so in-flight IO can be awaited/canceled without publishing completions into torn-down queue memory.
  • Virtio-blk: implement abort_queue() to await io_uring-backed IOs to completion while discarding used-ring completions on reset/disable.
  • PCIe & NVMe: preserve PCIe presence-detect across port reset, and clear NVMe shadow-doorbell mappings on controller reset; add regression tests for PCIe presence.

Reviewed changes

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

Show a summary per file
File Description
vm/devices/virtio/virtio/src/transport/task.rs Switch reset/disable teardown to abort_queue() for all queues.
vm/devices/virtio/virtio/src/device.rs Add abort_queue() to the virtio device traits (typed + dyn).
vm/devices/virtio/virtio_blk/src/lib.rs Implement virtio-blk reset/disable abort path by draining in-flight IO and discarding used-ring completions.
vm/devices/storage/nvme/src/workers/coordinator.rs Reset NVMe doorbell backing store on controller reset to prevent stale shadow mappings.
vm/devices/storage/nvme/src/queue.rs Add DoorbellMemory::reset() helper to restore power-on host-backed doorbells.
vm/devices/pci/pcie/src/switch.rs Reset downstream ports via port reset to preserve presence detect; add regression test behind switch.
vm/devices/pci/pcie/src/root.rs Reset root ports via port reset to preserve presence detect.
vm/devices/pci/pcie/src/port.rs Add PcieDownstreamPort::reset() that re-asserts presence when a link is still connected; add regression test.

Comment thread vm/devices/virtio/virtio/src/device.rs Outdated
Comment thread vm/devices/virtio/virtio_blk/src/lib.rs Outdated
Copilot AI review requested due to automatic review settings July 10, 2026 11:24
@bitranox
bitranox force-pushed the fix-pcie-device-reset branch from e4e37fd to 92c61c5 Compare July 10, 2026 11:24

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 2 comments.

Comment thread vm/devices/virtio/virtio/src/device.rs Outdated
Comment thread vm/devices/virtio/virtio_blk/src/lib.rs
Copilot AI review requested due to automatic review settings July 10, 2026 11:33
@bitranox
bitranox force-pushed the fix-pcie-device-reset branch from 92c61c5 to b3e04ed Compare July 10, 2026 11:33

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 2 comments.

Comment thread vm/devices/virtio/virtio/src/device.rs Outdated
Comment thread vm/devices/virtio/virtio/src/device.rs Outdated
Copilot AI review requested due to automatic review settings July 10, 2026 11:40
@bitranox
bitranox force-pushed the fix-pcie-device-reset branch from b3e04ed to 7245cf7 Compare July 10, 2026 11:40

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/virtio/virtio/src/transport/task.rs Outdated
… guest reset

On a guest reboot, emulated PCIe devices either vanished from the guest or
corrupted the rebooted guest's memory. Three fixes:

pcie: a VM reset resets device config space, which clears the downstream-port
slot-status Presence Detect bit. The connected device (the port's link)
survives the reset, so the slot is still occupied, but the guest's pciehp
driver reads the port after reboot, sees no presence, and removes the
still-attached device: an emulated disk or NIC disappears on every reboot
until a manual PCI rescan. Re-derive presence from the link on reset, for both
root-complex root ports and switch downstream ports.

virtio: the reset/disable teardown drained each queue with stop_queue, which
posts completions to the used ring. A disk read submitted before the reset
completes asynchronously and writes into guest memory the rebooted guest has
already reused. Add VirtioDevice::abort_queue, used by the teardown path: it
awaits the in-flight IO to completion, so it finishes while the guest is
stopped, then discards the completion without posting. The default falls back
to stop_queue; virtio-blk overrides it. The suspend/resume path still posts.

nvme: a shadow-doorbell mapping installed by Doorbell Buffer Config survived
controller reset, so after a reboot the controller wrote shadow event_idx into
the stale guest address the rebooted guest had reused. Reset the doorbell
store to its power-on host-backed state on controller reset.

Tested by rebooting a Linux guest with virtio-blk, nvme, and virtio-net
attached in a loop: before, guest memory was corrupted on the first reboot
(random anon_vma / slab / rbtree oopses); after, it survives repeated reboots
with the devices intact.
Copilot AI review requested due to automatic review settings July 10, 2026 11:45
@bitranox
bitranox force-pushed the fix-pcie-device-reset branch from 7245cf7 to 2fa5c2e Compare July 10, 2026 11:45

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 no new comments.

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.

2 participants