mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-08 02:03:56 -06:00
pci: add reserved slot check to do_pci_register_device()
Add a new slot_reserved_mask bitmask to PCIBus indicating whether or not each PCI slot on the bus is reserved. Ensure that it is initialised to zero to maintain the existing behaviour that all slots are available by default, and add the additional check with appropriate error reporting to do_pci_register_device(). Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Marcel Apfelbaum <marcel@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
9b717a3a13
commit
8b8849844f
2 changed files with 16 additions and 3 deletions
18
hw/pci/pci.c
18
hw/pci/pci.c
|
@ -373,6 +373,7 @@ static void pci_bus_init(PCIBus *bus, DeviceState *parent,
|
|||
{
|
||||
assert(PCI_FUNC(devfn_min) == 0);
|
||||
bus->devfn_min = devfn_min;
|
||||
bus->slot_reserved_mask = 0x0;
|
||||
bus->address_space_mem = address_space_mem;
|
||||
bus->address_space_io = address_space_io;
|
||||
|
||||
|
@ -958,6 +959,11 @@ static bool pci_bus_devfn_available(PCIBus *bus, int devfn)
|
|||
return !(bus->devices[devfn]);
|
||||
}
|
||||
|
||||
static bool pci_bus_devfn_reserved(PCIBus *bus, int devfn)
|
||||
{
|
||||
return bus->slot_reserved_mask & (1UL << PCI_SLOT(devfn));
|
||||
}
|
||||
|
||||
/* -1 for devfn means auto assign */
|
||||
static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
|
||||
const char *name, int devfn,
|
||||
|
@ -981,14 +987,20 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
|
|||
if (devfn < 0) {
|
||||
for(devfn = bus->devfn_min ; devfn < ARRAY_SIZE(bus->devices);
|
||||
devfn += PCI_FUNC_MAX) {
|
||||
if (pci_bus_devfn_available(bus, devfn)) {
|
||||
if (pci_bus_devfn_available(bus, devfn) &&
|
||||
!pci_bus_devfn_reserved(bus, devfn)) {
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
error_setg(errp, "PCI: no slot/function available for %s, all in use",
|
||||
name);
|
||||
error_setg(errp, "PCI: no slot/function available for %s, all in use "
|
||||
"or reserved", name);
|
||||
return NULL;
|
||||
found: ;
|
||||
} else if (pci_bus_devfn_reserved(bus, devfn)) {
|
||||
error_setg(errp, "PCI: slot %d function %d not available for %s,"
|
||||
" reserved",
|
||||
PCI_SLOT(devfn), PCI_FUNC(devfn), name);
|
||||
return NULL;
|
||||
} else if (!pci_bus_devfn_available(bus, devfn)) {
|
||||
error_setg(errp, "PCI: slot %d function %d not available for %s,"
|
||||
" in use by %s",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue