pci: Cleanups & preparations for KVM device assignment
cover pci: Cleanups & preparations for KVM device assignment
Besides some smaller cleanups, this series has two main topics:
The first is the already posted PCI IRQ routing lookup and notifier. The lookup has been based on the cached routing Michael suggested also for emulated devices. However, this still introduces a new callback and keeps the bus irq_count untouched due to the vmstate complications when changing it.
The second half refactors PCI device address parsing, introducing an universal parsing function. It is then used to provide a new qdev property that accepts fully qualified PCI addresses (domain:bus:device. function).
These two major changes will help refactoring PCI device assignment in qemu-kvm in order to upstream it soon. But also the upcoming VFIO-based assignment should be able to benefit.
Jan Kiszka (13):
pci: Refactor pci_change_irq_level
pci: Fold pci_bus_new_inplace into pci_bus_new
pci: Introduce cached device INTx routing
pci: Rename map_irq to route_pin
pci: Add pci_device_route_intx_to_irq
pci: Add INTx routing notifier
pci: Make domain and bus unsigned in pci_read_devaddr
pci: Export pci_parse_devaddr instead of pci_read_devaddr
pci: Introduce and apply PCIDeviceAddress
pci: Fix coding style of pci_parse_devaddr
Move pci_parse_devaddr to qdev-properties
qdev-properties: Use qemu_parse_pci_devaddr for pci-devfn property
qdev-properties: Add pci-devaddr property
hw/alpha_sys.h | 2 +- hw/alpha_typhoon.c | 4 +- hw/apb_pci.c | 6 +- hw/bonito.c | 2 +- hw/dec_pci.c | 2 +- hw/grackle_pci.c | 1 + hw/gt64xxx.c | 1 + hw/ioh3420.c | 5 +- hw/ioh3420.h | 3 +- hw/pci-hotplug.c | 33 +++++-- hw/pci.c | 212 ++++++++++++++++++++++------------------------- hw/pci.h | 40 +++++++--- hw/pci_bridge.c | 18 +++- hw/pci_bridge.h | 4 +- hw/pci_bridge_dev.c | 7 +- hw/pci_internals.h | 5 +- hw/piix_pci.c | 25 +++++- hw/ppc4xx_pci.c | 2 +- hw/ppce500_pci.c | 2 +- hw/prep_pci.c | 2 +- hw/qdev-properties.c | 142 ++++++++++++++++++++++++++++---- hw/qdev.h | 10 ++ hw/sh_pci.c | 2 +- hw/spapr_pci.c | 2 +- hw/unin_pci.c | 4 +- hw/versatile_pci.c | 2 +- hw/xio3130_downstream.c | 5 +- hw/xio3130_downstream.h | 3 +- hw/xio3130_upstream.c | 5 +- hw/xio3130_upstream.h | 3 +- qemu-common.h | 7 ++ 31 files changed, 371 insertions(+), 190 deletions(-)
Signature · 1 line
1.7.3.4
PATCH 1/13 pci: Refactor pci_change_irq_level
Align the bus traversal in pci_change_irq_level to other functions. They use PCIBus:parent_dev to detect the root.
--- hw/pci.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-)
hw/pci.c +4 -4
@@ -115,13 +115,13 @@ static inline void pci_set_irq_state(PCIDevice *d, int irq_num, int level)static void pci_change_irq_level (PCIDevice *pci_dev,int irq_num,int change) {PCIBus *bus; -for (;;) { + +do { bus = pci_dev->bus; irq_num = bus->map_irq (pci_dev, irq_num); -if (bus->set_irq) -break ; pci_dev = bus->parent_dev; - } + }while (pci_dev); + bus->irq_count[irq_num] += change; bus->set_irq (bus->irq_opaque, irq_num, bus->irq_count[irq_num] !=0 ); }
Signature · 1 line
1.7.3.4
Michael S. Tsirkin
AppliedRe: [Qemu-devel] [PATCH 01/13] pci: Refactor pci_change_irq_level
Quoted 4 lines · Jan Kiszka
Align the bus traversal in
pci_change_irq_levelto other functions. They use PCIBus:parent_dev to detect the root.Signed-off-by Jan Kiszka <[email protected]>
Applied.
Quoted 28 lines
--- hw/pci.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-)hw/pci.c +4
-4@@ -115,13 +115,13 @@ static inline void pci_set_irq_state(PCIDevice *d, int irq_num, int level)static void pci_change_irq_level (PCIDevice *pci_dev,int irq_num,int change) {PCIBus *bus; -for (;;) { + +do { bus = pci_dev->bus; irq_num = bus->map_irq (pci_dev, irq_num); -if (bus->set_irq) -break ; pci_dev = bus->parent_dev; - } + }while (pci_dev); + bus->irq_count[irq_num] += change; bus->set_irq (bus->irq_opaque, irq_num, bus->irq_count[irq_num] !=0 ); }Signature · 1 line
1.7.3.4
PATCH 2/13 pci: Fold pci_bus_new_inplace into pci_bus_new
In reply to Jan KiszkaThere are no external users for this function.
--- hw/pci.c | 29 +++++++++++------------------ hw/pci.h | 5 ----- 2 files changed, 11 insertions(+), 23 deletions(-)
hw/pci.c +11 -18
@@ -259,36 +259,29 @@ int pci_find_domain(const PCIBus *bus)return -1 ; } -void pci_bus_new_inplace (PCIBus *bus,DeviceState *parent, -const char *name, -MemoryRegion *address_space_mem, -MemoryRegion *address_space_io, -uint8_t devfn_min) +PCIBus *pci_bus_new (DeviceState *parent,const char *name, +MemoryRegion *address_space_mem, +MemoryRegion *address_space_io, +uint8_t devfn_min) { -qbus_create_inplace (&bus->qbus, &pci_bus_info, parent, name); +PCIBus *bus; + + bus =g_malloc0 (sizeof (*bus)); + bus->qbus.qdev_allocated =1 ; +assert (PCI_FUNC (devfn_min) ==0 ); bus->devfn_min = devfn_min; bus->address_space_mem = address_space_mem; bus->address_space_io = address_space_io; +qbus_create_inplace (&bus->qbus, &pci_bus_info, parent, name); +/* host bridge */ QLIST_INIT (&bus->child);pci_host_bus_register (0 , bus);/* for now only pci domain 0 is supported */ vmstate_register (NULL ,-1 , &vmstate_pcibus, bus); -} - -PCIBus *pci_bus_new (DeviceState *parent,const char *name, -MemoryRegion *address_space_mem, -MemoryRegion *address_space_io, -uint8_t devfn_min) -{ -PCIBus *bus; - bus =g_malloc0 (sizeof (*bus)); - bus->qbus.qdev_allocated =1 ; -pci_bus_new_inplace (bus, parent, name, address_space_mem, - address_space_io, devfn_min);return bus; }
hw/pci.h +0 -5
@@ -285,11 +285,6 @@ typedef enum {typedef int (*pci_hotplug_fn )(DeviceState *qdev,PCIDevice *pci_dev,PCIHotplugState state); -void pci_bus_new_inplace (PCIBus *bus,DeviceState *parent, -const char *name, -MemoryRegion *address_space_mem, -MemoryRegion *address_space_io, -uint8_t devfn_min); PCIBus *pci_bus_new(DeviceState *parent, const char *name, MemoryRegion *address_space_mem, MemoryRegion *address_space_io,
Signature · 1 line
1.7.3.4
Andreas Färber
NAKRe: [Qemu-devel] [PATCH 02/13] pci: Fold pci_bus_new_inplace into pci_bus_new
Am 04.06.2012 10:52, schrieb Jan Kiszka:
Quoted 3 lines
There are no external users for this function.
Signed-off-by Jan Kiszka <[email protected]>
Nack, please take a look at my recent prep_pci RFC series. Instead of dropping _inplace we need to convert all PCI host controllers to initialize the bus in-place for the QOM realize model to work.
Andreas
Signature · 2 lines
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [PATCH 02/13] pci: Fold pci_bus_new_inplace into pci_bus_new
Quoted 8 lines · Andreas Färber
Am 04.06.2012 10:52, schrieb Jan Kiszka:
Quoted 3 lines
There are no external users for this function.
Signed-off-by Jan Kiszka <[email protected]>Nack, please take a look at my recent
prep_pciRFC series. Instead of dropping_inplacewe need to convert all PCI host controllers to initialize the bus in-place for the QOM realize model to work.
No problem, I can drop this patch. Was just an observation based on the in-tree history.
Jan
PATCH 3/13 pci: Introduce cached device INTx routing
In reply to Jan KiszkaBased on the original version by Michael Tsirkin: Instead of traversing the PCI bus hierarchy from a device to the host bridge, cache this path in PCIDevice and use it directly on interrupt delivery. This will specifically pay off with more complex topologies than the current single host bus.
--- hw/pci.c | 53 ++++++++++++++++++++++++++++++++++++++++++++--------- hw/pci.h | 4 ++++ 2 files changed, 48 insertions(+), 9 deletions(-)
hw/pci.c +44 -9
@@ -68,6 +68,8 @@ static void pci_update_mappings(PCIDevice *d);static void pci_set_irq (void *opaque,int irq_num,int level);static int pci_add_option_rom (PCIDevice *pdev,bool is_default_rom);static void pci_del_option_rom (PCIDevice *pdev); +static void pci_for_each_device_under_bus (PCIBus *bus, +void (*fn)(PCIBus *b,PCIDevice *d));static uint16_t pci_default_sub_vendor_id =PCI_SUBVENDOR_ID_REDHAT_QUMRANET ;static uint16_t pci_default_sub_device_id =PCI_SUBDEVICE_ID_QEMU ;
@@ -112,18 +114,49 @@ static inline void pci_set_irq_state(PCIDevice *d, int irq_num, int level) d->irq_state |= level << irq_num; } -static void pci_change_irq_level (PCIDevice *pci_dev,int irq_num,int change) +static void pci_set_device_intx_routing (PCIBus *bus,PCIDevice *dev) { -PCIBus *bus; +int pin, output_pin; +PCIDevice *pci_dev; + +/* We might be too early, i.e. before pci_bus_irqs was called. +* We will be called again when this happened. */ +if (!bus->map_irq) { +return ; + } + +for (pin =0 ; pin <PCI_NUM_PINS ; pin++) { + pci_dev = dev; + output_pin = pin; +do { + bus = pci_dev->bus; + output_pin = bus->map_irq (pci_dev, output_pin); + pci_dev = bus->parent_dev; + }while (pci_dev); + + dev->host_intx_pin[pin] = output_pin; + dev->host_bus = bus; + } +} + +static void pci_set_bus_intx_routing (PCIBus *bus) +{ +PCIBus *sec; + +pci_for_each_device_under_bus (bus, pci_set_device_intx_routing); -do { - bus = pci_dev->bus; - irq_num = bus->map_irq (pci_dev, irq_num); - pci_dev = bus->parent_dev; - }while (pci_dev); + QLIST_FOREACH(sec, &bus->child, sibling) { +pci_set_bus_intx_routing (sec); + } +} + +static void pci_change_irq_level (PCIDevice *dev,int pin,int change) +{ +PCIBus *bus = dev->host_bus; +int output_pin = dev->host_intx_pin[pin]; - bus->irq_count[irq_num] += change; - bus->set_irq (bus->irq_opaque, irq_num, bus->irq_count[irq_num] !=0 ); + bus->irq_count[output_pin] += change; + bus->set_irq (bus->irq_opaque, output_pin, bus->irq_count[output_pin] !=0 ); }int pci_bus_get_irq_level (PCIBus *bus,int irq_num)
@@ -293,6 +326,7 @@ void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, bus->irq_opaque = irq_opaque; bus->nirq = nirq; bus->irq_count =g_malloc0 (nirq *sizeof (bus->irq_count[0 ])); +pci_set_bus_intx_routing (bus); }void pci_bus_hotplug (PCIBus *bus,pci_hotplug_fn hotplug,DeviceState *qdev)
@@ -798,6 +832,7 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus, bus->devices[devfn] = pci_dev; pci_dev->irq =qemu_allocate_irqs (pci_set_irq, pci_dev,PCI_NUM_PINS ); pci_dev->version_id =2 ;/* Current pci device vmstate version */ +pci_set_device_intx_routing (bus, pci_dev);return pci_dev; }
hw/pci.h +4 -0
@@ -211,6 +211,10 @@ struct PCIDevice {/* Current IRQ levels. Used internally by the generic PCI code. */ uint8_t irq_state; +/* Used internally by PCI code to cache the interrupt routing */ +PCIBus *host_bus; +int host_intx_pin[PCI_NUM_PINS ]; +/* Capability bits */ uint32_t cap_present;
Signature · 1 line
1.7.3.4
Re: [Qemu-devel] [PATCH 03/13] pci: Introduce cached device INTx routing
Quoted 7 lines · Jan Kiszka
Based on the original version by Michael Tsirkin: Instead of traversing the PCI bus hierarchy from a device to the host bridge, cache this path in PCIDevice and use it directly on interrupt delivery. This will specifically pay off with more complex topologies than the current single host bus.
Signed-off-by Jan Kiszka <[email protected]>
OK, I applied this. I still think we should go the extra mile and cache the final IRQ not just the root intx. But that can be a patch on top.
Quoted 98 lines
--- hw/pci.c | 53 ++++++++++++++++++++++++++++++++++++++++++++--------- hw/pci.h | 4 ++++ 2 files changed, 48 insertions(+), 9 deletions(-)hw/pci.c +44
-9@@ -68,6 +68,8 @@ static void pci_update_mappings(PCIDevice *d);static void pci_set_irq (void *opaque,int irq_num,int level);static int pci_add_option_rom (PCIDevice *pdev,bool is_default_rom);static void pci_del_option_rom (PCIDevice *pdev); +static void pci_for_each_device_under_bus (PCIBus *bus, +void (*fn)(PCIBus *b,PCIDevice *d));static uint16_t pci_default_sub_vendor_id =PCI_SUBVENDOR_ID_REDHAT_QUMRANET ;static uint16_t pci_default_sub_device_id =PCI_SUBDEVICE_ID_QEMU ;@@ -112,18 +114,49 @@ static inline void pci_set_irq_state(PCIDevice *d, int irq_num, int level) d->irq_state |= level << irq_num; } -static void pci_change_irq_level (PCIDevice *pci_dev,int irq_num,int change) +static void pci_set_device_intx_routing (PCIBus *bus,PCIDevice *dev) { -PCIBus *bus; +int pin, output_pin; +PCIDevice *pci_dev; + +/* We might be too early, i.e. before pci_bus_irqs was called. +* We will be called again when this happened. */ +if (!bus->map_irq) { +return ; + } + +for (pin =0 ; pin <PCI_NUM_PINS ; pin++) { + pci_dev = dev; + output_pin = pin; +do { + bus = pci_dev->bus; + output_pin = bus->map_irq (pci_dev, output_pin); + pci_dev = bus->parent_dev; + }while (pci_dev); + + dev->host_intx_pin[pin] = output_pin; + dev->host_bus = bus; + } +} + +static void pci_set_bus_intx_routing (PCIBus *bus) +{ +PCIBus *sec; + +pci_for_each_device_under_bus (bus, pci_set_device_intx_routing); -do { - bus = pci_dev->bus; - irq_num = bus->map_irq (pci_dev, irq_num); - pci_dev = bus->parent_dev; - }while (pci_dev); + QLIST_FOREACH(sec, &bus->child, sibling) { +pci_set_bus_intx_routing (sec); + } +} + +static void pci_change_irq_level (PCIDevice *dev,int pin,int change) +{ +PCIBus *bus = dev->host_bus; +int output_pin = dev->host_intx_pin[pin]; - bus->irq_count[irq_num] += change; - bus->set_irq (bus->irq_opaque, irq_num, bus->irq_count[irq_num] !=0 ); + bus->irq_count[output_pin] += change; + bus->set_irq (bus->irq_opaque, output_pin, bus->irq_count[output_pin] !=0 ); }int pci_bus_get_irq_level (PCIBus *bus,int irq_num)@@ -293,6 +326,7 @@ void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, bus->irq_opaque = irq_opaque; bus->nirq = nirq; bus->irq_count =g_malloc0 (nirq *sizeof (bus->irq_count[0 ])); +pci_set_bus_intx_routing (bus); }void pci_bus_hotplug (PCIBus *bus,pci_hotplug_fn hotplug,DeviceState *qdev)@@ -798,6 +832,7 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus, bus->devices[devfn] = pci_dev; pci_dev->irq =qemu_allocate_irqs (pci_set_irq, pci_dev,PCI_NUM_PINS ); pci_dev->version_id =2 ;/* Current pci device vmstate version */ +pci_set_device_intx_routing (bus, pci_dev);return pci_dev; }hw/pci.h +0
-0
hw/pci.h struct PCIDevice { · line 217
Quoted 7 lines
hw/pci.h +4
-0@@ -211,6 +211,10 @@ struct PCIDevice {/* Current IRQ levels. Used internally by the generic PCI code. */ uint8_t irq_state; +/* Used internally by PCI code to cache the interrupt routing */ +PCIBus *host_bus; +int host_intx_pin[PCI_NUM_PINS ]; +
A better name would be root_XXXX: host is an overloaded term. I applied such a patch.
Quoted 5 lines
hw/pci.h +0
-0/* Capability bits */ uint32_t cap_present;Signature · 1 line
1.7.3.4
PATCH 4/13 pci: Rename map_irq to route_pin
In reply to Jan KiszkaTo avoid confusion with the board-level IRQ the host bridge triggers on output, rename the per-bridge routing function for the INTx pins to pci_route_pin_fn. Also adjust variable names of that type. And rename pci_bridge_map_irq to pci_bridge_prepare, which better reflects the job of that function.
--- hw/alpha_sys.h | 2 +- hw/alpha_typhoon.c | 2 +- hw/apb_pci.c | 4 ++-- hw/dec_pci.c | 2 +- hw/ioh3420.c | 5 +++-- hw/ioh3420.h | 3 ++- hw/pci.c | 14 ++++++++------ hw/pci.h | 8 +++++--- hw/pci_bridge.c | 10 +++++----- hw/pci_bridge.h | 4 ++-- hw/pci_bridge_dev.c | 7 ++++--- hw/pci_internals.h | 4 ++-- hw/xio3130_downstream.c | 5 +++-- hw/xio3130_downstream.h | 3 ++- hw/xio3130_upstream.c | 5 +++-- hw/xio3130_upstream.h | 3 ++- 16 files changed, 46 insertions(+), 35 deletions(-)
hw/alpha_sys.h +1 -1
@@ -12,7 +12,7 @@PCIBus *typhoon_init (ram_addr_t ,ISABus **,qemu_irq *,CPUAlphaState *[4 ], -pci_map_irq_fn ); +pci_route_pin_fn );/* alpha_pci.c. */ extern const MemoryRegionOps alpha_pci_bw_io_ops;
hw/alpha_typhoon.c +1 -1
@@ -693,7 +693,7 @@ static void typhoon_alarm_timer(void *opaque)PCIBus *typhoon_init (ram_addr_t ram_size,ISABus **isa_bus,qemu_irq *p_rtc_irq, -CPUAlphaState *cpus[4 ],pci_map_irq_fn sys_map_irq) +CPUAlphaState *cpus[4 ],pci_route_pin_fn sys_map_irq) {const uint64_t MB =1024 *1024 ;const uint64_t GB =1024 *MB ;
hw/apb_pci.c +2 -2
@@ -392,7 +392,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base, pci_dev =pci_create_multifunction (d->bus,PCI_DEVFN (1 ,0 ), true,"pbm-bridge" ); br =DO_UPCAST (PCIBridge, dev, pci_dev); -pci_bridge_map_irq (br,"Advanced PCI Bus secondary bridge 1" , +pci_bridge_prepare (br,"Advanced PCI Bus secondary bridge 1" , pci_apb_map_irq);qdev_init_nofail (&pci_dev->qdev); *bus2 =pci_bridge_get_sec_bus (br);
@@ -400,7 +400,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base, pci_dev =pci_create_multifunction (d->bus,PCI_DEVFN (1 ,1 ), true,"pbm-bridge" ); br =DO_UPCAST (PCIBridge, dev, pci_dev); -pci_bridge_map_irq (br,"Advanced PCI Bus secondary bridge 2" , +pci_bridge_prepare (br,"Advanced PCI Bus secondary bridge 2" , pci_apb_map_irq);qdev_init_nofail (&pci_dev->qdev); *bus3 =pci_bridge_get_sec_bus (br);
hw/dec_pci.c +1 -1
@@ -81,7 +81,7 @@ PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn) dev =pci_create_multifunction (parent_bus, devfn, false,"dec-21154-p2p-bridge" ); br =DO_UPCAST (PCIBridge, dev, dev); -pci_bridge_map_irq (br,"DEC 21154 PCI-PCI bridge" , dec_map_irq); +pci_bridge_prepare (br,"DEC 21154 PCI-PCI bridge" , dec_map_irq);qdev_init_nofail (&dev->qdev);return pci_bridge_get_sec_bus (br); }
hw/ioh3420.c +3 -2
@@ -164,7 +164,8 @@ static int ioh3420_exitfn(PCIDevice *d) }PCIESlot *ioh3420_init (PCIBus *bus,int devfn,bool multifunction, -const char *bus_name,pci_map_irq_fn map_irq, +const char *bus_name, +pci_route_pin_fn route_intx_pin,uint8_t port,uint8_t chassis,uint16_t slot) {PCIDevice *d;
@@ -178,7 +179,7 @@ PCIESlot *ioh3420_init(PCIBus *bus, int devfn, bool multifunction, br =DO_UPCAST (PCIBridge, dev, d); qdev = &br->dev.qdev; -pci_bridge_map_irq (br, bus_name, map_irq); +pci_bridge_prepare (br, bus_name, route_intx_pin);qdev_prop_set_uint8 (qdev,"port" , port);qdev_prop_set_uint8 (qdev,"chassis" , chassis);qdev_prop_set_uint16 (qdev,"slot" , slot);
hw/ioh3420.h +2 -1
@@ -4,7 +4,8 @@#include "pcie_port.h" PCIESlot *ioh3420_init (PCIBus *bus,int devfn,bool multifunction, -const char *bus_name,pci_map_irq_fn map_irq, +const char *bus_name, +pci_route_pin_fn route_intx_pin,uint8_t port,uint8_t chassis,uint16_t slot);#endif /* QEMU_IOH3420_H */
hw/pci.c +8 -6
@@ -121,7 +121,7 @@ static void pci_set_device_intx_routing(PCIBus *bus, PCIDevice *dev)/* We might be too early, i.e. before pci_bus_irqs was called. * We will be called again when this happened. */ -if (!bus->map_irq) { +if (!bus->route_intx_pin) {return ; }
@@ -130,7 +130,7 @@ static void pci_set_device_intx_routing(PCIBus *bus, PCIDevice *dev) output_pin = pin;do { bus = pci_dev->bus; - output_pin = bus->map_irq (pci_dev, output_pin); + output_pin = bus->route_intx_pin (pci_dev, output_pin); pci_dev = bus->parent_dev; }while (pci_dev);
@@ -318,11 +318,12 @@ PCIBus *pci_bus_new(DeviceState *parent, const char *name,return bus; } -void pci_bus_irqs (PCIBus *bus,pci_set_irq_fn set_irq,pci_map_irq_fn map_irq, +void pci_bus_irqs (PCIBus *bus,pci_set_irq_fn set_irq, +pci_route_pin_fn route_intx_pin,void *irq_opaque,int nirq) { bus->set_irq = set_irq; - bus->map_irq = map_irq; + bus->route_intx_pin = route_intx_pin; bus->irq_opaque = irq_opaque; bus->nirq = nirq; bus->irq_count =g_malloc0 (nirq *sizeof (bus->irq_count[0 ]));
@@ -337,7 +338,8 @@ void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug, DeviceState *qdev) } PCIBus *pci_register_bus(DeviceState *parent, const char *name, - pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, + pci_set_irq_fn set_irq, + pci_route_pin_fn route_intx_pin, void *irq_opaque, MemoryRegion *address_space_mem, MemoryRegion *address_space_io,
@@ -347,7 +349,7 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name, bus =pci_bus_new (parent, name, address_space_mem, address_space_io, devfn_min); -pci_bus_irqs (bus, set_irq, map_irq, irq_opaque, nirq); +pci_bus_irqs (bus, set_irq, route_intx_pin, irq_opaque, nirq);return bus; }
hw/pci.h +5 -3
@@ -279,7 +279,7 @@ MemoryRegion *pci_address_space(PCIDevice *dev);MemoryRegion *pci_address_space_io (PCIDevice *dev);typedef void (*pci_set_irq_fn )(void *opaque,int irq_num,int level); -typedef int (*pci_map_irq_fn )(PCIDevice *pci_dev,int irq_num); +typedef int (*pci_route_pin_fn )(PCIDevice *pci_dev,int pin); typedef enum { PCI_HOTPLUG_DISABLED,
@@ -293,12 +293,14 @@ PCIBus *pci_bus_new(DeviceState *parent, const char *name, MemoryRegion *address_space_mem, MemoryRegion *address_space_io, uint8_t devfn_min); -void pci_bus_irqs (PCIBus *bus,pci_set_irq_fn set_irq,pci_map_irq_fn map_irq, +void pci_bus_irqs (PCIBus *bus,pci_set_irq_fn set_irq, +pci_route_pin_fn route_intx_pin,void *irq_opaque,int nirq);int pci_bus_get_irq_level (PCIBus *bus,int irq_num);void pci_bus_hotplug (PCIBus *bus,pci_hotplug_fn hotplug,DeviceState *dev); PCIBus *pci_register_bus(DeviceState *parent, const char *name, - pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, + pci_set_irq_fn set_irq, + pci_route_pin_fn route_intx_pin, void *irq_opaque, MemoryRegion *address_space_mem, MemoryRegion *address_space_io,
hw/pci_bridge.c +5 -5
@@ -327,7 +327,7 @@ int pci_bridge_initfn(PCIDevice *dev)qbus_create_inplace (&sec_bus->qbus, &pci_bus_info, &dev->qdev, br->bus_name); sec_bus->parent_dev = dev; - sec_bus->map_irq = br->map_irq; + sec_bus->route_intx_pin = br->route_intx_pin; sec_bus->address_space_mem = &br->address_space_mem;memory_region_init (&br->address_space_mem,"pci_bridge_pci" ,INT64_MAX ); sec_bus->address_space_io = &br->address_space_io;
@@ -353,12 +353,12 @@ int pci_bridge_exitfn(PCIDevice *pci_dev)/* * before qdev initialization(qdev_init()), this function sets bus_name and -* map_irq callback which are necessry for pci_bridge_initfn() to +* route_intx_pin callback which are necessry for pci_bridge_initfn() to * initialize bus. */ -void pci_bridge_map_irq (PCIBridge *br,const char * bus_name, -pci_map_irq_fn map_irq) +void pci_bridge_prepare (PCIBridge *br,const char * bus_name, +pci_route_pin_fn route_intx_pin) { - br->map_irq = map_irq; + br->route_intx_pin = route_intx_pin; br->bus_name = bus_name; }
hw/pci_bridge.h +2 -2
@@ -52,8 +52,8 @@ int pci_bridge_exitfn(PCIDevice *pci_dev);* map_irq callback which are necessry for pci_bridge_initfn() to * initialize bus. */ -void pci_bridge_map_irq (PCIBridge *br,const char * bus_name, -pci_map_irq_fn map_irq); +void pci_bridge_prepare (PCIBridge *br,const char * bus_name, +pci_route_pin_fn route_intx_pin);#endif /* QEMU_PCI_BRIDGE_H */ /*
hw/pci_bridge_dev.c +4 -3
@@ -43,9 +43,9 @@ typedef struct PCIBridgeDev PCIBridgeDev;/* Mapping mandated by PCI-to-PCI Bridge architecture specification, * revision 1.2 */ /* Table 9-1: Interrupt Binding for Devices Behind a Bridge */ -static int pci_bridge_dev_map_irq_fn (PCIDevice *dev,int irq_num) +static int pci_bridge_dev_route_intx_pin (PCIDevice *dev,int pin) { -return (irq_num +PCI_SLOT (dev->devfn)) %PCI_NUM_PINS ; +return (pin +PCI_SLOT (dev->devfn)) %PCI_NUM_PINS ; }static int pci_bridge_dev_initfn (PCIDevice *dev)
@@ -53,7 +53,8 @@ static int pci_bridge_dev_initfn(PCIDevice *dev)PCIBridge *br =DO_UPCAST (PCIBridge, dev, dev);PCIBridgeDev *bridge_dev =DO_UPCAST (PCIBridgeDev, bridge, br);int err; -pci_bridge_map_irq (br,NULL , pci_bridge_dev_map_irq_fn); + +pci_bridge_prepare (br,NULL , pci_bridge_dev_route_intx_pin); err =pci_bridge_initfn (dev);if (err) { goto bridge_error;
hw/pci_internals.h +2 -2
@@ -18,7 +18,7 @@ struct PCIBus {BusState qbus;uint8_t devfn_min;pci_set_irq_fn set_irq; -pci_map_irq_fn map_irq; +pci_route_pin_fn route_intx_pin;pci_hotplug_fn hotplug;DeviceState *hotplug_qdev;void *irq_opaque;
@@ -59,7 +59,7 @@ struct PCIBridge {MemoryRegion alias_pref_mem;MemoryRegion alias_mem;MemoryRegion alias_io; -pci_map_irq_fn map_irq; +pci_route_pin_fn route_intx_pin;const char *bus_name; };
hw/xio3130_downstream.c +3 -2
@@ -128,7 +128,8 @@ static int xio3130_downstream_exitfn(PCIDevice *d) }PCIESlot *xio3130_downstream_init (PCIBus *bus,int devfn,bool multifunction, -const char *bus_name,pci_map_irq_fn map_irq, +const char *bus_name, +pci_route_pin_fn route_intx_pin,uint8_t port,uint8_t chassis,uint16_t slot) {
@@ -144,7 +145,7 @@ PCIESlot *xio3130_downstream_init(PCIBus *bus, int devfn, bool multifunction, br =DO_UPCAST (PCIBridge, dev, d); qdev = &br->dev.qdev; -pci_bridge_map_irq (br, bus_name, map_irq); +pci_bridge_prepare (br, bus_name, route_intx_pin);qdev_prop_set_uint8 (qdev,"port" , port);qdev_prop_set_uint8 (qdev,"chassis" , chassis);qdev_prop_set_uint16 (qdev,"slot" , slot);
hw/xio3130_downstream.h +2 -1
@@ -4,7 +4,8 @@#include "pcie_port.h" PCIESlot *xio3130_downstream_init (PCIBus *bus,int devfn,bool multifunction, -const char *bus_name,pci_map_irq_fn map_irq, +const char *bus_name, +pci_route_pin_fn route_intx_pin,uint8_t port,uint8_t chassis,uint16_t slot);
hw/xio3130_upstream.c +3 -2
@@ -110,7 +110,8 @@ static int xio3130_upstream_exitfn(PCIDevice *d) }PCIEPort *xio3130_upstream_init (PCIBus *bus,int devfn,bool multifunction, -const char *bus_name,pci_map_irq_fn map_irq, +const char *bus_name, +pci_route_pin_fn route_intx_pin,uint8_t port) {PCIDevice *d;
@@ -124,7 +125,7 @@ PCIEPort *xio3130_upstream_init(PCIBus *bus, int devfn, bool multifunction, br =DO_UPCAST (PCIBridge, dev, d); qdev = &br->dev.qdev; -pci_bridge_map_irq (br, bus_name, map_irq); +pci_bridge_prepare (br, bus_name, route_intx_pin);qdev_prop_set_uint8 (qdev,"port" , port);qdev_init_nofail (qdev);
hw/xio3130_upstream.h +2 -1
@@ -4,7 +4,8 @@#include "pcie_port.h" PCIEPort *xio3130_upstream_init (PCIBus *bus,int devfn,bool multifunction, -const char *bus_name,pci_map_irq_fn map_irq, +const char *bus_name, +pci_route_pin_fn route_intx_pin,uint8_t port);#endif /* QEMU_XIO3130_H */
Signature · 1 line
1.7.3.4
Michael S. Tsirkin
AppliedRe: [Qemu-devel] [PATCH 04/13] pci: Rename map_irq to route_pin
Quoted 7 lines · Jan Kiszka
To avoid confusion with the board-level IRQ the host bridge triggers on output, rename the per-bridge routing function for the INTx pins to
pci_route_pin_fn. Also adjust variable names of that type. And renamepci_bridge_map_irqtopci_bridge_prepare, which better reflects the job of that function.Signed-off-by Jan Kiszka <[email protected]>
Applied.
Quoted 372 lines
--- hw/alpha_sys.h | 2 +- hw/alpha_typhoon.c | 2 +- hw/apb_pci.c | 4 ++-- hw/dec_pci.c | 2 +- hw/ioh3420.c | 5 +++-- hw/ioh3420.h | 3 ++- hw/pci.c | 14 ++++++++------ hw/pci.h | 8 +++++--- hw/pci_bridge.c | 10 +++++----- hw/pci_bridge.h | 4 ++-- hw/pci_bridge_dev.c | 7 ++++--- hw/pci_internals.h | 4 ++-- hw/xio3130_downstream.c | 5 +++-- hw/xio3130_downstream.h | 3 ++- hw/xio3130_upstream.c | 5 +++-- hw/xio3130_upstream.h | 3 ++- 16 files changed, 46 insertions(+), 35 deletions(-)hw/alpha_sys.h +1
-1@@ -12,7 +12,7 @@PCIBus *typhoon_init (ram_addr_t ,ISABus **,qemu_irq *,CPUAlphaState *[4 ], -pci_map_irq_fn ); +pci_route_pin_fn );/* alpha_pci.c. */ extern const MemoryRegionOps alpha_pci_bw_io_ops;hw/alpha_typhoon.c +1
-1@@ -693,7 +693,7 @@ static void typhoon_alarm_timer(void *opaque)PCIBus *typhoon_init (ram_addr_t ram_size,ISABus **isa_bus,qemu_irq *p_rtc_irq, -CPUAlphaState *cpus[4 ],pci_map_irq_fn sys_map_irq) +CPUAlphaState *cpus[4 ],pci_route_pin_fn sys_map_irq) {const uint64_t MB =1024 *1024 ;const uint64_t GB =1024 *MB ;hw/apb_pci.c +2
-2@@ -392,7 +392,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base, pci_dev =pci_create_multifunction (d->bus,PCI_DEVFN (1 ,0 ), true,"pbm-bridge" ); br =DO_UPCAST (PCIBridge, dev, pci_dev); -pci_bridge_map_irq (br,"Advanced PCI Bus secondary bridge 1" , +pci_bridge_prepare (br,"Advanced PCI Bus secondary bridge 1" , pci_apb_map_irq);qdev_init_nofail (&pci_dev->qdev); *bus2 =pci_bridge_get_sec_bus (br);@@ -400,7 +400,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base, pci_dev =pci_create_multifunction (d->bus,PCI_DEVFN (1 ,1 ), true,"pbm-bridge" ); br =DO_UPCAST (PCIBridge, dev, pci_dev); -pci_bridge_map_irq (br,"Advanced PCI Bus secondary bridge 2" , +pci_bridge_prepare (br,"Advanced PCI Bus secondary bridge 2" , pci_apb_map_irq);qdev_init_nofail (&pci_dev->qdev); *bus3 =pci_bridge_get_sec_bus (br);hw/dec_pci.c +1
-1@@ -81,7 +81,7 @@ PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn) dev =pci_create_multifunction (parent_bus, devfn, false,"dec-21154-p2p-bridge" ); br =DO_UPCAST (PCIBridge, dev, dev); -pci_bridge_map_irq (br,"DEC 21154 PCI-PCI bridge" , dec_map_irq); +pci_bridge_prepare (br,"DEC 21154 PCI-PCI bridge" , dec_map_irq);qdev_init_nofail (&dev->qdev);return pci_bridge_get_sec_bus (br); }hw/ioh3420.c +3
-2@@ -164,7 +164,8 @@ static int ioh3420_exitfn(PCIDevice *d) }PCIESlot *ioh3420_init (PCIBus *bus,int devfn,bool multifunction, -const char *bus_name,pci_map_irq_fn map_irq, +const char *bus_name, +pci_route_pin_fn route_intx_pin,uint8_t port,uint8_t chassis,uint16_t slot) {PCIDevice *d;@@ -178,7 +179,7 @@ PCIESlot *ioh3420_init(PCIBus *bus, int devfn, bool multifunction, br =DO_UPCAST (PCIBridge, dev, d); qdev = &br->dev.qdev; -pci_bridge_map_irq (br, bus_name, map_irq); +pci_bridge_prepare (br, bus_name, route_intx_pin);qdev_prop_set_uint8 (qdev,"port" , port);qdev_prop_set_uint8 (qdev,"chassis" , chassis);qdev_prop_set_uint16 (qdev,"slot" , slot);hw/ioh3420.h +2
-1@@ -4,7 +4,8 @@#include "pcie_port.h" PCIESlot *ioh3420_init (PCIBus *bus,int devfn,bool multifunction, -const char *bus_name,pci_map_irq_fn map_irq, +const char *bus_name, +pci_route_pin_fn route_intx_pin,uint8_t port,uint8_t chassis,uint16_t slot);#endif /* QEMU_IOH3420_H */ hw/pci.c +8
-6@@ -121,7 +121,7 @@ static void pci_set_device_intx_routing(PCIBus *bus, PCIDevice *dev)/* We might be too early, i.e. before pci_bus_irqs was called. * We will be called again when this happened. */ -if (!bus->map_irq) { +if (!bus->route_intx_pin) {return ; }@@ -130,7 +130,7 @@ static void pci_set_device_intx_routing(PCIBus *bus, PCIDevice *dev) output_pin = pin;do { bus = pci_dev->bus; - output_pin = bus->map_irq (pci_dev, output_pin); + output_pin = bus->route_intx_pin (pci_dev, output_pin); pci_dev = bus->parent_dev; }while (pci_dev);@@ -318,11 +318,12 @@ PCIBus *pci_bus_new(DeviceState *parent, const char *name,return bus; } -void pci_bus_irqs (PCIBus *bus,pci_set_irq_fn set_irq,pci_map_irq_fn map_irq, +void pci_bus_irqs (PCIBus *bus,pci_set_irq_fn set_irq, +pci_route_pin_fn route_intx_pin,void *irq_opaque,int nirq) { bus->set_irq = set_irq; - bus->map_irq = map_irq; + bus->route_intx_pin = route_intx_pin; bus->irq_opaque = irq_opaque; bus->nirq = nirq; bus->irq_count =g_malloc0 (nirq *sizeof (bus->irq_count[0 ]));@@ -337,7 +338,8 @@ void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug, DeviceState *qdev) } PCIBus *pci_register_bus(DeviceState *parent, const char *name, - pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, + pci_set_irq_fn set_irq, + pci_route_pin_fn route_intx_pin, void *irq_opaque, MemoryRegion *address_space_mem, MemoryRegion *address_space_io,@@ -347,7 +349,7 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name, bus =pci_bus_new (parent, name, address_space_mem, address_space_io, devfn_min); -pci_bus_irqs (bus, set_irq, map_irq, irq_opaque, nirq); +pci_bus_irqs (bus, set_irq, route_intx_pin, irq_opaque, nirq);return bus; }hw/pci.h +5
-3@@ -279,7 +279,7 @@ MemoryRegion *pci_address_space(PCIDevice *dev);MemoryRegion *pci_address_space_io (PCIDevice *dev);typedef void (*pci_set_irq_fn )(void *opaque,int irq_num,int level); -typedef int (*pci_map_irq_fn )(PCIDevice *pci_dev,int irq_num); +typedef int (*pci_route_pin_fn )(PCIDevice *pci_dev,int pin); typedef enum { PCI_HOTPLUG_DISABLED,@@ -293,12 +293,14 @@ PCIBus *pci_bus_new(DeviceState *parent, const char *name, MemoryRegion *address_space_mem, MemoryRegion *address_space_io, uint8_t devfn_min); -void pci_bus_irqs (PCIBus *bus,pci_set_irq_fn set_irq,pci_map_irq_fn map_irq, +void pci_bus_irqs (PCIBus *bus,pci_set_irq_fn set_irq, +pci_route_pin_fn route_intx_pin,void *irq_opaque,int nirq);int pci_bus_get_irq_level (PCIBus *bus,int irq_num);void pci_bus_hotplug (PCIBus *bus,pci_hotplug_fn hotplug,DeviceState *dev); PCIBus *pci_register_bus(DeviceState *parent, const char *name, - pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, + pci_set_irq_fn set_irq, + pci_route_pin_fn route_intx_pin, void *irq_opaque, MemoryRegion *address_space_mem, MemoryRegion *address_space_io,hw/pci_bridge.c +5
-5@@ -327,7 +327,7 @@ int pci_bridge_initfn(PCIDevice *dev)qbus_create_inplace (&sec_bus->qbus, &pci_bus_info, &dev->qdev, br->bus_name); sec_bus->parent_dev = dev; - sec_bus->map_irq = br->map_irq; + sec_bus->route_intx_pin = br->route_intx_pin; sec_bus->address_space_mem = &br->address_space_mem;memory_region_init (&br->address_space_mem,"pci_bridge_pci" ,INT64_MAX ); sec_bus->address_space_io = &br->address_space_io;@@ -353,12 +353,12 @@ int pci_bridge_exitfn(PCIDevice *pci_dev)/* * before qdev initialization(qdev_init()), this function sets bus_name and -* map_irq callback which are necessry for pci_bridge_initfn() to +* route_intx_pin callback which are necessry for pci_bridge_initfn() to * initialize bus. */ -void pci_bridge_map_irq (PCIBridge *br,const char * bus_name, -pci_map_irq_fn map_irq) +void pci_bridge_prepare (PCIBridge *br,const char * bus_name, +pci_route_pin_fn route_intx_pin) { - br->map_irq = map_irq; + br->route_intx_pin = route_intx_pin; br->bus_name = bus_name; }hw/pci_bridge.h +2
-2@@ -52,8 +52,8 @@ int pci_bridge_exitfn(PCIDevice *pci_dev);* map_irq callback which are necessry for pci_bridge_initfn() to * initialize bus. */ -void pci_bridge_map_irq (PCIBridge *br,const char * bus_name, -pci_map_irq_fn map_irq); +void pci_bridge_prepare (PCIBridge *br,const char * bus_name, +pci_route_pin_fn route_intx_pin);#endif /* QEMU_PCI_BRIDGE_H */ /* hw/pci_bridge_dev.c +4
-3@@ -43,9 +43,9 @@ typedef struct PCIBridgeDev PCIBridgeDev;/* Mapping mandated by PCI-to-PCI Bridge architecture specification, * revision 1.2 */ /* Table 9-1: Interrupt Binding for Devices Behind a Bridge */ -static int pci_bridge_dev_map_irq_fn (PCIDevice *dev,int irq_num) +static int pci_bridge_dev_route_intx_pin (PCIDevice *dev,int pin) { -return (irq_num +PCI_SLOT (dev->devfn)) %PCI_NUM_PINS ; +return (pin +PCI_SLOT (dev->devfn)) %PCI_NUM_PINS ; }static int pci_bridge_dev_initfn (PCIDevice *dev)@@ -53,7 +53,8 @@ static int pci_bridge_dev_initfn(PCIDevice *dev)PCIBridge *br =DO_UPCAST (PCIBridge, dev, dev);PCIBridgeDev *bridge_dev =DO_UPCAST (PCIBridgeDev, bridge, br);int err; -pci_bridge_map_irq (br,NULL , pci_bridge_dev_map_irq_fn); + +pci_bridge_prepare (br,NULL , pci_bridge_dev_route_intx_pin); err =pci_bridge_initfn (dev);if (err) { goto bridge_error;hw/pci_internals.h +2
-2@@ -18,7 +18,7 @@ struct PCIBus {BusState qbus;uint8_t devfn_min;pci_set_irq_fn set_irq; -pci_map_irq_fn map_irq; +pci_route_pin_fn route_intx_pin;pci_hotplug_fn hotplug;DeviceState *hotplug_qdev;void *irq_opaque;@@ -59,7 +59,7 @@ struct PCIBridge {MemoryRegion alias_pref_mem;MemoryRegion alias_mem;MemoryRegion alias_io; -pci_map_irq_fn map_irq; +pci_route_pin_fn route_intx_pin;const char *bus_name; };hw/xio3130_downstream.c +3
-2@@ -128,7 +128,8 @@ static int xio3130_downstream_exitfn(PCIDevice *d) }PCIESlot *xio3130_downstream_init (PCIBus *bus,int devfn,bool multifunction, -const char *bus_name,pci_map_irq_fn map_irq, +const char *bus_name, +pci_route_pin_fn route_intx_pin,uint8_t port,uint8_t chassis,uint16_t slot) {@@ -144,7 +145,7 @@ PCIESlot *xio3130_downstream_init(PCIBus *bus, int devfn, bool multifunction, br =DO_UPCAST (PCIBridge, dev, d); qdev = &br->dev.qdev; -pci_bridge_map_irq (br, bus_name, map_irq); +pci_bridge_prepare (br, bus_name, route_intx_pin);qdev_prop_set_uint8 (qdev,"port" , port);qdev_prop_set_uint8 (qdev,"chassis" , chassis);qdev_prop_set_uint16 (qdev,"slot" , slot);hw/xio3130_downstream.h +2
-1@@ -4,7 +4,8 @@#include "pcie_port.h" PCIESlot *xio3130_downstream_init (PCIBus *bus,int devfn,bool multifunction, -const char *bus_name,pci_map_irq_fn map_irq, +const char *bus_name, +pci_route_pin_fn route_intx_pin,uint8_t port,uint8_t chassis,uint16_t slot);hw/xio3130_upstream.c +3
-2@@ -110,7 +110,8 @@ static int xio3130_upstream_exitfn(PCIDevice *d) }PCIEPort *xio3130_upstream_init (PCIBus *bus,int devfn,bool multifunction, -const char *bus_name,pci_map_irq_fn map_irq, +const char *bus_name, +pci_route_pin_fn route_intx_pin,uint8_t port) {PCIDevice *d;@@ -124,7 +125,7 @@ PCIEPort *xio3130_upstream_init(PCIBus *bus, int devfn, bool multifunction, br =DO_UPCAST (PCIBridge, dev, d); qdev = &br->dev.qdev; -pci_bridge_map_irq (br, bus_name, map_irq); +pci_bridge_prepare (br, bus_name, route_intx_pin);qdev_prop_set_uint8 (qdev,"port" , port);qdev_init_nofail (qdev);hw/xio3130_upstream.h +2
-1@@ -4,7 +4,8 @@#include "pcie_port.h" PCIEPort *xio3130_upstream_init (PCIBus *bus,int devfn,bool multifunction, -const char *bus_name,pci_map_irq_fn map_irq, +const char *bus_name, +pci_route_pin_fn route_intx_pin,uint8_t port);#endif /* QEMU_XIO3130_H */ Signature · 1 line
1.7.3.4
Re: [Qemu-devel] [PATCH 04/13] pci: Rename map_irq to route_pin
In reply to Jan KiszkaQuoted 7 lines · Jan Kiszka
To avoid confusion with the board-level IRQ the host bridge triggers on output, rename the per-bridge routing function for the INTx pins to
pci_route_pin_fn. Also adjust variable names of that type. And renamepci_bridge_map_irqtopci_bridge_prepare, which better reflects the job of that function.Signed-off-by Jan Kiszka <[email protected]>
BTW there was a minor conflict when applying this, it would help me if you base future patches in this series on my pci branch.
Quoted 372 lines
--- hw/alpha_sys.h | 2 +- hw/alpha_typhoon.c | 2 +- hw/apb_pci.c | 4 ++-- hw/dec_pci.c | 2 +- hw/ioh3420.c | 5 +++-- hw/ioh3420.h | 3 ++- hw/pci.c | 14 ++++++++------ hw/pci.h | 8 +++++--- hw/pci_bridge.c | 10 +++++----- hw/pci_bridge.h | 4 ++-- hw/pci_bridge_dev.c | 7 ++++--- hw/pci_internals.h | 4 ++-- hw/xio3130_downstream.c | 5 +++-- hw/xio3130_downstream.h | 3 ++- hw/xio3130_upstream.c | 5 +++-- hw/xio3130_upstream.h | 3 ++- 16 files changed, 46 insertions(+), 35 deletions(-)hw/alpha_sys.h +1
-1@@ -12,7 +12,7 @@PCIBus *typhoon_init (ram_addr_t ,ISABus **,qemu_irq *,CPUAlphaState *[4 ], -pci_map_irq_fn ); +pci_route_pin_fn );/* alpha_pci.c. */ extern const MemoryRegionOps alpha_pci_bw_io_ops;hw/alpha_typhoon.c +1
-1@@ -693,7 +693,7 @@ static void typhoon_alarm_timer(void *opaque)PCIBus *typhoon_init (ram_addr_t ram_size,ISABus **isa_bus,qemu_irq *p_rtc_irq, -CPUAlphaState *cpus[4 ],pci_map_irq_fn sys_map_irq) +CPUAlphaState *cpus[4 ],pci_route_pin_fn sys_map_irq) {const uint64_t MB =1024 *1024 ;const uint64_t GB =1024 *MB ;hw/apb_pci.c +2
-2@@ -392,7 +392,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base, pci_dev =pci_create_multifunction (d->bus,PCI_DEVFN (1 ,0 ), true,"pbm-bridge" ); br =DO_UPCAST (PCIBridge, dev, pci_dev); -pci_bridge_map_irq (br,"Advanced PCI Bus secondary bridge 1" , +pci_bridge_prepare (br,"Advanced PCI Bus secondary bridge 1" , pci_apb_map_irq);qdev_init_nofail (&pci_dev->qdev); *bus2 =pci_bridge_get_sec_bus (br);@@ -400,7 +400,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base, pci_dev =pci_create_multifunction (d->bus,PCI_DEVFN (1 ,1 ), true,"pbm-bridge" ); br =DO_UPCAST (PCIBridge, dev, pci_dev); -pci_bridge_map_irq (br,"Advanced PCI Bus secondary bridge 2" , +pci_bridge_prepare (br,"Advanced PCI Bus secondary bridge 2" , pci_apb_map_irq);qdev_init_nofail (&pci_dev->qdev); *bus3 =pci_bridge_get_sec_bus (br);hw/dec_pci.c +1
-1@@ -81,7 +81,7 @@ PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn) dev =pci_create_multifunction (parent_bus, devfn, false,"dec-21154-p2p-bridge" ); br =DO_UPCAST (PCIBridge, dev, dev); -pci_bridge_map_irq (br,"DEC 21154 PCI-PCI bridge" , dec_map_irq); +pci_bridge_prepare (br,"DEC 21154 PCI-PCI bridge" , dec_map_irq);qdev_init_nofail (&dev->qdev);return pci_bridge_get_sec_bus (br); }hw/ioh3420.c +3
-2@@ -164,7 +164,8 @@ static int ioh3420_exitfn(PCIDevice *d) }PCIESlot *ioh3420_init (PCIBus *bus,int devfn,bool multifunction, -const char *bus_name,pci_map_irq_fn map_irq, +const char *bus_name, +pci_route_pin_fn route_intx_pin,uint8_t port,uint8_t chassis,uint16_t slot) {PCIDevice *d;@@ -178,7 +179,7 @@ PCIESlot *ioh3420_init(PCIBus *bus, int devfn, bool multifunction, br =DO_UPCAST (PCIBridge, dev, d); qdev = &br->dev.qdev; -pci_bridge_map_irq (br, bus_name, map_irq); +pci_bridge_prepare (br, bus_name, route_intx_pin);qdev_prop_set_uint8 (qdev,"port" , port);qdev_prop_set_uint8 (qdev,"chassis" , chassis);qdev_prop_set_uint16 (qdev,"slot" , slot);hw/ioh3420.h +2
-1@@ -4,7 +4,8 @@#include "pcie_port.h" PCIESlot *ioh3420_init (PCIBus *bus,int devfn,bool multifunction, -const char *bus_name,pci_map_irq_fn map_irq, +const char *bus_name, +pci_route_pin_fn route_intx_pin,uint8_t port,uint8_t chassis,uint16_t slot);#endif /* QEMU_IOH3420_H */ hw/pci.c +8
-6@@ -121,7 +121,7 @@ static void pci_set_device_intx_routing(PCIBus *bus, PCIDevice *dev)/* We might be too early, i.e. before pci_bus_irqs was called. * We will be called again when this happened. */ -if (!bus->map_irq) { +if (!bus->route_intx_pin) {return ; }@@ -130,7 +130,7 @@ static void pci_set_device_intx_routing(PCIBus *bus, PCIDevice *dev) output_pin = pin;do { bus = pci_dev->bus; - output_pin = bus->map_irq (pci_dev, output_pin); + output_pin = bus->route_intx_pin (pci_dev, output_pin); pci_dev = bus->parent_dev; }while (pci_dev);@@ -318,11 +318,12 @@ PCIBus *pci_bus_new(DeviceState *parent, const char *name,return bus; } -void pci_bus_irqs (PCIBus *bus,pci_set_irq_fn set_irq,pci_map_irq_fn map_irq, +void pci_bus_irqs (PCIBus *bus,pci_set_irq_fn set_irq, +pci_route_pin_fn route_intx_pin,void *irq_opaque,int nirq) { bus->set_irq = set_irq; - bus->map_irq = map_irq; + bus->route_intx_pin = route_intx_pin; bus->irq_opaque = irq_opaque; bus->nirq = nirq; bus->irq_count =g_malloc0 (nirq *sizeof (bus->irq_count[0 ]));@@ -337,7 +338,8 @@ void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug, DeviceState *qdev) } PCIBus *pci_register_bus(DeviceState *parent, const char *name, - pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, + pci_set_irq_fn set_irq, + pci_route_pin_fn route_intx_pin, void *irq_opaque, MemoryRegion *address_space_mem, MemoryRegion *address_space_io,@@ -347,7 +349,7 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name, bus =pci_bus_new (parent, name, address_space_mem, address_space_io, devfn_min); -pci_bus_irqs (bus, set_irq, map_irq, irq_opaque, nirq); +pci_bus_irqs (bus, set_irq, route_intx_pin, irq_opaque, nirq);return bus; }hw/pci.h +5
-3@@ -279,7 +279,7 @@ MemoryRegion *pci_address_space(PCIDevice *dev);MemoryRegion *pci_address_space_io (PCIDevice *dev);typedef void (*pci_set_irq_fn )(void *opaque,int irq_num,int level); -typedef int (*pci_map_irq_fn )(PCIDevice *pci_dev,int irq_num); +typedef int (*pci_route_pin_fn )(PCIDevice *pci_dev,int pin); typedef enum { PCI_HOTPLUG_DISABLED,@@ -293,12 +293,14 @@ PCIBus *pci_bus_new(DeviceState *parent, const char *name, MemoryRegion *address_space_mem, MemoryRegion *address_space_io, uint8_t devfn_min); -void pci_bus_irqs (PCIBus *bus,pci_set_irq_fn set_irq,pci_map_irq_fn map_irq, +void pci_bus_irqs (PCIBus *bus,pci_set_irq_fn set_irq, +pci_route_pin_fn route_intx_pin,void *irq_opaque,int nirq);int pci_bus_get_irq_level (PCIBus *bus,int irq_num);void pci_bus_hotplug (PCIBus *bus,pci_hotplug_fn hotplug,DeviceState *dev); PCIBus *pci_register_bus(DeviceState *parent, const char *name, - pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, + pci_set_irq_fn set_irq, + pci_route_pin_fn route_intx_pin, void *irq_opaque, MemoryRegion *address_space_mem, MemoryRegion *address_space_io,hw/pci_bridge.c +5
-5@@ -327,7 +327,7 @@ int pci_bridge_initfn(PCIDevice *dev)qbus_create_inplace (&sec_bus->qbus, &pci_bus_info, &dev->qdev, br->bus_name); sec_bus->parent_dev = dev; - sec_bus->map_irq = br->map_irq; + sec_bus->route_intx_pin = br->route_intx_pin; sec_bus->address_space_mem = &br->address_space_mem;memory_region_init (&br->address_space_mem,"pci_bridge_pci" ,INT64_MAX ); sec_bus->address_space_io = &br->address_space_io;@@ -353,12 +353,12 @@ int pci_bridge_exitfn(PCIDevice *pci_dev)/* * before qdev initialization(qdev_init()), this function sets bus_name and -* map_irq callback which are necessry for pci_bridge_initfn() to +* route_intx_pin callback which are necessry for pci_bridge_initfn() to * initialize bus. */ -void pci_bridge_map_irq (PCIBridge *br,const char * bus_name, -pci_map_irq_fn map_irq) +void pci_bridge_prepare (PCIBridge *br,const char * bus_name, +pci_route_pin_fn route_intx_pin) { - br->map_irq = map_irq; + br->route_intx_pin = route_intx_pin; br->bus_name = bus_name; }hw/pci_bridge.h +2
-2@@ -52,8 +52,8 @@ int pci_bridge_exitfn(PCIDevice *pci_dev);* map_irq callback which are necessry for pci_bridge_initfn() to * initialize bus. */ -void pci_bridge_map_irq (PCIBridge *br,const char * bus_name, -pci_map_irq_fn map_irq); +void pci_bridge_prepare (PCIBridge *br,const char * bus_name, +pci_route_pin_fn route_intx_pin);#endif /* QEMU_PCI_BRIDGE_H */ /* hw/pci_bridge_dev.c +4
-3@@ -43,9 +43,9 @@ typedef struct PCIBridgeDev PCIBridgeDev;/* Mapping mandated by PCI-to-PCI Bridge architecture specification, * revision 1.2 */ /* Table 9-1: Interrupt Binding for Devices Behind a Bridge */ -static int pci_bridge_dev_map_irq_fn (PCIDevice *dev,int irq_num) +static int pci_bridge_dev_route_intx_pin (PCIDevice *dev,int pin) { -return (irq_num +PCI_SLOT (dev->devfn)) %PCI_NUM_PINS ; +return (pin +PCI_SLOT (dev->devfn)) %PCI_NUM_PINS ; }static int pci_bridge_dev_initfn (PCIDevice *dev)@@ -53,7 +53,8 @@ static int pci_bridge_dev_initfn(PCIDevice *dev)PCIBridge *br =DO_UPCAST (PCIBridge, dev, dev);PCIBridgeDev *bridge_dev =DO_UPCAST (PCIBridgeDev, bridge, br);int err; -pci_bridge_map_irq (br,NULL , pci_bridge_dev_map_irq_fn); + +pci_bridge_prepare (br,NULL , pci_bridge_dev_route_intx_pin); err =pci_bridge_initfn (dev);if (err) { goto bridge_error;hw/pci_internals.h +2
-2@@ -18,7 +18,7 @@ struct PCIBus {BusState qbus;uint8_t devfn_min;pci_set_irq_fn set_irq; -pci_map_irq_fn map_irq; +pci_route_pin_fn route_intx_pin;pci_hotplug_fn hotplug;DeviceState *hotplug_qdev;void *irq_opaque;@@ -59,7 +59,7 @@ struct PCIBridge {MemoryRegion alias_pref_mem;MemoryRegion alias_mem;MemoryRegion alias_io; -pci_map_irq_fn map_irq; +pci_route_pin_fn route_intx_pin;const char *bus_name; };hw/xio3130_downstream.c +3
-2@@ -128,7 +128,8 @@ static int xio3130_downstream_exitfn(PCIDevice *d) }PCIESlot *xio3130_downstream_init (PCIBus *bus,int devfn,bool multifunction, -const char *bus_name,pci_map_irq_fn map_irq, +const char *bus_name, +pci_route_pin_fn route_intx_pin,uint8_t port,uint8_t chassis,uint16_t slot) {@@ -144,7 +145,7 @@ PCIESlot *xio3130_downstream_init(PCIBus *bus, int devfn, bool multifunction, br =DO_UPCAST (PCIBridge, dev, d); qdev = &br->dev.qdev; -pci_bridge_map_irq (br, bus_name, map_irq); +pci_bridge_prepare (br, bus_name, route_intx_pin);qdev_prop_set_uint8 (qdev,"port" , port);qdev_prop_set_uint8 (qdev,"chassis" , chassis);qdev_prop_set_uint16 (qdev,"slot" , slot);hw/xio3130_downstream.h +2
-1@@ -4,7 +4,8 @@#include "pcie_port.h" PCIESlot *xio3130_downstream_init (PCIBus *bus,int devfn,bool multifunction, -const char *bus_name,pci_map_irq_fn map_irq, +const char *bus_name, +pci_route_pin_fn route_intx_pin,uint8_t port,uint8_t chassis,uint16_t slot);hw/xio3130_upstream.c +3
-2@@ -110,7 +110,8 @@ static int xio3130_upstream_exitfn(PCIDevice *d) }PCIEPort *xio3130_upstream_init (PCIBus *bus,int devfn,bool multifunction, -const char *bus_name,pci_map_irq_fn map_irq, +const char *bus_name, +pci_route_pin_fn route_intx_pin,uint8_t port) {PCIDevice *d;@@ -124,7 +125,7 @@ PCIEPort *xio3130_upstream_init(PCIBus *bus, int devfn, bool multifunction, br =DO_UPCAST (PCIBridge, dev, d); qdev = &br->dev.qdev; -pci_bridge_map_irq (br, bus_name, map_irq); +pci_bridge_prepare (br, bus_name, route_intx_pin);qdev_prop_set_uint8 (qdev,"port" , port);qdev_init_nofail (qdev);hw/xio3130_upstream.h +2
-1@@ -4,7 +4,8 @@#include "pcie_port.h" PCIEPort *xio3130_upstream_init (PCIBus *bus,int devfn,bool multifunction, -const char *bus_name,pci_map_irq_fn map_irq, +const char *bus_name, +pci_route_pin_fn route_intx_pin,uint8_t port);#endif /* QEMU_XIO3130_H */ Signature · 1 line
1.7.3.4
PATCH 5/13 pci: Add pci_device_route_intx_to_irq
In reply to Jan KiszkaAdd a PCI IRQ path discovery function that walks from a given device to the host bridge, returning the mode (enabled/inverted/disabled) and the IRQ number that is reported to the attached interrupt controller. For this purpose, another host bridge callback function is introduced:route_intx_to_irq. It is so far only implemented by the PIIX3, other host bridges can be added later on as required.
Will be used for KVM PCI device assignment and VFIO.
--- hw/alpha_typhoon.c | 2 +- hw/apb_pci.c | 2 +- hw/bonito.c | 2 +- hw/grackle_pci.c | 1 + hw/gt64xxx.c | 1 + hw/pci.c | 14 +++++++++++++- hw/pci.h | 13 +++++++++++++ hw/pci_internals.h | 1 + hw/piix_pci.c | 23 ++++++++++++++++++++--- hw/ppc4xx_pci.c | 2 +- hw/ppce500_pci.c | 2 +- hw/prep_pci.c | 2 +- hw/sh_pci.c | 2 +- hw/spapr_pci.c | 2 +- hw/unin_pci.c | 4 ++-- hw/versatile_pci.c | 2 +- 16 files changed, 60 insertions(+), 15 deletions(-)
hw/alpha_typhoon.c +1 -1
@@ -764,7 +764,7 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus, &s->pchip.reg_io); b =pci_register_bus (&s->host.busdev.qdev,"pci" , - typhoon_set_irq, sys_map_irq, s, + typhoon_set_irq, sys_map_irq,NULL , s, &s->pchip.reg_mem, addr_space_io,0 ,64 ); s->host.bus = b;
hw/apb_pci.c +1 -1
@@ -378,7 +378,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,memory_region_add_subregion (get_system_memory (), mem_base, &d->pci_mmio); d->bus =pci_register_bus (&d->busdev.qdev,"pci" , - pci_apb_set_irq, pci_pbm_map_irq, d, + pci_apb_set_irq, pci_pbm_map_irq,NULL , d, &d->pci_mmio,get_system_io (),0 ,32 );
hw/bonito.c +1 -1
@@ -750,7 +750,7 @@ PCIBus *bonito_init(qemu_irq *pic) dev =qdev_create (NULL ,"Bonito-pcihost" ); pcihost =FROM_SYSBUS (BonitoState,sysbus_from_qdev (dev)); b =pci_register_bus (&pcihost->busdev.qdev,"pci" , pci_bonito_set_irq, - pci_bonito_map_irq, pic,get_system_memory (), + pci_bonito_map_irq,NULL , pic,get_system_memory (),get_system_io (),0x28 ,32 ); pcihost->bus = b;
hw/grackle_pci.c +1 -0
@@ -85,6 +85,7 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic, d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci", pci_grackle_set_irq, pci_grackle_map_irq, + NULL, pic, &d->pci_mmio, address_space_io,
hw/gt64xxx.c +1 -0
@@ -1093,6 +1093,7 @@ PCIBus *gt64120_register(qemu_irq *pic) d =FROM_SYSBUS (GT64120State, s); d->pci.bus = pci_register_bus(&d->busdev.qdev, "pci", gt64120_pci_set_irq, gt64120_pci_map_irq, + NULL, pic, get_system_memory(), get_system_io(),
hw/pci.c +13 -1
@@ -320,10 +320,12 @@ PCIBus *pci_bus_new(DeviceState *parent, const char *name,void pci_bus_irqs (PCIBus *bus,pci_set_irq_fn set_irq,pci_route_pin_fn route_intx_pin, +pci_route_irq_fn route_intx_to_irq,void *irq_opaque,int nirq) { bus->set_irq = set_irq; bus->route_intx_pin = route_intx_pin; + bus->route_intx_to_irq = route_intx_to_irq; bus->irq_opaque = irq_opaque; bus->nirq = nirq; bus->irq_count =g_malloc0 (nirq *sizeof (bus->irq_count[0 ]));
@@ -340,6 +342,7 @@ void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug, DeviceState *qdev) PCIBus *pci_register_bus(DeviceState *parent, const char *name, pci_set_irq_fn set_irq, pci_route_pin_fn route_intx_pin, + pci_route_irq_fn route_intx_to_irq, void *irq_opaque, MemoryRegion *address_space_mem, MemoryRegion *address_space_io,
@@ -349,7 +352,8 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name, bus =pci_bus_new (parent, name, address_space_mem, address_space_io, devfn_min); -pci_bus_irqs (bus, set_irq, route_intx_pin, irq_opaque, nirq); +pci_bus_irqs (bus, set_irq, route_intx_pin, route_intx_to_irq, irq_opaque, + nirq);return bus; }
@@ -1089,6 +1093,14 @@ static void pci_set_irq(void *opaque, int irq_num, int level)pci_change_irq_level (pci_dev, irq_num, change); } +PCIINTxRoute pci_device_route_intx_to_irq (PCIDevice *dev,int pin) +{ +PCIBus *bus = dev->host_bus; + +assert (bus->route_intx_to_irq); +return bus->route_intx_to_irq (bus->irq_opaque, dev->host_intx_pin[pin]); +} +/***********************************************************/ /* monitor info on PCI */
hw/pci.h +13 -0
@@ -141,6 +141,15 @@ enum {#define PCI_DEVICE_GET_CLASS (obj) \ OBJECT_GET_CLASS(PCIDeviceClass, (obj), TYPE_PCI_DEVICE) +typedef struct PCIINTxRoute { +enum { +PCI_INTX_ENABLED , +PCI_INTX_INVERTED , +PCI_INTX_DISABLED , + } mode; +int irq; +}PCIINTxRoute ; + typedef struct PCIDeviceClass { DeviceClass parent_class;
@@ -280,6 +289,7 @@ MemoryRegion *pci_address_space_io(PCIDevice *dev);typedef void (*pci_set_irq_fn )(void *opaque,int irq_num,int level);typedef int (*pci_route_pin_fn )(PCIDevice *pci_dev,int pin); +typedef PCIINTxRoute (*pci_route_irq_fn )(void *opaque,int pin); typedef enum { PCI_HOTPLUG_DISABLED,
@@ -295,16 +305,19 @@ PCIBus *pci_bus_new(DeviceState *parent, const char *name, uint8_t devfn_min);void pci_bus_irqs (PCIBus *bus,pci_set_irq_fn set_irq,pci_route_pin_fn route_intx_pin, +pci_route_irq_fn route_intx_to_irq,void *irq_opaque,int nirq);int pci_bus_get_irq_level (PCIBus *bus,int irq_num);void pci_bus_hotplug (PCIBus *bus,pci_hotplug_fn hotplug,DeviceState *dev);PCIBus *pci_register_bus (DeviceState *parent,const char *name,pci_set_irq_fn set_irq,pci_route_pin_fn route_intx_pin, +pci_route_irq_fn route_intx_to_irq,void *irq_opaque,MemoryRegion *address_space_mem,MemoryRegion *address_space_io,uint8_t devfn_min,int nirq); +PCIINTxRoute pci_device_route_intx_to_irq (PCIDevice *dev,int pin);void pci_device_reset (PCIDevice *dev);void pci_bus_reset (PCIBus *bus);
hw/pci_internals.h +1 -0
@@ -19,6 +19,7 @@ struct PCIBus {uint8_t devfn_min;pci_set_irq_fn set_irq;pci_route_pin_fn route_intx_pin; +pci_route_irq_fn route_intx_to_irq;pci_hotplug_fn hotplug;DeviceState *hotplug_qdev;void *irq_opaque;
hw/piix_pci.c +20 -3
@@ -89,6 +89,7 @@ struct PCII440FXState {#define I440FX_SMRAM 0x72static void piix3_set_irq (void *opaque,int pirq,int level); +static PCIINTxRoute piix3_route_intx_pin_to_irq (void *opaque,int pci_intx);static void piix3_write_config_xen (PCIDevice *dev,uint32_t address,uint32_t val,int len);
@@ -308,13 +309,13 @@ static PCIBus *i440fx_common_init(const char *device_name,if (xen_enabled ()) { piix3 =DO_UPCAST (PIIX3State, dev,pci_create_simple_multifunction (b,-1 , true,"PIIX3-xen" )); -pci_bus_irqs (b, xen_piix3_set_irq, xen_pci_slot_get_pirq, +pci_bus_irqs (b, xen_piix3_set_irq, xen_pci_slot_get_pirq,NULL , piix3,XEN_PIIX_NUM_PIRQS ); }else { piix3 =DO_UPCAST (PIIX3State, dev,pci_create_simple_multifunction (b,-1 , true,"PIIX3" )); -pci_bus_irqs (b, piix3_set_irq, pci_slot_get_pirq, piix3, -PIIX_NUM_PIRQS ); +pci_bus_irqs (b, piix3_set_irq, pci_slot_get_pirq, + piix3_route_intx_pin_to_irq, piix3,PIIX_NUM_PIRQS ); } piix3->pic = pic; *isa_bus = DO_UPCAST(ISABus, qbus,
@@ -386,6 +387,22 @@ static void piix3_set_irq(void *opaque, int pirq, int level)piix3_set_irq_level (piix3, pirq, level); } +static PCIINTxRoute piix3_route_intx_pin_to_irq (void *opaque,int pin) +{ +PIIX3State *piix3 = opaque; +int irq = piix3->dev.config[PIIX_PIRQC + pin]; +PCIINTxRoute route; + +if (irq <PIIX_NUM_PIC_IRQS ) { + route.mode =PCI_INTX_ENABLED ; + route.irq = irq; + }else { + route.mode =PCI_INTX_DISABLED ; + route.irq =-1 ; + } +return route; +} +/* irq routing is changed. so rebuild bitmap */ static void piix3_update_irq_levels (PIIX3State *piix3) {
hw/ppc4xx_pci.c +1 -1
@@ -343,7 +343,7 @@ static int ppc4xx_pcihost_initfn(SysBusDevice *dev) } b =pci_register_bus (&s->pci_state.busdev.qdev,NULL , ppc4xx_pci_set_irq, - ppc4xx_pci_map_irq, s->irq,get_system_memory (), + ppc4xx_pci_map_irq,NULL , s->irq,get_system_memory (),get_system_io (),0 ,4 ); s->pci_state.bus = b;
hw/ppce500_pci.c +1 -1
@@ -318,7 +318,7 @@ static int e500_pcihost_initfn(SysBusDevice *dev) } b =pci_register_bus (&s->pci_state.busdev.qdev,NULL , mpc85xx_pci_set_irq, - mpc85xx_pci_map_irq, s->irq, address_space_mem, + mpc85xx_pci_map_irq,NULL , s->irq, address_space_mem, address_space_io,PCI_DEVFN (0x11 ,0 ),4 ); s->pci_state.bus = b;
hw/prep_pci.c +1 -1
@@ -108,7 +108,7 @@ static int raven_pcihost_init(SysBusDevice *dev) } bus =pci_register_bus (&h->busdev.qdev,NULL , - prep_set_irq, prep_map_irq, s->irq, + prep_set_irq, prep_map_irq,NULL , s->irq, address_space_mem, address_space_io,0 ,4 ); h->bus = bus;
hw/sh_pci.c +1 -1
@@ -120,7 +120,7 @@ static int sh_pci_device_init(SysBusDevice *dev)sysbus_init_irq (dev, &s->irq[i]); } s->bus = pci_register_bus(&s->busdev.qdev, "pci", - sh_pci_set_irq, sh_pci_map_irq, + sh_pci_set_irq, sh_pci_map_irq, NULL, s->irq, get_system_memory(), get_system_io(),
hw/spapr_pci.c +1 -1
@@ -306,7 +306,7 @@ static int spapr_phb_init(SysBusDevice *s) bus =pci_register_bus (&phb->busdev.qdev, phb->busname ? phb->busname : phb->dtbusname, - pci_spapr_set_irq, pci_spapr_map_irq, phb, + pci_spapr_set_irq, pci_spapr_map_irq,NULL , phb, &phb->memspace, &phb->iospace,PCI_DEVFN (0 ,0 ),PCI_NUM_PINS ); phb->host_state.bus = bus;
hw/unin_pci.c +2 -2
@@ -227,7 +227,7 @@ PCIBus *pci_pmac_init(qemu_irq *pic, d->host_state.bus =pci_register_bus (dev,"pci" , pci_unin_set_irq, pci_unin_map_irq, - pic, +NULL , pic, &d->pci_mmio, address_space_io,PCI_DEVFN (11 ,0 ),4 );
@@ -293,7 +293,7 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic, d->host_state.bus =pci_register_bus (dev,"pci" , pci_unin_set_irq, pci_unin_map_irq, - pic, +NULL , pic, &d->pci_mmio, address_space_io,PCI_DEVFN (11 ,0 ),4 );
hw/versatile_pci.c +1 -1
@@ -68,7 +68,7 @@ static int pci_vpb_init(SysBusDevice *dev)sysbus_init_irq (dev, &s->irq[i]); } bus =pci_register_bus (&dev->qdev,"pci" , - pci_vpb_set_irq, pci_vpb_map_irq, s->irq, + pci_vpb_set_irq, pci_vpb_map_irq,NULL , s->irq,get_system_memory (),get_system_io (),PCI_DEVFN (11 ,0 ),4 );
Signature · 1 line
1.7.3.4
Re: [Qemu-devel] [PATCH 05/13] pci: Add pci_device_route_intx_to_irq
Quoted 5 lines · Jan Kiszka
hw/pci.c +1
-0@@ -1089,6 +1093,14 @@ static void pci_set_irq(void *opaque, int irq_num, int level)pci_change_irq_level (pci_dev, irq_num, change); } +PCIINTxRoute pci_device_route_intx_to_irq (PCIDevice *dev,int pin)
hw/pci.c static void pci_set_irq(void *opaque, int irq_num, int level) · line 1106
Quoted 10 lines
hw/pci.c +7
-0+{ +PCIBus *bus = dev->host_bus; + +assert (bus->route_intx_to_irq); +return bus->route_intx_to_irq (bus->irq_opaque, dev->host_intx_pin[pin]); +} +/***********************************************************/ /* monitor info on PCI */
Just an idea: can devices cache this result, bypassing the intx to irq lookup on data path?
Quoted 6 lines
hw/pci.h +0
-0@@ -141,6 +141,15 @@ enum {#define PCI_DEVICE_GET_CLASS (obj) \
hw/pci.h enum { · line 151
Quoted 10 lines
hw/pci.h +8
-0OBJECT_GET_CLASS(PCIDeviceClass, (obj), TYPE_PCI_DEVICE) +typedef struct PCIINTxRoute { +enum { +PCI_INTX_ENABLED , +PCI_INTX_INVERTED , +PCI_INTX_DISABLED , + } mode; +int irq; +}PCIINTxRoute ;
Is this INTX route or IRQ route?
Is the INTX enabled/disabled/inverted or the IRQ?
I have the impression it's the IRQ, in the apic. PCI INTX are never inverted they are always active low.
Re: [Qemu-devel] [PATCH 05/13] pci: Add pci_device_route_intx_to_irq
Quoted 5 lines · Michael S. Tsirkin
Quoted 4 lines · Jan Kiszka
hw/pci.c +0
-0@@ -1089,6 +1093,14 @@ static void pci_set_irq(void *opaque, int irq_num, int level)pci_change_irq_level (pci_dev, irq_num, change); }
Quoted 14 lines
hw/pci.c static void pci_set_irq(void *opaque, int irq_num, int level) · line 1106
Quoted 11 lines
hw/pci.c +8
-0+PCIINTxRoute pci_device_route_intx_to_irq (PCIDevice *dev,int pin) +{ +PCIBus *bus = dev->host_bus; + +assert (bus->route_intx_to_irq); +return bus->route_intx_to_irq (bus->irq_opaque, dev->host_intx_pin[pin]); +} +/***********************************************************/ /* monitor info on PCI */ Just an idea: can devices cache this result, bypassing the intx to irq lookup on data path?
That lookup is part of set_irq which we don't bypass so far and where this is generally trivial. If we want to cache the effects of set_irq as well, I guess things would become pretty complex (e.g. due to vmstate compatibility), and I'm unsure if it would buy us much.
Quoted 21 lines
Quoted 7 lines
hw/pci.h +0
-0@@ -141,6 +141,15 @@ enum {#define PCI_DEVICE_GET_CLASS (obj) \hw/pci.h enum { · line 151
Quoted 10 lines
hw/pci.h +8
-0OBJECT_GET_CLASS(PCIDeviceClass, (obj), TYPE_PCI_DEVICE) +typedef struct PCIINTxRoute { +enum { +PCI_INTX_ENABLED , +PCI_INTX_INVERTED , +PCI_INTX_DISABLED , + } mode; +int irq; +}PCIINTxRoute ;Is this INTX route or IRQ route?
Is the INTX enabled/disabled/inverted or the IRQ?
Quoted 2 lines
I have the impression it's the IRQ, in the apic. PCI INTX are never inverted they are always active low.
This should be considered as "the route *of* an INTx", not "to some IRQ". I could call it PCIINTxToIRQRoute if you prefer, but it's a bit lengthy.
Jan
Re: [Qemu-devel] [PATCH 05/13] pci: Add pci_device_route_intx_to_irq
Quoted 21 lines · Jan Kiszka
Quoted 5 lines · Michael S. Tsirkin
Quoted 4 lines · Jan Kiszka
hw/pci.c +0
-0@@ -1089,6 +1093,14 @@ static void pci_set_irq(void *opaque, int irq_num, int level)pci_change_irq_level (pci_dev, irq_num, change); }Quoted 14 lines
hw/pci.c static void pci_set_irq(void *opaque, int irq_num, int level) · line 1106
Quoted 11 lines
hw/pci.c +8
-0+PCIINTxRoute pci_device_route_intx_to_irq (PCIDevice *dev,int pin) +{ +PCIBus *bus = dev->host_bus; + +assert (bus->route_intx_to_irq); +return bus->route_intx_to_irq (bus->irq_opaque, dev->host_intx_pin[pin]); +} +/***********************************************************/ /* monitor info on PCI */ Just an idea: can devices cache this result, bypassing the intx to irq lookup on data path?
Quoted 4 lines
That lookup is part of
set_irqwhich we don't bypass so far and where this is generally trivial. If we want to cache the effects ofset_irqas well, I guess things would become pretty complex (e.g. due to vmstate compatibility), and I'm unsure if it would buy us much.
This is less for performance but more for making
everyone use the same infrastructure rather than
assigned devices being the weird case.
Quoted 21 lines
Quoted 21 lines
Quoted 7 lines
hw/pci.h +0
-0@@ -141,6 +141,15 @@ enum {#define PCI_DEVICE_GET_CLASS (obj) \hw/pci.h enum { · line 151
Quoted 10 lines
hw/pci.h +8
-0OBJECT_GET_CLASS(PCIDeviceClass, (obj), TYPE_PCI_DEVICE) +typedef struct PCIINTxRoute { +enum { +PCI_INTX_ENABLED , +PCI_INTX_INVERTED , +PCI_INTX_DISABLED , + } mode; +int irq; +}PCIINTxRoute ;Is this INTX route or IRQ route?
Is the INTX enabled/disabled/inverted or the IRQ?
Quoted 8 lines
Quoted 2 lines
I have the impression it's the IRQ, in the apic. PCI INTX are never inverted they are always active low.
This should be considered as "the route *of* an INTx", not "to some IRQ". I could call it PCIINTxToIRQRoute if you prefer, but it's a bit lengthy.
Jan
Yes but the polarity is in apic? Or is it in host bridge?
Signature · 1 line
MST
Re: [Qemu-devel] [PATCH 05/13] pci: Add pci_device_route_intx_to_irq
Quoted 22 lines · Michael S. Tsirkin
Quoted 21 lines · Jan Kiszka
Quoted 19 lines · Michael S. Tsirkin
Quoted 5 lines · Jan Kiszka
hw/pci.c +1
-0@@ -1089,6 +1093,14 @@ static void pci_set_irq(void *opaque, int irq_num, int level)pci_change_irq_level (pci_dev, irq_num, change); } +PCIINTxRoute pci_device_route_intx_to_irq (PCIDevice *dev,int pin)hw/pci.c static void pci_set_irq(void *opaque, int irq_num, int level) · line 1106
Quoted 10 lines
hw/pci.c +7
-0+{ +PCIBus *bus = dev->host_bus; + +assert (bus->route_intx_to_irq); +return bus->route_intx_to_irq (bus->irq_opaque, dev->host_intx_pin[pin]); +} +/***********************************************************/ /* monitor info on PCI */ Just an idea: can devices cache this result, bypassing the intx to irq lookup on data path?
Quoted 8 lines
Quoted 4 lines
That lookup is part of
set_irqwhich we don't bypass so far and where this is generally trivial. If we want to cache the effects ofset_irqas well, I guess things would become pretty complex (e.g. due to vmstate compatibility), and I'm unsure if it would buy us much.This is less for performance but more for making
everyone use the same infrastructure rather than
assigned devices being the weird case.
Device assignment is weird. It bypasses all state updates as it does not have to bother about migratability.
Well, of course we could cache the host bridge routing result as well, for every device. It would have to be in addition to host_intx_pin. But the result would look pretty strange to me.
In any case, I would prefer to do this, if at all, on top of this series, specifically as it will require to touch all host bridges.
Quoted 25 lines
Quoted 25 lines
Quoted 24 lines
Quoted 8 lines
hw/pci.h +0
-0@@ -141,6 +141,15 @@ enum {#define PCI_DEVICE_GET_CLASS (obj) \hw/pci.h enum { · line 151
Quoted 10 lines
hw/pci.h +8
-0OBJECT_GET_CLASS(PCIDeviceClass, (obj), TYPE_PCI_DEVICE) +typedef struct PCIINTxRoute { +enum { +PCI_INTX_ENABLED , +PCI_INTX_INVERTED , +PCI_INTX_DISABLED , + } mode; +int irq; +}PCIINTxRoute ;Is this INTX route or IRQ route?
Is the INTX enabled/disabled/inverted or the IRQ?I have the impression it's the IRQ, in the apic. PCI INTX are never inverted they are always active low.
Quoted 8 lines
Quoted 5 lines
This should be considered as "the route *of* an INTx", not "to some IRQ". I could call it PCIINTxToIRQRoute if you prefer, but it's a bit lengthy.
Jan
Yes but the polarity is in apic? Or is it in host bridge?
Nope (then we would not have to bother). At least one host bridge (bonito) is apparently able to invert the polarity.
Jan
Re: [Qemu-devel] [PATCH 05/13] pci: Add pci_device_route_intx_to_irq
Quoted 35 lines · Jan Kiszka
Quoted 22 lines · Michael S. Tsirkin
Quoted 21 lines · Jan Kiszka
Quoted 19 lines · Michael S. Tsirkin
Quoted 5 lines · Jan Kiszka
hw/pci.c +1
-0@@ -1089,6 +1093,14 @@ static void pci_set_irq(void *opaque, int irq_num, int level)pci_change_irq_level (pci_dev, irq_num, change); } +PCIINTxRoute pci_device_route_intx_to_irq (PCIDevice *dev,int pin)hw/pci.c static void pci_set_irq(void *opaque, int irq_num, int level) · line 1106
Quoted 10 lines
hw/pci.c +7
-0+{ +PCIBus *bus = dev->host_bus; + +assert (bus->route_intx_to_irq); +return bus->route_intx_to_irq (bus->irq_opaque, dev->host_intx_pin[pin]); +} +/***********************************************************/ /* monitor info on PCI */ Just an idea: can devices cache this result, bypassing the intx to irq lookup on data path?
Quoted 8 lines
Quoted 4 lines
That lookup is part of
set_irqwhich we don't bypass so far and where this is generally trivial. If we want to cache the effects ofset_irqas well, I guess things would become pretty complex (e.g. due to vmstate compatibility), and I'm unsure if it would buy us much.This is less for performance but more for making
everyone use the same infrastructure rather than
assigned devices being the weird case.Device assignment is weird. It bypasses all state updates as it does not have to bother about migratability.
Quoted 6 lines
Well, of course we could cache the host bridge routing result as well, for every device. It would have to be in addition to
host_intx_pin. But the result would look pretty strange to me.In any case, I would prefer to do this, if at all, on top of this series, specifically as it will require to touch all host bridges.
Yes that's fine.
Quoted 39 lines
Quoted 25 lines
Quoted 25 lines
Quoted 24 lines
Quoted 8 lines
hw/pci.h +0
-0@@ -141,6 +141,15 @@ enum {#define PCI_DEVICE_GET_CLASS (obj) \hw/pci.h enum { · line 151
Quoted 10 lines
hw/pci.h +8
-0OBJECT_GET_CLASS(PCIDeviceClass, (obj), TYPE_PCI_DEVICE) +typedef struct PCIINTxRoute { +enum { +PCI_INTX_ENABLED , +PCI_INTX_INVERTED , +PCI_INTX_DISABLED , + } mode; +int irq; +}PCIINTxRoute ;Is this INTX route or IRQ route?
Is the INTX enabled/disabled/inverted or the IRQ?I have the impression it's the IRQ, in the apic. PCI INTX are never inverted they are always active low.
Quoted 8 lines
Quoted 5 lines
This should be considered as "the route *of* an INTx", not "to some IRQ". I could call it PCIINTxToIRQRoute if you prefer, but it's a bit lengthy.
Jan
Yes but the polarity is in apic? Or is it in host bridge?
Nope (then we would not have to bother). At least one host bridge (bonito) is apparently able to invert the polarity.
Jan
Re: [Qemu-devel] [PATCH 05/13] pci: Add pci_device_route_intx_to_irq
In reply to Jan KiszkaQuoted 35 lines · Jan Kiszka
Quoted 22 lines · Michael S. Tsirkin
Quoted 21 lines · Jan Kiszka
Quoted 19 lines · Michael S. Tsirkin
Quoted 5 lines · Jan Kiszka
hw/pci.c +1
-0@@ -1089,6 +1093,14 @@ static void pci_set_irq(void *opaque, int irq_num, int level)pci_change_irq_level (pci_dev, irq_num, change); } +PCIINTxRoute pci_device_route_intx_to_irq (PCIDevice *dev,int pin)hw/pci.c static void pci_set_irq(void *opaque, int irq_num, int level) · line 1106
Quoted 10 lines
hw/pci.c +7
-0+{ +PCIBus *bus = dev->host_bus; + +assert (bus->route_intx_to_irq); +return bus->route_intx_to_irq (bus->irq_opaque, dev->host_intx_pin[pin]); +} +/***********************************************************/ /* monitor info on PCI */ Just an idea: can devices cache this result, bypassing the intx to irq lookup on data path?
Quoted 8 lines
Quoted 4 lines
That lookup is part of
set_irqwhich we don't bypass so far and where this is generally trivial. If we want to cache the effects ofset_irqas well, I guess things would become pretty complex (e.g. due to vmstate compatibility), and I'm unsure if it would buy us much.This is less for performance but more for making
everyone use the same infrastructure rather than
assigned devices being the weird case.Device assignment is weird. It bypasses all state updates as it does not have to bother about migratability.
Quoted 6 lines
Well, of course we could cache the host bridge routing result as well, for every device. It would have to be in addition to
host_intx_pin. But the result would look pretty strange to me.In any case, I would prefer to do this, if at all, on top of this series, specifically as it will require to touch all host bridges.
I'd like to ponder this a bit more then.
If the claim is that device assignment is only needed for piix anyway, then why not make it depend on piix *explicitly*? Yes ugly but this will make it very easy to find and address any missing pieces.
As it is you are adding APIs that in theory address non PIIX issues but in practice don't implement for non PIIX. So we never really know.
Quoted 39 lines
Quoted 25 lines
Quoted 25 lines
Quoted 24 lines
Quoted 8 lines
hw/pci.h +0
-0@@ -141,6 +141,15 @@ enum {#define PCI_DEVICE_GET_CLASS (obj) \hw/pci.h enum { · line 151
Quoted 10 lines
hw/pci.h +8
-0OBJECT_GET_CLASS(PCIDeviceClass, (obj), TYPE_PCI_DEVICE) +typedef struct PCIINTxRoute { +enum { +PCI_INTX_ENABLED , +PCI_INTX_INVERTED , +PCI_INTX_DISABLED , + } mode; +int irq; +}PCIINTxRoute ;Is this INTX route or IRQ route?
Is the INTX enabled/disabled/inverted or the IRQ?I have the impression it's the IRQ, in the apic. PCI INTX are never inverted they are always active low.
Quoted 8 lines
Quoted 5 lines
This should be considered as "the route *of* an INTx", not "to some IRQ". I could call it PCIINTxToIRQRoute if you prefer, but it's a bit lengthy.
Jan
Yes but the polarity is in apic? Or is it in host bridge?
Nope (then we would not have to bother). At least one host bridge (bonito) is apparently able to invert the polarity.
Jan
Re: [Qemu-devel] [PATCH 05/13] pci: Add pci_device_route_intx_to_irq
Quoted 43 lines · Michael S. Tsirkin
Quoted 35 lines · Jan Kiszka
Quoted 22 lines · Michael S. Tsirkin
Quoted 21 lines · Jan Kiszka
Quoted 19 lines · Michael S. Tsirkin
Quoted 5 lines · Jan Kiszka
hw/pci.c +1
-0@@ -1089,6 +1093,14 @@ static void pci_set_irq(void *opaque, int irq_num, int level)pci_change_irq_level (pci_dev, irq_num, change); } +PCIINTxRoute pci_device_route_intx_to_irq (PCIDevice *dev,int pin)hw/pci.c static void pci_set_irq(void *opaque, int irq_num, int level) · line 1106
Quoted 10 lines
hw/pci.c +7
-0+{ +PCIBus *bus = dev->host_bus; + +assert (bus->route_intx_to_irq); +return bus->route_intx_to_irq (bus->irq_opaque, dev->host_intx_pin[pin]); +} +/***********************************************************/ /* monitor info on PCI */ Just an idea: can devices cache this result, bypassing the intx to irq lookup on data path?
Quoted 8 lines
Quoted 4 lines
That lookup is part of
set_irqwhich we don't bypass so far and where this is generally trivial. If we want to cache the effects ofset_irqas well, I guess things would become pretty complex (e.g. due to vmstate compatibility), and I'm unsure if it would buy us much.This is less for performance but more for making
everyone use the same infrastructure rather than
assigned devices being the weird case.Device assignment is weird. It bypasses all state updates as it does not have to bother about migratability.
Quoted 6 lines
Well, of course we could cache the host bridge routing result as well, for every device. It would have to be in addition to
host_intx_pin. But the result would look pretty strange to me.In any case, I would prefer to do this, if at all, on top of this series, specifically as it will require to touch all host bridges.
Quoted 6 lines
I'd like to ponder this a bit more then.
If the claim is that device assignment is only needed for piix anyway, then why not make it depend on piix *explicitly*? Yes ugly but this will make it very easy to find and address any missing pieces.
Because it is conceptually independent of the PIIX, we will need it for successors of that x86 chipset as well, and I won't add the ugly hack of qemu-kvm upstream
Quoted 4 lines
As it is you are adding APIs that in theory address non PIIX issues but in practice don't implement for non PIIX. So we never really know.
I once hacked q35 to make it work with device assignment. This really requires something like this. It actually requires something generic, independent of PCI, but that's too much for this round.
Jan
Re: [Qemu-devel] [PATCH 05/13] pci: Add pci_device_route_intx_to_irq
Quoted 46 lines · Jan Kiszka
Quoted 45 lines · Michael S. Tsirkin
Quoted 35 lines · Jan Kiszka
Quoted 22 lines · Michael S. Tsirkin
Quoted 21 lines · Jan Kiszka
Quoted 19 lines · Michael S. Tsirkin
Quoted 5 lines · Jan Kiszka
(quoted diff) +1
-0@@ -1089,6 +1093,14 @@ static void pci_set_irq(void *opaque, int irq_num, int level) pci_change_irq_level(pci_dev, irq_num, change); } +PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin)Review static void pci_set_irq(void *opaque, int irq_num, int level) · line 1106
Quoted 10 lines
(quoted diff) +7
-0+{ + PCIBus *bus = dev->host_bus; + + assert(bus->route_intx_to_irq); + return bus->route_intx_to_irq(bus->irq_opaque, dev->host_intx_pin[pin]); +} + /***********************************************************/ /* monitor info on PCI */Just an idea: can devices cache this result, bypassing the intx to irq lookup on data path?
Quoted 8 lines
Quoted 4 lines
That lookup is part of
set_irqwhich we don't bypass so far and where this is generally trivial. If we want to cache the effects ofset_irqas well, I guess things would become pretty complex (e.g. due to vmstate compatibility), and I'm unsure if it would buy us much.This is less for performance but more for making
everyone use the same infrastructure rather than
assigned devices being the weird case.Device assignment is weird. It bypasses all state updates as it does not have to bother about migratability.
Quoted 6 lines
Well, of course we could cache the host bridge routing result as well, for every device. It would have to be in addition to
host_intx_pin. But the result would look pretty strange to me.In any case, I would prefer to do this, if at all, on top of this series, specifically as it will require to touch all host bridges.
I'd like to ponder this a bit more then.
Quoted 8 lines
Quoted 4 lines
If the claim is that device assignment is only needed for piix anyway, then why not make it depend on piix *explicitly*? Yes ugly but this will make it very easy to find and address any missing pieces.
Because it is conceptually independent of the PIIX, we will need it for successors of that x86 chipset as well, and I won't add the ugly hack of qemu-kvm upstream
So you look at an API and see it requires a route callback. And you ask "why doesn't chipset X implement it"? And the answer is "because it's only used by device assignment". Which you will only know if you read this thread. So it's a hack. And I'd rather have the hacks in device-assignment.c than in pci.c even if the former are nastier.
Quoted 7 lines
Quoted 4 lines
As it is you are adding APIs that in theory address non PIIX issues but in practice don't implement for non PIIX. So we never really know.
I once hacked q35 to make it work with device assignment. This really requires something like this.
Yes I'm aware of this motivation. This does not do much to address the concerns though.
Quoted 4 lines
It actually requires something generic, independent of PCI, but that's too much for this round.
Jan
And this just makes the concerns worse :(
Signature · 1 line
MST
Re: [Qemu-devel] [PATCH 05/13] pci: Add pci_device_route_intx_to_irq
Quoted 56 lines · Michael S. Tsirkin
Quoted 46 lines · Jan Kiszka
Quoted 45 lines · Michael S. Tsirkin
Quoted 35 lines · Jan Kiszka
Quoted 22 lines · Michael S. Tsirkin
Quoted 21 lines · Jan Kiszka
Quoted 19 lines · Michael S. Tsirkin
Quoted 5 lines · Jan Kiszka
(quoted diff) +1
-0@@ -1089,6 +1093,14 @@ static void pci_set_irq(void *opaque, int irq_num, int level) pci_change_irq_level(pci_dev, irq_num, change); } +PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin)Review static void pci_set_irq(void *opaque, int irq_num, int level) · line 1106
Quoted 10 lines
(quoted diff) +7
-0+{ + PCIBus *bus = dev->host_bus; + + assert(bus->route_intx_to_irq); + return bus->route_intx_to_irq(bus->irq_opaque, dev->host_intx_pin[pin]); +} + /***********************************************************/ /* monitor info on PCI */Just an idea: can devices cache this result, bypassing the intx to irq lookup on data path?
Quoted 8 lines
Quoted 4 lines
That lookup is part of
set_irqwhich we don't bypass so far and where this is generally trivial. If we want to cache the effects ofset_irqas well, I guess things would become pretty complex (e.g. due to vmstate compatibility), and I'm unsure if it would buy us much.This is less for performance but more for making
everyone use the same infrastructure rather than
assigned devices being the weird case.Device assignment is weird. It bypasses all state updates as it does not have to bother about migratability.
Quoted 6 lines
Well, of course we could cache the host bridge routing result as well, for every device. It would have to be in addition to
host_intx_pin. But the result would look pretty strange to me.In any case, I would prefer to do this, if at all, on top of this series, specifically as it will require to touch all host bridges.
I'd like to ponder this a bit more then.
Quoted 8 lines
Quoted 4 lines
If the claim is that device assignment is only needed for piix anyway, then why not make it depend on piix *explicitly*? Yes ugly but this will make it very easy to find and address any missing pieces.
Because it is conceptually independent of the PIIX, we will need it for successors of that x86 chipset as well, and I won't add the ugly hack of qemu-kvm upstream
Quoted 6 lines
So you look at an API and see it requires a route callback. And you ask "why doesn't chipset X implement it"? And the answer is "because it's only used by device assignment". Which you will only know if you read this thread. So it's a hack. And I'd rather have the hacks in
device-assignment.cthan inpci.ceven if the former are nastier.
I don't share your view on this. It is surely _not_ a hack, specifically when compared to what we have so far and what could be done otherwise, e.g. hacking device-assignment and PIIX to make them cooperate (sorry, I would vote against such an attempt). This is just a partially used generic API. Any chipset not providing the required routing function will cause an assert once some tries to make use of it.
So, what can I do to make this API more acceptable for you?
Jan
Re: [Qemu-devel] [PATCH 05/13] pci: Add pci_device_route_intx_to_irq
Quoted 71 lines · Jan Kiszka
Quoted 56 lines · Michael S. Tsirkin
Quoted 46 lines · Jan Kiszka
Quoted 45 lines · Michael S. Tsirkin
Quoted 35 lines · Jan Kiszka
Quoted 22 lines · Michael S. Tsirkin
Quoted 21 lines · Jan Kiszka
Quoted 19 lines · Michael S. Tsirkin
Quoted 5 lines · Jan Kiszka
(quoted diff) +1
-0@@ -1089,6 +1093,14 @@ static void pci_set_irq(void *opaque, int irq_num, int level) pci_change_irq_level(pci_dev, irq_num, change); } +PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin)Review static void pci_set_irq(void *opaque, int irq_num, int level) · line 1106
Quoted 10 lines
(quoted diff) +7
-0+{ + PCIBus *bus = dev->host_bus; + + assert(bus->route_intx_to_irq); + return bus->route_intx_to_irq(bus->irq_opaque, dev->host_intx_pin[pin]); +} + /***********************************************************/ /* monitor info on PCI */Just an idea: can devices cache this result, bypassing the intx to irq lookup on data path?
Quoted 8 lines
Quoted 4 lines
That lookup is part of
set_irqwhich we don't bypass so far and where this is generally trivial. If we want to cache the effects ofset_irqas well, I guess things would become pretty complex (e.g. due to vmstate compatibility), and I'm unsure if it would buy us much.This is less for performance but more for making
everyone use the same infrastructure rather than
assigned devices being the weird case.Device assignment is weird. It bypasses all state updates as it does not have to bother about migratability.
Quoted 6 lines
Well, of course we could cache the host bridge routing result as well, for every device. It would have to be in addition to
host_intx_pin. But the result would look pretty strange to me.In any case, I would prefer to do this, if at all, on top of this series, specifically as it will require to touch all host bridges.
I'd like to ponder this a bit more then.
Quoted 8 lines
Quoted 4 lines
If the claim is that device assignment is only needed for piix anyway, then why not make it depend on piix *explicitly*? Yes ugly but this will make it very easy to find and address any missing pieces.
Because it is conceptually independent of the PIIX, we will need it for successors of that x86 chipset as well, and I won't add the ugly hack of qemu-kvm upstream
Quoted 6 lines
So you look at an API and see it requires a route callback. And you ask "why doesn't chipset X implement it"? And the answer is "because it's only used by device assignment". Which you will only know if you read this thread. So it's a hack. And I'd rather have the hacks in
device-assignment.cthan inpci.ceven if the former are nastier.I don't share your view on this. It is surely _not_ a hack, specifically when compared to what we have so far and what could be done otherwise, e.g. hacking device-assignment and PIIX to make them cooperate (sorry, I would vote against such an attempt). This is just a partially used generic API. Any chipset not providing the required routing function will cause an assert once some tries to make use of it.
Quoted 4 lines
So, what can I do to make this API more acceptable for you?
Jan
The idea that I suggested above would address this concern. Or wait a bit, maybe I'll come around when I ponder the alternatives.
Signature · 1 line
MST
Re: [Qemu-devel] [PATCH 05/13] pci: Add pci_device_route_intx_to_irq
In reply to Jan KiszkaQuoted 64 lines · Jan Kiszka
Quoted 56 lines · Michael S. Tsirkin
Quoted 46 lines · Jan Kiszka
Quoted 45 lines · Michael S. Tsirkin
Quoted 35 lines · Jan Kiszka
Quoted 22 lines · Michael S. Tsirkin
Quoted 21 lines · Jan Kiszka
Quoted 19 lines · Michael S. Tsirkin
Quoted 5 lines · Jan Kiszka
(quoted diff) +1
-0@@ -1089,6 +1093,14 @@ static void pci_set_irq(void *opaque, int irq_num, int level) pci_change_irq_level(pci_dev, irq_num, change); } +PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin)Review static void pci_set_irq(void *opaque, int irq_num, int level) · line 1106
Quoted 10 lines
(quoted diff) +7
-0+{ + PCIBus *bus = dev->host_bus; + + assert(bus->route_intx_to_irq); + return bus->route_intx_to_irq(bus->irq_opaque, dev->host_intx_pin[pin]); +} + /***********************************************************/ /* monitor info on PCI */Just an idea: can devices cache this result, bypassing the intx to irq lookup on data path?
Quoted 8 lines
Quoted 4 lines
That lookup is part of
set_irqwhich we don't bypass so far and where this is generally trivial. If we want to cache the effects ofset_irqas well, I guess things would become pretty complex (e.g. due to vmstate compatibility), and I'm unsure if it would buy us much.This is less for performance but more for making
everyone use the same infrastructure rather than
assigned devices being the weird case.Device assignment is weird. It bypasses all state updates as it does not have to bother about migratability.
Quoted 6 lines
Well, of course we could cache the host bridge routing result as well, for every device. It would have to be in addition to
host_intx_pin. But the result would look pretty strange to me.In any case, I would prefer to do this, if at all, on top of this series, specifically as it will require to touch all host bridges.
I'd like to ponder this a bit more then.
Quoted 8 lines
Quoted 4 lines
If the claim is that device assignment is only needed for piix anyway, then why not make it depend on piix *explicitly*? Yes ugly but this will make it very easy to find and address any missing pieces.
Because it is conceptually independent of the PIIX, we will need it for successors of that x86 chipset as well, and I won't add the ugly hack of qemu-kvm upstream
Quoted 6 lines
So you look at an API and see it requires a route callback. And you ask "why doesn't chipset X implement it"? And the answer is "because it's only used by device assignment". Which you will only know if you read this thread. So it's a hack. And I'd rather have the hacks in
device-assignment.cthan inpci.ceven if the former are nastier.
Quoted 6 lines
I don't share your view on this. It is surely _not_ a hack, specifically when compared to what we have so far and what could be done otherwise, e.g. hacking device-assignment and PIIX to make them cooperate (sorry, I would vote against such an attempt). This is just a partially used generic API. Any chipset not providing the required routing function will cause an assert once some tries to make use of it.
I agree, and frankly it sounds like a rather biased attitude against device assignment. piix and q35 may be the only initial chipsets to implement this, but VFIO is designed to be architecture neutral. It's already working on POWER. Interrupt routing is one of the most intrusive parts because we cannot know from inside the device assignment code how the chipset exposes intx out to an irq. Jan's interface makes it easy for a chipset to add this, versus hacks in device assignment code, even if they were possible. If it needs to be tweaked for other chipsets, we'll do that when they come. Please don't roadblock device assignment or VFIO support by not allowing us a well architected, generic interface to track interrupts. Thanks,
Alex
Re: [Qemu-devel] [PATCH 05/13] pci: Add pci_device_route_intx_to_irq
Quoted 72 lines · Alex Williamson
Quoted 64 lines · Jan Kiszka
Quoted 56 lines · Michael S. Tsirkin
Quoted 46 lines · Jan Kiszka
Quoted 45 lines · Michael S. Tsirkin
Quoted 35 lines · Jan Kiszka
Quoted 22 lines · Michael S. Tsirkin
Quoted 21 lines · Jan Kiszka
Quoted 19 lines · Michael S. Tsirkin
Quoted 5 lines · Jan Kiszka
(quoted diff) +1
-0@@ -1089,6 +1093,14 @@ static void pci_set_irq(void *opaque, int irq_num, int level) pci_change_irq_level(pci_dev, irq_num, change); } +PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin)Review static void pci_set_irq(void *opaque, int irq_num, int level) · line 1106
Quoted 10 lines
(quoted diff) +7
-0+{ + PCIBus *bus = dev->host_bus; + + assert(bus->route_intx_to_irq); + return bus->route_intx_to_irq(bus->irq_opaque, dev->host_intx_pin[pin]); +} + /***********************************************************/ /* monitor info on PCI */Just an idea: can devices cache this result, bypassing the intx to irq lookup on data path?
Quoted 8 lines
Quoted 4 lines
That lookup is part of
set_irqwhich we don't bypass so far and where this is generally trivial. If we want to cache the effects ofset_irqas well, I guess things would become pretty complex (e.g. due to vmstate compatibility), and I'm unsure if it would buy us much.This is less for performance but more for making
everyone use the same infrastructure rather than
assigned devices being the weird case.Device assignment is weird. It bypasses all state updates as it does not have to bother about migratability.
Quoted 6 lines
Well, of course we could cache the host bridge routing result as well, for every device. It would have to be in addition to
host_intx_pin. But the result would look pretty strange to me.In any case, I would prefer to do this, if at all, on top of this series, specifically as it will require to touch all host bridges.
I'd like to ponder this a bit more then.
Quoted 8 lines
Quoted 4 lines
If the claim is that device assignment is only needed for piix anyway, then why not make it depend on piix *explicitly*? Yes ugly but this will make it very easy to find and address any missing pieces.
Because it is conceptually independent of the PIIX, we will need it for successors of that x86 chipset as well, and I won't add the ugly hack of qemu-kvm upstream
Quoted 6 lines
So you look at an API and see it requires a route callback. And you ask "why doesn't chipset X implement it"? And the answer is "because it's only used by device assignment". Which you will only know if you read this thread. So it's a hack. And I'd rather have the hacks in
device-assignment.cthan inpci.ceven if the former are nastier.Quoted 6 lines
I don't share your view on this. It is surely _not_ a hack, specifically when compared to what we have so far and what could be done otherwise, e.g. hacking device-assignment and PIIX to make them cooperate (sorry, I would vote against such an attempt). This is just a partially used generic API. Any chipset not providing the required routing function will cause an assert once some tries to make use of it.
Quoted 5 lines
I agree, and frankly it sounds like a rather biased attitude against device assignment.
piix and q35 may be the only initial chipsets to
implement this, but VFIO is designed to be architecture neutral. It's already working on POWER.
Not with this patch it doesn't.
Quoted 10 lines
Interrupt routing is one of the most
intrusive parts because we cannot know from inside the device assignment code how the chipset exposes intx out to an irq. Jan's interface makes it easy for a chipset to add this, versus hacks in device assignment code, even if they were possible. If it needs to be tweaked for other chipsets, we'll do that when they come. Please don't roadblock device assignment or VFIO support by not allowing us a well architected, generic interface to track interrupts. Thanks,Alex
Problems are:
1. This sticks NULL in all chipsets except one. This means it's hard to find and fill out.
2. Adds a function, in every chipset, that is only used by assignment. This means many maintainers have no way to test it.
Ways to handle this that came up so far, in order of my preference:
1. Cache all of route in devices.
2. Some ugly hack in device assignment.
3. Merge as is and fix it when it gets broken.
So if you expect me to merge this work, then either Jan does (1), or gives up and does (2), or I find some time and do (1), or I fail to do
(1) and get convinced that we need to do (3). Or someone else gets involved.
Signature · 1 line
MST
Re: [Qemu-devel] [PATCH 05/13] pci: Add pci_device_route_intx_to_irq
Quoted 73 lines · Michael S. Tsirkin
Quoted 72 lines · Alex Williamson
Quoted 70 lines · Jan Kiszka
Quoted 56 lines · Michael S. Tsirkin
Quoted 46 lines · Jan Kiszka
Quoted 45 lines · Michael S. Tsirkin
Quoted 35 lines · Jan Kiszka
Quoted 22 lines · Michael S. Tsirkin
Quoted 21 lines · Jan Kiszka
Quoted 19 lines · Michael S. Tsirkin
Quoted 5 lines · Jan Kiszka
(quoted diff) +1
-0@@ -1089,6 +1093,14 @@ static void pci_set_irq(void *opaque, int irq_num, int level) pci_change_irq_level(pci_dev, irq_num, change); } +PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin)Review static void pci_set_irq(void *opaque, int irq_num, int level) · line 1106
Quoted 10 lines
(quoted diff) +7
-0+{ + PCIBus *bus = dev->host_bus; + + assert(bus->route_intx_to_irq); + return bus->route_intx_to_irq(bus->irq_opaque, dev->host_intx_pin[pin]); +} + /***********************************************************/ /* monitor info on PCI */Just an idea: can devices cache this result, bypassing the intx to irq lookup on data path?
Quoted 8 lines
Quoted 4 lines
That lookup is part of
set_irqwhich we don't bypass so far and where this is generally trivial. If we want to cache the effects ofset_irqas well, I guess things would become pretty complex (e.g. due to vmstate compatibility), and I'm unsure if it would buy us much.This is less for performance but more for making
everyone use the same infrastructure rather than
assigned devices being the weird case.Device assignment is weird. It bypasses all state updates as it does not have to bother about migratability.
Quoted 6 lines
Well, of course we could cache the host bridge routing result as well, for every device. It would have to be in addition to
host_intx_pin. But the result would look pretty strange to me.In any case, I would prefer to do this, if at all, on top of this series, specifically as it will require to touch all host bridges.
I'd like to ponder this a bit more then.
Quoted 8 lines
Quoted 4 lines
If the claim is that device assignment is only needed for piix anyway, then why not make it depend on piix *explicitly*? Yes ugly but this will make it very easy to find and address any missing pieces.
Because it is conceptually independent of the PIIX, we will need it for successors of that x86 chipset as well, and I won't add the ugly hack of qemu-kvm upstream
Quoted 6 lines
So you look at an API and see it requires a route callback. And you ask "why doesn't chipset X implement it"? And the answer is "because it's only used by device assignment". Which you will only know if you read this thread. So it's a hack. And I'd rather have the hacks in
device-assignment.cthan inpci.ceven if the former are nastier.I don't share your view on this. It is surely _not_ a hack, specifically when compared to what we have so far and what could be done otherwise, e.g. hacking device-assignment and PIIX to make them cooperate (sorry, I would vote against such an attempt). This is just a partially used generic API. Any chipset not providing the required routing function will cause an assert once some tries to make use of it.
Quoted 7 lines
Quoted 5 lines
I agree, and frankly it sounds like a rather biased attitude against device assignment.
piix and q35 may be the only initial chipsets to
implement this, but VFIO is designed to be architecture neutral. It's already working on POWER.Not with this patch it doesn't.
Alexey, how are you handling INTx routing and EOI on POWER?
Quoted 9 lines
Quoted 9 lines
Interrupt routing is one of the most
intrusive parts because we cannot know from inside the device assignment code how the chipset exposes intx out to an irq. Jan's interface makes it easy for a chipset to add this, versus hacks in device assignment code, even if they were possible. If it needs to be tweaked for other chipsets, we'll do that when they come. Please don't roadblock device assignment or VFIO support by not allowing us a well architected, generic interface to track interrupts. Thanks,
Quoted 5 lines
Quoted 1 line
Alex
Problems are:
1. This sticks NULL in all chipsets except one. This means it's hard to find and fill out.
I don't buy that. Look for all the callers, find the one that's not NULL, look at what it does... How's that a problem? This can be solved by documentation.
Quoted 2 lines
2. Adds a function, in every chipset, that is only used by assignment. This means many maintainers have no way to test it.
It's effectively optional, so they don't have to implement it. They can wait to care about it until they want device assignment. This can also be solved by documentation so the maintainer knows when and how this is used and can choose to implement it or not.
Quoted 2 lines
Ways to handle this that came up so far, in order of my preference:
1. Cache all of route in devices.
How do we get the route to cache it?
Quoted 1 line
2. Some ugly hack in device assignment.
We still have the problem of how do we get the route to start with?
Quoted 1 line
3. Merge as is and fix it when it gets broken.
Isn't that how open source works? ;^)
Quoted 4 lines
So if you expect me to merge this work, then either Jan does (1), or gives up and does (2), or I find some time and do (1), or I fail to do
(1) and get convinced that we need to do (3). Or someone else gets involved.
I still have trouble seeing how (3) is a problem. The translation of an INTx to an irq is chipset specific. We need a chipset function to perform that transform. We don't know how to do this for every chipset in the tree, nor do many of those chipset care at the moment about device assignment. Jan has created an arrangement where chipsets can easily opt-in to this support. Aside from asking us to go spend a month digging up specs for every chipset in tree and trying to implement this ourselves, what kind of enhancement to the interface are you looking for? Thanks,
Alex
Re: [Qemu-devel] [PATCH 05/13] pci: Add pci_device_route_intx_to_irq
Quoted 95 lines · Alex Williamson
Quoted 73 lines · Michael S. Tsirkin
Quoted 72 lines · Alex Williamson
Quoted 70 lines · Jan Kiszka
Quoted 56 lines · Michael S. Tsirkin
Quoted 46 lines · Jan Kiszka
Quoted 45 lines · Michael S. Tsirkin
Quoted 35 lines · Jan Kiszka
Quoted 22 lines · Michael S. Tsirkin
Quoted 21 lines · Jan Kiszka
Quoted 19 lines · Michael S. Tsirkin
Quoted 5 lines · Jan Kiszka
(quoted diff) +1
-0@@ -1089,6 +1093,14 @@ static void pci_set_irq(void *opaque, int irq_num, int level) pci_change_irq_level(pci_dev, irq_num, change); } +PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin)Review static void pci_set_irq(void *opaque, int irq_num, int level) · line 1106
Quoted 10 lines
(quoted diff) +7
-0+{ + PCIBus *bus = dev->host_bus; + + assert(bus->route_intx_to_irq); + return bus->route_intx_to_irq(bus->irq_opaque, dev->host_intx_pin[pin]); +} + /***********************************************************/ /* monitor info on PCI */Just an idea: can devices cache this result, bypassing the intx to irq lookup on data path?
Quoted 8 lines
Quoted 4 lines
That lookup is part of
set_irqwhich we don't bypass so far and where this is generally trivial. If we want to cache the effects ofset_irqas well, I guess things would become pretty complex (e.g. due to vmstate compatibility), and I'm unsure if it would buy us much.This is less for performance but more for making
everyone use the same infrastructure rather than
assigned devices being the weird case.Device assignment is weird. It bypasses all state updates as it does not have to bother about migratability.
Quoted 6 lines
Well, of course we could cache the host bridge routing result as well, for every device. It would have to be in addition to
host_intx_pin. But the result would look pretty strange to me.In any case, I would prefer to do this, if at all, on top of this series, specifically as it will require to touch all host bridges.
I'd like to ponder this a bit more then.
Quoted 8 lines
Quoted 4 lines
If the claim is that device assignment is only needed for piix anyway, then why not make it depend on piix *explicitly*? Yes ugly but this will make it very easy to find and address any missing pieces.
Because it is conceptually independent of the PIIX, we will need it for successors of that x86 chipset as well, and I won't add the ugly hack of qemu-kvm upstream
Quoted 6 lines
So you look at an API and see it requires a route callback. And you ask "why doesn't chipset X implement it"? And the answer is "because it's only used by device assignment". Which you will only know if you read this thread. So it's a hack. And I'd rather have the hacks in
device-assignment.cthan inpci.ceven if the former are nastier.I don't share your view on this. It is surely _not_ a hack, specifically when compared to what we have so far and what could be done otherwise, e.g. hacking device-assignment and PIIX to make them cooperate (sorry, I would vote against such an attempt). This is just a partially used generic API. Any chipset not providing the required routing function will cause an assert once some tries to make use of it.
Quoted 7 lines
Quoted 5 lines
I agree, and frankly it sounds like a rather biased attitude against device assignment.
piix and q35 may be the only initial chipsets to
implement this, but VFIO is designed to be architecture neutral. It's already working on POWER.Not with this patch it doesn't.
Alexey, how are you handling INTx routing and EOI on POWER?
Quoted 11 lines
Quoted 10 lines
Interrupt routing is one of the most
intrusive parts because we cannot know from inside the device assignment code how the chipset exposes intx out to an irq. Jan's interface makes it easy for a chipset to add this, versus hacks in device assignment code, even if they were possible. If it needs to be tweaked for other chipsets, we'll do that when they come. Please don't roadblock device assignment or VFIO support by not allowing us a well architected, generic interface to track interrupts. Thanks,Alex
Quoted 7 lines
Quoted 3 lines
Problems are:
1. This sticks NULL in all chipsets except one. This means it's hard to find and fill out.I don't buy that. Look for all the callers, find the one that's not NULL, look at what it does... How's that a problem? This can be solved by documentation.
Yes but it's not there.
Quoted 7 lines
Quoted 2 lines
2. Adds a function, in every chipset, that is only used by assignment. This means many maintainers have no way to test it.
It's effectively optional, so they don't have to implement it. They can wait to care about it until they want device assignment. This can also be solved by documentation so the maintainer knows when and how this is used and can choose to implement it or not.
No, what I meant is it's hard to test on systems where it's implemented.
Quoted 4 lines
Quoted 2 lines
Ways to handle this that came up so far, in order of my preference:
1. Cache all of route in devices.How do we get the route to cache it?
Move routing logic from piix3_set_irq_level
to a route_intx callback, or equivalent.
Then you just look it up in device->root_route.
Quoted 3 lines
Quoted 1 line
2. Some ugly hack in device assignment.
We still have the problem of how do we get the route to start with?
You are asking how an ugly hack might work? Think it up yourself, I'm not gonnu mention hacks at this point yet.
Quoted 3 lines
Quoted 1 line
3. Merge as is and fix it when it gets broken.
Isn't that how open source works? ;^)
It works by darwinism. This is exactly what's going on here.
Quoted 15 lines
Quoted 4 lines
So if you expect me to merge this work, then either Jan does (1), or gives up and does (2), or I find some time and do (1), or I fail to do
(1) and get convinced that we need to do (3). Or someone else gets involved.I still have trouble seeing how (3) is a problem. The translation of an INTx to an irq is chipset specific. We need a chipset function to perform that transform. We don't know how to do this for every chipset in the tree, nor do many of those chipset care at the moment about device assignment. Jan has created an arrangement where chipsets can easily opt-in to this support. Aside from asking us to go spend a month digging up specs for every chipset in tree and trying to implement this ourselves, what kind of enhancement to the interface are you looking for? Thanks,
Quoted 1 line
Alex
Sorry I don't understand what you are talking about.
It's better to have one way to determine interrupt routing than two. It can be done, and IIUC Jan doesn't disagree.
There are gnarly issues related to migration compatibility
with old qemu sorrounding the solution which makes Jan think it's too complex, but nothing remotely related to digging up any specs.
Signature · 1 line
MST
Re: [Qemu-devel] [PATCH 05/13] pci: Add pci_device_route_intx_to_irq
Quoted 15 lines · Michael S. Tsirkin
Quoted 15 lines
Quoted 4 lines
So if you expect me to merge this work, then either Jan does (1), or gives up and does (2), or I find some time and do (1), or I fail to do
(1) and get convinced that we need to do (3). Or someone else gets involved.I still have trouble seeing how (3) is a problem. The translation of an INTx to an irq is chipset specific. We need a chipset function to perform that transform. We don't know how to do this for every chipset in the tree, nor do many of those chipset care at the moment about device assignment. Jan has created an arrangement where chipsets can easily opt-in to this support. Aside from asking us to go spend a month digging up specs for every chipset in tree and trying to implement this ourselves, what kind of enhancement to the interface are you looking for? Thanks,
Quoted 8 lines
Quoted 1 line
Alex
Sorry I don't understand what you are talking about.
It's better to have one way to determine interrupt routing than two. It can be done, and IIUC Jan doesn't disagree.
There are gnarly issues related to migration compatibility
with old qemu sorrounding the solution which makes Jan think it's too complex, but nothing remotely related to digging up any specs.
Caching the host bridge generically means changing all chipsets and, well, also testing that they still work afterward. As explained before, I'd really like to avoid doing this in a single step.
And there are still migration issues - as explained based on the PIIX3. Until it is officially stated that we give up on backward migratability, it will be quite some effort (ie. lots of additional code) to provide compatibility on top of generic intx-to-irq routing.
This interface here is surely not the perfect solution. But it is better than a) hacking device assignment and VFIO into a specific chipset and
b) starting a huge refactoring now. We can surely tweak some aspects of this approach before merging, e.g. documentation. But lets try to move forward in small, well testable steps. I really don't see the need for touching all chipsets and migration formats for this purpose ATM.
Jan
Re: [Qemu-devel] [PATCH 05/13] pci: Add pci_device_route_intx_to_irq
Quoted 3 lines · Jan Kiszka
Caching the host bridge generically means changing all chipsets and, well, also testing that they still work afterward. As explained before, I'd really like to avoid doing this in a single step.
Surely it is not hard to find a way to switch chipsets gradually.
Signature · 1 line
MST
Re: [Qemu-devel] [PATCH 05/13] pci: Add pci_device_route_intx_to_irq
Quoted 6 lines · Michael S. Tsirkin
Quoted 3 lines · Jan Kiszka
Caching the host bridge generically means changing all chipsets and, well, also testing that they still work afterward. As explained before, I'd really like to avoid doing this in a single step.
Surely it is not hard to find a way to switch chipsets gradually.
Just to stress: the problem is that with this patch there are 2 ways to get routing even for piix.
So instead of your patch which caches just intx route
but always, and which I applied, you could have one that only caches if the root supplies a new route callback.
Then to set irq, you check cache and if not valid, fallback on the legacy interface.
With time we convert everyone and drop the legacy interface.
Quoted 2 lines
Signature · 1 line
MST
PATCH 6/13 pci: Add INTx routing notifier
In reply to Jan KiszkaThis per-device notifier shall be triggered by any interrupt router along the path of a device's legacy interrupt signal on routing changes. For simplicity reasons and as this is a slow path anyway, no further details on the routing changes are provided. Instead, the callback is expected to use pci_device_get_host_irq to check the effect of the change.
Will be used by KVM PCI device assignment and VFIO.
--- hw/pci.c | 19 +++++++++++++++++++ hw/pci.h | 7 +++++++ hw/pci_bridge.c | 8 ++++++++ hw/piix_pci.c | 2 ++ 4 files changed, 36 insertions(+), 0 deletions(-)
hw/pci.c +19 -0
@@ -1101,6 +1101,25 @@ PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin)return bus->route_intx_to_irq (bus->irq_opaque, dev->host_intx_pin[pin]); } +void pci_bus_fire_intx_routing_notifier (PCIBus *bus) +{ +PCIDevice *dev; +int i; + +for (i =0 ; i <ARRAY_SIZE (bus->devices); ++i) { + dev = bus->devices[i]; +if (dev && dev->intx_routing_notifier) { + dev->intx_routing_notifier (dev); + } + } +} + +void pci_device_set_intx_routing_notifier (PCIDevice *dev, +INTxRoutingNotifier notifier) +{ + dev->intx_routing_notifier = notifier; +} +/***********************************************************/ /* monitor info on PCI */
hw/pci.h +7 -0
@@ -182,6 +182,7 @@ typedef struct PCIDeviceClass {const char *romfile; } PCIDeviceClass; +typedef void (*INTxRoutingNotifier )(PCIDevice *dev);typedef int (*MSIVectorUseNotifier )(PCIDevice *dev,unsigned int vector,MSIMessage msg);typedef void (*MSIVectorReleaseNotifier )(PCIDevice *dev,unsigned int vector);
@@ -261,6 +262,9 @@ struct PCIDevice {MemoryRegion rom;uint32_t rom_bar; +/* INTx routing notifier */ +INTxRoutingNotifier intx_routing_notifier; +/* MSI-X notifiers */ MSIVectorUseNotifier msix_vector_use_notifier;MSIVectorReleaseNotifier msix_vector_release_notifier;
@@ -318,6 +322,9 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name,MemoryRegion *address_space_io, uint8_t devfn_min, int nirq);PCIINTxRoute pci_device_route_intx_to_irq (PCIDevice *dev,int pin); +void pci_bus_fire_intx_routing_notifier (PCIBus *bus); +void pci_device_set_intx_routing_notifier (PCIDevice *dev, +INTxRoutingNotifier notifier);void pci_device_reset (PCIDevice *dev);void pci_bus_reset (PCIBus *bus);
hw/pci_bridge.c +8 -0
@@ -298,6 +298,13 @@ void pci_bridge_reset(DeviceState *qdev)pci_bridge_reset_reg (dev); } +static void pci_bridge_intx_routing_update (PCIDevice *dev) +{ +PCIBridge *br =DO_UPCAST (PCIBridge, dev, dev); + +pci_bus_fire_intx_routing_notifier (&br->sec_bus); +} +/* default qdev initialization function for PCI-to-PCI bridge */ int pci_bridge_initfn (PCIDevice *dev) {
@@ -333,6 +340,7 @@ int pci_bridge_initfn(PCIDevice *dev) sec_bus->address_space_io = &br->address_space_io;memory_region_init (&br->address_space_io,"pci_bridge_io" ,65536 );pci_bridge_region_init (br); +pci_device_set_intx_routing_notifier (dev, pci_bridge_intx_routing_update);QLIST_INIT (&sec_bus->child);QLIST_INSERT_HEAD (&parent->child, sec_bus, sibling);return 0 ;
hw/piix_pci.c +2 -0
@@ -422,6 +422,8 @@ static void piix3_write_config(PCIDevice *dev,if (ranges_overlap (address, len,PIIX_PIRQC ,4 )) {PIIX3State *piix3 =DO_UPCAST (PIIX3State, dev, dev);int pic_irq; + +pci_bus_fire_intx_routing_notifier (piix3->dev.bus);piix3_update_irq_levels (piix3);for (pic_irq =0 ; pic_irq <PIIX_NUM_PIC_IRQS ; pic_irq++) {piix3_set_irq_pic (piix3, pic_irq);
Signature · 1 line
1.7.3.4
Re: [Qemu-devel] [PATCH 06/13] pci: Add INTx routing notifier
Quoted 6 lines · Jan Kiszka
This per-device notifier shall be triggered by any interrupt router along the path of a device's legacy interrupt signal on routing changes. For simplicity reasons and as this is a slow path anyway, no further details on the routing changes are provided. Instead, the callback is expected to use
pci_device_get_host_irqto check the effect of the change.
pci_device_get_host_irq isn't in the cards anymore, no?
Quoted 114 lines
Will be used by KVM PCI device assignment and VFIO.
Acked-by Alex Williamson <[email protected]>Signed-off-by Jan Kiszka <[email protected]>--- hw/pci.c | 19 +++++++++++++++++++ hw/pci.h | 7 +++++++ hw/pci_bridge.c | 8 ++++++++ hw/piix_pci.c | 2 ++ 4 files changed, 36 insertions(+), 0 deletions(-)hw/pci.c +19
-0@@ -1101,6 +1101,25 @@ PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin)return bus->route_intx_to_irq (bus->irq_opaque, dev->host_intx_pin[pin]); } +void pci_bus_fire_intx_routing_notifier (PCIBus *bus) +{ +PCIDevice *dev; +int i; + +for (i =0 ; i <ARRAY_SIZE (bus->devices); ++i) { + dev = bus->devices[i]; +if (dev && dev->intx_routing_notifier) { + dev->intx_routing_notifier (dev); + } + } +} + +void pci_device_set_intx_routing_notifier (PCIDevice *dev, +INTxRoutingNotifier notifier) +{ + dev->intx_routing_notifier = notifier; +} +/***********************************************************/ /* monitor info on PCI */ hw/pci.h +7
-0@@ -182,6 +182,7 @@ typedef struct PCIDeviceClass {const char *romfile; } PCIDeviceClass; +typedef void (*INTxRoutingNotifier )(PCIDevice *dev);typedef int (*MSIVectorUseNotifier )(PCIDevice *dev,unsigned int vector,MSIMessage msg);typedef void (*MSIVectorReleaseNotifier )(PCIDevice *dev,unsigned int vector);@@ -261,6 +262,9 @@ struct PCIDevice {MemoryRegion rom;uint32_t rom_bar; +/* INTx routing notifier */ +INTxRoutingNotifier intx_routing_notifier; +/* MSI-X notifiers */ MSIVectorUseNotifier msix_vector_use_notifier;MSIVectorReleaseNotifier msix_vector_release_notifier;@@ -318,6 +322,9 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name,MemoryRegion *address_space_io, uint8_t devfn_min, int nirq);PCIINTxRoute pci_device_route_intx_to_irq (PCIDevice *dev,int pin); +void pci_bus_fire_intx_routing_notifier (PCIBus *bus); +void pci_device_set_intx_routing_notifier (PCIDevice *dev, +INTxRoutingNotifier notifier);void pci_device_reset (PCIDevice *dev);void pci_bus_reset (PCIBus *bus);hw/pci_bridge.c +8
-0@@ -298,6 +298,13 @@ void pci_bridge_reset(DeviceState *qdev)pci_bridge_reset_reg (dev); } +static void pci_bridge_intx_routing_update (PCIDevice *dev) +{ +PCIBridge *br =DO_UPCAST (PCIBridge, dev, dev); + +pci_bus_fire_intx_routing_notifier (&br->sec_bus); +} +/* default qdev initialization function for PCI-to-PCI bridge */ int pci_bridge_initfn (PCIDevice *dev) {@@ -333,6 +340,7 @@ int pci_bridge_initfn(PCIDevice *dev) sec_bus->address_space_io = &br->address_space_io;memory_region_init (&br->address_space_io,"pci_bridge_io" ,65536 );pci_bridge_region_init (br); +pci_device_set_intx_routing_notifier (dev, pci_bridge_intx_routing_update);QLIST_INIT (&sec_bus->child);QLIST_INSERT_HEAD (&parent->child, sec_bus, sibling);return 0 ;hw/piix_pci.c +2
-0@@ -422,6 +422,8 @@ static void piix3_write_config(PCIDevice *dev,if (ranges_overlap (address, len,PIIX_PIRQC ,4 )) {PIIX3State *piix3 =DO_UPCAST (PIIX3State, dev, dev);int pic_irq; + +pci_bus_fire_intx_routing_notifier (piix3->dev.bus);piix3_update_irq_levels (piix3);for (pic_irq =0 ; pic_irq <PIIX_NUM_PIC_IRQS ; pic_irq++) {piix3_set_irq_pic (piix3, pic_irq);Signature · 1 line
1.7.3.4
Re: [Qemu-devel] [PATCH 06/13] pci: Add INTx routing notifier
Quoted 9 lines · Michael S. Tsirkin
Quoted 6 lines · Jan Kiszka
This per-device notifier shall be triggered by any interrupt router along the path of a device's legacy interrupt signal on routing changes. For simplicity reasons and as this is a slow path anyway, no further details on the routing changes are provided. Instead, the callback is expected to use
pci_device_get_host_irqto check the effect of the change.
pci_device_get_host_irqisn't in the cards anymore, no?
Yep, must be pci_device_route_intx_to_irq. Will fix if this series requires more than dropping patch 2. Otherwise, I would ask you to replace it on merge.
Thanks,
Jan
PATCH v2 6/13 pci: Add INTx routing notifier
In reply to Jan KiszkaThis per-device notifier shall be triggered by any interrupt router along the path of a device's legacy interrupt signal on routing changes. For simplicity reasons and as this is a slow path anyway, no further details on the routing changes are provided. Instead, the callback is expected to use pci_device_route_intx_to_irq to check the effect of the change.
Will be used by KVM PCI device assignment and VFIO.
---
v2: Fixed the commit log to mention pci_device_route_intx_to_irq.
hw/pci.c | 19 +++++++++++++++++++ hw/pci.h | 7 +++++++ hw/pci_bridge.c | 8 ++++++++ hw/piix_pci.c | 2 ++ 4 files changed, 36 insertions(+), 0 deletions(-)
hw/pci.c +19 -0
@@ -1108,6 +1108,25 @@ PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin)return bus->route_intx_to_irq (bus->irq_opaque, dev->host_intx_pin[pin]); } +void pci_bus_fire_intx_routing_notifier (PCIBus *bus) +{ +PCIDevice *dev; +int i; + +for (i =0 ; i <ARRAY_SIZE (bus->devices); ++i) { + dev = bus->devices[i]; +if (dev && dev->intx_routing_notifier) { + dev->intx_routing_notifier (dev); + } + } +} + +void pci_device_set_intx_routing_notifier (PCIDevice *dev, +INTxRoutingNotifier notifier) +{ + dev->intx_routing_notifier = notifier; +} +/***********************************************************/ /* monitor info on PCI */
hw/pci.h +7 -0
@@ -182,6 +182,7 @@ typedef struct PCIDeviceClass {const char *romfile; } PCIDeviceClass; +typedef void (*INTxRoutingNotifier )(PCIDevice *dev);typedef int (*MSIVectorUseNotifier )(PCIDevice *dev,unsigned int vector,MSIMessage msg);typedef void (*MSIVectorReleaseNotifier )(PCIDevice *dev,unsigned int vector);
@@ -261,6 +262,9 @@ struct PCIDevice {MemoryRegion rom;uint32_t rom_bar; +/* INTx routing notifier */ +INTxRoutingNotifier intx_routing_notifier; +/* MSI-X notifiers */ MSIVectorUseNotifier msix_vector_use_notifier;MSIVectorReleaseNotifier msix_vector_release_notifier;
@@ -323,6 +327,9 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name,MemoryRegion *address_space_io, uint8_t devfn_min, int nirq);PCIINTxRoute pci_device_route_intx_to_irq (PCIDevice *dev,int pin); +void pci_bus_fire_intx_routing_notifier (PCIBus *bus); +void pci_device_set_intx_routing_notifier (PCIDevice *dev, +INTxRoutingNotifier notifier);void pci_device_reset (PCIDevice *dev);void pci_bus_reset (PCIBus *bus);
hw/pci_bridge.c +8 -0
@@ -298,6 +298,13 @@ void pci_bridge_reset(DeviceState *qdev)pci_bridge_reset_reg (dev); } +static void pci_bridge_intx_routing_update (PCIDevice *dev) +{ +PCIBridge *br =DO_UPCAST (PCIBridge, dev, dev); + +pci_bus_fire_intx_routing_notifier (&br->sec_bus); +} +/* default qdev initialization function for PCI-to-PCI bridge */ int pci_bridge_initfn (PCIDevice *dev) {
@@ -333,6 +340,7 @@ int pci_bridge_initfn(PCIDevice *dev) sec_bus->address_space_io = &br->address_space_io;memory_region_init (&br->address_space_io,"pci_bridge_io" ,65536 );pci_bridge_region_init (br); +pci_device_set_intx_routing_notifier (dev, pci_bridge_intx_routing_update);QLIST_INIT (&sec_bus->child);QLIST_INSERT_HEAD (&parent->child, sec_bus, sibling);return 0 ;
hw/piix_pci.c +2 -0
@@ -422,6 +422,8 @@ static void piix3_write_config(PCIDevice *dev,if (ranges_overlap (address, len,PIIX_PIRQC ,4 )) {PIIX3State *piix3 =DO_UPCAST (PIIX3State, dev, dev);int pic_irq; + +pci_bus_fire_intx_routing_notifier (piix3->dev.bus);piix3_update_irq_levels (piix3);for (pic_irq =0 ; pic_irq <PIIX_NUM_PIC_IRQS ; pic_irq++) {piix3_set_irq_pic (piix3, pic_irq);
Signature · 1 line
1.7.3.4
Re: [Qemu-devel] [PATCH 06/13] pci: Add INTx routing notifier
In reply to Jan KiszkaQuoted 29 lines · Jan Kiszka
This per-device notifier shall be triggered by any interrupt router along the path of a device's legacy interrupt signal on routing changes. For simplicity reasons and as this is a slow path anyway, no further details on the routing changes are provided. Instead, the callback is expected to use
pci_device_get_host_irqto check the effect of the change.Will be used by KVM PCI device assignment and VFIO.
Acked-by Alex Williamson <[email protected]>Signed-off-by Jan Kiszka <[email protected]>--- hw/pci.c | 19 +++++++++++++++++++ hw/pci.h | 7 +++++++ hw/pci_bridge.c | 8 ++++++++ hw/piix_pci.c | 2 ++ 4 files changed, 36 insertions(+), 0 deletions(-)hw/pci.c +3
-0@@ -1101,6 +1101,25 @@ PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin)return bus->route_intx_to_irq (bus->irq_opaque, dev->host_intx_pin[pin]); } +void pci_bus_fire_intx_routing_notifier (PCIBus *bus) +{ +PCIDevice *dev;
hw/pci.c PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin) · line 1116
Quoted 10 lines
hw/pci.c +10
-0+int i; + +for (i =0 ; i <ARRAY_SIZE (bus->devices); ++i) { + dev = bus->devices[i]; +if (dev && dev->intx_routing_notifier) { + dev->intx_routing_notifier (dev); + } + } +} +
No documentation and it's not obvious when do you need
to do this.
It would seem from the name that it should be called after you change interrupt routing at the specific bus?
Quoted 1 line
From commit log it would seem that even irq changes should
invoke this. So why isn't this notifier at the host bridge then?
hw/pci.c PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin) · line 1122
Quoted 6 lines
hw/pci.c +6
-0+void pci_device_set_intx_routing_notifier (PCIDevice *dev, +INTxRoutingNotifier notifier) +{ + dev->intx_routing_notifier = notifier; +} +
No documentation, and it's not obvious.
Why is this getting PCIDevice?
Does this notify users about updates to this device? Updates below this device?
Above this device?
hw/pci.h typedef struct PCIDeviceClass { · line 185
Quoted 12 lines
/***********************************************************/ /* monitor info on PCI */
hw/pci.h +1
-0@@ -182,6 +182,7 @@ typedef struct PCIDeviceClass {const char *romfile; } PCIDeviceClass; +typedef void (*INTxRoutingNotifier )(PCIDevice *dev);
Let's call it PCIINTx.... please
Quoted 14 lines
hw/pci.h +3
-0typedef int (*MSIVectorUseNotifier )(PCIDevice *dev,unsigned int vector,MSIMessage msg);typedef void (*MSIVectorReleaseNotifier )(PCIDevice *dev,unsigned int vector);@@ -261,6 +262,9 @@ struct PCIDevice {MemoryRegion rom;uint32_t rom_bar; +/* INTx routing notifier */ +INTxRoutingNotifier intx_routing_notifier; +/* MSI-X notifiers */ MSIVectorUseNotifier msix_vector_use_notifier;MSIVectorReleaseNotifier msix_vector_release_notifier;
hw/pci.h PCIBus *pci_register_bus(DeviceState *parent, const char *name, · line 325
Quoted 4 lines
hw/pci.h +1
-0@@ -318,6 +322,9 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name,MemoryRegion *address_space_io, uint8_t devfn_min, int nirq);PCIINTxRoute pci_device_route_intx_to_irq (PCIDevice *dev,int pin); +void pci_bus_fire_intx_routing_notifier (PCIBus *bus);
Well true it fires the notifier but what it does conceptually is update intx routing.
Quoted 46 lines
hw/pci.h +2
-0+void pci_device_set_intx_routing_notifier (PCIDevice *dev, +INTxRoutingNotifier notifier);void pci_device_reset (PCIDevice *dev);void pci_bus_reset (PCIBus *bus);hw/pci_bridge.c +8
-0@@ -298,6 +298,13 @@ void pci_bridge_reset(DeviceState *qdev)pci_bridge_reset_reg (dev); } +static void pci_bridge_intx_routing_update (PCIDevice *dev) +{ +PCIBridge *br =DO_UPCAST (PCIBridge, dev, dev); + +pci_bus_fire_intx_routing_notifier (&br->sec_bus); +} +/* default qdev initialization function for PCI-to-PCI bridge */ int pci_bridge_initfn (PCIDevice *dev) {@@ -333,6 +340,7 @@ int pci_bridge_initfn(PCIDevice *dev) sec_bus->address_space_io = &br->address_space_io;memory_region_init (&br->address_space_io,"pci_bridge_io" ,65536 );pci_bridge_region_init (br); +pci_device_set_intx_routing_notifier (dev, pci_bridge_intx_routing_update);QLIST_INIT (&sec_bus->child);QLIST_INSERT_HEAD (&parent->child, sec_bus, sibling);return 0 ;hw/piix_pci.c +2
-0@@ -422,6 +422,8 @@ static void piix3_write_config(PCIDevice *dev,if (ranges_overlap (address, len,PIIX_PIRQC ,4 )) {PIIX3State *piix3 =DO_UPCAST (PIIX3State, dev, dev);int pic_irq; + +pci_bus_fire_intx_routing_notifier (piix3->dev.bus);piix3_update_irq_levels (piix3);for (pic_irq =0 ; pic_irq <PIIX_NUM_PIC_IRQS ; pic_irq++) {piix3_set_irq_pic (piix3, pic_irq);Signature · 1 line
1.7.3.4
Re: [Qemu-devel] [PATCH 06/13] pci: Add INTx routing notifier
Quoted 27 lines · Michael S. Tsirkin
Quoted 26 lines · Jan Kiszka
This per-device notifier shall be triggered by any interrupt router along the path of a device's legacy interrupt signal on routing changes. For simplicity reasons and as this is a slow path anyway, no further details on the routing changes are provided. Instead, the callback is expected to use
pci_device_get_host_irqto check the effect of the change.Will be used by KVM PCI device assignment and VFIO.
Acked-by Alex Williamson <[email protected]>Signed-off-by Jan Kiszka <[email protected]>--- hw/pci.c | 19 +++++++++++++++++++ hw/pci.h | 7 +++++++ hw/pci_bridge.c | 8 ++++++++ hw/piix_pci.c | 2 ++ 4 files changed, 36 insertions(+), 0 deletions(-)hw/pci.c +0
-0@@ -1101,6 +1101,25 @@ PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin)return bus->route_intx_to_irq (bus->irq_opaque, dev->host_intx_pin[pin]); }
Quoted 16 lines
hw/pci.c PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin) · line 1116
Quoted 13 lines
hw/pci.c +13
-0+void pci_bus_fire_intx_routing_notifier (PCIBus *bus) +{ +PCIDevice *dev; +int i; + +for (i =0 ; i <ARRAY_SIZE (bus->devices); ++i) { + dev = bus->devices[i]; +if (dev && dev->intx_routing_notifier) { + dev->intx_routing_notifier (dev); + } + } +} +No documentation and it's not obvious when do you need to do this.
Yes, will add some lines.
Quoted 2 lines
It would seem from the name that it should be called after you change interrupt routing at the specific bus?
Correct.
Quoted 3 lines
From commit log it would seem that even irq changes should invoke this. So why isn't this notifier at the host bridge then?
Can't follow, where does the commit log imply this? It is only about routing changes, not IRQ level changes.
Quoted 13 lines
hw/pci.c PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin) · line 1122
Quoted 7 lines
hw/pci.c +6
-0+void pci_device_set_intx_routing_notifier (PCIDevice *dev, +INTxRoutingNotifier notifier) +{ + dev->intx_routing_notifier = notifier; +} +No documentation, and it's not obvious.
Why is this getting PCIDevice?
Does this notify users about updates to this device? Updates below this device?
Above this device?
It informs about changes on the route of the device interrupts to the output of the host bridge.
Quoted 12 lines
Quoted 12 lines
hw/pci.c +0
-0/***********************************************************/ /* monitor info on PCI */ hw/pci.h +0
-0@@ -182,6 +182,7 @@ typedef struct PCIDeviceClass {const char *romfile; } PCIDeviceClass;
Quoted 3 lines
hw/pci.h typedef struct PCIDeviceClass { · line 185
Quoted 1 line
hw/pci.h +1
-0+typedef void (*INTxRoutingNotifier )(PCIDevice *dev);Let's call it PCIINTx.... please
OK.
Quoted 8 lines
Quoted 8 lines
hw/pci.h +0
-0typedef int (*MSIVectorUseNotifier )(PCIDevice *dev,unsigned int vector,MSIMessage msg);typedef void (*MSIVectorReleaseNotifier )(PCIDevice *dev,unsigned int vector);@@ -261,6 +262,9 @@ struct PCIDevice {MemoryRegion rom;uint32_t rom_bar;
Quoted 14 lines
hw/pci.h PCIBus *pci_register_bus(DeviceState *parent, const char *name, · line 325
Quoted 11 lines
hw/pci.h +4
-0+/* INTx routing notifier */ +INTxRoutingNotifier intx_routing_notifier; +/* MSI-X notifiers */ MSIVectorUseNotifier msix_vector_use_notifier;MSIVectorReleaseNotifier msix_vector_release_notifier;@@ -318,6 +322,9 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name,MemoryRegion *address_space_io, uint8_t devfn_min, int nirq);PCIINTxRoute pci_device_route_intx_to_irq (PCIDevice *dev,int pin); +void pci_bus_fire_intx_routing_notifier (PCIBus *bus);Well true it fires the notifier but what it does conceptually is update intx routing.
Nope, it informs about updates _after_ they happened.
Quoted 39 lines
Quoted 39 lines
hw/pci.h +2
-0+void pci_device_set_intx_routing_notifier (PCIDevice *dev, +INTxRoutingNotifier notifier);void pci_device_reset (PCIDevice *dev);void pci_bus_reset (PCIBus *bus);hw/pci_bridge.c +8
-0@@ -298,6 +298,13 @@ void pci_bridge_reset(DeviceState *qdev)pci_bridge_reset_reg (dev); } +static void pci_bridge_intx_routing_update (PCIDevice *dev) +{ +PCIBridge *br =DO_UPCAST (PCIBridge, dev, dev); + +pci_bus_fire_intx_routing_notifier (&br->sec_bus); +} +/* default qdev initialization function for PCI-to-PCI bridge */ int pci_bridge_initfn (PCIDevice *dev) {@@ -333,6 +340,7 @@ int pci_bridge_initfn(PCIDevice *dev) sec_bus->address_space_io = &br->address_space_io;memory_region_init (&br->address_space_io,"pci_bridge_io" ,65536 );pci_bridge_region_init (br); +pci_device_set_intx_routing_notifier (dev, pci_bridge_intx_routing_update);QLIST_INIT (&sec_bus->child);QLIST_INSERT_HEAD (&parent->child, sec_bus, sibling);return 0 ;hw/piix_pci.c +0
-0@@ -422,6 +422,8 @@ static void piix3_write_config(PCIDevice *dev,if (ranges_overlap (address, len,PIIX_PIRQC ,4 )) {PIIX3State *piix3 =DO_UPCAST (PIIX3State, dev, dev);
Quoted 10 lines
Quoted 8 lines
hw/piix_pci.c +2
-0int pic_irq; + +pci_bus_fire_intx_routing_notifier (piix3->dev.bus);piix3_update_irq_levels (piix3);for (pic_irq =0 ; pic_irq <PIIX_NUM_PIC_IRQS ; pic_irq++) {piix3_set_irq_pic (piix3, pic_irq);Signature · 1 line
1.7.3.4
Thanks,
Jan
Re: [Qemu-devel] [PATCH 06/13] pci: Add INTx routing notifier
Quoted 45 lines · Jan Kiszka
Quoted 27 lines · Michael S. Tsirkin
Quoted 26 lines · Jan Kiszka
This per-device notifier shall be triggered by any interrupt router along the path of a device's legacy interrupt signal on routing changes. For simplicity reasons and as this is a slow path anyway, no further details on the routing changes are provided. Instead, the callback is expected to use
pci_device_get_host_irqto check the effect of the change.Will be used by KVM PCI device assignment and VFIO.
Acked-by Alex Williamson <[email protected]>Signed-off-by Jan Kiszka <[email protected]>--- hw/pci.c | 19 +++++++++++++++++++ hw/pci.h | 7 +++++++ hw/pci_bridge.c | 8 ++++++++ hw/piix_pci.c | 2 ++ 4 files changed, 36 insertions(+), 0 deletions(-)hw/pci.c +0
-0@@ -1101,6 +1101,25 @@ PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin)return bus->route_intx_to_irq (bus->irq_opaque, dev->host_intx_pin[pin]); }Quoted 16 lines
hw/pci.c PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin) · line 1116
Quoted 13 lines
hw/pci.c +13
-0+void pci_bus_fire_intx_routing_notifier (PCIBus *bus) +{ +PCIDevice *dev; +int i; + +for (i =0 ; i <ARRAY_SIZE (bus->devices); ++i) { + dev = bus->devices[i]; +if (dev && dev->intx_routing_notifier) { + dev->intx_routing_notifier (dev); + } + } +} +No documentation and it's not obvious when do you need to do this.
Quoted 1 line
Yes, will add some lines.
Also, who calls this? Apparently it's invoked from pci_bridge_intx_routing_update?
Quoted 11 lines
Quoted 2 lines
It would seem from the name that it should be called after you change interrupt routing at the specific bus?
Correct.
Quoted 3 lines
From commit log it would seem that even irq changes should invoke this. So why isn't this notifier at the host bridge then?
Can't follow, where does the commit log imply this? It is only about routing changes, not IRQ level changes.
Not sure - it says use pci_device_get_host_irq
so the implication is users cache the result ofpci_device_get_host_irq?
Quoted 57 lines
Quoted 13 lines
hw/pci.c PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin) · line 1122
Quoted 7 lines
hw/pci.c +6
-0+void pci_device_set_intx_routing_notifier (PCIDevice *dev, +INTxRoutingNotifier notifier) +{ + dev->intx_routing_notifier = notifier; +} +No documentation, and it's not obvious.
Why is this getting PCIDevice?
Does this notify users about updates to this device? Updates below this device?
Above this device?It informs about changes on the route of the device interrupts to the output of the host bridge.
Quoted 12 lines
Quoted 12 lines
hw/pci.c +0
-0/***********************************************************/ /* monitor info on PCI */ hw/pci.h +0
-0@@ -182,6 +182,7 @@ typedef struct PCIDeviceClass {const char *romfile; } PCIDeviceClass;Quoted 3 lines
hw/pci.h typedef struct PCIDeviceClass { · line 185
Quoted 1 line
hw/pci.h +1
-0+typedef void (*INTxRoutingNotifier )(PCIDevice *dev);Let's call it PCIINTx.... please
OK.
Quoted 8 lines
Quoted 8 lines
hw/pci.h +0
-0typedef int (*MSIVectorUseNotifier )(PCIDevice *dev,unsigned int vector,MSIMessage msg);typedef void (*MSIVectorReleaseNotifier )(PCIDevice *dev,unsigned int vector);@@ -261,6 +262,9 @@ struct PCIDevice {MemoryRegion rom;uint32_t rom_bar;Quoted 14 lines
hw/pci.h PCIBus *pci_register_bus(DeviceState *parent, const char *name, · line 325
Quoted 11 lines
hw/pci.h +4
-0+/* INTx routing notifier */ +INTxRoutingNotifier intx_routing_notifier; +/* MSI-X notifiers */ MSIVectorUseNotifier msix_vector_use_notifier;MSIVectorReleaseNotifier msix_vector_release_notifier;@@ -318,6 +322,9 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name,MemoryRegion *address_space_io, uint8_t devfn_min, int nirq);PCIINTxRoute pci_device_route_intx_to_irq (PCIDevice *dev,int pin); +void pci_bus_fire_intx_routing_notifier (PCIBus *bus);Well true it fires the notifier but what it does conceptually is update intx routing.
Quoted 1 line
Nope, it informs about updates _after_ they happened.
Don't we need to update the cached pin if this happens? If yes I would this a better API would both update the cache and then trigger a notifier.
And the notifier can then be cache change notifier, and the "fire" function would instead be "update_cache".
Quoted 14 lines
Quoted 14 lines
Quoted 14 lines
hw/pci.h +2
-0+void pci_device_set_intx_routing_notifier (PCIDevice *dev, +INTxRoutingNotifier notifier);void pci_device_reset (PCIDevice *dev);void pci_bus_reset (PCIBus *bus);hw/pci_bridge.c +0
-0@@ -298,6 +298,13 @@ void pci_bridge_reset(DeviceState *qdev)pci_bridge_reset_reg (dev); }
Quoted 7 lines
Quoted 7 lines
hw/pci_bridge.c void pci_bridge_reset(DeviceState *qdev) · line 307
Quoted 7 lines
hw/pci_bridge.c +7
-0+static void pci_bridge_intx_routing_update (PCIDevice *dev) +{ +PCIBridge *br =DO_UPCAST (PCIBridge, dev, dev); + +pci_bus_fire_intx_routing_notifier (&br->sec_bus); +} +
I'd prefer a version that uses a simple loop,
not recursion. For example it is not clear
at this point for which devices is it OK to set
the notifier and which assume the notifier
recurses to children.
Quoted 32 lines
Quoted 18 lines
Quoted 18 lines
hw/pci_bridge.c +1
-0/* default qdev initialization function for PCI-to-PCI bridge */ int pci_bridge_initfn (PCIDevice *dev) {@@ -333,6 +340,7 @@ int pci_bridge_initfn(PCIDevice *dev) sec_bus->address_space_io = &br->address_space_io;memory_region_init (&br->address_space_io,"pci_bridge_io" ,65536 );pci_bridge_region_init (br); +pci_device_set_intx_routing_notifier (dev, pci_bridge_intx_routing_update);QLIST_INIT (&sec_bus->child);QLIST_INSERT_HEAD (&parent->child, sec_bus, sibling);return 0 ;hw/piix_pci.c +0
-0@@ -422,6 +422,8 @@ static void piix3_write_config(PCIDevice *dev,if (ranges_overlap (address, len,PIIX_PIRQC ,4 )) {PIIX3State *piix3 =DO_UPCAST (PIIX3State, dev, dev);Quoted 10 lines
Quoted 8 lines
hw/piix_pci.c +2
-0int pic_irq; + +pci_bus_fire_intx_routing_notifier (piix3->dev.bus);piix3_update_irq_levels (piix3);for (pic_irq =0 ; pic_irq <PIIX_NUM_PIC_IRQS ; pic_irq++) {piix3_set_irq_pic (piix3, pic_irq);Signature · 1 line
1.7.3.4Thanks,
Jan
Re: [Qemu-devel] [PATCH 06/13] pci: Add INTx routing notifier
Quoted 46 lines · Michael S. Tsirkin
Quoted 45 lines · Jan Kiszka
Quoted 43 lines · Michael S. Tsirkin
Quoted 29 lines · Jan Kiszka
This per-device notifier shall be triggered by any interrupt router along the path of a device's legacy interrupt signal on routing changes. For simplicity reasons and as this is a slow path anyway, no further details on the routing changes are provided. Instead, the callback is expected to use
pci_device_get_host_irqto check the effect of the change.Will be used by KVM PCI device assignment and VFIO.
Acked-by Alex Williamson <[email protected]>Signed-off-by Jan Kiszka <[email protected]>--- hw/pci.c | 19 +++++++++++++++++++ hw/pci.h | 7 +++++++ hw/pci_bridge.c | 8 ++++++++ hw/piix_pci.c | 2 ++ 4 files changed, 36 insertions(+), 0 deletions(-)hw/pci.c +3
-0@@ -1101,6 +1101,25 @@ PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin)return bus->route_intx_to_irq (bus->irq_opaque, dev->host_intx_pin[pin]); } +void pci_bus_fire_intx_routing_notifier (PCIBus *bus) +{ +PCIDevice *dev;hw/pci.c PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin) · line 1116
Quoted 10 lines
hw/pci.c +10
-0+int i; + +for (i =0 ; i <ARRAY_SIZE (bus->devices); ++i) { + dev = bus->devices[i]; +if (dev && dev->intx_routing_notifier) { + dev->intx_routing_notifier (dev); + } + } +} +No documentation and it's not obvious when do you need to do this.
Quoted 4 lines
Quoted 1 line
Yes, will add some lines.
Also, who calls this? Apparently it's invoked from
pci_bridge_intx_routing_update?
That's to forward the change reported from the parent bus. In fact, PCI does not allow pin routing changes once the device is plugged. The only change can come from the host bridge's configuration.
So there are two types of users:
- the host bridge after internal configuration changes
- a PCI-PCI bridge to forward the notification to its children
Quoted 11 lines
Quoted 11 lines
Quoted 4 lines
It would seem from the name that it should be called after you change interrupt routing at the specific bus?
Correct.
Quoted 3 lines
From commit log it would seem that even irq changes should invoke this. So why isn't this notifier at the host bridge then?
Quoted 6 lines
Quoted 2 lines
Can't follow, where does the commit log imply this? It is only about routing changes, not IRQ level changes.
Not sure - it says use
pci_device_get_host_irq
so the implication is users cache the result ofpci_device_get_host_irq?
That's the old name, I've sent v2 where the commitlog was fixed.
Quoted 58 lines
Quoted 58 lines
Quoted 14 lines
hw/pci.c PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin) · line 1122
Quoted 8 lines
hw/pci.c +6
-0+void pci_device_set_intx_routing_notifier (PCIDevice *dev, +INTxRoutingNotifier notifier) +{ + dev->intx_routing_notifier = notifier; +} +No documentation, and it's not obvious.
Why is this getting PCIDevice?
Does this notify users about updates to this device? Updates below this device?
Above this device?It informs about changes on the route of the device interrupts to the output of the host bridge.
Quoted 12 lines
Quoted 12 lines
hw/pci.c +0
-0/***********************************************************/ /* monitor info on PCI */ hw/pci.h +0
-0@@ -182,6 +182,7 @@ typedef struct PCIDeviceClass {const char *romfile; } PCIDeviceClass;Quoted 3 lines
hw/pci.h typedef struct PCIDeviceClass { · line 185
Quoted 1 line
hw/pci.h +1
-0+typedef void (*INTxRoutingNotifier )(PCIDevice *dev);Let's call it PCIINTx.... please
OK.
Quoted 22 lines
Quoted 15 lines
hw/pci.h +3
-0typedef int (*MSIVectorUseNotifier )(PCIDevice *dev,unsigned int vector,MSIMessage msg);typedef void (*MSIVectorReleaseNotifier )(PCIDevice *dev,unsigned int vector);@@ -261,6 +262,9 @@ struct PCIDevice {MemoryRegion rom;uint32_t rom_bar; +/* INTx routing notifier */ +INTxRoutingNotifier intx_routing_notifier; +/* MSI-X notifiers */ MSIVectorUseNotifier msix_vector_use_notifier;MSIVectorReleaseNotifier msix_vector_release_notifier;hw/pci.h PCIBus *pci_register_bus(DeviceState *parent, const char *name, · line 325
Quoted 4 lines
hw/pci.h +1
-0@@ -318,6 +322,9 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name,MemoryRegion *address_space_io, uint8_t devfn_min, int nirq);PCIINTxRoute pci_device_route_intx_to_irq (PCIDevice *dev,int pin); +void pci_bus_fire_intx_routing_notifier (PCIBus *bus);Well true it fires the notifier but what it does conceptually is update intx routing.
Quoted 7 lines
Quoted 1 line
Nope, it informs about updates _after_ they happened.
Don't we need to update the cached pin if this happens? If yes I would this a better API would both update the cache and then trigger a notifier.
And the notifier can then be cache change notifier, and the "fire" function would instead be "update_cache".
See above, the cached part of the route is static anyway. What changes is the host bridge configuration.
Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
hw/pci.h +2
-0+void pci_device_set_intx_routing_notifier (PCIDevice *dev, +INTxRoutingNotifier notifier);void pci_device_reset (PCIDevice *dev);void pci_bus_reset (PCIBus *bus);hw/pci_bridge.c +0
-0@@ -298,6 +298,13 @@ void pci_bridge_reset(DeviceState *qdev)pci_bridge_reset_reg (dev); }
Quoted 13 lines
Quoted 7 lines
Quoted 7 lines
hw/pci_bridge.c void pci_bridge_reset(DeviceState *qdev) · line 307
Quoted 7 lines
hw/pci_bridge.c +7
-0+static void pci_bridge_intx_routing_update (PCIDevice *dev) +{ +PCIBridge *br =DO_UPCAST (PCIBridge, dev, dev); + +pci_bus_fire_intx_routing_notifier (&br->sec_bus); +} +I'd prefer a version that uses a simple loop,
not recursion. For example it is not clear
at this point for which devices is it OK to set
the notifier and which assume the notifier
recurses to children.
The notification must be forwarded to any secondary bus because any device below can have a notifier registered. And I think recursion is the cleaner approach for this as we can have complex topologies.
Jan
Re: [Qemu-devel] [PATCH 06/13] pci: Add INTx routing notifier
Quoted 71 lines · Jan Kiszka
Quoted 46 lines · Michael S. Tsirkin
Quoted 45 lines · Jan Kiszka
Quoted 43 lines · Michael S. Tsirkin
Quoted 29 lines · Jan Kiszka
This per-device notifier shall be triggered by any interrupt router along the path of a device's legacy interrupt signal on routing changes. For simplicity reasons and as this is a slow path anyway, no further details on the routing changes are provided. Instead, the callback is expected to use
pci_device_get_host_irqto check the effect of the change.Will be used by KVM PCI device assignment and VFIO.
Acked-by Alex Williamson <[email protected]>Signed-off-by Jan Kiszka <[email protected]>--- hw/pci.c | 19 +++++++++++++++++++ hw/pci.h | 7 +++++++ hw/pci_bridge.c | 8 ++++++++ hw/piix_pci.c | 2 ++ 4 files changed, 36 insertions(+), 0 deletions(-)hw/pci.c +3
-0@@ -1101,6 +1101,25 @@ PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin)return bus->route_intx_to_irq (bus->irq_opaque, dev->host_intx_pin[pin]); } +void pci_bus_fire_intx_routing_notifier (PCIBus *bus) +{ +PCIDevice *dev;hw/pci.c PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin) · line 1116
Quoted 10 lines
hw/pci.c +10
-0+int i; + +for (i =0 ; i <ARRAY_SIZE (bus->devices); ++i) { + dev = bus->devices[i]; +if (dev && dev->intx_routing_notifier) { + dev->intx_routing_notifier (dev); + } + } +} +No documentation and it's not obvious when do you need to do this.
Quoted 4 lines
Quoted 1 line
Yes, will add some lines.
Also, who calls this? Apparently it's invoked from
pci_bridge_intx_routing_update?That's to forward the change reported from the parent bus. In fact, PCI does not allow pin routing changes once the device is plugged. The only change can come from the host bridge's configuration.
So there are two types of users:
- the host bridge after internal configuration changes
- a PCI-PCI bridge to forward the notification to its childrenQuoted 11 lines
Quoted 11 lines
Quoted 4 lines
It would seem from the name that it should be called after you change interrupt routing at the specific bus?
Correct.
Quoted 3 lines
From commit log it would seem that even irq changes should invoke this. So why isn't this notifier at the host bridge then?
Quoted 8 lines
Quoted 6 lines
Quoted 2 lines
Can't follow, where does the commit log imply this? It is only about routing changes, not IRQ level changes.
Not sure - it says use
pci_device_get_host_irq
so the implication is users cache the result ofpci_device_get_host_irq?That's the old name, I've sent v2 where the commitlog was fixed.
Yes but still. If users cache the irq they need to get notified about *that*. Not about intx routing.
Quoted 60 lines
Quoted 60 lines
Quoted 59 lines
Quoted 14 lines
hw/pci.c PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin) · line 1122
Quoted 8 lines
hw/pci.c +6
-0+void pci_device_set_intx_routing_notifier (PCIDevice *dev, +INTxRoutingNotifier notifier) +{ + dev->intx_routing_notifier = notifier; +} +No documentation, and it's not obvious.
Why is this getting PCIDevice?
Does this notify users about updates to this device? Updates below this device?
Above this device?It informs about changes on the route of the device interrupts to the output of the host bridge.
Quoted 12 lines
Quoted 12 lines
hw/pci.c +0
-0/***********************************************************/ /* monitor info on PCI */ hw/pci.h +0
-0@@ -182,6 +182,7 @@ typedef struct PCIDeviceClass {const char *romfile; } PCIDeviceClass;Quoted 3 lines
hw/pci.h typedef struct PCIDeviceClass { · line 185
Quoted 1 line
hw/pci.h +1
-0+typedef void (*INTxRoutingNotifier )(PCIDevice *dev);Let's call it PCIINTx.... please
OK.
Quoted 8 lines
Quoted 8 lines
hw/pci.h +0
-0typedef int (*MSIVectorUseNotifier )(PCIDevice *dev,unsigned int vector,MSIMessage msg);typedef void (*MSIVectorReleaseNotifier )(PCIDevice *dev,unsigned int vector);@@ -261,6 +262,9 @@ struct PCIDevice {MemoryRegion rom;uint32_t rom_bar;Quoted 14 lines
hw/pci.h PCIBus *pci_register_bus(DeviceState *parent, const char *name, · line 325
Quoted 11 lines
hw/pci.h +4
-0+/* INTx routing notifier */ +INTxRoutingNotifier intx_routing_notifier; +/* MSI-X notifiers */ MSIVectorUseNotifier msix_vector_use_notifier;MSIVectorReleaseNotifier msix_vector_release_notifier;@@ -318,6 +322,9 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name,MemoryRegion *address_space_io, uint8_t devfn_min, int nirq);PCIINTxRoute pci_device_route_intx_to_irq (PCIDevice *dev,int pin); +void pci_bus_fire_intx_routing_notifier (PCIBus *bus);Well true it fires the notifier but what it does conceptually is update intx routing.
Nope, it informs about updates _after_ they happened.
Quoted 8 lines
Quoted 5 lines
Don't we need to update the cached pin if this happens? If yes I would this a better API would both update the cache and then trigger a notifier.
And the notifier can then be cache change notifier, and the "fire" function would instead be "update_cache".See above, the cached part of the route is static anyway. What changes is the host bridge configuration.
You are saying it is only the intx to irq routing that can change?
So maybe "pci_bus_update_intx_to_irq_routing"?
Quoted 29 lines
Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
hw/pci.h +2
-0+void pci_device_set_intx_routing_notifier (PCIDevice *dev, +INTxRoutingNotifier notifier);void pci_device_reset (PCIDevice *dev);void pci_bus_reset (PCIBus *bus);hw/pci_bridge.c +0
-0@@ -298,6 +298,13 @@ void pci_bridge_reset(DeviceState *qdev)pci_bridge_reset_reg (dev); }Quoted 13 lines
Quoted 7 lines
Quoted 7 lines
hw/pci_bridge.c void pci_bridge_reset(DeviceState *qdev) · line 307
Quoted 7 lines
hw/pci_bridge.c +7
-0+static void pci_bridge_intx_routing_update (PCIDevice *dev) +{ +PCIBridge *br =DO_UPCAST (PCIBridge, dev, dev); + +pci_bus_fire_intx_routing_notifier (&br->sec_bus); +} +I'd prefer a version that uses a simple loop,
not recursion. For example it is not clear
at this point for which devices is it OK to set
the notifier and which assume the notifier
recurses to children.
Quoted 6 lines
The notification must be forwarded to any secondary bus because any device below can have a notifier registered. And I think recursion is the cleaner approach for this as we can have complex topologies.
Jan
I don't think it's ever more complex than a tree.
Signature · 1 line
MST
Re: [Qemu-devel] [PATCH 06/13] pci: Add INTx routing notifier
Quoted 6 lines · Michael S. Tsirkin
Quoted 6 lines
Quoted 6 lines
Quoted 5 lines
Quoted 2 lines
From commit log it would seem that even irq changes should invoke this. So why isn't this notifier at the host bridge then?
Can't follow, where does the commit log imply this? It is only about routing changes, not IRQ level changes.
Quoted 8 lines
Quoted 5 lines
Quoted 3 lines
Not sure - it says use
pci_device_get_host_irq
so the implication is users cache the result ofpci_device_get_host_irq?That's the old name, I've sent v2 where the commitlog was fixed.
Yes but still. If users cache the irq they need to get notified about *that*. Not about intx routing.
The user caches the route of a device INTx to the host bridge output (precisely what pci_device_route_inx_to_irq returns), and for changes of that result it gets a notification this way. Nothing else.
Quoted 67 lines
Quoted 67 lines
Quoted 66 lines
Quoted 59 lines
Quoted 15 lines
hw/pci.c PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin) · line 1122
Quoted 9 lines
hw/pci.c +6
-0+void pci_device_set_intx_routing_notifier (PCIDevice *dev, +INTxRoutingNotifier notifier) +{ + dev->intx_routing_notifier = notifier; +} +No documentation, and it's not obvious.
Why is this getting PCIDevice?
Does this notify users about updates to this device? Updates below this device?
Above this device?It informs about changes on the route of the device interrupts to the output of the host bridge.
Quoted 12 lines
Quoted 12 lines
/***********************************************************/ /* monitor info on PCI */
hw/pci.h +0
-0@@ -182,6 +182,7 @@ typedef struct PCIDeviceClass {const char *romfile; } PCIDeviceClass;Quoted 3 lines
hw/pci.h typedef struct PCIDeviceClass { · line 185
Quoted 1 line
hw/pci.h +1
-0+typedef void (*INTxRoutingNotifier )(PCIDevice *dev);Let's call it PCIINTx.... please
OK.
Quoted 8 lines
Quoted 8 lines
hw/pci.h +0
-0typedef int (*MSIVectorUseNotifier )(PCIDevice *dev,unsigned int vector,MSIMessage msg);typedef void (*MSIVectorReleaseNotifier )(PCIDevice *dev,unsigned int vector);@@ -261,6 +262,9 @@ struct PCIDevice {MemoryRegion rom;uint32_t rom_bar;Quoted 14 lines
hw/pci.h PCIBus *pci_register_bus(DeviceState *parent, const char *name, · line 325
Quoted 11 lines
hw/pci.h +4
-0+/* INTx routing notifier */ +INTxRoutingNotifier intx_routing_notifier; +/* MSI-X notifiers */ MSIVectorUseNotifier msix_vector_use_notifier;MSIVectorReleaseNotifier msix_vector_release_notifier;@@ -318,6 +322,9 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name,MemoryRegion *address_space_io, uint8_t devfn_min, int nirq);PCIINTxRoute pci_device_route_intx_to_irq (PCIDevice *dev,int pin); +void pci_bus_fire_intx_routing_notifier (PCIBus *bus);Well true it fires the notifier but what it does conceptually is update intx routing.
Quoted 1 line
Nope, it informs about updates _after_ they happened.
Don't we need to update the cached pin if this happens? If yes I would this a better API would both update the cache and then trigger a notifier.
And the notifier can then be cache change notifier, and the "fire" function would instead be "update_cache".
Quoted 6 lines
Quoted 2 lines
See above, the cached part of the route is static anyway. What changes is the host bridge configuration.
You are saying it is only the intx to irq routing that can change?
So maybe "pci_bus_update_intx_to_irq_routing"?
Again, this function does not _update_ anything. It informs about a host-bridge-specific update, i.e. something that happened outside the generic code beforehand.
Quoted 30 lines
Quoted 30 lines
Quoted 29 lines
Quoted 16 lines
Quoted 16 lines
Quoted 16 lines
hw/pci.h +2
-0+void pci_device_set_intx_routing_notifier (PCIDevice *dev, +INTxRoutingNotifier notifier);void pci_device_reset (PCIDevice *dev);void pci_bus_reset (PCIBus *bus);hw/pci_bridge.c +0
-0@@ -298,6 +298,13 @@ void pci_bridge_reset(DeviceState *qdev)pci_bridge_reset_reg (dev); }Quoted 7 lines
Quoted 7 lines
hw/pci_bridge.c void pci_bridge_reset(DeviceState *qdev) · line 307
Quoted 7 lines
hw/pci_bridge.c +7
-0+static void pci_bridge_intx_routing_update (PCIDevice *dev) +{ +PCIBridge *br =DO_UPCAST (PCIBridge, dev, dev); + +pci_bus_fire_intx_routing_notifier (&br->sec_bus); +} +I'd prefer a version that uses a simple loop,
not recursion. For example it is not clear
at this point for which devices is it OK to set
the notifier and which assume the notifier
recurses to children.
Quoted 9 lines
Quoted 6 lines
The notification must be forwarded to any secondary bus because any device below can have a notifier registered. And I think recursion is the cleaner approach for this as we can have complex topologies.
Jan
I don't think it's ever more complex than a tree.
For sure, and this is what the recursive invocation addresses.
Jan
Re: [Qemu-devel] [PATCH 06/13] pci: Add INTx routing notifier
Quoted 135 lines · Jan Kiszka
Quoted 6 lines · Michael S. Tsirkin
Quoted 6 lines
Quoted 6 lines
Quoted 5 lines
Quoted 2 lines
From commit log it would seem that even irq changes should invoke this. So why isn't this notifier at the host bridge then?
Can't follow, where does the commit log imply this? It is only about routing changes, not IRQ level changes.
Quoted 8 lines
Quoted 5 lines
Quoted 3 lines
Not sure - it says use
pci_device_get_host_irq
so the implication is users cache the result ofpci_device_get_host_irq?That's the old name, I've sent v2 where the commitlog was fixed.
Yes but still. If users cache the irq they need to get notified about *that*. Not about intx routing.
The user caches the route of a device INTx to the host bridge output (precisely what
pci_device_route_inx_to_irqreturns), and for changes of that result it gets a notification this way. Nothing else.Quoted 67 lines
Quoted 67 lines
Quoted 66 lines
Quoted 59 lines
Quoted 15 lines
Review
Quoted 9 lines
(quoted diff) +6
-0+void pci_device_set_intx_routing_notifier(PCIDevice *dev, + INTxRoutingNotifier notifier) +{ + dev->intx_routing_notifier = notifier; +} +No documentation, and it's not obvious.
Why is this getting PCIDevice?
Does this notify users about updates to this device? Updates below this device?
Above this device?It informs about changes on the route of the device interrupts to the output of the host bridge.
Quoted 12 lines
Quoted 12 lines
/***********************************************************/ /* monitor info on PCI */
hw/pci.h +0
-0@@ -182,6 +182,7 @@ typedef struct PCIDeviceClass {const char *romfile; } PCIDeviceClass;Quoted 3 lines
hw/pci.h typedef struct PCIDeviceClass { · line 185
Quoted 1 line
hw/pci.h +1
-0+typedef void (*INTxRoutingNotifier )(PCIDevice *dev);Let's call it PCIINTx.... please
OK.
Quoted 8 lines
Quoted 8 lines
hw/pci.h +0
-0typedef int (*MSIVectorUseNotifier )(PCIDevice *dev,unsigned int vector,MSIMessage msg);typedef void (*MSIVectorReleaseNotifier )(PCIDevice *dev,unsigned int vector);@@ -261,6 +262,9 @@ struct PCIDevice {MemoryRegion rom;uint32_t rom_bar;Quoted 14 lines
hw/pci.h PCIBus *pci_register_bus(DeviceState *parent, const char *name, · line 325
Quoted 11 lines
hw/pci.h +4
-0+/* INTx routing notifier */ +INTxRoutingNotifier intx_routing_notifier; +/* MSI-X notifiers */ MSIVectorUseNotifier msix_vector_use_notifier;MSIVectorReleaseNotifier msix_vector_release_notifier;@@ -318,6 +322,9 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name,MemoryRegion *address_space_io, uint8_t devfn_min, int nirq);PCIINTxRoute pci_device_route_intx_to_irq (PCIDevice *dev,int pin); +void pci_bus_fire_intx_routing_notifier (PCIBus *bus);Well true it fires the notifier but what it does conceptually is update intx routing.
Quoted 1 line
Nope, it informs about updates _after_ they happened.
Don't we need to update the cached pin if this happens? If yes I would this a better API would both update the cache and then trigger a notifier.
And the notifier can then be cache change notifier, and the "fire" function would instead be "update_cache".Quoted 6 lines
Quoted 2 lines
See above, the cached part of the route is static anyway. What changes is the host bridge configuration.
You are saying it is only the intx to irq routing that can change?
So maybe "pci_bus_update_intx_to_irq_routing"?Again, this function does not _update_ anything. It informs about a host-bridge-specific update, i.e. something that happened outside the generic code beforehand.
Quoted 37 lines
Quoted 36 lines
Quoted 16 lines
Quoted 16 lines
Quoted 16 lines
Quoted 16 lines
hw/pci.h +2
-0+void pci_device_set_intx_routing_notifier (PCIDevice *dev, +INTxRoutingNotifier notifier);void pci_device_reset (PCIDevice *dev);void pci_bus_reset (PCIBus *bus);hw/pci_bridge.c +0
-0@@ -298,6 +298,13 @@ void pci_bridge_reset(DeviceState *qdev)pci_bridge_reset_reg (dev); }Quoted 13 lines
Quoted 7 lines
Quoted 7 lines
hw/pci_bridge.c void pci_bridge_reset(DeviceState *qdev) · line 307
Quoted 7 lines
hw/pci_bridge.c +7
-0+static void pci_bridge_intx_routing_update (PCIDevice *dev) +{ +PCIBridge *br =DO_UPCAST (PCIBridge, dev, dev); + +pci_bus_fire_intx_routing_notifier (&br->sec_bus); +} +I'd prefer a version that uses a simple loop,
not recursion. For example it is not clear
at this point for which devices is it OK to set
the notifier and which assume the notifier
recurses to children.The notification must be forwarded to any secondary bus because any device below can have a notifier registered. And I think recursion is the cleaner approach for this as we can have complex topologies.
Jan
Quoted 7 lines
Quoted 2 lines
I don't think it's ever more complex than a tree.
For sure, and this is what the recursive invocation addresses.
Jan
It's OK to use recursion but when done through a callback like this it's unreadable.
Also, you need to setup you cache after intx cache has been initialized, and you provide no clean way to do that.
One way to fix all this is call the notifier for devices, if set, from pci_set_bus_intx_routing.
Then assume that intx to irq translations can be cached even though they aren't now. So you will need to invoke pci_set_bus_intx_routing on intx to irq mapping changes, and that fires the notifier for free.
Signature · 1 line
MST
Re: [Qemu-devel] [PATCH 06/13] pci: Add INTx routing notifier
Quoted 2 lines · Michael S. Tsirkin
It's OK to use recursion but when done through a callback like this it's unreadable.
Isn't the alternative poking into foreign bridge device states for their secondary buses?
Quoted 2 lines
Also, you need to setup you cache after intx cache has been initialized, and you provide no clean way to do that.
Once a PCI device is registered, the INTx route can be queried. So the device user will call pci_device_route_intx_to_irq once (e.g. in the device init function which is invoked afterward) to fill its cache and receive a notification if an update is needed. I do not see why, and specifically how you could query the route earlier or register a callback.
Quoted 7 lines
One way to fix all this is call the notifier for devices, if set, from
pci_set_bus_intx_routing.
Then assume that intx to irq translations can be cached even though they aren't now. So you will need to invokepci_set_bus_intx_routingon intx to irq mapping changes, and that fires the notifier for free.
pci_set_bus_intx_routing is really only for the initial setup of the static INTx pin routes. And this happens on pci_bus_irqs/pci_register_bus, ie. triggered by the host bridge. By that time, there can't be any notifier listeners - as there are no devices yet.
Jan
Re: [Qemu-devel] [PATCH 06/13] pci: Add INTx routing notifier
Quoted 6 lines · Jan Kiszka
Quoted 2 lines · Michael S. Tsirkin
It's OK to use recursion but when done through a callback like this it's unreadable.
Isn't the alternative poking into foreign bridge device states for their secondary buses?
pci_set_bus_intx_routing does this already.
Quoted 8 lines
Quoted 2 lines
Also, you need to setup you cache after intx cache has been initialized, and you provide no clean way to do that.
Once a PCI device is registered, the INTx route can be queried. So the device user will call
pci_device_route_intx_to_irqonce (e.g. in the device init function which is invoked afterward) to fill its cache and receive a notification if an update is needed. I do not see why, and specifically how you could query the route earlier or register a callback.
Before pci_bus_irqs is called.
Why is another question.
Quoted 8 lines
Quoted 7 lines
One way to fix all this is call the notifier for devices, if set, from
pci_set_bus_intx_routing.
Then assume that intx to irq translations can be cached even though they aren't now. So you will need to invokepci_set_bus_intx_routingon intx to irq mapping changes, and that fires the notifier for free.
Quoted 7 lines
pci_set_bus_intx_routingis really only for the initial setup of the static INTx pin routes. And this happens on pci_bus_irqs/pci_register_bus, ie. triggered by the host bridge. By that time, there can't be any notifier listeners - as there are no devices yet.Jan
What I am saying is we'll cache the final IRQ at some point. Pretend it's already that way so callers are ready for this.
Signature · 1 line
MST
Re: [Qemu-devel] [PATCH 06/13] pci: Add INTx routing notifier
Quoted 9 lines · Michael S. Tsirkin
Quoted 6 lines · Jan Kiszka
Quoted 2 lines · Michael S. Tsirkin
It's OK to use recursion but when done through a callback like this it's unreadable.
Isn't the alternative poking into foreign bridge device states for their secondary buses?
pci_set_bus_intx_routingdoes this already.
True. OK, I can do the recursion in pci_bus_fire_intx_routing_notifier directly instead of pushing this into the bridge.
Quoted 26 lines
Quoted 9 lines
Quoted 3 lines
Also, you need to setup you cache after intx cache has been initialized, and you provide no clean way to do that.
Once a PCI device is registered, the INTx route can be queried. So the device user will call
pci_device_route_intx_to_irqonce (e.g. in the device init function which is invoked afterward) to fill its cache and receive a notification if an update is needed. I do not see why, and specifically how you could query the route earlier or register a callback.Before
pci_bus_irqsis called.
Why is another question.Quoted 13 lines
Quoted 7 lines
One way to fix all this is call the notifier for devices, if set, from
pci_set_bus_intx_routing.
Then assume that intx to irq translations can be cached even though they aren't now. So you will need to invokepci_set_bus_intx_routingon intx to irq mapping changes, and that fires the notifier for free.
pci_set_bus_intx_routingis really only for the initial setup of the static INTx pin routes. And this happens on pci_bus_irqs/pci_register_bus, ie. triggered by the host bridge. By that time, there can't be any notifier listeners - as there are no devices yet.
Quoted 5 lines
Quoted 2 lines
Jan
What I am saying is we'll cache the final IRQ at some point. Pretend it's already that way so callers are ready for this.
This wouldn't change the picture very much: Before the host bridge is fully initialized, there is no valid route available. But before that, there is also no device attached to it. So the invocation pattern wouldn't change.
What would change is the semantic of the interface to the host bridge. So what about this: provide a public pci_root_bus_intx_routing_updated which so far just calls the internal-use-only pci_bus_fire_intx_routing_notifier?
Jan
Re: [Qemu-devel] [PATCH 06/13] pci: Add INTx routing notifier
Quoted 51 lines · Jan Kiszka
Quoted 9 lines · Michael S. Tsirkin
Quoted 6 lines · Jan Kiszka
Quoted 2 lines · Michael S. Tsirkin
It's OK to use recursion but when done through a callback like this it's unreadable.
Isn't the alternative poking into foreign bridge device states for their secondary buses?
pci_set_bus_intx_routingdoes this already.True. OK, I can do the recursion in
pci_bus_fire_intx_routing_notifierdirectly instead of pushing this into the bridge.Quoted 26 lines
Quoted 9 lines
Quoted 3 lines
Also, you need to setup you cache after intx cache has been initialized, and you provide no clean way to do that.
Once a PCI device is registered, the INTx route can be queried. So the device user will call
pci_device_route_intx_to_irqonce (e.g. in the device init function which is invoked afterward) to fill its cache and receive a notification if an update is needed. I do not see why, and specifically how you could query the route earlier or register a callback.Before
pci_bus_irqsis called.
Why is another question.Quoted 13 lines
Quoted 7 lines
One way to fix all this is call the notifier for devices, if set, from
pci_set_bus_intx_routing.
Then assume that intx to irq translations can be cached even though they aren't now. So you will need to invokepci_set_bus_intx_routingon intx to irq mapping changes, and that fires the notifier for free.
pci_set_bus_intx_routingis really only for the initial setup of the static INTx pin routes. And this happens on pci_bus_irqs/pci_register_bus, ie. triggered by the host bridge. By that time, there can't be any notifier listeners - as there are no devices yet.Quoted 5 lines
Quoted 2 lines
Jan
What I am saying is we'll cache the final IRQ at some point. Pretend it's already that way so callers are ready for this.
This wouldn't change the picture very much: Before the host bridge is fully initialized, there is no valid route available. But before that, there is also no device attached to it. So the invocation pattern wouldn't change.
Quoted 7 lines
What would change is the semantic of the interface to the host bridge. So what about this: provide a public
pci_root_bus_intx_routing_updatedwhich so far just calls the internal-use-onlypci_bus_fire_intx_routing_notifier?Jan
I think a better name is pci_bus_update_intx_irq_cache or something like that.
And I really think it's better to recalculate the intx routing there as well, so that if some bus implements a dynamic route_intx it just needs to call this after update.
Signature · 1 line
MST
Re: [Qemu-devel] [PATCH 06/13] pci: Add INTx routing notifier
Quoted 57 lines · Michael S. Tsirkin
Quoted 56 lines · Jan Kiszka
Quoted 9 lines · Michael S. Tsirkin
Quoted 6 lines · Jan Kiszka
Quoted 2 lines · Michael S. Tsirkin
It's OK to use recursion but when done through a callback like this it's unreadable.
Isn't the alternative poking into foreign bridge device states for their secondary buses?
pci_set_bus_intx_routingdoes this already.True. OK, I can do the recursion in
pci_bus_fire_intx_routing_notifierdirectly instead of pushing this into the bridge.Quoted 26 lines
Quoted 9 lines
Quoted 3 lines
Also, you need to setup you cache after intx cache has been initialized, and you provide no clean way to do that.
Once a PCI device is registered, the INTx route can be queried. So the device user will call
pci_device_route_intx_to_irqonce (e.g. in the device init function which is invoked afterward) to fill its cache and receive a notification if an update is needed. I do not see why, and specifically how you could query the route earlier or register a callback.Before
pci_bus_irqsis called.
Why is another question.Quoted 13 lines
Quoted 7 lines
One way to fix all this is call the notifier for devices, if set, from
pci_set_bus_intx_routing.
Then assume that intx to irq translations can be cached even though they aren't now. So you will need to invokepci_set_bus_intx_routingon intx to irq mapping changes, and that fires the notifier for free.
pci_set_bus_intx_routingis really only for the initial setup of the static INTx pin routes. And this happens on pci_bus_irqs/pci_register_bus, ie. triggered by the host bridge. By that time, there can't be any notifier listeners - as there are no devices yet.Quoted 5 lines
Quoted 2 lines
Jan
What I am saying is we'll cache the final IRQ at some point. Pretend it's already that way so callers are ready for this.
This wouldn't change the picture very much: Before the host bridge is fully initialized, there is no valid route available. But before that, there is also no device attached to it. So the invocation pattern wouldn't change.
What would change is the semantic of the interface to the host bridge. So what about this: provide a public
pci_root_bus_intx_routing_updatedwhich so far just calls the internal-use-onlypci_bus_fire_intx_routing_notifier?
Quoted 5 lines
Quoted 2 lines
Jan
I think a better name is
pci_bus_update_intx_irq_cacheor something like that.
At least "update cache" is not a better description as it implies in the function name the required steps of the implementation. In fact, this function /may/ update a cache and will fire notifiers. But that's nothing the care should worry about.
Quoted 5 lines
And I really think it's better to recalculate the intx routing there as well, so that if some bus implements a dynamic
route_intxit just needs to call this after update.
I thought dynamic routing is disallowed according to the spec? If not, I agree.
Jan
Re: [Qemu-devel] [PATCH 06/13] pci: Add INTx routing notifier
Quoted 58 lines · Jan Kiszka
Quoted 57 lines · Michael S. Tsirkin
Quoted 56 lines · Jan Kiszka
Quoted 9 lines · Michael S. Tsirkin
Quoted 6 lines · Jan Kiszka
Quoted 2 lines · Michael S. Tsirkin
It's OK to use recursion but when done through a callback like this it's unreadable.
Isn't the alternative poking into foreign bridge device states for their secondary buses?
pci_set_bus_intx_routingdoes this already.True. OK, I can do the recursion in
pci_bus_fire_intx_routing_notifierdirectly instead of pushing this into the bridge.Quoted 26 lines
Quoted 9 lines
Quoted 3 lines
Also, you need to setup you cache after intx cache has been initialized, and you provide no clean way to do that.
Once a PCI device is registered, the INTx route can be queried. So the device user will call
pci_device_route_intx_to_irqonce (e.g. in the device init function which is invoked afterward) to fill its cache and receive a notification if an update is needed. I do not see why, and specifically how you could query the route earlier or register a callback.Before
pci_bus_irqsis called.
Why is another question.Quoted 13 lines
Quoted 7 lines
One way to fix all this is call the notifier for devices, if set, from
pci_set_bus_intx_routing.
Then assume that intx to irq translations can be cached even though they aren't now. So you will need to invokepci_set_bus_intx_routingon intx to irq mapping changes, and that fires the notifier for free.
pci_set_bus_intx_routingis really only for the initial setup of the static INTx pin routes. And this happens on pci_bus_irqs/pci_register_bus, ie. triggered by the host bridge. By that time, there can't be any notifier listeners - as there are no devices yet.Quoted 5 lines
Quoted 2 lines
Jan
What I am saying is we'll cache the final IRQ at some point. Pretend it's already that way so callers are ready for this.
This wouldn't change the picture very much: Before the host bridge is fully initialized, there is no valid route available. But before that, there is also no device attached to it. So the invocation pattern wouldn't change.
What would change is the semantic of the interface to the host bridge. So what about this: provide a public
pci_root_bus_intx_routing_updatedwhich so far just calls the internal-use-onlypci_bus_fire_intx_routing_notifier?
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
Jan
I think a better name is
pci_bus_update_intx_irq_cacheor something like that.At least "update cache" is not a better description as it implies in the function name the required steps of the implementation.
That's only reasonable: saying what a function does limits the implementation at some level.
If you don't you end up with no way to understand it or check for correctness unless you find and read all callers as well.
Quoted 2 lines
In fact, this
function /may/ update a cache and will fire notifiers.
notifiers *if any*. And the only reason to have a notifier is if you cache the routing.
Quoted 1 line
But that's nothing the care should worry about.
IMO function name should say what it does, not
how it does it (fire notifiers) or when
it should be called (routing updated).
Quoted 11 lines
Quoted 5 lines
And I really think it's better to recalculate the intx routing there as well, so that if some bus implements a dynamic
route_intxit just needs to call this after update.I thought dynamic routing is disallowed according to the spec? If not, I agree.
Jan
I think it is in pci to pci bridges, but might not be in pci host bridges. It's not a hard requirement though, but nice to have.
Signature · 1 line
MST
Re: [Qemu-devel] [PATCH 06/13] pci: Add INTx routing notifier
In reply to Jan KiszkaQuoted 20 lines · Jan Kiszka
Quoted 20 lines
Quoted 19 lines
Quoted 9 lines
Quoted 9 lines
Quoted 8 lines
Review PCIBus *pci_register_bus(DeviceState *parent, const char *name, · line 325
Quoted 5 lines
(quoted diff) +1
-0@@ -318,6 +322,9 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name, MemoryRegion *address_space_io, uint8_t devfn_min, int nirq); PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin); +void pci_bus_fire_intx_routing_notifier(PCIBus *bus);Well true it fires the notifier but what it does conceptually is update intx routing.
Quoted 7 lines
Quoted 1 line
Nope, it informs about updates _after_ they happened.
Don't we need to update the cached pin if this happens? If yes I would this a better API would both update the cache and then trigger a notifier.
And the notifier can then be cache change notifier, and the "fire" function would instead be "update_cache".See above, the cached part of the route is static anyway. What changes is the host bridge configuration.
Quoted 7 lines
Quoted 3 lines
You are saying it is only the intx to irq routing that can change?
So maybe "pci_bus_update_intx_to_irq_routing"?Again, this function does not _update_ anything. It informs about a host-bridge-specific update, i.e. something that happened outside the generic code beforehand.
Yes it does what it says but it's an ugly interface all the same. What does a host device emulation care about notifiers? It's an implementation detail.
The *real* reason is that someone caches intx to irq routing and you need to update that cache.
So just say so.
Signature · 1 line
MST
PATCH 7/13 pci: Make domain and bus unsigned in pci_read_devaddr
In reply to Jan KiszkaIt's the more appropriate type as there are no negative domain or bus values.
--- hw/pci-hotplug.c | 4 ++-- hw/pci.c | 11 ++++++----- hw/pci.h | 4 ++-- 3 files changed, 10 insertions(+), 9 deletions(-)
hw/pci-hotplug.c +2 -2
@@ -108,7 +108,7 @@ static int scsi_hot_add(Monitor *mon, DeviceState *adapter,int pci_drive_hot_add (Monitor *mon,const QDict *qdict,DriveInfo *dinfo,int type) { -int dom, pci_bus; +unsigned int dom, pci_bus;unsigned slot;PCIDevice *dev;const char *pci_addr =qdict_get_str (qdict,"pci_addr" );
@@ -257,7 +257,7 @@ void pci_device_hot_add(Monitor *mon, const QDict *qdict)static int pci_device_hot_remove (Monitor *mon,const char *pci_addr) {PCIDevice *d; -int dom, bus; +unsigned int dom, bus;unsigned slot;Error *local_err =NULL ;
hw/pci.c +6 -5
@@ -512,8 +512,9 @@ static void pci_set_default_subsystem_id(PCIDevice *pci_dev)* Parse [[<domain>:]<bus>:]<slot>, return -1 on error if funcp == NULL * [[<domain>:]<bus>:]<slot>.<func>, return -1 on error */ -static int pci_parse_devaddr (const char *addr,int *domp,int *busp, -unsigned int *slotp,unsigned int *funcp) +static int pci_parse_devaddr (const char *addr,unsigned int *domp, +unsigned int *busp,unsigned int *slotp, +unsigned int *funcp) {const char *p;char *e;
@@ -571,8 +572,8 @@ static int pci_parse_devaddr(const char *addr, int *domp, int *busp,return 0 ; } -int pci_read_devaddr (Monitor *mon,const char *addr,int *domp,int *busp, -unsigned *slotp) +int pci_read_devaddr (Monitor *mon,const char *addr,unsigned int *domp, +unsigned int *busp,unsigned *slotp) {/* strip legacy tag */ if (!strncmp (addr,"pci_addr=" ,9 )) {
@@ -587,7 +588,7 @@ int pci_read_devaddr(Monitor *mon, const char *addr, int *domp, int *busp,PCIBus *pci_get_bus_devfn (int *devfnp,const char *devaddr) { -int dom, bus; +unsigned int dom, bus;unsigned slot;if (!devaddr) {
hw/pci.h +2 -2
@@ -340,8 +340,8 @@ PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn);int pci_qdev_find_device (const char *id,PCIDevice **pdev);PCIBus *pci_get_bus_devfn (int *devfnp,const char *devaddr); -int pci_read_devaddr (Monitor *mon,const char *addr,int *domp,int *busp, -unsigned *slotp); +int pci_read_devaddr (Monitor *mon,const char *addr,unsigned int *domp, +unsigned int *busp,unsigned *slotp);void pci_device_deassert_intx (PCIDevice *dev);
Signature · 1 line
1.7.3.4
PATCH 8/13 pci: Export pci_parse_devaddr instead of pci_read_devaddr
In reply to Jan KiszkaThe latter is an internal helper for PCI hotplug. So move it where it belongs - before someone misuses it - and export the more versatile pci_parse_devaddr instead.
--- hw/pci-hotplug.c | 18 ++++++++++++++++-- hw/pci.c | 19 ++----------------- hw/pci.h | 4 ++-- 3 files changed, 20 insertions(+), 21 deletions(-)
hw/pci-hotplug.c +16 -2
@@ -34,6 +34,20 @@#include "blockdev.h" #include "error.h" +static int read_pci_devaddr (Monitor *mon,const char *addr,unsigned int *domp, +unsigned int *busp,unsigned *slotp) +{ +/* strip legacy tag */ +if (!strncmp (addr,"pci_addr=" ,9 )) { + addr +=9 ; + } +if (pci_parse_devaddr (addr, domp, busp, slotp,NULL )) { +monitor_printf (mon,"Invalid pci address\n" ); +return -1 ; + } +return 0 ; +} +#if defined(TARGET_I386 ) static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon, const char *devaddr,
@@ -115,7 +129,7 @@ int pci_drive_hot_add(Monitor *mon, const QDict *qdict,switch (type) {case IF_SCSI : -if (pci_read_devaddr (mon, pci_addr, &dom, &pci_bus, &slot)) { +if (read_pci_devaddr (mon, pci_addr, &dom, &pci_bus, &slot)) { goto err; } dev = pci_find_device(pci_find_root_bus(dom), pci_bus,
@@ -261,7 +275,7 @@ static int pci_device_hot_remove(Monitor *mon, const char *pci_addr)unsigned slot;Error *local_err =NULL ; -if (pci_read_devaddr (mon, pci_addr, &dom, &bus, &slot)) { +if (read_pci_devaddr (mon, pci_addr, &dom, &bus, &slot)) {return -1 ; }
hw/pci.c +2 -17
@@ -512,9 +512,8 @@ static void pci_set_default_subsystem_id(PCIDevice *pci_dev)* Parse [[<domain>:]<bus>:]<slot>, return -1 on error if funcp == NULL * [[<domain>:]<bus>:]<slot>.<func>, return -1 on error */ -static int pci_parse_devaddr (const char *addr,unsigned int *domp, -unsigned int *busp,unsigned int *slotp, -unsigned int *funcp) +int pci_parse_devaddr (const char *addr,unsigned int *domp,unsigned int *busp, +unsigned int *slotp,unsigned int *funcp) {const char *p;char *e;
@@ -572,20 +571,6 @@ static int pci_parse_devaddr(const char *addr, unsigned int *domp,return 0 ; } -int pci_read_devaddr (Monitor *mon,const char *addr,unsigned int *domp, -unsigned int *busp,unsigned *slotp) -{ -/* strip legacy tag */ -if (!strncmp (addr,"pci_addr=" ,9 )) { - addr +=9 ; - } -if (pci_parse_devaddr (addr, domp, busp, slotp,NULL )) { -monitor_printf (mon,"Invalid pci address\n" ); -return -1 ; - } -return 0 ; -} -PCIBus *pci_get_bus_devfn (int *devfnp,const char *devaddr) {unsigned int dom, bus;
hw/pci.h +2 -2
@@ -340,8 +340,8 @@ PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn);int pci_qdev_find_device (const char *id,PCIDevice **pdev);PCIBus *pci_get_bus_devfn (int *devfnp,const char *devaddr); -int pci_read_devaddr (Monitor *mon,const char *addr,unsigned int *domp, -unsigned int *busp,unsigned *slotp); +int pci_parse_devaddr (const char *addr,unsigned int *domp,unsigned int *busp, +unsigned int *slotp,unsigned int *funcp);void pci_device_deassert_intx (PCIDevice *dev);
Signature · 1 line
1.7.3.4
PATCH 9/13 pci: Introduce and apply PCIDeviceAddress
In reply to Jan KiszkaThis type encapsulates everything from domain to function. Use it first to simplify the pci_parse_devaddr interface.
--- hw/pci-hotplug.c | 29 ++++++++++++++--------------- hw/pci.c | 31 ++++++++++++++----------------- hw/pci.h | 6 ++++-- qemu-common.h | 7 +++++++ 4 files changed, 39 insertions(+), 34 deletions(-)
hw/pci-hotplug.c +14 -15
@@ -34,14 +34,14 @@#include "blockdev.h" #include "error.h" -static int read_pci_devaddr (Monitor *mon,const char *addr,unsigned int *domp, -unsigned int *busp,unsigned *slotp) +static int read_pci_devaddr (Monitor *mon,const char *addrstr, +PCIDeviceAddress *addr) {/* strip legacy tag */ -if (!strncmp (addr,"pci_addr=" ,9 )) { - addr +=9 ; +if (!strncmp (addrstr,"pci_addr=" ,9 )) { + addrstr +=9 ; } -if (pci_parse_devaddr (addr, domp, busp, slotp,NULL )) { +if (pci_parse_devaddr (addrstr, addr,0 )) {monitor_printf (mon,"Invalid pci address\n" );return -1 ; }
@@ -122,18 +122,17 @@ static int scsi_hot_add(Monitor *mon, DeviceState *adapter,int pci_drive_hot_add (Monitor *mon,const QDict *qdict,DriveInfo *dinfo,int type) { -unsigned int dom, pci_bus; -unsigned slot; +PCIDeviceAddress addr;PCIDevice *dev;const char *pci_addr =qdict_get_str (qdict,"pci_addr" );switch (type) {case IF_SCSI : -if (read_pci_devaddr (mon, pci_addr, &dom, &pci_bus, &slot)) { +if (read_pci_devaddr (mon, pci_addr, &addr)) { goto err; } - dev =pci_find_device (pci_find_root_bus (dom), pci_bus, -PCI_DEVFN (slot,0 )); + dev =pci_find_device (pci_find_root_bus (addr.domain), addr.bus, +PCI_DEVFN (addr.slot,0 ));if (!dev) {monitor_printf (mon,"no pci device with address %s\n" , pci_addr); goto err;
@@ -270,18 +269,18 @@ void pci_device_hot_add(Monitor *mon, const QDict *qdict)static int pci_device_hot_remove (Monitor *mon,const char *pci_addr) { +PCIDeviceAddress addr;PCIDevice *d; -unsigned int dom, bus; -unsigned slot;Error *local_err =NULL ; -if (read_pci_devaddr (mon, pci_addr, &dom, &bus, &slot)) { +if (read_pci_devaddr (mon, pci_addr, &addr)) {return -1 ; } - d =pci_find_device (pci_find_root_bus (dom), bus,PCI_DEVFN (slot,0 )); + d =pci_find_device (pci_find_root_bus (addr.domain), addr.bus, +PCI_DEVFN (addr.slot,0 ));if (!d) { -monitor_printf (mon,"slot %d empty\n" , slot); +monitor_printf (mon,"slot %d empty\n" , addr.slot);return -1 ; }
hw/pci.c +14 -17
@@ -509,20 +509,20 @@ static void pci_set_default_subsystem_id(PCIDevice *pci_dev) }/* -* Parse [[<domain>:]<bus>:]<slot>, return -1 on error if funcp == NULL +* Parse [[<domain>:]<bus>:]<slot>, return -1 on error if !PCI_DEVADDR_WITH_FUNC * [[<domain>:]<bus>:]<slot>.<func>, return -1 on error */ -int pci_parse_devaddr (const char *addr,unsigned int *domp,unsigned int *busp, -unsigned int *slotp,unsigned int *funcp) +int pci_parse_devaddr (const char *addrstr,PCIDeviceAddress *addr, +unsigned int flags) {const char *p;char *e;unsigned long val;unsigned long dom =0 , bus =0 ; -unsigned int slot =0 ; +unsigned int slot;unsigned int func =0 ; - p = addr; + p = addrstr; val =strtoul (p, &e,16 );if (e == p)return -1 ;
@@ -544,7 +544,7 @@ int pci_parse_devaddr(const char *addr, unsigned int *domp, unsigned int *busp, slot = val; -if (funcp !=NULL ) { +if (flags &PCI_DEVADDR_WITH_FUNC ) {if (*e !='.' )return -1 ;
@@ -556,37 +556,34 @@ int pci_parse_devaddr(const char *addr, unsigned int *domp, unsigned int *busp, func = val; } -/* if funcp == NULL func is 0 */ if (dom >0xffff || bus >0xff || slot >0x1f || func >7 )return -1 ;if (*e)return -1 ; - *domp = dom; - *busp = bus; - *slotp = slot; -if (funcp !=NULL ) - *funcp = func; + addr->domain = dom; + addr->bus = bus; + addr->slot = slot; + addr->function = func;return 0 ; }PCIBus *pci_get_bus_devfn (int *devfnp,const char *devaddr) { -unsigned int dom, bus; -unsigned slot; +PCIDeviceAddress addr;if (!devaddr) { *devfnp =-1 ;return pci_find_bus_nr (pci_find_root_bus (0 ),0 ); } -if (pci_parse_devaddr (devaddr, &dom, &bus, &slot,NULL ) <0 ) { +if (pci_parse_devaddr (devaddr, &addr,0 ) <0 ) {return NULL ; } - *devfnp =PCI_DEVFN (slot,0 ); -return pci_find_bus_nr (pci_find_root_bus (dom), bus); + *devfnp =PCI_DEVFN (addr.slot,0 ); +return pci_find_bus_nr (pci_find_root_bus (addr.domain), addr.bus); }static void pci_init_cmask (PCIDevice *dev)
hw/pci.h +4 -2
@@ -340,8 +340,10 @@ PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn);int pci_qdev_find_device (const char *id,PCIDevice **pdev);PCIBus *pci_get_bus_devfn (int *devfnp,const char *devaddr); -int pci_parse_devaddr (const char *addr,unsigned int *domp,unsigned int *busp, -unsigned int *slotp,unsigned int *funcp); +#define PCI_DEVADDR_WITH_FUNC 2 + +int pci_parse_devaddr (const char *addrstr,PCIDeviceAddress *addr, +unsigned int flags);void pci_device_deassert_intx (PCIDevice *dev);
qemu-common.h +7 -0
@@ -274,6 +274,13 @@ typedef enum LostTickPolicy { LOST_TICK_MAX } LostTickPolicy; +typedef struct PCIDeviceAddress { +unsigned int domain; +unsigned int bus; +unsigned int slot; +unsigned int function; +}PCIDeviceAddress ; +void tcg_exec_init (unsigned long tb_size);bool tcg_enabled (void );
Signature · 1 line
1.7.3.4
Re: [Qemu-devel] [PATCH 09/13] pci: Introduce and apply PCIDeviceAddress
Quoted 4 lines · Jan Kiszka
This type encapsulates everything from domain to function. Use it first to simplify the
pci_parse_devaddrinterface.Signed-off-by Jan Kiszka <[email protected]>
OK.
Except this really is a legacy interface.
So please call it PCILegacyDeviceAddress
or something like that.
Quoted 200 lines
--- hw/pci-hotplug.c | 29 ++++++++++++++--------------- hw/pci.c | 31 ++++++++++++++----------------- hw/pci.h | 6 ++++-- qemu-common.h | 7 +++++++ 4 files changed, 39 insertions(+), 34 deletions(-)hw/pci-hotplug.c +14
-15@@ -34,14 +34,14 @@#include "blockdev.h" #include "error.h" -static int read_pci_devaddr (Monitor *mon,const char *addr,unsigned int *domp, -unsigned int *busp,unsigned *slotp) +static int read_pci_devaddr (Monitor *mon,const char *addrstr, +PCIDeviceAddress *addr) {/* strip legacy tag */ -if (!strncmp (addr,"pci_addr=" ,9 )) { - addr +=9 ; +if (!strncmp (addrstr,"pci_addr=" ,9 )) { + addrstr +=9 ; } -if (pci_parse_devaddr (addr, domp, busp, slotp,NULL )) { +if (pci_parse_devaddr (addrstr, addr,0 )) {monitor_printf (mon,"Invalid pci address\n" );return -1 ; }@@ -122,18 +122,17 @@ static int scsi_hot_add(Monitor *mon, DeviceState *adapter,int pci_drive_hot_add (Monitor *mon,const QDict *qdict,DriveInfo *dinfo,int type) { -unsigned int dom, pci_bus; -unsigned slot; +PCIDeviceAddress addr;PCIDevice *dev;const char *pci_addr =qdict_get_str (qdict,"pci_addr" );switch (type) {case IF_SCSI : -if (read_pci_devaddr (mon, pci_addr, &dom, &pci_bus, &slot)) { +if (read_pci_devaddr (mon, pci_addr, &addr)) { goto err; } - dev =pci_find_device (pci_find_root_bus (dom), pci_bus, -PCI_DEVFN (slot,0 )); + dev =pci_find_device (pci_find_root_bus (addr.domain), addr.bus, +PCI_DEVFN (addr.slot,0 ));if (!dev) {monitor_printf (mon,"no pci device with address %s\n" , pci_addr); goto err;@@ -270,18 +269,18 @@ void pci_device_hot_add(Monitor *mon, const QDict *qdict)static int pci_device_hot_remove (Monitor *mon,const char *pci_addr) { +PCIDeviceAddress addr;PCIDevice *d; -unsigned int dom, bus; -unsigned slot;Error *local_err =NULL ; -if (read_pci_devaddr (mon, pci_addr, &dom, &bus, &slot)) { +if (read_pci_devaddr (mon, pci_addr, &addr)) {return -1 ; } - d =pci_find_device (pci_find_root_bus (dom), bus,PCI_DEVFN (slot,0 )); + d =pci_find_device (pci_find_root_bus (addr.domain), addr.bus, +PCI_DEVFN (addr.slot,0 ));if (!d) { -monitor_printf (mon,"slot %d empty\n" , slot); +monitor_printf (mon,"slot %d empty\n" , addr.slot);return -1 ; }hw/pci.c +14
-17@@ -509,20 +509,20 @@ static void pci_set_default_subsystem_id(PCIDevice *pci_dev) }/* -* Parse [[<domain>:]<bus>:]<slot>, return -1 on error if funcp == NULL +* Parse [[<domain>:]<bus>:]<slot>, return -1 on error if !PCI_DEVADDR_WITH_FUNC * [[<domain>:]<bus>:]<slot>.<func>, return -1 on error */ -int pci_parse_devaddr (const char *addr,unsigned int *domp,unsigned int *busp, -unsigned int *slotp,unsigned int *funcp) +int pci_parse_devaddr (const char *addrstr,PCIDeviceAddress *addr, +unsigned int flags) {const char *p;char *e;unsigned long val;unsigned long dom =0 , bus =0 ; -unsigned int slot =0 ; +unsigned int slot;unsigned int func =0 ; - p = addr; + p = addrstr; val =strtoul (p, &e,16 );if (e == p)return -1 ;@@ -544,7 +544,7 @@ int pci_parse_devaddr(const char *addr, unsigned int *domp, unsigned int *busp, slot = val; -if (funcp !=NULL ) { +if (flags &PCI_DEVADDR_WITH_FUNC ) {if (*e !='.' )return -1 ;@@ -556,37 +556,34 @@ int pci_parse_devaddr(const char *addr, unsigned int *domp, unsigned int *busp, func = val; } -/* if funcp == NULL func is 0 */ if (dom >0xffff || bus >0xff || slot >0x1f || func >7 )return -1 ;if (*e)return -1 ; - *domp = dom; - *busp = bus; - *slotp = slot; -if (funcp !=NULL ) - *funcp = func; + addr->domain = dom; + addr->bus = bus; + addr->slot = slot; + addr->function = func;return 0 ; }PCIBus *pci_get_bus_devfn (int *devfnp,const char *devaddr) { -unsigned int dom, bus; -unsigned slot; +PCIDeviceAddress addr;if (!devaddr) { *devfnp =-1 ;return pci_find_bus_nr (pci_find_root_bus (0 ),0 ); } -if (pci_parse_devaddr (devaddr, &dom, &bus, &slot,NULL ) <0 ) { +if (pci_parse_devaddr (devaddr, &addr,0 ) <0 ) {return NULL ; } - *devfnp =PCI_DEVFN (slot,0 ); -return pci_find_bus_nr (pci_find_root_bus (dom), bus); + *devfnp =PCI_DEVFN (addr.slot,0 ); +return pci_find_bus_nr (pci_find_root_bus (addr.domain), addr.bus); }static void pci_init_cmask (PCIDevice *dev)hw/pci.h +4
-2@@ -340,8 +340,10 @@ PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn);int pci_qdev_find_device (const char *id,PCIDevice **pdev);PCIBus *pci_get_bus_devfn (int *devfnp,const char *devaddr); -int pci_parse_devaddr (const char *addr,unsigned int *domp,unsigned int *busp, -unsigned int *slotp,unsigned int *funcp); +#define PCI_DEVADDR_WITH_FUNC 2 + +int pci_parse_devaddr (const char *addrstr,PCIDeviceAddress *addr, +unsigned int flags);void pci_device_deassert_intx (PCIDevice *dev);qemu-common.h +7
-0@@ -274,6 +274,13 @@ typedef enum LostTickPolicy { LOST_TICK_MAX } LostTickPolicy; +typedef struct PCIDeviceAddress { +unsigned int domain; +unsigned int bus; +unsigned int slot; +unsigned int function; +}PCIDeviceAddress ; +void tcg_exec_init (unsigned long tb_size);bool tcg_enabled (void );Signature · 1 line
1.7.3.4
Re: [Qemu-devel] [PATCH 09/13] pci: Introduce and apply PCIDeviceAddress
Quoted 10 lines · Michael S. Tsirkin
Quoted 4 lines · Jan Kiszka
This type encapsulates everything from domain to function. Use it first to simplify the
pci_parse_devaddrinterface.Signed-off-by Jan Kiszka <[email protected]>OK.
Except this really is a legacy interface.
So please call it PCILegacyDeviceAddress
or something like that.
Nope. It might be used for legacy addressing of emulated devices, but it's not legacy for PCI host devices. The address container is neutral /wrt its usage.
Jan
PATCH 10/13 pci: Fix coding style of pci_parse_devaddr
In reply to Jan KiszkaSo that we can move it unmodified without raising alarms. No functional changes.
--- hw/pci.c | 52 ++++++++++++++++++++++++++++------------------------ 1 files changed, 28 insertions(+), 24 deletions(-)
hw/pci.c +28 -24
@@ -524,43 +524,47 @@ int pci_parse_devaddr(const char *addrstr, PCIDeviceAddress *addr, p = addrstr; val =strtoul (p, &e,16 ); -if (e == p) -return -1 ; +if (e == p) { +return -1 ; + }if (*e ==':' ) { - bus = val; - p = e +1 ; - val =strtoul (p, &e,16 ); -if (e == p) -return -1 ; -if (*e ==':' ) { - dom = bus; - bus = val; - p = e +1 ; - val =strtoul (p, &e,16 ); -if (e == p) -return -1 ; - } + bus = val; + p = e +1 ; + val =strtoul (p, &e,16 ); +if (e == p) { +return -1 ; + } +if (*e ==':' ) { + dom = bus; + bus = val; + p = e +1 ; + val =strtoul (p, &e,16 ); +if (e == p) { +return -1 ; + } + } } slot = val;if (flags &PCI_DEVADDR_WITH_FUNC ) { -if (*e !='.' ) +if (*e !='.' ) {return -1 ; - + } p = e +1 ; val =strtoul (p, &e,16 ); -if (e == p) +if (e == p) {return -1 ; - + } func = val; } -if (dom >0xffff || bus >0xff || slot >0x1f || func >7 ) -return -1 ; - -if (*e) -return -1 ; +if (dom >0xffff || bus >0xff || slot >0x1f || func >7 ) { +return -1 ; + } +if (*e) { +return -1 ; + } addr->domain = dom; addr->bus = bus;
Signature · 1 line
1.7.3.4
PATCH 11/13 Move pci_parse_devaddr to qdev-properties
In reply to Jan KiszkaWe will some use this function also for property parsing, so move it over unmodified and rename it.
--- hw/pci-hotplug.c | 2 +- hw/pci.c | 67 +------------------------------------------------- hw/pci.h | 5 --- hw/qdev-properties.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ hw/qdev.h | 5 +++ 5 files changed, 72 insertions(+), 72 deletions(-)
hw/pci-hotplug.c +1 -1
@@ -41,7 +41,7 @@ static int read_pci_devaddr(Monitor *mon, const char *addrstr,if (!strncmp (addrstr,"pci_addr=" ,9 )) { addrstr +=9 ; } -if (pci_parse_devaddr (addrstr, addr,0 )) { +if (qemu_parse_pci_devaddr (addrstr, addr,0 )) {monitor_printf (mon,"Invalid pci address\n" );return -1 ; }
hw/pci.c +1 -66
79 lines not on this page · raw message
hw/pci.h +0 -5
@@ -340,11 +340,6 @@ PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn);int pci_qdev_find_device (const char *id,PCIDevice **pdev);PCIBus *pci_get_bus_devfn (int *devfnp,const char *devaddr); -#define PCI_DEVADDR_WITH_FUNC 2 - -int pci_parse_devaddr (const char *addrstr,PCIDeviceAddress *addr, -unsigned int flags); -void pci_device_deassert_intx (PCIDevice *dev); static inline void
hw/qdev-properties.c +65 -0
71 lines not on this page · raw message
hw/qdev.h +5 -0
@@ -360,4 +360,9 @@ void qdev_set_parent_bus(DeviceState *dev, BusState *bus);extern int qdev_hotplug; +#define PCI_DEVADDR_WITH_FUNC 2 + +int qemu_parse_pci_devaddr (const char *addrstr,PCIDeviceAddress *addr, +unsigned int flags); +#endif
Signature · 1 line
1.7.3.4
Re: [Qemu-devel] [PATCH 11/13] Move pci_parse_devaddr to qdev-properties
Am 04.06.2012 10:52, schrieb Jan Kiszka:
Quoted 4 lines
We will some use this function also for property parsing, so move it over unmodified and rename it.
Signed-off-by Jan Kiszka <[email protected]>
These last three patches collide with Paolo's QOM properties
refactoring: qdev properties are being generalized to Object and on my GitHub "realize" branch are being moved to qom/object-properties.c (object.c in the original series). Please defer this change.
Thanks,
Andreas
Signature · 2 lines
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [PATCH 11/13] Move pci_parse_devaddr to qdev-properties
Quoted 10 lines · Andreas Färber
Am 04.06.2012 10:52, schrieb Jan Kiszka:
Quoted 4 lines
We will some use this function also for property parsing, so move it over unmodified and rename it.
Signed-off-by Jan Kiszka <[email protected]>These last three patches collide with Paolo's QOM properties
refactoring: qdev properties are being generalized to Object and on my GitHub "realize" branch are being moved toqom/object-properties.c(object.cin the original series). Please defer this change.
Depends on how long merging of those branches shall take. This is some important piece for preparing device assignment for upstream, thus finally closing the qemu-kvm fork. I need all this back-merged in qemu-kvm soon to proceed.
Can you (both) comment on the merge schedule for your patches? Are we talking about a week or so?
Jan
Re: [Qemu-devel] [PATCH 11/13] Move pci_parse_devaddr to qdev-properties
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Am 07.06.2012 17:11, schrieb Jan Kiszka:
Quoted 7 lines · Andreas Färber
Quoted 5 lines
These last three patches collide with Paolo's QOM properties
refactoring: qdev properties are being generalized to Object and on my GitHub "realize" branch are being moved toqom/object-properties.c(object.cin the original series). Please defer this change.
Quoted 7 lines
Depends on how long merging of those branches shall take. This is some important piece for preparing device assignment for upstream, thus finally closing the qemu-kvm fork. I need all this back-merged in qemu-kvm soon to proceed.
Can you (both) comment on the merge schedule for your patches? Are we talking about a week or so?
I'm working towards sending the updated patches from realize branch today and the PULL by tomorrow. When it gets merged I cannot predict.
We could speed this up if Paolo takes a look at what I have so far, starting at "qdev: Push state up to Object":
https://github.com/afaerber/qemu-cpu/commits/realize
- From there on I expect it's gonna be cherry-picking and rebasing again.
Maybe split your series in two? I can cc you on the PULL so that you can rebase and immediately piggyback the property changes. ;)
Andreas
- --
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg -----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.18 (GNU/Linux)
iQIcBAEBAgAGBQJP0M8rAAoJEPou0S0+fgE/928P/jTqH25GYtdtqPYLVkjRcMjL mRTl2ar8UOuqFdFFZMKOtoGXNK2lmcqAHkQ8++EkFdhzlrVvLOGVhG4/abRKr8Bx dKv5j1xNSW1wG7arDIWQj6EuKOBuzlCtBrHrU83vq5hcx3usJZJUJeoLH1D1D9st FCMRPy1g4NLIqPhoOfp1muqP9VLBVwmpKuFzXTe1Z3l4eIRY61jNKfnQF9zczUWy eJj2ntvBFOOD9myyCfyEcw1bnLNA7UalyhSGQ4ien8novlyYXCqT5+1uLdYeUmdm BTlPXlyRs5yrawFn2VlKEULxKQWyb+ddJzM+ppHGzdFRz4keqwkbGaCfKliuDJbN AASeN4IWLJMCJxz68eZvKSvzMn5A2IzwtFx0N04l4rZbTlylQtoZ5/W4D//+mH2n hOvZNptsI5Ht29G1hDL5z/VdseRV3XjR64S578bKOj1icpNLfmV4uyNA/gwMOp8Q htzaswdSMejeeJvbxylEtuh1phyMJmnwUf2L+JuG1Ay1v3QngrsVX2gJqnC8ES3w LqiIf1J08T9BhPLYrmm3pAsb5dorSLz+vZmhVB3iZlQAJXuEAjyaZoZJo/u02zY1 BRGfG0HCB4b94FVpcTTorFjf57oSB4MG/xN31rtovBX25oRXNFMWqemetF8A8IWc kprIWBCzOSC2ZGE1SXzL
=DLcx
-----END PGP SIGNATURE-----
Re: [Qemu-devel] [PATCH 11/13] Move pci_parse_devaddr to qdev-properties
Quoted 13 lines · Andreas Färber
Am 07.06.2012 17:11, schrieb Jan Kiszka:
Quoted 11 lines · Andreas Färber
Quoted 5 lines
These last three patches collide with Paolo's QOM properties
refactoring: qdev properties are being generalized to Object and on my GitHub "realize" branch are being moved toqom/object-properties.c(object.cin the original series). Please defer this change.Depends on how long merging of those branches shall take. This is some important piece for preparing device assignment for upstream, thus finally closing the qemu-kvm fork. I need all this back-merged in qemu-kvm soon to proceed.
Quoted 5 lines
Quoted 2 lines
Can you (both) comment on the merge schedule for your patches? Are we talking about a week or so?
I'm working towards sending the updated patches from realize branch today and the PULL by tomorrow. When it gets merged I cannot predict.
To my understanding, patch 2 of your series faces some discussions, and the rest will require refactoring once that has settled. So I guess it's better now to proceed with my patches and rebase your changes on top of them, right?
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Re: [Qemu-devel] [PATCH 11/13] Move pci_parse_devaddr to qdev-properties
Am 08.06.2012 12:57, schrieb Jan Kiszka:
Quoted 17 lines · Andreas Färber
Quoted 16 lines
Am 07.06.2012 17:11, schrieb Jan Kiszka:
Quoted 14 lines · Andreas Färber
Quoted 5 lines
These last three patches collide with Paolo's QOM properties
refactoring: qdev properties are being generalized to Object and on my GitHub "realize" branch are being moved toqom/object-properties.c(object.cin the original series). Please defer this change.Depends on how long merging of those branches shall take. This is some important piece for preparing device assignment for upstream, thus finally closing the qemu-kvm fork. I need all this back-merged in qemu-kvm soon to proceed.
Can you (both) comment on the merge schedule for your patches? Are we talking about a week or so?
Quoted 7 lines
Quoted 2 lines
I'm working towards sending the updated patches from realize branch today and the PULL by tomorrow. When it gets merged I cannot predict.
To my understanding, patch 2 of your series faces some discussions, and the rest will require refactoring once that has settled. So I guess it's better now to proceed with my patches and rebase your changes on top of them, right?
No, there's a patch queue of 28 before the patches under discussion, some of which touch qdev-properties.c as well. Those under discussion are not on qom-next yet.
What's open is that the Makefile series has not been pulled yet and pretty much everyone will need to rebase on that if it gets applied. Hoping for a statement from Anthony there.
Can't understand that you're trying to push your v1 so hard now when our series have been on the list for much longer. ;)
Cheers,
Andreas
Signature · 2 lines
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [PATCH 11/13] Move pci_parse_devaddr to qdev-properties
Quoted 26 lines · Andreas Färber
Am 08.06.2012 12:57, schrieb Jan Kiszka:
Quoted 17 lines · Andreas Färber
Quoted 16 lines
Am 07.06.2012 17:11, schrieb Jan Kiszka:
Quoted 14 lines · Andreas Färber
Quoted 5 lines
These last three patches collide with Paolo's QOM properties
refactoring: qdev properties are being generalized to Object and on my GitHub "realize" branch are being moved toqom/object-properties.c(object.cin the original series). Please defer this change.Depends on how long merging of those branches shall take. This is some important piece for preparing device assignment for upstream, thus finally closing the qemu-kvm fork. I need all this back-merged in qemu-kvm soon to proceed.
Can you (both) comment on the merge schedule for your patches? Are we talking about a week or so?
Quoted 7 lines
Quoted 2 lines
I'm working towards sending the updated patches from realize branch today and the PULL by tomorrow. When it gets merged I cannot predict.
To my understanding, patch 2 of your series faces some discussions, and the rest will require refactoring once that has settled. So I guess it's better now to proceed with my patches and rebase your changes on top of them, right?
Quoted 6 lines
No, there's a patch queue of 28 before the patches under discussion, some of which touch
qdev-properties.cas well. Those under discussion are not on qom-next yet.
What's open is that theMakefileseries has not been pulled yet and pretty much everyone will need to rebase on that if it gets applied. Hoping for a statement from Anthony there.
As I was on CC in that second series, right after you told me you would CC me to allow tracking progress. So I was assuming it was related to this topic.
Quoted 3 lines
Can't understand that you're trying to push your v1 so hard now when our series have been on the list for much longer. ;)
I explained the reason, and I think my patches (minus the dropped one) are ready based on the feedback.
I'm fine if important central refactorings close master for a short period at the beginning of a merge window and require rebasing of other patches afterward. But that should really be *short*.
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Re: [Qemu-devel] [PATCH 11/13] Move pci_parse_devaddr to qdev-properties
Am 08.06.2012 14:14, schrieb Jan Kiszka:
Quoted 10 lines · Andreas Färber
Quoted 2 lines
Can't understand that you're trying to push your v1 so hard now when our series have been on the list for much longer. ;)
I explained the reason, and I think my patches (minus the dropped one) are ready based on the feedback.
I'm fine if important central refactorings close master for a short period at the beginning of a merge window and require rebasing of other patches afterward. But that should really be *short*.
We had a long Hard Freeze that closed master. Your patches are new, so I oppose you sneaking by and having me rebase Paolo's patches on yours. If someone else wants to rebase them on yours that's fine with me.
Andreas
Signature · 2 lines
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [PATCH 11/13] Move pci_parse_devaddr to qdev-properties
Quoted 8 lines · Andreas Färber
Am 08.06.2012 14:14, schrieb Jan Kiszka:
Quoted 7 lines · Andreas Färber
Quoted 2 lines
Can't understand that you're trying to push your v1 so hard now when our series have been on the list for much longer. ;)
I explained the reason, and I think my patches (minus the dropped one) are ready based on the feedback.
Quoted 7 lines
Quoted 3 lines
I'm fine if important central refactorings close master for a short period at the beginning of a merge window and require rebasing of other patches afterward. But that should really be *short*.
We had a long Hard Freeze that closed master. Your patches are new, so I oppose you sneaking by and having me rebase Paolo's patches on yours. If someone else wants to rebase them on yours that's fine with me.
If your patches get merged over the next week, I'm fine. If not, be warned to see me grumbling again. ;)
Michael, unless there are other remarks, 1 and 3-10 could be picked up by you and pushed already. I'll send an update for 6 to fix the commit log.
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Re: [Qemu-devel] [PATCH 11/13] Move pci_parse_devaddr to qdev-properties
Quoted 17 lines · Jan Kiszka
Quoted 8 lines · Andreas Färber
Am 08.06.2012 14:14, schrieb Jan Kiszka:
Quoted 7 lines · Andreas Färber
Quoted 2 lines
Can't understand that you're trying to push your v1 so hard now when our series have been on the list for much longer. ;)
I explained the reason, and I think my patches (minus the dropped one) are ready based on the feedback.
Quoted 7 lines
Quoted 3 lines
I'm fine if important central refactorings close master for a short period at the beginning of a merge window and require rebasing of other patches afterward. But that should really be *short*.
We had a long Hard Freeze that closed master. Your patches are new, so I oppose you sneaking by and having me rebase Paolo's patches on yours. If someone else wants to rebase them on yours that's fine with me.
Quoted 7 lines
If your patches get merged over the next week, I'm fine. If not, be warned to see me grumbling again. ;)
Michael, unless there are other remarks, 1 and 3-10 could be picked up by you and pushed already. I'll send an update for 6 to fix the commit log.
Jan
They look ready to me too, so I can pick your patches up and put them on the pci branch. Prefer doing it Sunday when I'm rested.
But FYI I just sent a pull request to Anthony Thursday and I try not to flood him with more than one a week unless there's a huge regression to fix.
If large changes land in master meanwhile we'll have to resolve the conflict but that's par for the course.
Quoted 3 lines
Signature · 2 lines
Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Re: [Qemu-devel] [PATCH 11/13] Move pci_parse_devaddr to qdev-properties
Quoted 24 lines · Michael S. Tsirkin
Quoted 23 lines · Jan Kiszka
Quoted 8 lines · Andreas Färber
Am 08.06.2012 14:14, schrieb Jan Kiszka:
Quoted 7 lines · Andreas Färber
Quoted 2 lines
Can't understand that you're trying to push your v1 so hard now when our series have been on the list for much longer. ;)
I explained the reason, and I think my patches (minus the dropped one) are ready based on the feedback.
Quoted 7 lines
Quoted 3 lines
I'm fine if important central refactorings close master for a short period at the beginning of a merge window and require rebasing of other patches afterward. But that should really be *short*.
We had a long Hard Freeze that closed master. Your patches are new, so I oppose you sneaking by and having me rebase Paolo's patches on yours. If someone else wants to rebase them on yours that's fine with me.
If your patches get merged over the next week, I'm fine. If not, be warned to see me grumbling again. ;)
Michael, unless there are other remarks, 1 and 3-10 could be picked up by you and pushed already. I'll send an update for 6 to fix the commit log.
Quoted 7 lines
Quoted 1 line
Jan
They look ready to me too, so I can pick your patches up and put them on the pci branch. Prefer doing it Sunday when I'm rested.
But FYI I just sent a pull request to Anthony Thursday and I try not to flood him with more than one a week unless there's a huge regression to fix.
FYI, I don't plan on applying any more pulls until Monday most likely as I'm flying back to the US tomorrow morning. If you want to update the PULL on Sunday, just send out a new request that includes the old and I'll ignore it.
Paolo's series may conflict, but I don't think resolving will be too hard.
Regards,
Anthony Liguori
Quoted 7 lines
If large changes land in master meanwhile we'll have to resolve the conflict but that's par for the course.
Quoted 3 lines
--
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux
Re: [Qemu-devel] [PATCH 11/13] Move pci_parse_devaddr to qdev-properties
In reply to Andreas FärberQuoted 10 lines · Andreas Färber
Am 04.06.2012 10:52, schrieb Jan Kiszka:
Quoted 4 lines
We will some use this function also for property parsing, so move it over unmodified and rename it.
Signed-off-by Jan Kiszka<[email protected]>These last three patches collide with Paolo's QOM properties
refactoring: qdev properties are being generalized to Object and on my GitHub "realize" branch are being moved toqom/object-properties.c(object.cin the original series). Please defer this change.
Sorry, this doesn't scale.
Patches need to go in when they're ready. If that means someone branch has a hard time rebasing, it probably means that branch should have attempted to merge sooner.
If you want to work out the issues earlier, then setup a next branch or something like that.
But don't expect someone else to hold up there work just because it conflicts with yours. That kind of ordering won't scale in a community as large as ours.
Regards,
Anthony Liguori
Quoted 4 lines
Thanks,
Andreas
Re: [Qemu-devel] [PATCH 11/13] Move pci_parse_devaddr to qdev-properties
Am 08.06.2012 15:55, schrieb Anthony Liguori:
Quoted 5 lines · Andreas Färber
Quoted 4 lines
Am 04.06.2012 10:52, schrieb Jan Kiszka:
Quoted 3 lines
We will some use this function also for property parsing, so move it over unmodified and rename it.
Quoted 8 lines
Quoted 6 lines
Quoted 1 line
Signed-off-by Jan Kiszka<[email protected]>These last three patches collide with Paolo's QOM properties
refactoring: qdev properties are being generalized to Object and on my GitHub "realize" branch are being moved toqom/object-properties.c(object.cin the original series). Please defer this change.Sorry, this doesn't scale.
Jinx! :)
Quoted 6 lines
Patches need to go in when they're ready. If that means someone branch has a hard time rebasing, it probably means that branch should have attempted to merge sooner.
If you want to work out the issues earlier, then setup a next branch or something like that.
We *are* talking about qom-NEXT here! It serves exactly that purpose, to have a known location for people to rebase on and to avoid conflicts. Jan was ignoring that, I'm guessing because he doesn't read qemu-devel unless cc'ed. And in turn I don't consider it the duty of the qom-next maintainer to check everyone's submission for possible fumbling in qdev/qom code and rebasing onto every random open PULL. (Note that I'm not complaining about properties being added in some random file, I am specifically annoyed about refactoring in hw/qdev-properties.c after these series have been around for like two months and after I officially announced the branch as requested by you.)
And let's not forget that a certain release manager promised to talk to me/us about the post-1.1 merge plan after rc4 but then instead decided to fold rc4 and final and opened up the master branch without discussing any merge strategy, contributing to this chaos. The way you are handling it, it is totally unclear for submaintainers in which order series are going to go in. So either we need to coordinate PULLs among each other as attempted here, or you as maintainer need to volunteer to merge such conflicting PULLs yourself and not just bouncing them.
Anyway, some people need to take care of packaging the tarball after it's released and your part in the release process is finished. That takes time, and your change of schedule stirred my time planning for a whole week. ;)
Plus a contributor to qom-next surpassing himself with another invasive refactoring that you wanted to fast-track wasn't helpful either.
Not to mention that this is also connected to a nack of yours for which we still don't have a solution, while the original author is on travels.
So yes, I could have started merging qom-next earlier (e.g., had I taken the decision to split it earlier) and you could've supported that effort better through early review, better planning and better communication.
Quoted 3 lines
But don't expect someone else to hold up there work just because it conflicts with yours. That kind of ordering won't scale in a community as large as ours.
I am only one and cannot rebase onto every open pull request, especially not for a branch that was only meant to bridge the imposed Hard Freeze and should thus go away quickly because no longer needed.
If it were a private branch/series of mine then that would be a different matter of course.
Nevertheless conflicts do happen and need to be resolved by someone. If you are volunteering, so that I don't have to speak up, that's fine with me. But saying that ordering doesn't scale in a community is not solving the problem.
Regards,
Andreas
Signature · 2 lines
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
PATCH 12/13 qdev-properties: Use qemu_parse_pci_devaddr for pci-devfn property
In reply to Jan KiszkaGeneralize qemu_parse_pci_devaddr by two flags so that it can be used for parsing pci-devfn properties as well.
--- hw/pci-hotplug.c | 2 +- hw/pci.c | 3 ++- hw/qdev-properties.c | 49 ++++++++++++++++++++++++------------------------- hw/qdev.h | 2 ++ 4 files changed, 29 insertions(+), 27 deletions(-)
hw/pci-hotplug.c +1 -1
@@ -41,7 +41,7 @@ static int read_pci_devaddr(Monitor *mon, const char *addrstr,if (!strncmp (addrstr,"pci_addr=" ,9 )) { addrstr +=9 ; } -if (qemu_parse_pci_devaddr (addrstr, addr,0 )) { +if (qemu_parse_pci_devaddr (addrstr, addr,PCI_DEVADDR_WITH_DOM_BUS_OPT )) {monitor_printf (mon,"Invalid pci address\n" );return -1 ; }
hw/pci.c +2 -1
@@ -517,7 +517,8 @@ PCIBus *pci_get_bus_devfn(int *devfnp, const char *devaddr)return pci_find_bus_nr (pci_find_root_bus (0 ),0 ); } -if (qemu_parse_pci_devaddr (devaddr, &addr,0 ) <0 ) { +if (qemu_parse_pci_devaddr (devaddr, &addr, +PCI_DEVADDR_WITH_DOM_BUS_OPT ) <0 ) {return NULL ; }
hw/qdev-properties.c +24 -25
82 lines not on this page · raw message
hw/qdev.h +2 -0
@@ -360,7 +360,9 @@ void qdev_set_parent_bus(DeviceState *dev, BusState *bus);extern int qdev_hotplug; +#define PCI_DEVADDR_WITH_DOM_BUS_OPT 1#define PCI_DEVADDR_WITH_FUNC 2 +#define PCI_DEVADDR_WITH_FUNC_OPT 4int qemu_parse_pci_devaddr (const char *addrstr,PCIDeviceAddress *addr,unsigned int flags);
Signature · 1 line
1.7.3.4
PATCH 13/13 qdev-properties: Add pci-devaddr property
In reply to Jan KiszkaAdd a property to receive a fully qualified PCI device address.
Will be used by KVM device assignment.
--- hw/qdev-properties.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ hw/qdev.h | 3 +++ 2 files changed, 51 insertions(+), 0 deletions(-)
hw/qdev-properties.c +48 -0
@@ -946,6 +946,54 @@ PropertyInfo qdev_prop_pci_devfn = { .max = 0xFFFFFFFFULL, }; +static void get_pci_devaddr (Object *obj,Visitor *v,void *opaque, +const char *name,Error **errp) +{ +DeviceState *dev =DEVICE (obj); +Property *prop = opaque; +PCIDeviceAddress *addr =qdev_get_prop_ptr (dev, prop); +char buffer[10 +3 +1 ]; +char *p = buffer; + +snprintf (buffer,sizeof (buffer),"%04x:%02x:%02x.%02x" , + addr->domain, addr->bus, addr->slot, addr->function); + +visit_type_str (v, &p, name, errp); +} + +static void set_pci_devaddr (Object *obj,Visitor *v,void *opaque, +const char *name,Error **errp) +{ +DeviceState *dev =DEVICE (obj); +Property *prop = opaque; +PCIDeviceAddress *addr =qdev_get_prop_ptr (dev, prop); +Error *local_err =NULL ; +char *str; + +if (dev->state !=DEV_STATE_CREATED ) { +error_set (errp,QERR_PERMISSION_DENIED ); +return ; + } + +visit_type_str (v, &str, name, &local_err); +if (local_err) { +error_propagate (errp, local_err); +return ; + } + +if (qemu_parse_pci_devaddr (str, addr, +PCI_DEVADDR_WITH_DOM_BUS_OPT | +PCI_DEVADDR_WITH_FUNC ) <0 ) { +error_set_from_qdev_prop_error (errp,EINVAL , dev, prop, str); + } +} + +PropertyInfo qdev_prop_pci_devaddr = { + .name ="pci-devaddr" , + .get = get_pci_devaddr, + .set = set_pci_devaddr, +}; +/* --- blocksize --- */ static void set_blocksize(Object *obj, Visitor *v, void *opaque,
hw/qdev.h +3 -0
@@ -224,6 +224,7 @@ extern PropertyInfo qdev_prop_drive;extern PropertyInfo qdev_prop_netdev;extern PropertyInfo qdev_prop_vlan;extern PropertyInfo qdev_prop_pci_devfn; +extern PropertyInfo qdev_prop_pci_devaddr;extern PropertyInfo qdev_prop_blocksize;#define DEFINE_PROP (_name, _state, _field, _prop, _type) { \
@@ -288,6 +289,8 @@ extern PropertyInfo qdev_prop_blocksize; LostTickPolicy)#define DEFINE_PROP_BLOCKSIZE (_n, _s, _f, _d) \ DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_blocksize, uint16_t) +#define DEFINE_PROP_PCI_DEVADDR (_n, _s, _f) \ + DEFINE_PROP(_n, _s, _f, qdev_prop_pci_devaddr, PCIDeviceAddress)#define DEFINE_PROP_END_OF_LIST () \ {}
Signature · 1 line
1.7.3.4
Re: [Qemu-devel] [PATCH 13/13] qdev-properties: Add pci-devaddr property
Quoted 5 lines · Jan Kiszka
Add a property to receive a fully qualified PCI device address.
Will be used by KVM device assignment.
Signed-off-by Jan Kiszka <[email protected]>
I'd like to ponder this a bit more. What bothers me is that this mixes two things:
- addressing of qemu devices
Using full device addresses there is a legacy feature, users really should supply the parent bus and the bus local address.
- addressing devices on the linux host for assignment It so happens that the syntax matches
the legacy naming very closely,
but conceptually is completely unrelated
Quoted 47 lines
--- hw/qdev-properties.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ hw/qdev.h | 3 +++ 2 files changed, 51 insertions(+), 0 deletions(-)hw/qdev-properties.c +34
-0@@ -946,6 +946,54 @@ PropertyInfo qdev_prop_pci_devfn = { .max = 0xFFFFFFFFULL, }; +static void get_pci_devaddr (Object *obj,Visitor *v,void *opaque, +const char *name,Error **errp) +{ +DeviceState *dev =DEVICE (obj); +Property *prop = opaque; +PCIDeviceAddress *addr =qdev_get_prop_ptr (dev, prop); +char buffer[10 +3 +1 ]; +char *p = buffer; + +snprintf (buffer,sizeof (buffer),"%04x:%02x:%02x.%02x" , + addr->domain, addr->bus, addr->slot, addr->function); + +visit_type_str (v, &p, name, errp); +} + +static void set_pci_devaddr (Object *obj,Visitor *v,void *opaque, +const char *name,Error **errp) +{ +DeviceState *dev =DEVICE (obj); +Property *prop = opaque; +PCIDeviceAddress *addr =qdev_get_prop_ptr (dev, prop); +Error *local_err =NULL ; +char *str; + +if (dev->state !=DEV_STATE_CREATED ) { +error_set (errp,QERR_PERMISSION_DENIED ); +return ; + } + +visit_type_str (v, &str, name, &local_err); +if (local_err) { +error_propagate (errp, local_err); +return ; + }
hw/qdev-properties.c PropertyInfo qdev_prop_pci_devfn = { · line 992
Quoted 10 lines
hw/qdev-properties.c +10
-0+ +if (qemu_parse_pci_devaddr (str, addr, +PCI_DEVADDR_WITH_DOM_BUS_OPT | +PCI_DEVADDR_WITH_FUNC ) <0 ) { +error_set_from_qdev_prop_error (errp,EINVAL , dev, prop, str); + } +} + +PropertyInfo qdev_prop_pci_devaddr = { + .name ="pci-devaddr" ,
This is a very confusing name. Something like host-pci-address? This also should be built on linux only.
Can this be part of device assignment code instead of qdev?
Quoted 30 lines
hw/qdev-properties.c +4
-0+ .get = get_pci_devaddr, + .set = set_pci_devaddr, +}; +/* --- blocksize --- */ static void set_blocksize(Object *obj, Visitor *v, void *opaque,hw/qdev.h +3
-0@@ -224,6 +224,7 @@ extern PropertyInfo qdev_prop_drive;extern PropertyInfo qdev_prop_netdev;extern PropertyInfo qdev_prop_vlan;extern PropertyInfo qdev_prop_pci_devfn; +extern PropertyInfo qdev_prop_pci_devaddr;extern PropertyInfo qdev_prop_blocksize;#define DEFINE_PROP (_name, _state, _field, _prop, _type) { \@@ -288,6 +289,8 @@ extern PropertyInfo qdev_prop_blocksize; LostTickPolicy)#define DEFINE_PROP_BLOCKSIZE (_n, _s, _f, _d) \ DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_blocksize, uint16_t) +#define DEFINE_PROP_PCI_DEVADDR (_n, _s, _f) \ + DEFINE_PROP(_n, _s, _f, qdev_prop_pci_devaddr, PCIDeviceAddress)#define DEFINE_PROP_END_OF_LIST () \ {}Signature · 1 line
1.7.3.4
Re: [Qemu-devel] [PATCH 13/13] qdev-properties: Add pci-devaddr property
Quoted 7 lines · Michael S. Tsirkin
Quoted 5 lines · Jan Kiszka
Add a property to receive a fully qualified PCI device address.
Will be used by KVM device assignment.
Signed-off-by Jan Kiszka <[email protected]>
Quoted 10 lines
I'd like to ponder this a bit more. What bothers me is that this mixes two things:
- addressing of qemu devices
Using full device addresses there is a legacy feature, users really should supply the parent bus and the bus local address.
- addressing devices on the linux host for assignment It so happens that the syntax matches
the legacy naming very closely,
but conceptually is completely unrelated
We can keep code duplications, of course.
Quoted 52 lines
Quoted 52 lines
--- hw/qdev-properties.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ hw/qdev.h | 3 +++ 2 files changed, 51 insertions(+), 0 deletions(-)hw/qdev-properties.c +38
-0@@ -946,6 +946,54 @@ PropertyInfo qdev_prop_pci_devfn = { .max = 0xFFFFFFFFULL, }; +static void get_pci_devaddr (Object *obj,Visitor *v,void *opaque, +const char *name,Error **errp) +{ +DeviceState *dev =DEVICE (obj); +Property *prop = opaque; +PCIDeviceAddress *addr =qdev_get_prop_ptr (dev, prop); +char buffer[10 +3 +1 ]; +char *p = buffer; + +snprintf (buffer,sizeof (buffer),"%04x:%02x:%02x.%02x" , + addr->domain, addr->bus, addr->slot, addr->function); + +visit_type_str (v, &p, name, errp); +} + +static void set_pci_devaddr (Object *obj,Visitor *v,void *opaque, +const char *name,Error **errp) +{ +DeviceState *dev =DEVICE (obj); +Property *prop = opaque; +PCIDeviceAddress *addr =qdev_get_prop_ptr (dev, prop); +Error *local_err =NULL ; +char *str; + +if (dev->state !=DEV_STATE_CREATED ) { +error_set (errp,QERR_PERMISSION_DENIED ); +return ; + } + +visit_type_str (v, &str, name, &local_err); +if (local_err) { +error_propagate (errp, local_err); +return ; + } + +if (qemu_parse_pci_devaddr (str, addr, +PCI_DEVADDR_WITH_DOM_BUS_OPT | +PCI_DEVADDR_WITH_FUNC ) <0 ) {
Quoted 8 lines
hw/qdev-properties.c PropertyInfo qdev_prop_pci_devfn = { · line 992
Quoted 6 lines
hw/qdev-properties.c +6
-0+error_set_from_qdev_prop_error (errp,EINVAL , dev, prop, str); + } +} + +PropertyInfo qdev_prop_pci_devaddr = { + .name ="pci-devaddr" ,This is a very confusing name. Something like host-pci-address?
That might be an option.
Quoted 1 line
This also should be built on linux only.
Why, what do we gain with #ifdefs? And isn't the addressing concept generic?
Quoted 1 line
Can this be part of device assignment code instead of qdev?
How does VFIO address their host devices? And Xen?
Jan
Re: [Qemu-devel] [PATCH 13/13] qdev-properties: Add pci-devaddr property
Quoted 82 lines · Jan Kiszka
Quoted 7 lines · Michael S. Tsirkin
Quoted 5 lines · Jan Kiszka
Add a property to receive a fully qualified PCI device address.
Will be used by KVM device assignment.
Signed-off-by Jan Kiszka <[email protected]>Quoted 10 lines
I'd like to ponder this a bit more. What bothers me is that this mixes two things:
- addressing of qemu devices
Using full device addresses there is a legacy feature, users really should supply the parent bus and the bus local address.
- addressing devices on the linux host for assignment It so happens that the syntax matches
the legacy naming very closely,
but conceptually is completely unrelatedWe can keep code duplications, of course.
Quoted 52 lines
Quoted 52 lines
--- hw/qdev-properties.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ hw/qdev.h | 3 +++ 2 files changed, 51 insertions(+), 0 deletions(-)hw/qdev-properties.c +38
-0@@ -946,6 +946,54 @@ PropertyInfo qdev_prop_pci_devfn = { .max = 0xFFFFFFFFULL, }; +static void get_pci_devaddr (Object *obj,Visitor *v,void *opaque, +const char *name,Error **errp) +{ +DeviceState *dev =DEVICE (obj); +Property *prop = opaque; +PCIDeviceAddress *addr =qdev_get_prop_ptr (dev, prop); +char buffer[10 +3 +1 ]; +char *p = buffer; + +snprintf (buffer,sizeof (buffer),"%04x:%02x:%02x.%02x" , + addr->domain, addr->bus, addr->slot, addr->function); + +visit_type_str (v, &p, name, errp); +} + +static void set_pci_devaddr (Object *obj,Visitor *v,void *opaque, +const char *name,Error **errp) +{ +DeviceState *dev =DEVICE (obj); +Property *prop = opaque; +PCIDeviceAddress *addr =qdev_get_prop_ptr (dev, prop); +Error *local_err =NULL ; +char *str; + +if (dev->state !=DEV_STATE_CREATED ) { +error_set (errp,QERR_PERMISSION_DENIED ); +return ; + } + +visit_type_str (v, &str, name, &local_err); +if (local_err) { +error_propagate (errp, local_err); +return ; + } + +if (qemu_parse_pci_devaddr (str, addr, +PCI_DEVADDR_WITH_DOM_BUS_OPT | +PCI_DEVADDR_WITH_FUNC ) <0 ) {Quoted 8 lines
hw/qdev-properties.c PropertyInfo qdev_prop_pci_devfn = { · line 992
Quoted 6 lines
hw/qdev-properties.c +6
-0+error_set_from_qdev_prop_error (errp,EINVAL , dev, prop, str); + } +} + +PropertyInfo qdev_prop_pci_devaddr = { + .name ="pci-devaddr" ,This is a very confusing name. Something like host-pci-address?
Quoted 5 lines
That might be an option.
Quoted 1 line
This also should be built on linux only.
Why, what do we gain with #ifdefs? And isn't the addressing concept generic?
Not the XXX:XX.X format. And not the concept of a domain.
Quoted 3 lines
Quoted 1 line
Can this be part of device assignment code instead of qdev?
How does VFIO address their host devices?
You get an fd I think. I think you don't need to know the host address.
Quoted 5 lines
And Xen?
Jan
Re: [Qemu-devel] [PATCH 13/13] qdev-properties: Add pci-devaddr property
Quoted 89 lines · Michael S. Tsirkin
Quoted 82 lines · Jan Kiszka
Quoted 7 lines · Michael S. Tsirkin
Quoted 5 lines · Jan Kiszka
Add a property to receive a fully qualified PCI device address.
Will be used by KVM device assignment.
Signed-off-by Jan Kiszka <[email protected]>Quoted 10 lines
I'd like to ponder this a bit more. What bothers me is that this mixes two things:
- addressing of qemu devices
Using full device addresses there is a legacy feature, users really should supply the parent bus and the bus local address.
- addressing devices on the linux host for assignment It so happens that the syntax matches
the legacy naming very closely,
but conceptually is completely unrelatedWe can keep code duplications, of course.
Quoted 52 lines
Quoted 52 lines
--- hw/qdev-properties.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ hw/qdev.h | 3 +++ 2 files changed, 51 insertions(+), 0 deletions(-)hw/qdev-properties.c +38
-0@@ -946,6 +946,54 @@ PropertyInfo qdev_prop_pci_devfn = { .max = 0xFFFFFFFFULL, }; +static void get_pci_devaddr (Object *obj,Visitor *v,void *opaque, +const char *name,Error **errp) +{ +DeviceState *dev =DEVICE (obj); +Property *prop = opaque; +PCIDeviceAddress *addr =qdev_get_prop_ptr (dev, prop); +char buffer[10 +3 +1 ]; +char *p = buffer; + +snprintf (buffer,sizeof (buffer),"%04x:%02x:%02x.%02x" , + addr->domain, addr->bus, addr->slot, addr->function); + +visit_type_str (v, &p, name, errp); +} + +static void set_pci_devaddr (Object *obj,Visitor *v,void *opaque, +const char *name,Error **errp) +{ +DeviceState *dev =DEVICE (obj); +Property *prop = opaque; +PCIDeviceAddress *addr =qdev_get_prop_ptr (dev, prop); +Error *local_err =NULL ; +char *str; + +if (dev->state !=DEV_STATE_CREATED ) { +error_set (errp,QERR_PERMISSION_DENIED ); +return ; + } + +visit_type_str (v, &str, name, &local_err); +if (local_err) { +error_propagate (errp, local_err); +return ; + } + +if (qemu_parse_pci_devaddr (str, addr, +PCI_DEVADDR_WITH_DOM_BUS_OPT | +PCI_DEVADDR_WITH_FUNC ) <0 ) {Quoted 8 lines
hw/qdev-properties.c PropertyInfo qdev_prop_pci_devfn = { · line 992
Quoted 6 lines
hw/qdev-properties.c +6
-0+error_set_from_qdev_prop_error (errp,EINVAL , dev, prop, str); + } +} + +PropertyInfo qdev_prop_pci_devaddr = { + .name ="pci-devaddr" ,This is a very confusing name. Something like host-pci-address?
Quoted 5 lines
That might be an option.
Quoted 1 line
This also should be built on linux only.
Why, what do we gain with #ifdefs? And isn't the addressing concept generic?
Quoted 7 lines
Not the XXX:XX.X format. And not the concept of a domain.
Quoted 3 lines
Quoted 1 line
Can this be part of device assignment code instead of qdev?
How does VFIO address their host devices?
You get an fd I think. I think you don't need to know the host address.
vfio_pci.c contains a nice function called "parse_hostaddr". You may guess what it does. ;)
So we need this generic service. Let's called it pci-host-devaddr and be fine?
Jan
Re: [Qemu-devel] [PATCH 13/13] qdev-properties: Add pci-devaddr property
Quoted 92 lines · Jan Kiszka
Quoted 91 lines · Michael S. Tsirkin
Quoted 82 lines · Jan Kiszka
Quoted 7 lines · Michael S. Tsirkin
Quoted 5 lines · Jan Kiszka
Add a property to receive a fully qualified PCI device address.
Will be used by KVM device assignment.
Signed-off-by Jan Kiszka <[email protected]>Quoted 10 lines
I'd like to ponder this a bit more. What bothers me is that this mixes two things:
- addressing of qemu devices
Using full device addresses there is a legacy feature, users really should supply the parent bus and the bus local address.
- addressing devices on the linux host for assignment It so happens that the syntax matches
the legacy naming very closely,
but conceptually is completely unrelatedWe can keep code duplications, of course.
Quoted 52 lines
Quoted 52 lines
--- hw/qdev-properties.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ hw/qdev.h | 3 +++ 2 files changed, 51 insertions(+), 0 deletions(-)hw/qdev-properties.c +38
-0@@ -946,6 +946,54 @@ PropertyInfo qdev_prop_pci_devfn = { .max = 0xFFFFFFFFULL, }; +static void get_pci_devaddr (Object *obj,Visitor *v,void *opaque, +const char *name,Error **errp) +{ +DeviceState *dev =DEVICE (obj); +Property *prop = opaque; +PCIDeviceAddress *addr =qdev_get_prop_ptr (dev, prop); +char buffer[10 +3 +1 ]; +char *p = buffer; + +snprintf (buffer,sizeof (buffer),"%04x:%02x:%02x.%02x" , + addr->domain, addr->bus, addr->slot, addr->function); + +visit_type_str (v, &p, name, errp); +} + +static void set_pci_devaddr (Object *obj,Visitor *v,void *opaque, +const char *name,Error **errp) +{ +DeviceState *dev =DEVICE (obj); +Property *prop = opaque; +PCIDeviceAddress *addr =qdev_get_prop_ptr (dev, prop); +Error *local_err =NULL ; +char *str; + +if (dev->state !=DEV_STATE_CREATED ) { +error_set (errp,QERR_PERMISSION_DENIED ); +return ; + } + +visit_type_str (v, &str, name, &local_err); +if (local_err) { +error_propagate (errp, local_err); +return ; + } + +if (qemu_parse_pci_devaddr (str, addr, +PCI_DEVADDR_WITH_DOM_BUS_OPT | +PCI_DEVADDR_WITH_FUNC ) <0 ) {Quoted 8 lines
hw/qdev-properties.c PropertyInfo qdev_prop_pci_devfn = { · line 992
Quoted 6 lines
hw/qdev-properties.c +6
-0+error_set_from_qdev_prop_error (errp,EINVAL , dev, prop, str); + } +} + +PropertyInfo qdev_prop_pci_devaddr = { + .name ="pci-devaddr" ,This is a very confusing name. Something like host-pci-address?
Quoted 5 lines
That might be an option.
Quoted 1 line
This also should be built on linux only.
Why, what do we gain with #ifdefs? And isn't the addressing concept generic?
Not the XXX:XX.X format. And not the concept of a domain.
Quoted 8 lines
Quoted 5 lines
Quoted 3 lines
Quoted 1 line
Can this be part of device assignment code instead of qdev?
How does VFIO address their host devices?
You get an fd I think. I think you don't need to know the host address.
vfio_pci.ccontains a nice function called "parse_hostaddr". You may guess what it does. ;)
Interesting. Why? This looks strange to me:
I would expect the admin to bind a device to vfio
the way it's now bound to a stub.
The pass /dev/vfioXXX to qemu.
Quoted 6 lines
So we need this generic service. Let's called it pci-host-devaddr and be fine?
Jan
Re: [Qemu-devel] [PATCH 13/13] qdev-properties: Add pci-devaddr property
Quoted 99 lines · Michael S. Tsirkin
Quoted 98 lines · Jan Kiszka
Quoted 96 lines · Michael S. Tsirkin
Quoted 82 lines · Jan Kiszka
Quoted 7 lines · Michael S. Tsirkin
Quoted 5 lines · Jan Kiszka
Add a property to receive a fully qualified PCI device address.
Will be used by KVM device assignment.
Signed-off-by Jan Kiszka <[email protected]>Quoted 10 lines
I'd like to ponder this a bit more. What bothers me is that this mixes two things:
- addressing of qemu devices
Using full device addresses there is a legacy feature, users really should supply the parent bus and the bus local address.
- addressing devices on the linux host for assignment It so happens that the syntax matches
the legacy naming very closely,
but conceptually is completely unrelatedWe can keep code duplications, of course.
Quoted 52 lines
Quoted 52 lines
--- hw/qdev-properties.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ hw/qdev.h | 3 +++ 2 files changed, 51 insertions(+), 0 deletions(-)hw/qdev-properties.c +38
-0@@ -946,6 +946,54 @@ PropertyInfo qdev_prop_pci_devfn = { .max = 0xFFFFFFFFULL, }; +static void get_pci_devaddr (Object *obj,Visitor *v,void *opaque, +const char *name,Error **errp) +{ +DeviceState *dev =DEVICE (obj); +Property *prop = opaque; +PCIDeviceAddress *addr =qdev_get_prop_ptr (dev, prop); +char buffer[10 +3 +1 ]; +char *p = buffer; + +snprintf (buffer,sizeof (buffer),"%04x:%02x:%02x.%02x" , + addr->domain, addr->bus, addr->slot, addr->function); + +visit_type_str (v, &p, name, errp); +} + +static void set_pci_devaddr (Object *obj,Visitor *v,void *opaque, +const char *name,Error **errp) +{ +DeviceState *dev =DEVICE (obj); +Property *prop = opaque; +PCIDeviceAddress *addr =qdev_get_prop_ptr (dev, prop); +Error *local_err =NULL ; +char *str; + +if (dev->state !=DEV_STATE_CREATED ) { +error_set (errp,QERR_PERMISSION_DENIED ); +return ; + } + +visit_type_str (v, &str, name, &local_err); +if (local_err) { +error_propagate (errp, local_err); +return ; + } + +if (qemu_parse_pci_devaddr (str, addr, +PCI_DEVADDR_WITH_DOM_BUS_OPT | +PCI_DEVADDR_WITH_FUNC ) <0 ) {Quoted 8 lines
hw/qdev-properties.c PropertyInfo qdev_prop_pci_devfn = { · line 992
Quoted 6 lines
hw/qdev-properties.c +6
-0+error_set_from_qdev_prop_error (errp,EINVAL , dev, prop, str); + } +} + +PropertyInfo qdev_prop_pci_devaddr = { + .name ="pci-devaddr" ,This is a very confusing name. Something like host-pci-address?
Quoted 5 lines
That might be an option.
Quoted 1 line
This also should be built on linux only.
Why, what do we gain with #ifdefs? And isn't the addressing concept generic?
Not the XXX:XX.X format. And not the concept of a domain.
Quoted 3 lines
Quoted 1 line
Can this be part of device assignment code instead of qdev?
How does VFIO address their host devices?
You get an fd I think. I think you don't need to know the host address.
Quoted 7 lines
Quoted 2 lines
vfio_pci.ccontains a nice function called "parse_hostaddr". You may guess what it does. ;)Interesting. Why? This looks strange to me:
I would expect the admin to bind a device to vfio
the way it's now bound to a stub.
The pass/dev/vfioXXXto qemu.
That's the "libvirt way". We surely also want the "qemu command line way" for which this kind of service is needed.
Jan
Re: [Qemu-devel] [PATCH 13/13] qdev-properties: Add pci-devaddr property
Quoted 108 lines · Jan Kiszka
Quoted 99 lines · Michael S. Tsirkin
Quoted 98 lines · Jan Kiszka
Quoted 96 lines · Michael S. Tsirkin
Quoted 82 lines · Jan Kiszka
Quoted 7 lines · Michael S. Tsirkin
Quoted 5 lines · Jan Kiszka
Add a property to receive a fully qualified PCI device address.
Will be used by KVM device assignment.
Signed-off-by Jan Kiszka <[email protected]>Quoted 10 lines
I'd like to ponder this a bit more. What bothers me is that this mixes two things:
- addressing of qemu devices
Using full device addresses there is a legacy feature, users really should supply the parent bus and the bus local address.
- addressing devices on the linux host for assignment It so happens that the syntax matches
the legacy naming very closely,
but conceptually is completely unrelatedWe can keep code duplications, of course.
Quoted 52 lines
Quoted 52 lines
--- hw/qdev-properties.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ hw/qdev.h | 3 +++ 2 files changed, 51 insertions(+), 0 deletions(-)hw/qdev-properties.c +38
-0@@ -946,6 +946,54 @@ PropertyInfo qdev_prop_pci_devfn = { .max = 0xFFFFFFFFULL, }; +static void get_pci_devaddr (Object *obj,Visitor *v,void *opaque, +const char *name,Error **errp) +{ +DeviceState *dev =DEVICE (obj); +Property *prop = opaque; +PCIDeviceAddress *addr =qdev_get_prop_ptr (dev, prop); +char buffer[10 +3 +1 ]; +char *p = buffer; + +snprintf (buffer,sizeof (buffer),"%04x:%02x:%02x.%02x" , + addr->domain, addr->bus, addr->slot, addr->function); + +visit_type_str (v, &p, name, errp); +} + +static void set_pci_devaddr (Object *obj,Visitor *v,void *opaque, +const char *name,Error **errp) +{ +DeviceState *dev =DEVICE (obj); +Property *prop = opaque; +PCIDeviceAddress *addr =qdev_get_prop_ptr (dev, prop); +Error *local_err =NULL ; +char *str; + +if (dev->state !=DEV_STATE_CREATED ) { +error_set (errp,QERR_PERMISSION_DENIED ); +return ; + } + +visit_type_str (v, &str, name, &local_err); +if (local_err) { +error_propagate (errp, local_err); +return ; + } + +if (qemu_parse_pci_devaddr (str, addr, +PCI_DEVADDR_WITH_DOM_BUS_OPT | +PCI_DEVADDR_WITH_FUNC ) <0 ) {Quoted 8 lines
hw/qdev-properties.c PropertyInfo qdev_prop_pci_devfn = { · line 992
Quoted 6 lines
hw/qdev-properties.c +6
-0+error_set_from_qdev_prop_error (errp,EINVAL , dev, prop, str); + } +} + +PropertyInfo qdev_prop_pci_devaddr = { + .name ="pci-devaddr" ,This is a very confusing name. Something like host-pci-address?
Quoted 5 lines
That might be an option.
Quoted 1 line
This also should be built on linux only.
Why, what do we gain with #ifdefs? And isn't the addressing concept generic?
Not the XXX:XX.X format. And not the concept of a domain.
Quoted 3 lines
Quoted 1 line
Can this be part of device assignment code instead of qdev?
How does VFIO address their host devices?
You get an fd I think. I think you don't need to know the host address.
Quoted 7 lines
Quoted 2 lines
vfio_pci.ccontains a nice function called "parse_hostaddr". You may guess what it does. ;)Interesting. Why? This looks strange to me:
I would expect the admin to bind a device to vfio
the way it's now bound to a stub.
The pass/dev/vfioXXXto qemu.
Quoted 5 lines
That's the "libvirt way". We surely also want the "qemu command line way" for which this kind of service is needed.
Jan
Yes, I imagine the qemu command line passing in /dev/vfioXXX, the libvirt way will pass in an fd for above. No?
Signature · 1 line
MST
Re: [Qemu-devel] [PATCH 13/13] qdev-properties: Add pci-devaddr property
Quoted 109 lines · Michael S. Tsirkin
Quoted 108 lines · Jan Kiszka
Quoted 106 lines · Michael S. Tsirkin
Quoted 92 lines · Jan Kiszka
Quoted 91 lines · Michael S. Tsirkin
Quoted 82 lines · Jan Kiszka
Quoted 7 lines · Michael S. Tsirkin
Quoted 5 lines · Jan Kiszka
Add a property to receive a fully qualified PCI device address.
Will be used by KVM device assignment.
Signed-off-by Jan Kiszka <[email protected]>Quoted 10 lines
I'd like to ponder this a bit more. What bothers me is that this mixes two things:
- addressing of qemu devices
Using full device addresses there is a legacy feature, users really should supply the parent bus and the bus local address.
- addressing devices on the linux host for assignment It so happens that the syntax matches
the legacy naming very closely,
but conceptually is completely unrelatedWe can keep code duplications, of course.
Quoted 52 lines
Quoted 52 lines
--- hw/qdev-properties.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ hw/qdev.h | 3 +++ 2 files changed, 51 insertions(+), 0 deletions(-)hw/qdev-properties.c +38
-0@@ -946,6 +946,54 @@ PropertyInfo qdev_prop_pci_devfn = { .max = 0xFFFFFFFFULL, }; +static void get_pci_devaddr (Object *obj,Visitor *v,void *opaque, +const char *name,Error **errp) +{ +DeviceState *dev =DEVICE (obj); +Property *prop = opaque; +PCIDeviceAddress *addr =qdev_get_prop_ptr (dev, prop); +char buffer[10 +3 +1 ]; +char *p = buffer; + +snprintf (buffer,sizeof (buffer),"%04x:%02x:%02x.%02x" , + addr->domain, addr->bus, addr->slot, addr->function); + +visit_type_str (v, &p, name, errp); +} + +static void set_pci_devaddr (Object *obj,Visitor *v,void *opaque, +const char *name,Error **errp) +{ +DeviceState *dev =DEVICE (obj); +Property *prop = opaque; +PCIDeviceAddress *addr =qdev_get_prop_ptr (dev, prop); +Error *local_err =NULL ; +char *str; + +if (dev->state !=DEV_STATE_CREATED ) { +error_set (errp,QERR_PERMISSION_DENIED ); +return ; + } + +visit_type_str (v, &str, name, &local_err); +if (local_err) { +error_propagate (errp, local_err); +return ; + } + +if (qemu_parse_pci_devaddr (str, addr, +PCI_DEVADDR_WITH_DOM_BUS_OPT | +PCI_DEVADDR_WITH_FUNC ) <0 ) {Quoted 8 lines
hw/qdev-properties.c PropertyInfo qdev_prop_pci_devfn = { · line 992
Quoted 6 lines
hw/qdev-properties.c +6
-0+error_set_from_qdev_prop_error (errp,EINVAL , dev, prop, str); + } +} + +PropertyInfo qdev_prop_pci_devaddr = { + .name ="pci-devaddr" ,This is a very confusing name. Something like host-pci-address?
Quoted 5 lines
That might be an option.
Quoted 1 line
This also should be built on linux only.
Why, what do we gain with #ifdefs? And isn't the addressing concept generic?
Not the XXX:XX.X format. And not the concept of a domain.
Quoted 8 lines
Quoted 5 lines
Quoted 3 lines
Quoted 1 line
Can this be part of device assignment code instead of qdev?
How does VFIO address their host devices?
You get an fd I think. I think you don't need to know the host address.
vfio_pci.ccontains a nice function called "parse_hostaddr". You may guess what it does. ;)Interesting. Why? This looks strange to me:
I would expect the admin to bind a device to vfio
the way it's now bound to a stub.
The pass/dev/vfioXXXto qemu.
Quoted 8 lines
Quoted 5 lines
That's the "libvirt way". We surely also want the "qemu command line way" for which this kind of service is needed.
Jan
Yes, I imagine the qemu command line passing in
/dev/vfioXXX, the libvirt way will pass in an fd for above. No?
As far as I understand the API, there is no device file per assigned device. Also, this [domain:]bus:dev.fn format is more handy for the command line.
Jan
Re: [Qemu-devel] [PATCH 13/13] qdev-properties: Add pci-devaddr property
Quoted 113 lines · Jan Kiszka
Quoted 112 lines · Michael S. Tsirkin
Quoted 111 lines · Jan Kiszka
Quoted 99 lines · Michael S. Tsirkin
Quoted 98 lines · Jan Kiszka
Quoted 96 lines · Michael S. Tsirkin
Quoted 82 lines · Jan Kiszka
Quoted 7 lines · Michael S. Tsirkin
Quoted 5 lines · Jan Kiszka
Add a property to receive a fully qualified PCI device address.
Will be used by KVM device assignment.
Signed-off-by Jan Kiszka <[email protected]>Quoted 10 lines
I'd like to ponder this a bit more. What bothers me is that this mixes two things:
- addressing of qemu devices
Using full device addresses there is a legacy feature, users really should supply the parent bus and the bus local address.
- addressing devices on the linux host for assignment It so happens that the syntax matches
the legacy naming very closely,
but conceptually is completely unrelatedWe can keep code duplications, of course.
Quoted 52 lines
Quoted 52 lines
--- hw/qdev-properties.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ hw/qdev.h | 3 +++ 2 files changed, 51 insertions(+), 0 deletions(-)hw/qdev-properties.c +38
-0@@ -946,6 +946,54 @@ PropertyInfo qdev_prop_pci_devfn = { .max = 0xFFFFFFFFULL, }; +static void get_pci_devaddr (Object *obj,Visitor *v,void *opaque, +const char *name,Error **errp) +{ +DeviceState *dev =DEVICE (obj); +Property *prop = opaque; +PCIDeviceAddress *addr =qdev_get_prop_ptr (dev, prop); +char buffer[10 +3 +1 ]; +char *p = buffer; + +snprintf (buffer,sizeof (buffer),"%04x:%02x:%02x.%02x" , + addr->domain, addr->bus, addr->slot, addr->function); + +visit_type_str (v, &p, name, errp); +} + +static void set_pci_devaddr (Object *obj,Visitor *v,void *opaque, +const char *name,Error **errp) +{ +DeviceState *dev =DEVICE (obj); +Property *prop = opaque; +PCIDeviceAddress *addr =qdev_get_prop_ptr (dev, prop); +Error *local_err =NULL ; +char *str; + +if (dev->state !=DEV_STATE_CREATED ) { +error_set (errp,QERR_PERMISSION_DENIED ); +return ; + } + +visit_type_str (v, &str, name, &local_err); +if (local_err) { +error_propagate (errp, local_err); +return ; + } + +if (qemu_parse_pci_devaddr (str, addr, +PCI_DEVADDR_WITH_DOM_BUS_OPT | +PCI_DEVADDR_WITH_FUNC ) <0 ) {Quoted 8 lines
hw/qdev-properties.c PropertyInfo qdev_prop_pci_devfn = { · line 992
Quoted 6 lines
hw/qdev-properties.c +6
-0+error_set_from_qdev_prop_error (errp,EINVAL , dev, prop, str); + } +} + +PropertyInfo qdev_prop_pci_devaddr = { + .name ="pci-devaddr" ,This is a very confusing name. Something like host-pci-address?
Quoted 5 lines
That might be an option.
Quoted 1 line
This also should be built on linux only.
Why, what do we gain with #ifdefs? And isn't the addressing concept generic?
Not the XXX:XX.X format. And not the concept of a domain.
Quoted 3 lines
Quoted 1 line
Can this be part of device assignment code instead of qdev?
How does VFIO address their host devices?
You get an fd I think. I think you don't need to know the host address.
Quoted 7 lines
Quoted 2 lines
vfio_pci.ccontains a nice function called "parse_hostaddr". You may guess what it does. ;)Interesting. Why? This looks strange to me:
I would expect the admin to bind a device to vfio
the way it's now bound to a stub.
The pass/dev/vfioXXXto qemu.That's the "libvirt way". We surely also want the "qemu command line way" for which this kind of service is needed.
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
Jan
Yes, I imagine the qemu command line passing in
/dev/vfioXXX, the libvirt way will pass in an fd for above. No?As far as I understand the API, there is no device file per assigned device.
Does it do pci_get_domain_bus_and_slot like kvm then? With all the warts like you have to remember to bind pci stub or you get two drivers for one device?
If true that's unfortunate IMHO.
Quoted 5 lines
Also, this [domain:]bus:dev.fn format is more handy for the command line.
Jan
Then users could add udev rules that will name vfio devices like this. Another interesting option: /dev/vfio/eth0/vf1. That's better I think: no one really likes running lspci and guessing the address from there.
Signature · 1 line
MST
Re: [Qemu-devel] [PATCH 13/13] qdev-properties: Add pci-devaddr property
Quoted 131 lines · Michael S. Tsirkin
Quoted 113 lines · Jan Kiszka
Quoted 112 lines · Michael S. Tsirkin
Quoted 111 lines · Jan Kiszka
Quoted 99 lines · Michael S. Tsirkin
Quoted 98 lines · Jan Kiszka
Quoted 96 lines · Michael S. Tsirkin
Quoted 82 lines · Jan Kiszka
Quoted 7 lines · Michael S. Tsirkin
Quoted 5 lines · Jan Kiszka
Add a property to receive a fully qualified PCI device address.
Will be used by KVM device assignment.
Signed-off-by Jan Kiszka <[email protected]>Quoted 10 lines
I'd like to ponder this a bit more. What bothers me is that this mixes two things:
- addressing of qemu devices
Using full device addresses there is a legacy feature, users really should supply the parent bus and the bus local address.
- addressing devices on the linux host for assignment It so happens that the syntax matches
the legacy naming very closely,
but conceptually is completely unrelatedWe can keep code duplications, of course.
Quoted 52 lines
Quoted 52 lines
--- hw/qdev-properties.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ hw/qdev.h | 3 +++ 2 files changed, 51 insertions(+), 0 deletions(-)hw/qdev-properties.c +38
-0@@ -946,6 +946,54 @@ PropertyInfo qdev_prop_pci_devfn = { .max = 0xFFFFFFFFULL, }; +static void get_pci_devaddr (Object *obj,Visitor *v,void *opaque, +const char *name,Error **errp) +{ +DeviceState *dev =DEVICE (obj); +Property *prop = opaque; +PCIDeviceAddress *addr =qdev_get_prop_ptr (dev, prop); +char buffer[10 +3 +1 ]; +char *p = buffer; + +snprintf (buffer,sizeof (buffer),"%04x:%02x:%02x.%02x" , + addr->domain, addr->bus, addr->slot, addr->function); + +visit_type_str (v, &p, name, errp); +} + +static void set_pci_devaddr (Object *obj,Visitor *v,void *opaque, +const char *name,Error **errp) +{ +DeviceState *dev =DEVICE (obj); +Property *prop = opaque; +PCIDeviceAddress *addr =qdev_get_prop_ptr (dev, prop); +Error *local_err =NULL ; +char *str; + +if (dev->state !=DEV_STATE_CREATED ) { +error_set (errp,QERR_PERMISSION_DENIED ); +return ; + } + +visit_type_str (v, &str, name, &local_err); +if (local_err) { +error_propagate (errp, local_err); +return ; + } + +if (qemu_parse_pci_devaddr (str, addr, +PCI_DEVADDR_WITH_DOM_BUS_OPT | +PCI_DEVADDR_WITH_FUNC ) <0 ) {Quoted 8 lines
hw/qdev-properties.c PropertyInfo qdev_prop_pci_devfn = { · line 992
Quoted 6 lines
hw/qdev-properties.c +6
-0+error_set_from_qdev_prop_error (errp,EINVAL , dev, prop, str); + } +} + +PropertyInfo qdev_prop_pci_devaddr = { + .name ="pci-devaddr" ,This is a very confusing name. Something like host-pci-address?
Quoted 5 lines
That might be an option.
Quoted 1 line
This also should be built on linux only.
Why, what do we gain with #ifdefs? And isn't the addressing concept generic?
Not the XXX:XX.X format. And not the concept of a domain.
Quoted 3 lines
Quoted 1 line
Can this be part of device assignment code instead of qdev?
How does VFIO address their host devices?
You get an fd I think. I think you don't need to know the host address.
Quoted 7 lines
Quoted 2 lines
vfio_pci.ccontains a nice function called "parse_hostaddr". You may guess what it does. ;)Interesting. Why? This looks strange to me:
I would expect the admin to bind a device to vfio
the way it's now bound to a stub.
The pass/dev/vfioXXXto qemu.That's the "libvirt way". We surely also want the "qemu command line way" for which this kind of service is needed.
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
Jan
Yes, I imagine the qemu command line passing in
/dev/vfioXXX, the libvirt way will pass in an fd for above. No?As far as I understand the API, there is no device file per assigned device.
Does it do
pci_get_domain_bus_and_slotlike kvm then? With all the warts like you have to remember to bind pci stub or you get two drivers for one device?
If true that's unfortunate IMHO.Quoted 3 lines
Also, this [domain:]bus:dev.fn format is more handy for the command line.
Quoted 7 lines
Quoted 2 lines
Jan
Then users could add udev rules that will name vfio devices like this. Another interesting option:
/dev/vfio/eth0/vf1. That's better I think: no one really likes running lspci and guessing the address from there.
That's not at all how VFIO works. /dev/vfio/# represents a group, which may contain one or more devices. Even if libvirt passes a file descriptor for the group, qemu needs to know which device in the group to add to the guest, so parsing a device address is still necessary. Thanks,
Alex
Re: [Qemu-devel] [PATCH 13/13] qdev-properties: Add pci-devaddr property
Quoted 17 lines · Alex Williamson
Quoted 17 lines
Quoted 17 lines
Quoted 16 lines
Quoted 8 lines
Quoted 7 lines
Quoted 2 lines
vfio_pci.ccontains a nice function called "parse_hostaddr". You may guess what it does. ;)Interesting. Why? This looks strange to me:
I would expect the admin to bind a device to vfio
the way it's now bound to a stub.
The pass/dev/vfioXXXto qemu.Quoted 5 lines
That's the "libvirt way". We surely also want the "qemu command line way" for which this kind of service is needed.
Jan
Yes, I imagine the qemu command line passing in
/dev/vfioXXX, the libvirt way will pass in an fd for above. No?
Quoted 7 lines
Quoted 7 lines
Quoted 2 lines
As far as I understand the API, there is no device file per assigned device.
Does it do
pci_get_domain_bus_and_slotlike kvm then? With all the warts like you have to remember to bind pci stub or you get two drivers for one device?
If true that's unfortunate IMHO.
I hope the answer to the above is no?
Quoted 11 lines
Quoted 10 lines
Quoted 5 lines
Also, this [domain:]bus:dev.fn format is more handy for the command line.
Jan
Then users could add udev rules that will name vfio devices like this. Another interesting option:
/dev/vfio/eth0/vf1. That's better I think: no one really likes running lspci and guessing the address from there.
Quoted 7 lines
That's not at all how VFIO works. /dev/vfio/# represents a group, which may contain one or more devices. Even if libvirt passes a file descriptor for the group, qemu needs to know which device in the group to add to the guest, so parsing a device address is still necessary. Thanks,
Alex
That's very unusual, and unfortunate. For example this means that I must update applications just because I move a card to another slot. UIO does not have this problem.
The fact that it's broken in kvm ATM seems to have made people think it's okay, but it really is a bug. We didn't fix it because vfio was supposed to be the solution.
I do realize you want to represent a group of devices somehow but can't this be solved without breaking naming devices with udev? For example, the device could be a file as well. You would then use the fd to identify the device within the group. And in a somewhat common case of a single device within the group, you can even make opening the group optional. Don't know if this fix I suggest makes sense at all but it's a real problem all the same.
Signature · 1 line
MST
Re: [Qemu-devel] [PATCH 13/13] qdev-properties: Add pci-devaddr property
Quoted 21 lines · Michael S. Tsirkin
Quoted 20 lines · Alex Williamson
Quoted 20 lines
Quoted 19 lines
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
Quoted 2 lines
vfio_pci.ccontains a nice function called "parse_hostaddr". You may guess what it does. ;)Interesting. Why? This looks strange to me:
I would expect the admin to bind a device to vfio
the way it's now bound to a stub.
The pass/dev/vfioXXXto qemu.Quoted 8 lines
Quoted 5 lines
That's the "libvirt way". We surely also want the "qemu command line way" for which this kind of service is needed.
Jan
Yes, I imagine the qemu command line passing in
/dev/vfioXXX, the libvirt way will pass in an fd for above. No?As far as I understand the API, there is no device file per assigned device.
Quoted 6 lines
Quoted 4 lines
Quoted 4 lines
Does it do
pci_get_domain_bus_and_slotlike kvm then? With all the warts like you have to remember to bind pci stub or you get two drivers for one device?
If true that's unfortunate IMHO.I hope the answer to the above is no?
No, it does a probe for devices. We need the devaddr to compare against dev_name of the device to figure out which device the user is attempting to identify.
Quoted 17 lines
Quoted 17 lines
Quoted 10 lines
Quoted 5 lines
Also, this [domain:]bus:dev.fn format is more handy for the command line.
Jan
Then users could add udev rules that will name vfio devices like this. Another interesting option:
/dev/vfio/eth0/vf1. That's better I think: no one really likes running lspci and guessing the address from there.That's not at all how VFIO works. /dev/vfio/# represents a group, which may contain one or more devices. Even if libvirt passes a file descriptor for the group, qemu needs to know which device in the group to add to the guest, so parsing a device address is still necessary. Thanks,
Quoted 8 lines
Quoted 1 line
Alex
That's very unusual, and unfortunate. For example this means that I must update applications just because I move a card to another slot. UIO does not have this problem.
The fact that it's broken in kvm ATM seems to have made people think it's okay, but it really is a bug. We didn't fix it because vfio was supposed to be the solution.
I don't know what you're talking about here. Are you suggesting that needing to specify -device pci-assign,host=3.0 changing to host=4.0 when you move a card is broken? How does UIO avoid such a problem. UIO-pci requires the user to use pci-sysfs for resource access, so it surely cares about the device address.
Quoted 7 lines
I do realize you want to represent a group of devices somehow but can't this be solved without breaking naming devices with udev? For example, the device could be a file as well. You would then use the fd to identify the device within the group. And in a somewhat common case of a single device within the group, you can even make opening the group optional. Don't know if this fix I suggest makes sense at all but it's a real problem all the same.
Unfortunately, exposing individual devices just confuses the ownership model we require for groups. It would provide the illusion of being able to assign an individual device, without the reality of the grouping. Groups are owned either by _a_ user or by the kernel, they can't be split across multiple users (at least not with any guarantees of isolation). The current interface makes this clear. Thanks,
Alex
Re: [Qemu-devel] [PATCH 13/13] qdev-properties: Add pci-devaddr property
Quoted 59 lines · Alex Williamson
Quoted 21 lines · Michael S. Tsirkin
Quoted 20 lines · Alex Williamson
Quoted 20 lines
Quoted 19 lines
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
Quoted 2 lines
vfio_pci.ccontains a nice function called "parse_hostaddr". You may guess what it does. ;)Interesting. Why? This looks strange to me:
I would expect the admin to bind a device to vfio
the way it's now bound to a stub.
The pass/dev/vfioXXXto qemu.Quoted 8 lines
Quoted 5 lines
That's the "libvirt way". We surely also want the "qemu command line way" for which this kind of service is needed.
Jan
Yes, I imagine the qemu command line passing in
/dev/vfioXXX, the libvirt way will pass in an fd for above. No?As far as I understand the API, there is no device file per assigned device.
Quoted 6 lines
Quoted 4 lines
Quoted 4 lines
Does it do
pci_get_domain_bus_and_slotlike kvm then? With all the warts like you have to remember to bind pci stub or you get two drivers for one device?
If true that's unfortunate IMHO.I hope the answer to the above is no?
No, it does a probe for devices. We need the devaddr to compare against
dev_nameof the device to figure out which device the user is attempting to identify.Quoted 17 lines
Quoted 17 lines
Quoted 10 lines
Quoted 5 lines
Also, this [domain:]bus:dev.fn format is more handy for the command line.
Jan
Then users could add udev rules that will name vfio devices like this. Another interesting option:
/dev/vfio/eth0/vf1. That's better I think: no one really likes running lspci and guessing the address from there.That's not at all how VFIO works. /dev/vfio/# represents a group, which may contain one or more devices. Even if libvirt passes a file descriptor for the group, qemu needs to know which device in the group to add to the guest, so parsing a device address is still necessary. Thanks,
Quoted 8 lines
Quoted 1 line
Alex
That's very unusual, and unfortunate. For example this means that I must update applications just because I move a card to another slot. UIO does not have this problem.
The fact that it's broken in kvm ATM seems to have made people think it's okay, but it really is a bug. We didn't fix it because vfio was supposed to be the solution.
Quoted 3 lines
I don't know what you're talking about here. Are you suggesting that needing to specify -device pci-assign,host=3.0 changing to host=4.0 when you move a card is broken?
Yes. Absolutely. Admin should be able to abstract it away without users knowing anything about it.
Quoted 1 line
How does UIO avoid such a problem.
Normally you use a misc device that you can name with udev.
Quoted 3 lines
UIO-pci
requires the user to use pci-sysfs for resource access, so it surely cares about the device address.
Only uio_pci_generic. Other uio devices let you drive the device.
Quoted 8 lines
Quoted 7 lines
I do realize you want to represent a group of devices somehow but can't this be solved without breaking naming devices with udev? For example, the device could be a file as well. You would then use the fd to identify the device within the group. And in a somewhat common case of a single device within the group, you can even make opening the group optional. Don't know if this fix I suggest makes sense at all but it's a real problem all the same.
Quoted 8 lines
Unfortunately, exposing individual devices just confuses the ownership model we require for groups. It would provide the illusion of being able to assign an individual device, without the reality of the grouping. Groups are owned either by _a_ user or by the kernel, they can't be split across multiple users (at least not with any guarantees of isolation). The current interface makes this clear. Thanks,
Alex
So do users pass in group=/dev/vfio/1,host=0:3.0 then?
Signature · 1 line
MST
Re: [Qemu-devel] [PATCH 13/13] qdev-properties: Add pci-devaddr property
Quoted 60 lines · Michael S. Tsirkin
Quoted 59 lines · Alex Williamson
Quoted 21 lines · Michael S. Tsirkin
Quoted 20 lines · Alex Williamson
Quoted 20 lines
Quoted 19 lines
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
Quoted 2 lines
vfio_pci.ccontains a nice function called "parse_hostaddr". You may guess what it does. ;)Interesting. Why? This looks strange to me:
I would expect the admin to bind a device to vfio
the way it's now bound to a stub.
The pass/dev/vfioXXXto qemu.Quoted 8 lines
Quoted 5 lines
That's the "libvirt way". We surely also want the "qemu command line way" for which this kind of service is needed.
Jan
Yes, I imagine the qemu command line passing in
/dev/vfioXXX, the libvirt way will pass in an fd for above. No?As far as I understand the API, there is no device file per assigned device.
Quoted 6 lines
Quoted 4 lines
Quoted 4 lines
Does it do
pci_get_domain_bus_and_slotlike kvm then? With all the warts like you have to remember to bind pci stub or you get two drivers for one device?
If true that's unfortunate IMHO.I hope the answer to the above is no?
No, it does a probe for devices. We need the devaddr to compare against
dev_nameof the device to figure out which device the user is attempting to identify.Quoted 25 lines
Quoted 11 lines
Quoted 10 lines
Quoted 5 lines
Also, this [domain:]bus:dev.fn format is more handy for the command line.
Jan
Then users could add udev rules that will name vfio devices like this. Another interesting option:
/dev/vfio/eth0/vf1. That's better I think: no one really likes running lspci and guessing the address from there.Quoted 7 lines
That's not at all how VFIO works. /dev/vfio/# represents a group, which may contain one or more devices. Even if libvirt passes a file descriptor for the group, qemu needs to know which device in the group to add to the guest, so parsing a device address is still necessary. Thanks,
Alex
That's very unusual, and unfortunate. For example this means that I must update applications just because I move a card to another slot. UIO does not have this problem.
The fact that it's broken in kvm ATM seems to have made people think it's okay, but it really is a bug. We didn't fix it because vfio was supposed to be the solution.
Quoted 6 lines
Quoted 3 lines
I don't know what you're talking about here. Are you suggesting that needing to specify -device pci-assign,host=3.0 changing to host=4.0 when you move a card is broken?
Yes. Absolutely. Admin should be able to abstract it away without users knowing anything about it.
We don't have UUIDs on PCI devices, so who's to say that the device that was in slot 3 is the same device that's now in slot 4 and the user should still have access to it? That sounds even more problematic.
Quoted 10 lines
Quoted 1 line
How does UIO avoid such a problem.
Normally you use a misc device that you can name with udev.
Quoted 3 lines
UIO-pci
requires the user to use pci-sysfs for resource access, so it surely cares about the device address.Only
uio_pci_generic. Other uio devices let you drive the device.
If this is actually a problem, this is the first ever complaint I've heard about it. As above, I don't think we can assume the same access when a device is moved.
Quoted 15 lines
Quoted 15 lines
Quoted 7 lines
I do realize you want to represent a group of devices somehow but can't this be solved without breaking naming devices with udev? For example, the device could be a file as well. You would then use the fd to identify the device within the group. And in a somewhat common case of a single device within the group, you can even make opening the group optional. Don't know if this fix I suggest makes sense at all but it's a real problem all the same.
Unfortunately, exposing individual devices just confuses the ownership model we require for groups. It would provide the illusion of being able to assign an individual device, without the reality of the grouping. Groups are owned either by _a_ user or by the kernel, they can't be split across multiple users (at least not with any guarantees of isolation). The current interface makes this clear. Thanks,
Quoted 3 lines
Quoted 1 line
Alex
So do users pass in group=/dev/vfio/1,host=0:3.0 then?
No, vfio syntax is -device vfio-pci,host=0:3.0, just like pci-assign. Qemu will figure out which group that device belongs to and "do the right thing". If we add support for libvirt passing a groupfd, it will be mostly the same, just using scm_rights to get the groupfd instead of opening it directly. Thanks,
Alex
Re: [Qemu-devel] [PATCH 13/13] qdev-properties: Add pci-devaddr property
Quoted 65 lines · Alex Williamson
Quoted 64 lines · Michael S. Tsirkin
Quoted 62 lines · Alex Williamson
Quoted 21 lines · Michael S. Tsirkin
Quoted 20 lines · Alex Williamson
Quoted 20 lines
Quoted 19 lines
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
Quoted 2 lines
vfio_pci.ccontains a nice function called "parse_hostaddr". You may guess what it does. ;)Interesting. Why? This looks strange to me:
I would expect the admin to bind a device to vfio
the way it's now bound to a stub.
The pass/dev/vfioXXXto qemu.Quoted 8 lines
Quoted 5 lines
That's the "libvirt way". We surely also want the "qemu command line way" for which this kind of service is needed.
Jan
Yes, I imagine the qemu command line passing in
/dev/vfioXXX, the libvirt way will pass in an fd for above. No?As far as I understand the API, there is no device file per assigned device.
Quoted 6 lines
Quoted 4 lines
Quoted 4 lines
Does it do
pci_get_domain_bus_and_slotlike kvm then? With all the warts like you have to remember to bind pci stub or you get two drivers for one device?
If true that's unfortunate IMHO.I hope the answer to the above is no?
No, it does a probe for devices. We need the devaddr to compare against
dev_nameof the device to figure out which device the user is attempting to identify.Quoted 17 lines
Quoted 17 lines
Quoted 10 lines
Quoted 5 lines
Also, this [domain:]bus:dev.fn format is more handy for the command line.
Jan
Then users could add udev rules that will name vfio devices like this. Another interesting option:
/dev/vfio/eth0/vf1. That's better I think: no one really likes running lspci and guessing the address from there.That's not at all how VFIO works. /dev/vfio/# represents a group, which may contain one or more devices. Even if libvirt passes a file descriptor for the group, qemu needs to know which device in the group to add to the guest, so parsing a device address is still necessary. Thanks,
Quoted 8 lines
Quoted 1 line
Alex
That's very unusual, and unfortunate. For example this means that I must update applications just because I move a card to another slot. UIO does not have this problem.
The fact that it's broken in kvm ATM seems to have made people think it's okay, but it really is a bug. We didn't fix it because vfio was supposed to be the solution.I don't know what you're talking about here. Are you suggesting that needing to specify -device pci-assign,host=3.0 changing to host=4.0 when you move a card is broken?
Quoted 6 lines
Quoted 2 lines
Yes. Absolutely. Admin should be able to abstract it away without users knowing anything about it.
We don't have UUIDs on PCI devices, so who's to say that the device that was in slot 3 is the same device that's now in slot 4 and the user should still have access to it? That sounds even more problematic.
PF has a driver loaded so you can identify that, and identify the VF through it. Again this is really policy, it should be up to the admin how to name the device.
Quoted 8 lines
Quoted 8 lines
Quoted 1 line
How does UIO avoid such a problem.
Normally you use a misc device that you can name with udev.
Quoted 3 lines
UIO-pci
requires the user to use pci-sysfs for resource access, so it surely cares about the device address.
Quoted 6 lines
Quoted 2 lines
Only
uio_pci_generic. Other uio devices let you drive the device.If this is actually a problem, this is the first ever complaint I've heard about it. As above, I don't think we can assume the same access when a device is moved.
I thought need for sane naming and for sysfs interface was discussed multiple times. But maybe I'm misremembering.
Quoted 19 lines
Quoted 15 lines
Quoted 15 lines
Quoted 7 lines
I do realize you want to represent a group of devices somehow but can't this be solved without breaking naming devices with udev? For example, the device could be a file as well. You would then use the fd to identify the device within the group. And in a somewhat common case of a single device within the group, you can even make opening the group optional. Don't know if this fix I suggest makes sense at all but it's a real problem all the same.
Unfortunately, exposing individual devices just confuses the ownership model we require for groups. It would provide the illusion of being able to assign an individual device, without the reality of the grouping. Groups are owned either by _a_ user or by the kernel, they can't be split across multiple users (at least not with any guarantees of isolation). The current interface makes this clear. Thanks,
Quoted 3 lines
Quoted 1 line
Alex
So do users pass in group=/dev/vfio/1,host=0:3.0 then?
Quoted 7 lines
No, vfio syntax is -device vfio-pci,host=0:3.0, just like pci-assign. Qemu will figure out which group that device belongs to and "do the right thing". If we add support for libvirt passing a groupfd, it will be mostly the same, just using
scm_rightsto get the groupfd instead of opening it directly. Thanks,Alex
Then how do you know which /dev/vfio/# to open?
Signature · 1 line
MST
Re: [Qemu-devel] [PATCH 13/13] qdev-properties: Add pci-devaddr property
Quoted 69 lines · Michael S. Tsirkin
Quoted 68 lines · Alex Williamson
Quoted 66 lines · Michael S. Tsirkin
Quoted 59 lines · Alex Williamson
Quoted 21 lines · Michael S. Tsirkin
Quoted 20 lines · Alex Williamson
Quoted 20 lines
Quoted 19 lines
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
Quoted 2 lines
vfio_pci.ccontains a nice function called "parse_hostaddr". You may guess what it does. ;)Interesting. Why? This looks strange to me:
I would expect the admin to bind a device to vfio
the way it's now bound to a stub.
The pass/dev/vfioXXXto qemu.Quoted 8 lines
Quoted 5 lines
That's the "libvirt way". We surely also want the "qemu command line way" for which this kind of service is needed.
Jan
Yes, I imagine the qemu command line passing in
/dev/vfioXXX, the libvirt way will pass in an fd for above. No?As far as I understand the API, there is no device file per assigned device.
Quoted 6 lines
Quoted 4 lines
Quoted 4 lines
Does it do
pci_get_domain_bus_and_slotlike kvm then? With all the warts like you have to remember to bind pci stub or you get two drivers for one device?
If true that's unfortunate IMHO.I hope the answer to the above is no?
No, it does a probe for devices. We need the devaddr to compare against
dev_nameof the device to figure out which device the user is attempting to identify.Quoted 17 lines
Quoted 17 lines
Quoted 10 lines
Quoted 5 lines
Also, this [domain:]bus:dev.fn format is more handy for the command line.
Jan
Then users could add udev rules that will name vfio devices like this. Another interesting option:
/dev/vfio/eth0/vf1. That's better I think: no one really likes running lspci and guessing the address from there.That's not at all how VFIO works. /dev/vfio/# represents a group, which may contain one or more devices. Even if libvirt passes a file descriptor for the group, qemu needs to know which device in the group to add to the guest, so parsing a device address is still necessary. Thanks,
Quoted 8 lines
Quoted 1 line
Alex
That's very unusual, and unfortunate. For example this means that I must update applications just because I move a card to another slot. UIO does not have this problem.
The fact that it's broken in kvm ATM seems to have made people think it's okay, but it really is a bug. We didn't fix it because vfio was supposed to be the solution.Quoted 3 lines
I don't know what you're talking about here. Are you suggesting that needing to specify -device pci-assign,host=3.0 changing to host=4.0 when you move a card is broken?
Yes. Absolutely. Admin should be able to abstract it away without users knowing anything about it.
Quoted 7 lines
Quoted 3 lines
We don't have UUIDs on PCI devices, so who's to say that the device that was in slot 3 is the same device that's now in slot 4 and the user should still have access to it? That sounds even more problematic.
PF has a driver loaded so you can identify that, and identify the VF through it. Again this is really policy, it should be up to the admin how to name the device.
Do PFs have a UUID? Some devices support a serial number, but that's not related to being a PF vs VF. We need to support both PFs and VFs regardless of whether they have any kind of UUID. I think we're inventing a problem though.
Quoted 11 lines
Quoted 11 lines
Quoted 10 lines
Quoted 1 line
How does UIO avoid such a problem.
Normally you use a misc device that you can name with udev.
Quoted 3 lines
UIO-pci
requires the user to use pci-sysfs for resource access, so it surely cares about the device address.Only
uio_pci_generic. Other uio devices let you drive the device.
Quoted 6 lines
Quoted 3 lines
If this is actually a problem, this is the first ever complaint I've heard about it. As above, I don't think we can assume the same access when a device is moved.
I thought need for sane naming and for sysfs interface was discussed multiple times. But maybe I'm misremembering.
There is sane naming and a sysfs interface...
Quoted 25 lines
Quoted 25 lines
Quoted 15 lines
Quoted 15 lines
Quoted 7 lines
I do realize you want to represent a group of devices somehow but can't this be solved without breaking naming devices with udev? For example, the device could be a file as well. You would then use the fd to identify the device within the group. And in a somewhat common case of a single device within the group, you can even make opening the group optional. Don't know if this fix I suggest makes sense at all but it's a real problem all the same.
Unfortunately, exposing individual devices just confuses the ownership model we require for groups. It would provide the illusion of being able to assign an individual device, without the reality of the grouping. Groups are owned either by _a_ user or by the kernel, they can't be split across multiple users (at least not with any guarantees of isolation). The current interface makes this clear. Thanks,
Quoted 3 lines
Quoted 1 line
Alex
So do users pass in group=/dev/vfio/1,host=0:3.0 then?
No, vfio syntax is -device vfio-pci,host=0:3.0, just like pci-assign. Qemu will figure out which group that device belongs to and "do the right thing". If we add support for libvirt passing a groupfd, it will be mostly the same, just using
scm_rightsto get the groupfd instead of opening it directly. Thanks,
Quoted 3 lines
Quoted 1 line
Alex
Then how do you know which /dev/vfio/# to open?
This is all in the documentation patch... groups are exposed in sysfs in /sys/kernel/iommu_groups. Each group has a unique number which is exposed as a directory. Each group directory has a subdirectory called devices which links to all devices in the group. Each device within a group as an iommu_group link back to the group directory. The /dev/vfio/# entry matches the group number in sysfs. So it's all pretty easy. Thanks,
Alex
Re: [Qemu-devel] [PATCH 13/13] qdev-properties: Add pci-devaddr property
Quoted 74 lines · Alex Williamson
Quoted 73 lines · Michael S. Tsirkin
Quoted 71 lines · Alex Williamson
Quoted 60 lines · Michael S. Tsirkin
Quoted 59 lines · Alex Williamson
Quoted 21 lines · Michael S. Tsirkin
Quoted 20 lines · Alex Williamson
Quoted 20 lines
Quoted 19 lines
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
Quoted 2 lines
vfio_pci.c contains a nice function called "parse_hostaddr". You may
guess what it does. ;)Interesting. Why? This looks strange to me:
I would expect the admin to bind a device to vfio
the way it's now bound to a stub.
The pass/dev/vfioXXXto qemu.Quoted 8 lines
Quoted 5 lines
That's the "libvirt way". We surely also want the "qemu command line way" for which this kind of service is needed.
Jan
Yes, I imagine the qemu command line passing in
/dev/vfioXXX, the libvirt way will pass in an fd for above. No?As far as I understand the API, there is no device file per assigned device.
Quoted 6 lines
Quoted 4 lines
Quoted 4 lines
Does it do
pci_get_domain_bus_and_slotlike kvm then? With all the warts like you have to remember to bind pci stub or you get two drivers for one device?
If true that's unfortunate IMHO.I hope the answer to the above is no?
No, it does a probe for devices. We need the devaddr to compare against
dev_nameof the device to figure out which device the user is attempting to identify.Quoted 25 lines
Quoted 11 lines
Quoted 10 lines
Quoted 5 lines
Also, this [domain:]bus:dev.fn format is more handy for the command line.
Jan
Then users could add udev rules that will name vfio devices like this. Another interesting option:
/dev/vfio/eth0/vf1. That's better I think: no one really likes running lspci and guessing the address from there.Quoted 7 lines
That's not at all how VFIO works. /dev/vfio/# represents a group, which may contain one or more devices. Even if libvirt passes a file descriptor for the group, qemu needs to know which device in the group to add to the guest, so parsing a device address is still necessary. Thanks,
Alex
That's very unusual, and unfortunate. For example this means that I must update applications just because I move a card to another slot. UIO does not have this problem.
The fact that it's broken in kvm ATM seems to have made people think it's okay, but it really is a bug. We didn't fix it because vfio was supposed to be the solution.Quoted 6 lines
Quoted 3 lines
I don't know what you're talking about here. Are you suggesting that needing to specify -device pci-assign,host=3.0 changing to host=4.0 when you move a card is broken?
Yes. Absolutely. Admin should be able to abstract it away without users knowing anything about it.
We don't have UUIDs on PCI devices, so who's to say that the device that was in slot 3 is the same device that's now in slot 4 and the user should still have access to it? That sounds even more problematic.
Quoted 7 lines
Quoted 3 lines
PF has a driver loaded so you can identify that, and identify the VF through it. Again this is really policy, it should be up to the admin how to name the device.
Do PFs have a UUID? Some devices support a serial number, but that's not related to being a PF vs VF. We need to support both PFs and VFs regardless of whether they have any kind of UUID.
This is a solved problem. udev has class-specific ways to get the device id and use it to find the name.
Quoted 1 line
I think we're inventing a problem though.
You think persistent names in udev were a solution in search of a problem?
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Quoted 10 lines
Quoted 1 line
How does UIO avoid such a problem.
Normally you use a misc device that you can name with udev.
Quoted 3 lines
UIO-pci
requires the user to use pci-sysfs for resource access, so it surely cares about the device address.Only
uio_pci_generic. Other uio devices let you drive the device.
Quoted 8 lines
Quoted 6 lines
Quoted 3 lines
If this is actually a problem, this is the first ever complaint I've heard about it. As above, I don't think we can assume the same access when a device is moved.
I thought need for sane naming and for sysfs interface was discussed multiple times. But maybe I'm misremembering.
There is sane naming and a sysfs interface...
It's not sane if the admin can't rename the device without breaking applications.
Quoted 37 lines
Quoted 25 lines
Quoted 25 lines
Quoted 15 lines
Quoted 15 lines
Quoted 7 lines
I do realize you want to represent a group of devices somehow but can't this be solved without breaking naming devices with udev? For example, the device could be a file as well. You would then use the fd to identify the device within the group. And in a somewhat common case of a single device within the group, you can even make opening the group optional. Don't know if this fix I suggest makes sense at all but it's a real problem all the same.
Unfortunately, exposing individual devices just confuses the ownership model we require for groups. It would provide the illusion of being able to assign an individual device, without the reality of the grouping. Groups are owned either by _a_ user or by the kernel, they can't be split across multiple users (at least not with any guarantees of isolation). The current interface makes this clear. Thanks,
Quoted 3 lines
Quoted 1 line
Alex
So do users pass in group=/dev/vfio/1,host=0:3.0 then?
No, vfio syntax is -device vfio-pci,host=0:3.0, just like pci-assign. Qemu will figure out which group that device belongs to and "do the right thing". If we add support for libvirt passing a groupfd, it will be mostly the same, just using
scm_rightsto get the groupfd instead of opening it directly. Thanks,Quoted 3 lines
Quoted 1 line
Alex
Then how do you know which /dev/vfio/# to open?
This is all in the documentation patch... groups are exposed in sysfs in
/sys/kernel/iommu_groups. Each group has a unique number which is exposed as a directory. Each group directory has a subdirectory called devices which links to all devices in the group. Each device within a group as aniommu_grouplink back to the group directory. The /dev/vfio/# entry matches the group number in sysfs. So it's all pretty easy. Thanks,
Quoted 1 line
Alex
So what's the problem to have devices in sysfs linked e.g. from /sys/class/vfio/ ? udev could create the nodes e.g. in /dev/vfio/devices/. User can then pass the device name and qemu can figure out the group from sysfs.
Signature · 1 line
MST
Re: [Qemu-devel] [PATCH 13/13] qdev-properties: Add pci-devaddr property
Quoted 79 lines · Michael S. Tsirkin
Quoted 78 lines · Alex Williamson
Quoted 76 lines · Michael S. Tsirkin
Quoted 65 lines · Alex Williamson
Quoted 64 lines · Michael S. Tsirkin
Quoted 62 lines · Alex Williamson
Quoted 21 lines · Michael S. Tsirkin
Quoted 20 lines · Alex Williamson
Quoted 20 lines
Quoted 19 lines
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
vfio_pci.c contains a nice function called "parse_hostaddr". You may
guess what it does. ;)Interesting. Why? This looks strange to me:
I would expect the admin to bind a device to vfio
the way it's now bound to a stub.
The pass /dev/vfioXXX to qemu.Quoted 8 lines
Quoted 5 lines
That's the "libvirt way". We surely also want the "qemu command line way" for which this kind of service is needed.
Jan
Yes, I imagine the qemu command line passing in
/dev/vfioXXX, the libvirt way will pass in an fd for above. No?As far as I understand the API, there is no device file per assigned device.
Quoted 6 lines
Quoted 4 lines
Quoted 4 lines
Does it do
pci_get_domain_bus_and_slotlike kvm then? With all the warts like you have to remember to bind pci stub or you get two drivers for one device?
If true that's unfortunate IMHO.I hope the answer to the above is no?
No, it does a probe for devices. We need the devaddr to compare against
dev_nameof the device to figure out which device the user is attempting to identify.Quoted 17 lines
Quoted 17 lines
Quoted 10 lines
Quoted 5 lines
Also, this [domain:]bus:dev.fn format is more handy for the command line.
Jan
Then users could add udev rules that will name vfio devices like this. Another interesting option:
/dev/vfio/eth0/vf1. That's better I think: no one really likes running lspci and guessing the address from there.That's not at all how VFIO works. /dev/vfio/# represents a group, which may contain one or more devices. Even if libvirt passes a file descriptor for the group, qemu needs to know which device in the group to add to the guest, so parsing a device address is still necessary. Thanks,
Quoted 8 lines
Quoted 1 line
Alex
That's very unusual, and unfortunate. For example this means that I must update applications just because I move a card to another slot. UIO does not have this problem.
The fact that it's broken in kvm ATM seems to have made people think it's okay, but it really is a bug. We didn't fix it because vfio was supposed to be the solution.I don't know what you're talking about here. Are you suggesting that needing to specify -device pci-assign,host=3.0 changing to host=4.0 when you move a card is broken?
Quoted 6 lines
Quoted 2 lines
Yes. Absolutely. Admin should be able to abstract it away without users knowing anything about it.
We don't have UUIDs on PCI devices, so who's to say that the device that was in slot 3 is the same device that's now in slot 4 and the user should still have access to it? That sounds even more problematic.
PF has a driver loaded so you can identify that, and identify the VF through it. Again this is really policy, it should be up to the admin how to name the device.
Quoted 6 lines
Quoted 3 lines
Do PFs have a UUID? Some devices support a serial number, but that's not related to being a PF vs VF. We need to support both PFs and VFs regardless of whether they have any kind of UUID.
This is a solved problem. udev has class-specific ways to get the device id and use it to find the name.
Usually via things discovered via device specific drivers, ex. MACs, disk UUIDs, etc. We don't have those in VFIO. Don't forget, VFIO is also device agnostic, VFIO-pci is just one possible driver backend.
Quoted 4 lines
Quoted 1 line
I think we're inventing a problem though.
You think persistent names in udev were a solution in search of a problem?
Of course not, but I've never heard any indication that this is a real problem for device assignment. If it is, like udev, why not solve it in userspace? The kernel doesn't provide the persistence that udev exposes.
Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
Quoted 14 lines
Quoted 10 lines
Quoted 1 line
How does UIO avoid such a problem.
Normally you use a misc device that you can name with udev.
Quoted 3 lines
UIO-pci
requires the user to use pci-sysfs for resource access, so it surely cares about the device address.Only
uio_pci_generic. Other uio devices let you drive the device.If this is actually a problem, this is the first ever complaint I've heard about it. As above, I don't think we can assume the same access when a device is moved.
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
I thought need for sane naming and for sysfs interface was discussed multiple times. But maybe I'm misremembering.
There is sane naming and a sysfs interface...
It's not sane if the admin can't rename the device without breaking applications.
Again, udev provides that persistence, not the kernel.
Quoted 37 lines
Quoted 37 lines
Quoted 25 lines
Quoted 25 lines
Quoted 15 lines
Quoted 15 lines
Quoted 7 lines
I do realize you want to represent a group of devices somehow but can't this be solved without breaking naming devices with udev? For example, the device could be a file as well. You would then use the fd to identify the device within the group. And in a somewhat common case of a single device within the group, you can even make opening the group optional. Don't know if this fix I suggest makes sense at all but it's a real problem all the same.
Unfortunately, exposing individual devices just confuses the ownership model we require for groups. It would provide the illusion of being able to assign an individual device, without the reality of the grouping. Groups are owned either by _a_ user or by the kernel, they can't be split across multiple users (at least not with any guarantees of isolation). The current interface makes this clear. Thanks,
Quoted 3 lines
Quoted 1 line
Alex
So do users pass in group=/dev/vfio/1,host=0:3.0 then?
No, vfio syntax is -device vfio-pci,host=0:3.0, just like pci-assign. Qemu will figure out which group that device belongs to and "do the right thing". If we add support for libvirt passing a groupfd, it will be mostly the same, just using
scm_rightsto get the groupfd instead of opening it directly. Thanks,Quoted 3 lines
Quoted 1 line
Alex
Then how do you know which /dev/vfio/# to open?
This is all in the documentation patch... groups are exposed in sysfs in
/sys/kernel/iommu_groups. Each group has a unique number which is exposed as a directory. Each group directory has a subdirectory called devices which links to all devices in the group. Each device within a group as aniommu_grouplink back to the group directory. The /dev/vfio/# entry matches the group number in sysfs. So it's all pretty easy. Thanks,
Quoted 4 lines
Quoted 1 line
Alex
So what's the problem to have devices in sysfs linked e.g. from
/sys/class/vfio/?
They have to be bound to a VFIO driver, ex. vfio-pci. We have iommu groups in sysfs and can use that for this purpose. I did have a class for this before iommu_group were more integrated at the device level, now it just seems redundant.
Quoted 3 lines
udev could create the nodes e.g. in
/dev/vfio/devices/. User can then pass the device name and qemu can figure out the group from sysfs.
As previously noted, we don't, and I don't think it makes sense to expose individual devices in VFIO as the interface is fundamentally group based by necessity. Groups are just containers and they do support a name, which is exposed in sysfs when it's used, but groups are created by topology and don't follow the devices, so I don't think that's what you're looking for. It seems that if someone wants to create persistence for VFIO, they just need to identify something unique about a device in sysfs, then follow the device to the group. Userpsace is far more capable of providing this than the kernel. Thanks,
Alex
Re: [Qemu-devel] [PATCH 13/13] qdev-properties: Add pci-devaddr property
Quoted 84 lines · Alex Williamson
Quoted 83 lines · Michael S. Tsirkin
Quoted 81 lines · Alex Williamson
Quoted 69 lines · Michael S. Tsirkin
Quoted 68 lines · Alex Williamson
Quoted 66 lines · Michael S. Tsirkin
Quoted 59 lines · Alex Williamson
Quoted 21 lines · Michael S. Tsirkin
Quoted 20 lines · Alex Williamson
Quoted 20 lines
Quoted 19 lines
Quoted 8 lines
Quoted 8 lines
vfio_pci.c contains a nice function called "parse_hostaddr". You may
guess what it does. ;)Interesting. Why? This looks strange to me:
I would expect the admin to bind a device to vfio
the way it's now bound to a stub.
The pass /dev/vfioXXX to qemu.Quoted 8 lines
Quoted 5 lines
That's the "libvirt way". We surely also want the "qemu command line
way" for which this kind of service is needed.Jan
Yes, I imagine the qemu command line passing in
/dev/vfioXXX, the libvirt way will pass in an fd for above. No?As far as I understand the API, there is no device file per assigned device.
Quoted 6 lines
Quoted 4 lines
Quoted 4 lines
Does it do
pci_get_domain_bus_and_slotlike kvm then? With all the warts like you have to remember to bind pci stub or you get two drivers for one device?
If true that's unfortunate IMHO.I hope the answer to the above is no?
No, it does a probe for devices. We need the devaddr to compare against
dev_nameof the device to figure out which device the user is attempting to identify.Quoted 17 lines
Quoted 17 lines
Quoted 10 lines
Quoted 5 lines
Also, this [domain:]bus:dev.fn format is more handy for the command line.
Jan
Then users could add udev rules that will name vfio devices like this. Another interesting option:
/dev/vfio/eth0/vf1. That's better I think: no one really likes running lspci and guessing the address from there.That's not at all how VFIO works. /dev/vfio/# represents a group, which may contain one or more devices. Even if libvirt passes a file descriptor for the group, qemu needs to know which device in the group to add to the guest, so parsing a device address is still necessary. Thanks,
Quoted 8 lines
Quoted 1 line
Alex
That's very unusual, and unfortunate. For example this means that I must update applications just because I move a card to another slot. UIO does not have this problem.
The fact that it's broken in kvm ATM seems to have made people think it's okay, but it really is a bug. We didn't fix it because vfio was supposed to be the solution.Quoted 3 lines
I don't know what you're talking about here. Are you suggesting that needing to specify -device pci-assign,host=3.0 changing to host=4.0 when you move a card is broken?
Yes. Absolutely. Admin should be able to abstract it away without users knowing anything about it.
Quoted 7 lines
Quoted 3 lines
We don't have UUIDs on PCI devices, so who's to say that the device that was in slot 3 is the same device that's now in slot 4 and the user should still have access to it? That sounds even more problematic.
PF has a driver loaded so you can identify that, and identify the VF through it. Again this is really policy, it should be up to the admin how to name the device.
Do PFs have a UUID? Some devices support a serial number, but that's not related to being a PF vs VF. We need to support both PFs and VFs regardless of whether they have any kind of UUID.
Quoted 6 lines
Quoted 2 lines
This is a solved problem. udev has class-specific ways to get the device id and use it to find the name.
Usually via things discovered via device specific drivers, ex. MACs, disk UUIDs, etc. We don't have those in VFIO. Don't forget, VFIO is also device agnostic, VFIO-pci is just one possible driver backend.
Exactly. But udev can see that what it got is a VF anf query the PF.
Quoted 7 lines
Quoted 4 lines
Quoted 1 line
I think we're inventing a problem though.
You think persistent names in udev were a solution in search of a problem?
Of course not, but I've never heard any indication that this is a real problem for device assignment.
How is it different from any other workload?
Quoted 3 lines
If it is, like udev, why not solve it in
userspace? The kernel doesn't provide the persistence that udev exposes.
To solve it you need to find the PF. Admin does it easily but VFIO conceptually handles one VF at a time. So let the admin set the name.
And it is better using standard udev tools than some hacked interface specific to vfio.
Quoted 18 lines
Quoted 18 lines
Quoted 18 lines
Quoted 17 lines
Quoted 8 lines
Quoted 8 lines
Quoted 1 line
How does UIO avoid such a problem.
Normally you use a misc device that you can name with udev.
Quoted 3 lines
UIO-pci
requires the user to use pci-sysfs for resource access, so it surely cares about the device address.Quoted 6 lines
Quoted 2 lines
Only
uio_pci_generic. Other uio devices let you drive the device.If this is actually a problem, this is the first ever complaint I've heard about it. As above, I don't think we can assume the same access when a device is moved.
I thought need for sane naming and for sysfs interface was discussed multiple times. But maybe I'm misremembering.
Quoted 6 lines
Quoted 4 lines
Quoted 1 line
There is sane naming and a sysfs interface...
It's not sane if the admin can't rename the device without breaking applications.
Again, udev provides that persistence, not the kernel.
So let it do its thing.
Quoted 51 lines
Quoted 37 lines
Quoted 37 lines
Quoted 25 lines
Quoted 25 lines
Quoted 15 lines
Quoted 15 lines
Quoted 7 lines
I do realize you want to represent a group of devices somehow but can't this be solved without breaking naming devices with udev? For example, the device could be a file as well. You would then use the fd to identify the device within the group. And in a somewhat common case of a single device within the group, you can even make opening the group optional. Don't know if this fix I suggest makes sense at all but it's a real problem all the same.
Unfortunately, exposing individual devices just confuses the ownership model we require for groups. It would provide the illusion of being able to assign an individual device, without the reality of the grouping. Groups are owned either by _a_ user or by the kernel, they can't be split across multiple users (at least not with any guarantees of isolation). The current interface makes this clear. Thanks,
Quoted 3 lines
Quoted 1 line
Alex
So do users pass in group=/dev/vfio/1,host=0:3.0 then?
No, vfio syntax is -device vfio-pci,host=0:3.0, just like pci-assign. Qemu will figure out which group that device belongs to and "do the right thing". If we add support for libvirt passing a groupfd, it will be mostly the same, just using
scm_rightsto get the groupfd instead of opening it directly. Thanks,Quoted 3 lines
Quoted 1 line
Alex
Then how do you know which /dev/vfio/# to open?
This is all in the documentation patch... groups are exposed in sysfs in
/sys/kernel/iommu_groups. Each group has a unique number which is exposed as a directory. Each group directory has a subdirectory called devices which links to all devices in the group. Each device within a group as aniommu_grouplink back to the group directory. The /dev/vfio/# entry matches the group number in sysfs. So it's all pretty easy. Thanks,Quoted 4 lines
Quoted 1 line
Alex
So what's the problem to have devices in sysfs linked e.g. from
/sys/class/vfio/?They have to be bound to a VFIO driver, ex. vfio-pci. We have iommu groups in sysfs and can use that for this purpose. I did have a class for this before
iommu_groupwere more integrated at the device level, now it just seems redundant.Quoted 3 lines
udev could create the nodes e.g. in
/dev/vfio/devices/. User can then pass the device name and qemu can figure out the group from sysfs.
Quoted 8 lines
As previously noted, we don't, and I don't think it makes sense to expose individual devices in VFIO as the interface is fundamentally group based by necessity. Groups are just containers and they do support a name, which is exposed in sysfs when it's used, but groups are created by topology and don't follow the devices, so I don't think that's what you're looking for. It seems that if someone wants to create persistence for VFIO, they just need to identify something unique about a device in sysfs, then follow the device to the group.
So you are forced to code this all upfront in qemu.
And since you don't in practice, no percictence and no way to provide it.
Quoted 2 lines
Userpsace
is far more capable of providing this than the kernel.
It's the admin that knows. Not applications.
Quoted 3 lines
Thanks,
Alex
Re: [Qemu-devel] [PATCH 13/13] qdev-properties: Add pci-devaddr property
In reply to Jan KiszkaQuoted 19 lines · Jan Kiszka
Quoted 7 lines · Michael S. Tsirkin
Quoted 5 lines · Jan Kiszka
Add a property to receive a fully qualified PCI device address.
Will be used by KVM device assignment.
Signed-off-by Jan Kiszka <[email protected]>Quoted 10 lines
I'd like to ponder this a bit more. What bothers me is that this mixes two things:
- addressing of qemu devices
Using full device addresses there is a legacy feature, users really should supply the parent bus and the bus local address.
- addressing devices on the linux host for assignment It so happens that the syntax matches
the legacy naming very closely,
but conceptually is completely unrelated
Quoted 1 line
We can keep code duplications, of course.
Just note that the parsing that we have is not even consistent. For example what does it mean not to supply an optional field, e.g. a function number, a domain number, etc? lspci and friends all treat any missing number as a wildcard:
$ lspci -s 0.1 15:00.1 FireWire (IEEE 1394): Ricoh Co Ltd R5C832 IEEE 1394 Controller (rev 04)
$ lspci -s .1 00:02.1 Display controller: Intel Corporation Mobile 4 Series Chipset Integrated Graphics Controller (rev 07) 00:1a.1 USB Controller: Intel Corporation 82801I (ICH9 Family) USB UHCI Controller #5 (rev 03) 00:1c.1 PCI bridge: Intel Corporation 82801I (ICH9 Family) PCI Express Port 2 (rev 03) 00:1d.1 USB Controller: Intel Corporation 82801I (ICH9 Family) USB UHCI Controller #2 (rev 03) 15:00.1 FireWire (IEEE 1394): Ricoh Co Ltd R5C832 IEEE 1394 Controller (rev 04)
We don't, and the only reason for that is that it's been buggy for a long time.
Signature · 1 line
MST