On 10/27/2026 9:43 AM, Shameer Kolothum Thodi wrote:
> 
> 
>> -----Original Message-----
>> From: Tushar Dave <[email protected]>
>> Sent: 16 September 2026 19:56
>> To: [email protected]
>> Cc: [email protected]; [email protected]; [email protected];
>> [email protected]; [email protected]; Alex Williamson
>> <[email protected]>; Jason Gunthorpe <[email protected]>; Shameer
>> Kolothum Thodi <[email protected]>
>> Subject: [PATCH 1/5] hw/pci: introduce PCI fixed BAR properties
>>
>> Add fixed-bar-N properties to PCIDevice to allow the guest address
>> of an individual PCI BAR to be explicitly specified. The properties
>> are available for PCI BARs 0 through 5 and accept QEMU size
>> values, for example fixed-bar-0=0x40000000 or fixed-bar-0=64G.
>>
>> e.g.
>> -device some-device,fixed-bar-0=<addr>[,fixed-bar-1=<addr>]...
>>
>> During realize, validate that each specified BAR exists and is a
>> memory BAR, and reject fixed BAR configuration for hot-plugged
>> devices.
>>
>> Signed-off-by: Tushar Dave <[email protected]>
>> ---
>>  hw/pci/pci.c                | 43 +++++++++++++++++++++++++++++++++++++
>>  include/hw/pci/pci_device.h |  7 ++++++
>>  2 files changed, 50 insertions(+)
>>
>> diff --git a/hw/pci/pci.c b/hw/pci/pci.c
>> index 0efb4eb4bb..775fef1beb 100644
>> --- a/hw/pci/pci.c
>> +++ b/hw/pci/pci.c
>> @@ -89,6 +89,12 @@ static const Property pci_props[] = {
>>      DEFINE_PROP_STRING("romfile", PCIDevice, romfile),
>>      DEFINE_PROP_UINT32("romsize", PCIDevice, romsize, UINT32_MAX),
>>      DEFINE_PROP_INT32("rombar",  PCIDevice, rom_bar, -1),
>> +    DEFINE_PROP_SIZE("fixed-bar-0", PCIDevice, fixed_bar_addr[0],
>> PCI_BAR_UNMAPPED),
>> +    DEFINE_PROP_SIZE("fixed-bar-1", PCIDevice, fixed_bar_addr[1],
>> PCI_BAR_UNMAPPED),
>> +    DEFINE_PROP_SIZE("fixed-bar-2", PCIDevice, fixed_bar_addr[2],
>> PCI_BAR_UNMAPPED),
>> +    DEFINE_PROP_SIZE("fixed-bar-3", PCIDevice, fixed_bar_addr[3],
>> PCI_BAR_UNMAPPED),
>> +    DEFINE_PROP_SIZE("fixed-bar-4", PCIDevice, fixed_bar_addr[4],
>> PCI_BAR_UNMAPPED),
>> +    DEFINE_PROP_SIZE("fixed-bar-5", PCIDevice, fixed_bar_addr[5],
>> PCI_BAR_UNMAPPED),
> 

Thank you for the review.

> These properties are exposed on all PCI devices, but only virt wires up
> the validation and fw_cfg export in this series. On other machines, a
> valid request would be accepted without placing the BAR, right?

Yes.
> 
> I think it is better we add a mechanism(MachineClass flag ?) and check
> that.

Sure, I will add a MachineClass flag 'bool pci_fixed_bar_supported'

-Tushar
> 
> Thanks,
> Shameer
> 
>>      DEFINE_PROP_BIT("multifunction", PCIDevice, cap_present,
>>                      QEMU_PCI_CAP_MULTIFUNCTION_BITNR, false),
>>      DEFINE_PROP_BIT("x-pcie-lnksta-dllla", PCIDevice, cap_present,
>> @@ -228,6 +234,36 @@ static void pci_bus_unrealize(BusState *qbus)
>>      vmstate_unregister(NULL, &vmstate_pcibus, bus);
>>  }
>>
>> +static void pci_check_fixed_bars(PCIDevice *pci_dev, Error **errp)
>> +{
>> +    PCIIORegion *r;
>> +    int i;
>> +
>> +    for (i = 0; i < PCI_NUM_REGIONS - 1; i++) {
>> +        if (pci_dev->fixed_bar_addr[i] == PCI_BAR_UNMAPPED) {
>> +            continue;
>> +        }
>> +
>> +        if (DEVICE(pci_dev)->hotplugged) {
>> +            error_setg(errp, "fixed-bar-%d is not supported on "
>> +                       "hot-plugged devices", i);
>> +            return;
>> +        }
>> +
>> +        r = &pci_dev->io_regions[i];
>> +        if (!r->size) {
>> +            error_setg(errp, "fixed-bar-%d: bar%d does not exist on %s",
>> +                       i, i, pci_dev->name);
>> +            return;
>> +        }
>> +        if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
>> +            error_setg(errp, "fixed-bar-%d: bar%d on %s is an I/O BAR, "
>> +                       "not a memory BAR", i, i, pci_dev->name);
>> +            return;
>> +        }
>> +    }
>> +}
>> +
>>  static int pcibus_num(PCIBus *bus)
>>  {
>>      if (pci_bus_is_root(bus)) {
>> @@ -2393,6 +2429,13 @@ static void pci_qdev_realize(DeviceState *qdev,
>> Error **errp)
>>          is_default_rom = true;
>>      }
>>
>> +    pci_check_fixed_bars(pci_dev, &local_err);
>> +    if (local_err) {
>> +        error_propagate(errp, local_err);
>> +        pci_qdev_unrealize(DEVICE(pci_dev));
>> +        return;
>> +    }
>> +
>>      pci_add_option_rom(pci_dev, is_default_rom, &local_err);
>>      if (local_err) {
>>          error_propagate(errp, local_err);
>> diff --git a/include/hw/pci/pci_device.h b/include/hw/pci/pci_device.h
>> index 5cac6e1688..fc5f50a1c4 100644
>> --- a/include/hw/pci/pci_device.h
>> +++ b/include/hw/pci/pci_device.h
>> @@ -187,6 +187,13 @@ struct PCIDevice {
>>      uint32_t max_bounce_buffer_size;
>>
>>      char *sriov_pf;
>> +
>> +    /*
>> +     * fixed_bar_addr[N] holds the guest address configured via the
>> +     * fixed-bar-N property for memory BAR N. PCI_BAR_UNMAPPED means
>> +     * the BAR's address is not fixed.
>> +     */
>> +    uint64_t  fixed_bar_addr[PCI_NUM_REGIONS - 1];
>>  };
>>
>>  static inline int pci_intx(PCIDevice *pci_dev)
>> --
>> 2.34.1
> 


Reply via email to