mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-01 14:53:54 -06:00
pci: fix 'hotplugglable' property behavior
Currently the property may flip its state during VM bring up or just doesn't work as the name implies. In particular with PCIE root port that has 'hotplug={on|off}' property, and when it's turned off, one would expect 'hotpluggable' == false for any devices attached to it. Which is not the case since qbus_is_hotpluggable() used by the property just checks for presence of any hotplug_handler set on bus. The problem is that name BusState::hotplug_handler from its inception is misnomer, as it handles not only hotplug but also in many cases coldplug as well (i.e. generic wiring interface), and it's fine to have hotplug_handler set on bus while it doesn't support hotplug (ex. pcie-slot with hotplug=off). Another case of root port flipping 'hotpluggable' state when ACPI PCI hotplug is enabled in this case root port with 'hotplug=off' starts as hotpluggable and then later on, pcihp hotplug_handler clears hotplug_handler explicitly after checking root port's 'hotplug' property. So root-port hotpluggablity check sort of works if pcihp is enabled but is broken if pcihp is disabled. One way to deal with the issue is to ask hotplug_handler if bus it controls is hotpluggable or not. To do that add is_hotpluggable_bus() hook to HotplugHandler interface and use it in 'hotpluggable' property + teach pcie-slot to actually look into 'hotplug' property state before deciding if bus is hotpluggable. Signed-off-by: Igor Mammedov <imammedo@redhat.com> Message-Id: <20230302161543.286002-13-imammedo@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
f40e6a4cc1
commit
ceefa0b746
3 changed files with 22 additions and 1 deletions
|
@ -812,7 +812,18 @@ void qbus_set_bus_hotplug_handler(BusState *bus);
|
|||
|
||||
static inline bool qbus_is_hotpluggable(BusState *bus)
|
||||
{
|
||||
return bus->hotplug_handler;
|
||||
HotplugHandler *plug_handler = bus->hotplug_handler;
|
||||
bool ret = !!plug_handler;
|
||||
|
||||
if (plug_handler) {
|
||||
HotplugHandlerClass *hdc;
|
||||
|
||||
hdc = HOTPLUG_HANDLER_GET_CLASS(plug_handler);
|
||||
if (hdc->is_hotpluggable_bus) {
|
||||
ret = hdc->is_hotpluggable_bus(plug_handler, bus);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue