On Fri, Aug 21, 2026 at 12:14:26PM +0100, Mark Cave-Ayland wrote:
> Move the ACPI_PCIHP_PROP_BSEL property to the PCIBus object and update all
> callers accordingly.
>
> Since the existing logic checks for the existence of the ACPI_PCIHP_PROP_BSEL
> property to enable the relevant ACPI changes, set the type of the underlying
> variable to uint32_t with a default value of UINT32_MAX indicating that the
> property has not been set.
>
> Signed-off-by: Mark Cave-Ayland <[email protected]>
> Reviewed-by: Marc-André Lureau <[email protected]>
> ---
> include/hw/pci/pci_bus.h | 2 ++
> hw/acpi/pci-bridge.c | 9 ++++++++-
> hw/acpi/pcihp.c | 30 ++++++++++++++----------------
> hw/arm/virt-acpi-build.c | 7 ++++++-
> hw/i386/acpi-build.c | 7 ++++++-
> hw/pci/pci.c | 7 +++++++
> 6 files changed, 43 insertions(+), 19 deletions(-)
>
> diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h
> index c738446788..7ecb23d13c 100644
> --- a/include/hw/pci/pci_bus.h
> +++ b/include/hw/pci/pci_bus.h
> @@ -56,6 +56,8 @@ struct PCIBus {
> int *irq_count;
>
> Notifier machine_done;
> +
> + uint32_t acpi_pcihp_bsel_val;
> };
>
> static inline bool pci_bus_is_cxl(PCIBus *bus)
> diff --git a/hw/acpi/pci-bridge.c b/hw/acpi/pci-bridge.c
> index 394a919479..1bfc5431f2 100644
> --- a/hw/acpi/pci-bridge.c
> +++ b/hw/acpi/pci-bridge.c
> @@ -23,6 +23,8 @@ void build_pci_bridge_aml(AcpiDevAmlIf *adev, Aml *scope)
>
> if (!DEVICE(br)->hotplugged) {
> PCIBus *sec_bus = pci_bridge_get_sec_bus(br);
> + Error *local_err = NULL;
> + uint32_t bsel;
>
> build_append_pci_bus_devices(scope, sec_bus);
>
> @@ -30,9 +32,14 @@ void build_pci_bridge_aml(AcpiDevAmlIf *adev, Aml *scope)
> * generate hotplug slots descriptors if
> * bridge has ACPI PCI hotplug attached,
> */
> - if (object_property_find(OBJECT(sec_bus), ACPI_PCIHP_PROP_BSEL)) {
> + bsel = object_property_get_uint(OBJECT(sec_bus),
> ACPI_PCIHP_PROP_BSEL,
> + &local_err);
> +
> + if (local_err == NULL && bsel != UINT32_MAX) {
> build_append_pcihp_slots(scope, sec_bus);
> }
> +
> + error_free(local_err);
IIUC, in this new approach the property should always exist and so I'd
expect object_property_get_uint to always succeed.
IOW, is something stopping us using &error_abort and merely checking
if (bsel != UINT32_MAX)
?
> }
> }
>
> diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
> index a91f523c93..b26ddf0a26 100644
> --- a/hw/acpi/pcihp.c
> +++ b/hw/acpi/pcihp.c
> @@ -58,7 +58,7 @@ typedef struct AcpiPciHpFind {
> static int acpi_pcihp_get_bsel(PCIBus *bus)
> {
> Error *local_err = NULL;
> - uint64_t bsel = object_property_get_uint(OBJECT(bus),
> ACPI_PCIHP_PROP_BSEL,
> + uint32_t bsel = object_property_get_uint(OBJECT(bus),
> ACPI_PCIHP_PROP_BSEL,
> &local_err);
>
> if (local_err || bsel >= ACPI_PCIHP_MAX_HOTPLUG_BUS) {
> @@ -78,18 +78,14 @@ typedef struct {
> static void *acpi_set_bsel(PCIBus *bus, void *opaque)
> {
> BSELInfo *info = opaque;
> - unsigned *bus_bsel;
> DeviceState *br = bus->qbus.parent;
> bool is_bridge = IS_PCI_BRIDGE(br);
>
> /* hotplugged bridges can't be described in ACPI ignore them */
> if (qbus_is_hotpluggable(BUS(bus))) {
> if (!is_bridge || (!br->hotplugged && info->has_bridge_hotplug)) {
> - bus_bsel = g_malloc(sizeof *bus_bsel);
> -
> - *bus_bsel = info->bsel_alloc++;
> - object_property_add_uint32_ptr(OBJECT(bus), ACPI_PCIHP_PROP_BSEL,
> - bus_bsel, OBJ_PROP_FLAG_READ);
> + object_property_set_uint(OBJECT(bus), ACPI_PCIHP_PROP_BSEL,
> + info->bsel_alloc++, NULL);
> }
> }
>
> @@ -730,14 +726,16 @@ bool build_append_notification_callback(Aml
> *parent_scope, const PCIBus *bus)
> /* If bus supports hotplug select it and notify about local events */
> bsel = object_property_get_qobject(OBJECT(bus), ACPI_PCIHP_PROP_BSEL,
> NULL);
> if (bsel) {
> - uint64_t bsel_val = qnum_get_uint(qobject_to(QNum, bsel));
> -
> - aml_append(method, aml_store(aml_int(bsel_val), aml_name("BNUM")));
> - aml_append(method, aml_call2("DVNT", aml_name("PCIU"),
> - aml_int(1))); /* Device Check */
> - aml_append(method, aml_call2("DVNT", aml_name("PCID"),
> - aml_int(3))); /* Eject Request */
> - nr_notifiers++;
> + uint32_t bsel_val = qnum_get_uint(qobject_to(QNum, bsel));
> +
> + if (bsel_val != UINT32_MAX) {
> + aml_append(method, aml_store(aml_int(bsel_val),
> aml_name("BNUM")));
> + aml_append(method, aml_call2("DVNT", aml_name("PCIU"),
> + aml_int(1))); /* Device Check */
> + aml_append(method, aml_call2("DVNT", aml_name("PCID"),
> + aml_int(3))); /* Eject Request */
> + nr_notifiers++;
> + }
> }
>
> /* Notify about child bus events in any case */
> @@ -848,7 +846,7 @@ void build_append_pcihp_slots(Aml *parent_scope, PCIBus
> *bus)
> Aml *dev, *notify_method = NULL, *method;
> QObject *bsel = object_property_get_qobject(OBJECT(bus),
> ACPI_PCIHP_PROP_BSEL, NULL);
> - uint64_t bsel_val = qnum_get_uint(qobject_to(QNum, bsel));
> + uint32_t bsel_val = qnum_get_uint(qobject_to(QNum, bsel));
> qobject_unref(bsel);
>
> aml_append(parent_scope, aml_name_decl("BSEL", aml_int(bsel_val)));
> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> index f6386088b6..7ba7b38773 100644
> --- a/hw/arm/virt-acpi-build.c
> +++ b/hw/arm/virt-acpi-build.c
> @@ -1207,6 +1207,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
> VirtMachineState *vms)
> AcpiTable table = { .sig = "DSDT", .rev = 2, .oem_id = vms->oem_id,
> .oem_table_id = vms->oem_table_id };
> Aml *pci0_scope;
> + Error *local_err = NULL;
> + uint32_t bsel;
>
> acpi_table_begin(&table, table_data);
> dsdt = init_aml_allocator();
> @@ -1269,9 +1271,12 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
> VirtMachineState *vms)
>
> aml_append(pci0_scope, build_pci_bridge_edsm());
> build_append_pci_bus_devices(pci0_scope, vms->bus);
> - if (object_property_find(OBJECT(vms->bus), ACPI_PCIHP_PROP_BSEL)) {
> + bsel = object_property_get_uint(OBJECT(vms->bus), ACPI_PCIHP_PROP_BSEL,
> + &local_err);
> + if (local_err == NULL && bsel != UINT32_MAX) {
> build_append_pcihp_slots(pci0_scope, vms->bus);
> }
> + error_free(local_err);
>
> if (vms->acpi_dev) {
> bool acpi_pcihp;
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 8837b69687..cc0b6e5633 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -1198,15 +1198,20 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
> sb_scope = aml_scope("\\_SB");
> {
> Object *pci_host = acpi_get_i386_pci_host();
> + Error *local_err = NULL;
> + uint32_t bsel;
>
> if (pci_host) {
> PCIBus *pbus = PCI_HOST_BRIDGE(pci_host)->bus;
> Aml *ascope = aml_scope("PCI0");
> /* Scan all PCI buses. Generate tables to support hotplug. */
> build_append_pci_bus_devices(ascope, pbus);
> - if (object_property_find(OBJECT(pbus), ACPI_PCIHP_PROP_BSEL)) {
> + bsel = object_property_get_uint(OBJECT(pbus),
> ACPI_PCIHP_PROP_BSEL,
> + &local_err);
> + if (local_err == NULL && bsel != UINT32_MAX) {
> build_append_pcihp_slots(ascope, pbus);
> }
> + error_free(local_err);
> aml_append(sb_scope, ascope);
> }
> }
> diff --git a/hw/pci/pci.c b/hw/pci/pci.c
> index d3191609e2..e8e8a3b767 100644
> --- a/hw/pci/pci.c
> +++ b/hw/pci/pci.c
> @@ -25,6 +25,7 @@
> #include "qemu/osdep.h"
> #include "qemu/datadir.h"
> #include "qemu/units.h"
> +#include "hw/acpi/pcihp.h"
> #include "hw/core/irq.h"
> #include "hw/pci/pci.h"
> #include "hw/pci/pci_bridge.h"
> @@ -187,6 +188,8 @@ static void pci_bus_realize(BusState *qbus, Error **errp)
> bus->machine_done.notify = pcibus_machine_done;
> qemu_add_machine_init_done_notifier(&bus->machine_done);
>
> + bus->acpi_pcihp_bsel_val = UINT32_MAX;
> +
> vmstate_register_any(NULL, &vmstate_pcibus, bus);
> }
>
> @@ -302,6 +305,10 @@ static void pci_bus_class_init(ObjectClass *klass, const
> void *data)
> pbc->numa_node = pcibus_numa_node;
>
> fwgc->get_data = pci_bus_fw_cfg_gen_data;
> +
> + object_class_property_add_uint32_ptr(klass, ACPI_PCIHP_PROP_BSEL,
> + offsetof(PCIBus,
> acpi_pcihp_bsel_val),
> + OBJ_PROP_FLAG_READWRITE);
> }
>
> static const TypeInfo pci_bus_info = {
> --
> 2.43.0
>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|