From f8f92bd628caaa726b0bb9e90ac12d37f154d7d1 Mon Sep 17 00:00:00 2001 From: CMGS Date: Tue, 19 May 2026 10:54:58 +0800 Subject: [PATCH] virtio-devices: 8 MiB-aligned initial BAR placement Windows 11 PnP rebalance rewrites peer BARs into the same range CH packed the initial layout at, causing move_bar() failures and boot deadlock. Pack Mmio64 BARs at 8 MiB stride. Mmio32 isn't wide enough for the same stride, but its BARs don't participate in guest BAR rebalancing. On restore, pin the BAR to the snapshot address (alignment=None) so a guest-relocated BAR with smaller alignment is accepted. Signed-off-by: CMGS --- virtio-devices/src/transport/pci_device.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/virtio-devices/src/transport/pci_device.rs b/virtio-devices/src/transport/pci_device.rs index 87b2a9d9f..5b0953eae 100644 --- a/virtio-devices/src/transport/pci_device.rs +++ b/virtio-devices/src/transport/pci_device.rs @@ -281,6 +281,8 @@ const MSIX_PBA_BAR_OFFSET: u64 = next_bar_addr(MSIX_TABLE_BAR_OFFSET, MSIX_TABLE const MSIX_PBA_SIZE: u64 = 0x800; // The BAR size must be a power of 2. const CAPABILITY_BAR_SIZE: u64 = (MSIX_PBA_BAR_OFFSET + MSIX_PBA_SIZE).next_power_of_two(); +// Align larger than natural alignment to work around Windows driver issues +const VIRTIO_PCI_BAR_ALIGN: u64 = 0x80_0000; const VIRTIO_COMMON_BAR_INDEX: u8 = 0; const VIRTIO_SHM_BAR_INDEX: usize = 2; @@ -1044,12 +1046,13 @@ impl PciDevice for VirtioPciDevice { // See http://docs.oasis-open.org/virtio/virtio/v1.0/cs04/virtio-v1.0-cs04.html#x1-740004 let (virtio_pci_bar_addr, region_type) = if use_64bit_bar { let region_type = PciBarRegionType::Memory64BitRegion; + let alignment = if restoring { + None + } else { + Some(VIRTIO_PCI_BAR_ALIGN) + }; let addr = mmio64_allocator - .allocate( - settings_bar_addr, - CAPABILITY_BAR_SIZE, - Some(CAPABILITY_BAR_SIZE), - ) + .allocate(settings_bar_addr, CAPABILITY_BAR_SIZE, alignment) .ok_or(PciDeviceError::IoAllocationFailed(CAPABILITY_BAR_SIZE))?; (addr, region_type) } else {