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>
This commit is contained in:
Alexey Gerasimenko
2026-03-13 16:47:16 +00:00
committed by Michael S. Tsirkin
parent eef8552c47
commit 412c48d054
2 changed files with 5 additions and 5 deletions

View File

@@ -306,12 +306,12 @@ static void mch_update_pciexbar(MCHPCIState *mch)
break;
case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_128M:
length = 128 * 1024 * 1024;
addr_mask |= MCH_HOST_BRIDGE_PCIEXBAR_128ADMSK |
MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK;
addr_mask |= MCH_HOST_BRIDGE_PCIEXBAR_128ADMSK;
break;
case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_64M:
length = 64 * 1024 * 1024;
addr_mask |= MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK;
addr_mask |= MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK |
MCH_HOST_BRIDGE_PCIEXBAR_128ADMSK;
break;
case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_RVD:
qemu_log_mask(LOG_GUEST_ERROR, "Q35: Reserved PCIEXBAR LENGTH\n");

View File

@@ -100,8 +100,8 @@ struct Q35PCIHost {
#define MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT 0xb0000000
#define MCH_HOST_BRIDGE_PCIEXBAR_MAX (0x10000000) /* 256M */
#define MCH_HOST_BRIDGE_PCIEXBAR_ADMSK Q35_MASK(64, 35, 28)
#define MCH_HOST_BRIDGE_PCIEXBAR_128ADMSK ((uint64_t)(1 << 26))
#define MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK ((uint64_t)(1 << 25))
#define MCH_HOST_BRIDGE_PCIEXBAR_128ADMSK ((uint64_t)(1 << 27))
#define MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK ((uint64_t)(1 << 26))
#define MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_MASK ((uint64_t)(0x3 << 1))
#define MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_256M ((uint64_t)(0x0 << 1))
#define MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_128M ((uint64_t)(0x1 << 1))