@samitouri / QOSamiQemu / commits / 412c48d054

q35: Fix incorrect values for PCIEXBAR masks

There are two small issues in PCIEXBAR address mask handling: - wrong bit positions for address mask bits (see PCIEXBAR description in Q35 datasheet) - incorrect usage of 64ADR_MASK Due to this, attempting to write a valid PCIEXBAR address may cause it to shift to another address, causing memory layout corruption where emulated MMIO regions may overlap real (passed through) MMIO ranges. Fix this by providing correct values. Fixes: df2d8b3ed4 ("q35: Introduce q35 pc based chipset emulator") Signed-off-by: Alexey Gerasimenko <x1917x@gmail.com> Signed-off-by: Thierry Escande <thierry.escande@vates.tech> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Message-Id: <20260313164649.794591-4-thierry.escande@vates.tech> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

Alexey Gerasimenko committed Mar 13, 2026 at 16:47 UTC 412c48d054b484a0f88d858dc554c24e07e94358
2 files changed +5 -5
hw/pci-host/q35.c
+3 -3
@@ -306,12 +306,12 @@ static void mch_update_pciexbar(MCHPCIState *mch)
306 break;
307 case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_128M:
308 length = 128 * 1024 * 1024;
309 - addr_mask |= MCH_HOST_BRIDGE_PCIEXBAR_128ADMSK |
310 - MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK;
309 + addr_mask |= MCH_HOST_BRIDGE_PCIEXBAR_128ADMSK;
310 break;
311 case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_64M:
312 length = 64 * 1024 * 1024;
314 - addr_mask |= MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK;
313 + addr_mask |= MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK |
314 + MCH_HOST_BRIDGE_PCIEXBAR_128ADMSK;
315 break;
316 case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_RVD:
317 qemu_log_mask(LOG_GUEST_ERROR, "Q35: Reserved PCIEXBAR LENGTH\n");
include/hw/pci-host/q35.h
+2 -2
@@ -100,8 +100,8 @@ struct Q35PCIHost {
100 #define MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT 0xb0000000
101 #define MCH_HOST_BRIDGE_PCIEXBAR_MAX (0x10000000) /* 256M */
102 #define MCH_HOST_BRIDGE_PCIEXBAR_ADMSK Q35_MASK(64, 35, 28)
103 -#define MCH_HOST_BRIDGE_PCIEXBAR_128ADMSK ((uint64_t)(1 << 26))
104 -#define MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK ((uint64_t)(1 << 25))
103 +#define MCH_HOST_BRIDGE_PCIEXBAR_128ADMSK ((uint64_t)(1 << 27))
104 +#define MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK ((uint64_t)(1 << 26))
105 #define MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_MASK ((uint64_t)(0x3 << 1))
106 #define MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_256M ((uint64_t)(0x0 << 1))
107 #define MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_128M ((uint64_t)(0x1 << 1))