Commit 00ebc44514 for qemu.org
commit 00ebc44514a67fb75a46d60e4b44614ebf91230f
Author: Jaehoon Kim <jhkim@linux.ibm.com>
Date: Fri Feb 6 10:46:02 2026 -0600
s390x/pci: Fix endianness for zPCI BAR values.
During zPCI scan, BAR configuration data retrieved via CLP Query was
misinterpreted due to an endianness mismatch between QEMU and the guest
kernel.
The guest kernel's clp_store_query_pci_fn() expects BAR values in
little-endian format and converts them with le32_to_cpu(). However, QEMU
was incorrectly sending them in big-endian format, not following the
architecture specification. This caused incorrect bit-swapping in the
kernel, leading zpci_setup_bus_resources() to perform registration checks
against invalid flags, making the process ineffective.
Observation values for zPCI device (NVMe passthrough):
LPAR from real CLP:
[ 0.865595] Resource: PCI Bus 0000:00 -> zdev->bar[0].val: 0x4
[ 0.865597] start: 0x4000000000000000
[ 0.865598] end: 0x4000000000003fff
[ 0.865600] flags: 0x100200
QEMU before fix (wrong):
[ 0.601083] Resource: PCI Bus 0001:00 -> zdev->bar[0].val: 0x4000000
[ 0.601085] start: 0x4003000000000000
[ 0.601086] end: 0x4003000000003fff
[ 0.601087] flags: 0x200
QEMU after fix (correct):
[ 0.601116] Resource: PCI Bus 0001:00 -> zdev->bar[0].val: 0x4
[ 0.601117] start: 0x4003000000000000
[ 0.601118] end: 0x4003000000003fff
[ 0.601119] flags: 0x100200
Signed-off-by: Jaehoon Kim <jhkim@linux.ibm.com>
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
Reviewed-by: Farhan Ali <alifm@linux.ibm.com>
Reviewed-by: Eric Farman <farman@linux.ibm.com>
Message-ID: <20260206164645.1845366-1-jhkim@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 6b67c3c109..10066ca618 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -307,7 +307,7 @@ int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t ra)
uint32_t data = pci_get_long(pbdev->pdev->config +
PCI_BASE_ADDRESS_0 + (i * 4));
- stl_be_p(&resquery->bar[i], data);
+ stl_le_p(&resquery->bar[i], data);
resquery->bar_size[i] = pbdev->pdev->io_regions[i].size ?
ctz64(pbdev->pdev->io_regions[i].size) : 0;
trace_s390_pci_bar(i,