Hi Alexander, On Fri, Oct 10, 2025 at 8:59 AM Alexander Bulekov <[email protected]> wrote: > > On 251008 1919, Navid Emamdoost wrote: > > The qpci_iomap() function fails with a fatal g_assert(addr) if it > > probes a PCI BAR that has a size of zero. This is expected behavior > > for certain devices, like the Q35 PCI Host Bridge, which have valid but > > unimplemented BARs. > > This assertion blocks the creation of fuzz targets for complex machine > > types that include these devices. > > Make the check conditional on !CONFIG_FUZZ. In fuzzing builds, a > > zero-sized BAR is now handled gracefully by returning an empty BAR > > struct, allowing fuzzing to proceed. The original assertion is kept for > > all other builds to maintain strict checking for qtest and production > > environments. > > Is there a way to determine whether a BAR is unimplememnted from the > PCIDev in generic_fuzz.c:pci_enum so that we can skip the call to iomap? >
Fair point. I don't think we have a reliable way to determine if a BAR is truly unimplemented from the PCIDevice model without probing it. If we moved that hardware probe into pci_enum, it would become inefficient for all the BARs that are implemented, as they would be probed twice: once in pci_enum just to check, and then again inside qpci_iomap to do the actual mapping. That's why I think delegating this check to qpci_iomap is the cleaner approach. > > > > Signed-off-by: Navid Emamdoost <[email protected]> > > --- > > tests/qtest/libqos/pci.c | 16 ++++++++++++++++ > > 1 file changed, 16 insertions(+) > > > > diff --git a/tests/qtest/libqos/pci.c b/tests/qtest/libqos/pci.c > > index a59197b992..df9e2a3993 100644 > > --- a/tests/qtest/libqos/pci.c > > +++ b/tests/qtest/libqos/pci.c > > @@ -541,6 +541,22 @@ QPCIBar qpci_iomap(QPCIDevice *dev, int barno, > > uint64_t *sizeptr) > > addr &= PCI_BASE_ADDRESS_MEM_MASK; > > } > > > > +#ifdef CONFIG_FUZZ > > + /* > > + * During fuzzing runs, an unimplemented BAR (addr=0) is not a fatal > > + * error. This occurs when probing devices like the Q35 host bridge. We > > + * return gracefully to allow fuzzing to continue. In non-fuzzing > > builds, > > + * we retain the original g_assert() to catch unexpected behavior. > > + */ > > + if (!addr) { > > + if (sizeptr) { > > + *sizeptr = 0; > > + } > > + memset(&bar, 0, sizeof(bar)); > > + return bar; > > + } > > +#endif > > + > > g_assert(addr); /* Must have *some* size bits */ > > > > size = 1U << ctz32(addr); > > -- > > 2.51.0.710.ga91ca5db03-goog > > > > -- Thank you, Navid.
