PCI: define PCIBUS_MAX_DEVICES and PCI_FUNCTIONS_PER_DEVICE in pci.h
PATCH 1/4 PCI: define PCIBUS_MAX_DEVICES and PCI_FUNCTIONS_PER_DEVICE in pci.h
And update the max function number used in struct PCIBus{} to PCIBUS_MAX_FUNCTIONS = PCI_FUNCTIONS_PER_DEVICE * PCIBUS_MAX_DEVICES
TODO:
according to Avi Kivity, PCIBus.devices[] should be renamed to functions[]
--- hw/pci.c | 2 +- hw/pci.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletions(-)
hw/pci.c +1 -1
@@ -47,7 +47,7 @@ struct PCIBus {pci_hotplug_fn hotplug;DeviceState *hotplug_qdev;void *irq_opaque; -PCIDevice *devices[256 ]; +PCIDevice *devices[PCIBUS_MAX_DEVICES *PCI_FUNCTIONS_PER_DEVICE ];PCIDevice *parent_dev;target_phys_addr_t mem_base;
hw/pci.h +2 -0
@@ -17,6 +17,8 @@ struct kvm_irq_routing_entry;#define PCI_SLOT (devfn) (((devfn) >> 3) & 0x1f)#define PCI_FUNC (devfn) ((devfn) & 0x07)#define PCI_FUNC_MAX 8 +#define PCI_FUNCTIONS_PER_DEVICE 8 +#define PCIBUS_MAX_DEVICES 32/* Class, Vendor and Device IDs from Linux's pci_ids.h */ #include "pci_ids.h"
PATCH 2/4 pci init: fail qemu if devfn exceeding the max function number supported on bus
Check if devfn < PCIBUS_MAX_DEVICES * PCI_FUNCTIONS_PER_DEVICE
--- hw/pci.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
hw/pci.c +1 -0
@@ -747,6 +747,7 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,PCIConfigWriteFunc *config_write, bool is_bridge) { + assert(devfn / PCI_FUNCTIONS_PER_DEVICE < PCIBUS_MAX_DEVICES);if (devfn <0 ) {for (devfn = bus->devfn_min ; devfn <ARRAY_SIZE (bus->devices); devfn +=PCI_FUNC_MAX ) {
PATCH 3/4 Check pci slot number against PCIBUS_MAX_DEVICES in parse_pci_devfn
In reply to Ken CCIf pci addr provided from command line is bigger than 32, PCIBUS_MAX_DEVICES, return error -EINVAL.
32 << 3 | 7 == 256 (PCIBUS_MAX_FUNCTIONS) PCIBUS_MAX_FUNCTIONS = PCIBUS_MAX_DEVICES * PCI_FUNCTIONS_PER_DEVICE
--- hw/qdev-properties.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-)
hw/qdev-properties.c +3 -1
@@ -1,5 +1,5 @@#include "net.h" -#include "qdev.h" +#include "pci.h" #include "qerror.h" void *qdev_get_prop_ptr (DeviceState *dev,Property *prop)
@@ -514,6 +514,8 @@ static int parse_pci_devfn(DeviceState *dev, Property *prop, const char *str)return -EINVAL ; } } +if (slot >=PCIBUS_MAX_DEVICES ) +return -EINVAL ;if (str[n] !='\0' )return -EINVAL ;if (fn >7 )
PATCH 4/4 Rename PCI_FUNC_MAX to PCI_FUNCTIONS_PER_DEVICES in pci.[ch]
In reply to Ken CCPCI_FUNC_MAX is introduced by 6eab3de16d36c48a983366b09d0a0029a5260bc3
and6fa84913eccec4266a27c81ae88465f6790742b9
which should be safe to rename to PCI_FUNCTIONS_PER_DEVICES.
--- hw/pci.c | 4 ++-- hw/pci.h | 1 - 2 files changed, 2 insertions(+), 3 deletions(-)
hw/pci.c +2 -2
@@ -711,7 +711,7 @@ static int pci_init_multifunction(PCIBus *bus, PCIDevice *dev)return 0 ; }/* function 0 indicates single function, so function > 0 must be NULL */ -for (func =1 ; func <PCI_FUNC_MAX ; ++func) { +for (func =1 ; func <PCI_FUNCTIONS_PER_DEVICE ; ++func) {if (bus->devices[PCI_DEVFN (slot, func)]) { error_report("PCI: %x.0 indicates single function, " "but %x.%x is already populated.",
@@ -750,7 +750,7 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,assert (devfn /PCI_FUNCTIONS_PER_DEVICE <PCIBUS_MAX_DEVICES );if (devfn <0 ) {for (devfn = bus->devfn_min ; devfn <ARRAY_SIZE (bus->devices); - devfn +=PCI_FUNC_MAX ) { + devfn +=PCI_FUNCTIONS_PER_DEVICE ) {if (!bus->devices[devfn]) goto found; }
hw/pci.h +0 -1
@@ -16,7 +16,6 @@ struct kvm_irq_routing_entry;#define PCI_DEVFN (slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))#define PCI_SLOT (devfn) (((devfn) >> 3) & 0x1f)#define PCI_FUNC (devfn) ((devfn) & 0x07) -#define PCI_FUNC_MAX 8#define PCI_FUNCTIONS_PER_DEVICE 8#define PCIBUS_MAX_DEVICES 32
Quoted 30 lines · Ken CC
And update the max function number used in struct PCIBus{} to
PCIBUS_MAX_FUNCTIONS=PCI_FUNCTIONS_PER_DEVICE*PCIBUS_MAX_DEVICESTODO:
according to Avi Kivity, PCIBus.devices[] should be renamed to functions[]Signed-off-by Ken CC <[email protected]>--- hw/pci.c | 2 +- hw/pci.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletions(-)hw/pci.c +1
-1@@ -47,7 +47,7 @@ struct PCIBus {pci_hotplug_fn hotplug;DeviceState *hotplug_qdev;void *irq_opaque; -PCIDevice *devices[256 ]; +PCIDevice *devices[PCIBUS_MAX_DEVICES *PCI_FUNCTIONS_PER_DEVICE ];PCIDevice *parent_dev;target_phys_addr_t mem_base;hw/pci.h +0
-0
hw/pci.h struct kvm_irq_routing_entry; · line 21
Quoted 5 lines
hw/pci.h +2
-0@@ -17,6 +17,8 @@ struct kvm_irq_routing_entry;#define PCI_SLOT (devfn) (((devfn) >> 3) & 0x1f)#define PCI_FUNC (devfn) ((devfn) & 0x07)#define PCI_FUNC_MAX 8 +#define PCI_FUNCTIONS_PER_DEVICE 8 +#define PCIBUS_MAX_DEVICES 32
PCI_FUNCTIONS_PER_DEVICE is same as PCI_FUNC_MAX. Why do we need another macro?
Quoted 2 lines
hw/pci.h +0
-0/* Class, Vendor and Device IDs from Linux's pci_ids.h */ #include "pci_ids.h"
Re: [PATCH 2/4] pci init: fail qemu if devfn exceeding the max function number supported on bus
In reply to Ken CCQuoted 12 lines · Ken CC
Check if devfn <
PCIBUS_MAX_DEVICES*PCI_FUNCTIONS_PER_DEVICESigned-off-by Ken CC <[email protected]>--- hw/pci.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)hw/pci.c +0
-0
hw/pci.c static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus, · line 750
Quoted 4 lines
hw/pci.c +1
-0@@ -747,6 +747,7 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,PCIConfigWriteFunc *config_write, bool is_bridge) { + assert(devfn / PCI_FUNCTIONS_PER_DEVICE < PCIBUS_MAX_DEVICES);
I guess it'll happen to work even for < 0, but it might be obvious to only do this in >= 0 case.
Just remove the 'else' and stick the assert there.
Quoted 3 lines
hw/pci.c +0
-0if (devfn <0 ) {for (devfn = bus->devfn_min ; devfn <ARRAY_SIZE (bus->devices); devfn +=PCI_FUNC_MAX ) {
Re: [PATCH 3/4] Check pci slot number against PCIBUS_MAX_DEVICES in parse_pci_devfn
In reply to Ken CCQuoted 5 lines · Ken CC
If pci addr provided from command line is bigger than 32,
PCIBUS_MAX_DEVICES, return error-EINVAL.32 << 3 | 7 == 256 (
PCIBUS_MAX_FUNCTIONS)PCIBUS_MAX_FUNCTIONS=PCIBUS_MAX_DEVICES*PCI_FUNCTIONS_PER_DEVICE
Not really sure what these equations mean, the patch makes sense though, we should validate input.
Quoted 25 lines
Signed-off-by Ken CC <[email protected]>--- hw/qdev-properties.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-)hw/qdev-properties.c +3
-1@@ -1,5 +1,5 @@#include "net.h" -#include "qdev.h" +#include "pci.h" #include "qerror.h" void *qdev_get_prop_ptr (DeviceState *dev,Property *prop)@@ -514,6 +514,8 @@ static int parse_pci_devfn(DeviceState *dev, Property *prop, const char *str)return -EINVAL ; } } +if (slot >=PCIBUS_MAX_DEVICES ) +return -EINVAL ;if (str[n] !='\0' )return -EINVAL ;if (fn >7 )
Re: [PATCH 4/4] Rename PCI_FUNC_MAX to PCI_FUNCTIONS_PER_DEVICES in pci.[ch]
In reply to Ken CCQuoted 7 lines · Ken CC
PCI_FUNC_MAXis introduced by6eab3de16d36c48a983366b09d0a0029a5260bc3
and6fa84913eccec4266a27c81ae88465f6790742b9
which should be safe to rename toPCI_FUNCTIONS_PER_DEVICES.Signed-off-by Ken CC <[email protected]>
I liked the shorter name better ...
Quoted 39 lines
--- hw/pci.c | 4 ++-- hw/pci.h | 1 - 2 files changed, 2 insertions(+), 3 deletions(-)hw/pci.c +2
-2@@ -711,7 +711,7 @@ static int pci_init_multifunction(PCIBus *bus, PCIDevice *dev)return 0 ; }/* function 0 indicates single function, so function > 0 must be NULL */ -for (func =1 ; func <PCI_FUNC_MAX ; ++func) { +for (func =1 ; func <PCI_FUNCTIONS_PER_DEVICE ; ++func) {if (bus->devices[PCI_DEVFN (slot, func)]) { error_report("PCI: %x.0 indicates single function, " "but %x.%x is already populated.",@@ -750,7 +750,7 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,assert (devfn /PCI_FUNCTIONS_PER_DEVICE <PCIBUS_MAX_DEVICES );if (devfn <0 ) {for (devfn = bus->devfn_min ; devfn <ARRAY_SIZE (bus->devices); - devfn +=PCI_FUNC_MAX ) { + devfn +=PCI_FUNCTIONS_PER_DEVICE ) {if (!bus->devices[devfn]) goto found; }hw/pci.h +0
-1@@ -16,7 +16,6 @@ struct kvm_irq_routing_entry;#define PCI_DEVFN (slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))#define PCI_SLOT (devfn) (((devfn) >> 3) & 0x1f)#define PCI_FUNC (devfn) ((devfn) & 0x07) -#define PCI_FUNC_MAX 8#define PCI_FUNCTIONS_PER_DEVICE 8#define PCIBUS_MAX_DEVICES 32