pci-assign: Switch to pci_device_route_intx_to_irq interface
PATCH 1/2 pci-assign: Switch to pci_device_route_intx_to_irq interface
From: Jan Kiszka <[email protected]>
Drop pci_map_irq/piix_get_irq in favor of upstream's new interface. This should also properly model disabling of the line at PCI host controller level.
--- hw/device-assignment.c | 29 +++++++++++++++++++---------- hw/pc.h | 4 ---- hw/pci.c | 4 ---- hw/pci.h | 2 -- hw/piix_pci.c | 7 ------- 5 files changed, 19 insertions(+), 27 deletions(-)
hw/device-assignment.c +19 -10
@@ -115,7 +115,7 @@ typedef struct AssignedDevice {AssignedDevRegion v_addrs[PCI_NUM_REGIONS -1 ];PCIDevRegions real_device;int run; -int girq; +PCIINTxRoute intx_route;uint16_t h_segnr;uint8_t h_busnr;uint8_t h_devfn;
@@ -865,21 +865,24 @@ static int assign_device(AssignedDevice *dev)static int assign_irq (AssignedDevice *dev) {struct kvm_assigned_irq assigned_irq_data; -int irq, r =0 ; +PCIINTxRoute intx_route; +int r =0 ;/* Interrupt PIN 0 means don't use INTx */ if (assigned_dev_pci_read_byte (&dev->dev,PCI_INTERRUPT_PIN ) ==0 )return 0 ; - irq =pci_map_irq (&dev->dev, dev->intpin); - irq =piix_get_irq (irq); + intx_route =pci_device_route_intx_to_irq (&dev->dev,0 ); +assert (intx_route.mode !=PCI_INTX_INVERTED ); -if (dev->girq == irq) +if (dev->intx_route.mode == intx_route.mode && + dev->intx_route.irq == intx_route.irq) {return r; + }memset (&assigned_irq_data,0 ,sizeof (assigned_irq_data)); assigned_irq_data.assigned_dev_id =calc_assigned_dev_id (dev); - assigned_irq_data.guest_irq = irq; + assigned_irq_data.guest_irq = intx_route.irq;if (dev->irq_requested_type) { assigned_irq_data.flags = dev->irq_requested_type; r =kvm_deassign_irq (kvm_state, &assigned_irq_data);
@@ -889,6 +892,11 @@ static int assign_irq(AssignedDevice *dev) dev->irq_requested_type =0 ; } +if (intx_route.mode ==PCI_INTX_DISABLED ) { + dev->intx_route = intx_route; +return 0 ; + } + retry: assigned_irq_data.flags =KVM_DEV_IRQ_GUEST_INTX ; if (dev->features & ASSIGNED_DEVICE_PREFER_MSI_MASK &&
@@ -917,7 +925,7 @@ retry:return r; } - dev->girq = irq; + dev->intx_route = intx_route; dev->irq_requested_type = assigned_irq_data.flags;return r; }
@@ -1029,7 +1037,7 @@ static void assigned_dev_update_msi(PCIDevice *pci_dev)perror ("assigned_dev_enable_msi: assign irq" ); } - assigned_dev->girq =-1 ; + assigned_dev->intx_route.mode =PCI_INTX_DISABLED ; assigned_dev->irq_requested_type = assigned_irq_data.flags; }else {assign_irq (assigned_dev);
@@ -1160,7 +1168,7 @@ static void assigned_dev_update_msix(PCIDevice *pci_dev)return ; } } - assigned_dev->girq =-1 ; + assigned_dev->intx_route.mode =PCI_INTX_DISABLED ; assigned_dev->irq_requested_type = assigned_irq_data.flags; }else {assign_irq (assigned_dev);
@@ -1784,7 +1792,8 @@ static int assigned_initfn(struct PCIDevice *pci_dev) e_intx = dev->dev.config[0x3d ] -1 ; dev->intpin = e_intx; dev->run =0 ; - dev->girq =-1 ; + dev->intx_route.mode =PCI_INTX_DISABLED ; + dev->intx_route.irq =-1 ; dev->h_segnr = dev->host.domain; dev->h_busnr = dev->host.bus; dev->h_devfn =PCI_DEVFN (dev->host.slot, dev->host.function);
hw/pc.h +0 -4
@@ -171,10 +171,6 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn,extern PCIDevice *piix4_dev;int piix4_init (PCIBus *bus,ISABus **isa_bus,int devfn); -int piix_get_irq (int pin); - -int ipf_map_irq (PCIDevice *pci_dev,int irq_num); -/* vga.c */ enum vga_retrace_method {VGA_RETRACE_DUMB ,
hw/pci.c +0 -4
@@ -1089,10 +1089,6 @@ static void pci_set_irq(void *opaque, int irq_num, int level)pci_change_irq_level (pci_dev, irq_num, change); } -int pci_map_irq (PCIDevice *pci_dev,int pin) -{ -return pci_dev->bus->map_irq (pci_dev, pin); -}/* Special hooks used by device assignment */ void pci_bus_set_route_irq_fn (PCIBus *bus,pci_route_irq_fn route_intx_to_irq) {
hw/pci.h +0 -2
@@ -274,8 +274,6 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num, uint8_t attr, MemoryRegion *memory);pcibus_t pci_get_bar_addr (PCIDevice *pci_dev,int region_num); -int pci_map_irq (PCIDevice *pci_dev,int pin); -int pci_add_capability (PCIDevice *pdev,uint8_t cap_id,uint8_t offset,uint8_t size);
hw/piix_pci.c +0 -7
@@ -435,13 +435,6 @@ static void piix3_write_config(PCIDevice *dev, } } -int piix_get_irq (int pin) -{ -if (piix3_dev) -return piix3_dev->dev.config[0x60 +pin]; -return 0 ; -} -static void piix3_write_config_xen (PCIDevice *dev,uint32_t address,uint32_t val,int len) {
Signature · 1 line
1.7.3.4
PATCH 2/2 pci-assign: Use pci_device_set_intx_routing_notifier
From: Jan Kiszka <[email protected]>
Replace the hack in pci_default_write_config with upstream's generic callback mechanism to get informed about changes on the PCI INTx routing.
--- hw/Makefile.objs | 3 +-- hw/device-assignment.c | 48 ++++++++++++++++-------------------------------- hw/device-assignment.h | 33 --------------------------------- hw/pc.h | 3 --- hw/pci.c | 11 ----------- hw/piix_pci.c | 3 --- 6 files changed, 17 insertions(+), 84 deletions(-) delete mode 100644 hw/device-assignment.h
hw/Makefile.objs +1 -2
@@ -3,7 +3,7 @@ hw-obj-y += loader.o hw-obj-$(CONFIG_VIRTIO) += virtio-console.o hw-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o hw-obj-y += fw_cfg.o -hw-obj-$(CONFIG_PCI) += pci_bridge.o pci_bridge_dev.o +hw-obj-$(CONFIG_PCI) += pci.o pci_bridge.o pci_bridge_dev.o hw-obj-$(CONFIG_PCI) += msix.o msi.o hw-obj-$(CONFIG_PCI) += shpc.o hw-obj-$(CONFIG_PCI) += slotid_cap.o
@@ -164,7 +164,6 @@ obj-$(CONFIG_SOFTMMU) += vhost_net.o obj-$(CONFIG_VHOST_NET) += vhost.o obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/ obj-$(CONFIG_NO_PCI) += pci-stub.o -obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_VGA) += vga.o obj-$(CONFIG_SOFTMMU) += device-hotplug.o obj-$(CONFIG_XEN) += xen_domainbuild.o xen_machine_pv.o
hw/device-assignment.c +16 -32
92 lines not on this page · raw message
hw/device-assignment.h deleted +0 -33
@@ -1,33 +0,0 @@ -/* -* Copyright (c) 2007, Neocleus Corporation. -* Copyright (c) 2007, Intel Corporation. -* -* This program is free software; you can redistribute it and/or modify it -* under the terms and conditions of the GNU General Public License, -* version 2, as published by the Free Software Foundation. -* -* This program is distributed in the hope it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* You should have received a copy of the GNU General Public License along with -* this program; if not, write to the Free Software Foundation, Inc., 59 Temple -* Place - Suite 330, Boston, MA 02111-1307 USA. -* -* Data structures for storing PCI state -* -* Adapted to kvm by Qumranet -* -* Copyright (c) 2007, Neocleus, Alex Novik ([email protected]) -* Copyright (c) 2007, Neocleus, Guy Zana ([email protected]) -* Copyright (C) 2008, Qumranet, Amit Shah ([email protected]) -* Copyright (C) 2008, Red Hat, Amit Shah ([email protected]) -*/ - -#ifndef __DEVICE_ASSIGNMENT_H__ -#define __DEVICE_ASSIGNMENT_H__ - -void assigned_dev_update_irqs (void ); - -#endif /* __DEVICE_ASSIGNMENT_H__ */
hw/pc.h +0 -3
@@ -149,9 +149,6 @@ void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr);extern int no_hpet;/* piix_pci.c */ -/* config space register for IRQ routing */ -#define PIIX_CONFIG_IRQ_ROUTE 0x60 -struct PCII440FXState ;typedef struct PCII440FXState PCII440FXState ;
hw/pci.c +0 -11
@@ -29,9 +29,6 @@#include "net.h" #include "sysemu.h" #include "loader.h" -#include "hw/pc.h" -#include "kvm.h" -#include "device-assignment.h" #include "range.h" #include "qmp-commands.h" #include "msi.h"
@@ -1048,14 +1045,6 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l) d->config[addr + i] = (d->config[addr + i] & ~wmask) | (val & wmask); d->config[addr + i] &= ~(val & w1cmask);/* W1C: Write 1 to Clear */ } - -#ifdef CONFIG_KVM_DEVICE_ASSIGNMENT -if (kvm_enabled () &&kvm_irqchip_in_kernel () && - addr >=PIIX_CONFIG_IRQ_ROUTE && - addr <PIIX_CONFIG_IRQ_ROUTE +4 ) -assigned_dev_update_irqs (); -#endif /* CONFIG_KVM_DEVICE_ASSIGNMENT */ - if (ranges_overlap(addr, l, PCI_BASE_ADDRESS_0, 24) || ranges_overlap(addr, l, PCI_ROM_ADDRESS, 4) || ranges_overlap(addr, l, PCI_ROM_ADDRESS1, 4) ||
hw/piix_pci.c +0 -3
@@ -250,8 +250,6 @@ static int i440fx_initfn(PCIDevice *dev)return 0 ; } -static PIIX3State *piix3_dev; - static PCIBus *i440fx_common_init(const char *device_name, PCII440FXState **pi440fx_state, int *piix3_devfn,
@@ -331,7 +329,6 @@ static PCIBus *i440fx_common_init(const char *device_name, ram_size =255 ; (*pi440fx_state)->dev.config[0x57 ]=ram_size; - piix3_dev = piix3;i440fx_update_memory_mappings (f);return b;
Signature · 1 line
1.7.3.4
Re: [PATCH 2/2] pci-assign: Use pci_device_set_intx_routing_notifier
Quoted 236 lines · Jan Kiszka
From: Jan Kiszka <[email protected]>
Replace the hack in
pci_default_write_configwith upstream's generic callback mechanism to get informed about changes on the PCI INTx routing.Signed-off-by Jan Kiszka <[email protected]>--- hw/Makefile.objs | 3 +-- hw/device-assignment.c | 48 ++++++++++++++++-------------------------------- hw/device-assignment.h | 33 --------------------------------- hw/pc.h | 3 --- hw/pci.c | 11 ----------- hw/piix_pci.c | 3 --- 6 files changed, 17 insertions(+), 84 deletions(-) delete mode 100644 hw/device-assignment.hhw/Makefile.objs +1
-2@@ -3,7 +3,7 @@ hw-obj-y += loader.o hw-obj-$(CONFIG_VIRTIO) += virtio-console.o hw-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o hw-obj-y += fw_cfg.o -hw-obj-$(CONFIG_PCI) += pci_bridge.o pci_bridge_dev.o +hw-obj-$(CONFIG_PCI) += pci.o pci_bridge.o pci_bridge_dev.o hw-obj-$(CONFIG_PCI) += msix.o msi.o hw-obj-$(CONFIG_PCI) += shpc.o hw-obj-$(CONFIG_PCI) += slotid_cap.o@@ -164,7 +164,6 @@ obj-$(CONFIG_SOFTMMU) += vhost_net.o obj-$(CONFIG_VHOST_NET) += vhost.o obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/ obj-$(CONFIG_NO_PCI) += pci-stub.o -obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_VGA) += vga.o obj-$(CONFIG_SOFTMMU) += device-hotplug.o obj-$(CONFIG_XEN) += xen_domainbuild.o xen_machine_pv.ohw/device-assignment.c +16
-32@@ -36,7 +36,6 @@#include "pc.h" #include "qemu-error.h" #include "console.h" -#include "device-assignment.h" #include "loader.h" #include "monitor.h" #include "range.h" @@ -143,6 +142,8 @@ typedef struct AssignedDevice {QLIST_ENTRY (AssignedDevice) next; } AssignedDevice; +static void assigned_dev_update_irq_routing (PCIDevice *dev); +static void assigned_dev_load_option_rom (AssignedDevice *dev);static void assigned_dev_unregister_msix_mmio (AssignedDevice *dev);@@ -869,8 +870,13 @@ static int assign_irq(AssignedDevice *dev)int r =0 ;/* Interrupt PIN 0 means don't use INTx */ -if (assigned_dev_pci_read_byte (&dev->dev,PCI_INTERRUPT_PIN ) ==0 ) +if (assigned_dev_pci_read_byte (&dev->dev,PCI_INTERRUPT_PIN ) ==0 ) { +pci_device_set_intx_routing_notifier (&dev->dev,NULL );return 0 ; + } + +pci_device_set_intx_routing_notifier (&dev->dev, + assigned_dev_update_irq_routing); intx_route =pci_device_route_intx_to_irq (&dev->dev,0 );assert (intx_route.mode !=PCI_INTX_INVERTED );@@ -944,43 +950,19 @@ static void deassign_device(AssignedDevice *dev) dev->dev.qdev.id, strerror(-r)); } -#if 0 -AssignedDevInfo *get_assigned_device (int pcibus,int slot) -{ -AssignedDevice *assigned_dev =NULL ; -AssignedDevInfo *adev =NULL ; - - QLIST_FOREACH(adev, &adev_head, next) { - assigned_dev = adev->assigned_dev; -if (pci_bus_num (assigned_dev->dev.bus) == pcibus && -PCI_SLOT (assigned_dev->dev.devfn) == slot) -return adev; - } - -return NULL ; -} -#endif -/* The pci config space got updated. Check if irq numbers have changed * for our devices */ -void assigned_dev_update_irqs (void ) +static void assigned_dev_update_irq_routing (PCIDevice *dev) { -AssignedDevice *dev, *next; +AssignedDevice *assigned_dev =DO_UPCAST (AssignedDevice, dev, dev);Error *err =NULL ;int r; - dev =QLIST_FIRST (&devs); -while (dev) { - next =QLIST_NEXT (dev, next); -if (dev->irq_requested_type &KVM_DEV_IRQ_HOST_INTX ) { - r =assign_irq (dev); -if (r <0 ) { -qdev_unplug (&dev->dev.qdev, &err); -assert (!err); - } - } - dev = next; + r =assign_irq (assigned_dev); +if (r <0 ) { +qdev_unplug (&dev->qdev, &err); +assert (!err); } }@@ -1009,6 +991,7 @@ static void assigned_dev_update_msi(PCIDevice *pci_dev)perror ("assigned_dev_update_msi: deassign irq" ); assigned_dev->irq_requested_type =0 ; +pci_device_set_intx_routing_notifier (pci_dev,NULL ); }if (ctrl_byte &PCI_MSI_FLAGS_ENABLE ) {@@ -1151,6 +1134,7 @@ static void assigned_dev_update_msix(PCIDevice *pci_dev)perror ("assigned_dev_update_msix: deassign irq" ); assigned_dev->irq_requested_type =0 ; +pci_device_set_intx_routing_notifier (pci_dev,NULL ); }if (ctrl_word &PCI_MSIX_FLAGS_ENABLE ) {hw/device-assignment.h deleted +0
-33@@ -1,33 +0,0 @@ -/* -* Copyright (c) 2007, Neocleus Corporation. -* Copyright (c) 2007, Intel Corporation. -* -* This program is free software; you can redistribute it and/or modify it -* under the terms and conditions of the GNU General Public License, -* version 2, as published by the Free Software Foundation. -* -* This program is distributed in the hope it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* You should have received a copy of the GNU General Public License along with -* this program; if not, write to the Free Software Foundation, Inc., 59 Temple -* Place - Suite 330, Boston, MA 02111-1307 USA. -* -* Data structures for storing PCI state -* -* Adapted to kvm by Qumranet -* -* Copyright (c) 2007, Neocleus, Alex Novik ([email protected]) -* Copyright (c) 2007, Neocleus, Guy Zana ([email protected]) -* Copyright (C) 2008, Qumranet, Amit Shah ([email protected]) -* Copyright (C) 2008, Red Hat, Amit Shah ([email protected]) -*/ - -#ifndef __DEVICE_ASSIGNMENT_H__ -#define __DEVICE_ASSIGNMENT_H__ - -void assigned_dev_update_irqs (void ); - -#endif /* __DEVICE_ASSIGNMENT_H__ */ hw/pc.h +0
-3@@ -149,9 +149,6 @@ void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr);extern int no_hpet;/* piix_pci.c */ -/* config space register for IRQ routing */ -#define PIIX_CONFIG_IRQ_ROUTE 0x60 -struct PCII440FXState ;typedef struct PCII440FXState PCII440FXState ;hw/pci.c +0
-11@@ -29,9 +29,6 @@#include "net.h" #include "sysemu.h" #include "loader.h" -#include "hw/pc.h" -#include "kvm.h" -#include "device-assignment.h" #include "range.h" #include "qmp-commands.h" #include "msi.h" @@ -1048,14 +1045,6 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l) d->config[addr + i] = (d->config[addr + i] & ~wmask) | (val & wmask); d->config[addr + i] &= ~(val & w1cmask);/* W1C: Write 1 to Clear */ } - -#ifdef CONFIG_KVM_DEVICE_ASSIGNMENT -if (kvm_enabled () &&kvm_irqchip_in_kernel () && - addr >=PIIX_CONFIG_IRQ_ROUTE && - addr <PIIX_CONFIG_IRQ_ROUTE +4 ) -assigned_dev_update_irqs (); -#endif /* CONFIG_KVM_DEVICE_ASSIGNMENT */ - if (ranges_overlap(addr, l, PCI_BASE_ADDRESS_0, 24) || ranges_overlap(addr, l, PCI_ROM_ADDRESS, 4) || ranges_overlap(addr, l, PCI_ROM_ADDRESS1, 4) ||hw/piix_pci.c +0
-2@@ -250,8 +250,6 @@ static int i440fx_initfn(PCIDevice *dev)return 0 ; } -static PIIX3State *piix3_dev; - static PCIBus *i440fx_common_init(const char *device_name, PCII440FXState **pi440fx_state, int *piix3_devfn,
hw/piix_pci.c static PCIBus *i440fx_common_init(const char *device_name, · line 334
Quoted 7 lines
hw/piix_pci.c +0
-1@@ -331,7 +329,6 @@ static PCIBus *i440fx_common_init(const char *device_name, ram_size =255 ; (*pi440fx_state)->dev.config[0x57 ]=ram_size; - piix3_dev = piix3;i440fx_update_memory_mappings (f);return b;
For vfio I chose to leave the intx routing notifier in place for msi & msix as we can easily ignore it when not using intx. I don't see much advantage to one over the other though.
Re: [PATCH 2/2] pci-assign: Use pci_device_set_intx_routing_notifier
Quoted 240 lines · Alex Williamson
Quoted 239 lines · Jan Kiszka
From: Jan Kiszka <[email protected]>
Replace the hack in
pci_default_write_configwith upstream's generic callback mechanism to get informed about changes on the PCI INTx routing.Signed-off-by Jan Kiszka <[email protected]>--- hw/Makefile.objs | 3 +-- hw/device-assignment.c | 48 ++++++++++++++++-------------------------------- hw/device-assignment.h | 33 --------------------------------- hw/pc.h | 3 --- hw/pci.c | 11 ----------- hw/piix_pci.c | 3 --- 6 files changed, 17 insertions(+), 84 deletions(-) delete mode 100644 hw/device-assignment.hhw/Makefile.objs +1
-2@@ -3,7 +3,7 @@ hw-obj-y += loader.o hw-obj-$(CONFIG_VIRTIO) += virtio-console.o hw-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o hw-obj-y += fw_cfg.o -hw-obj-$(CONFIG_PCI) += pci_bridge.o pci_bridge_dev.o +hw-obj-$(CONFIG_PCI) += pci.o pci_bridge.o pci_bridge_dev.o hw-obj-$(CONFIG_PCI) += msix.o msi.o hw-obj-$(CONFIG_PCI) += shpc.o hw-obj-$(CONFIG_PCI) += slotid_cap.o@@ -164,7 +164,6 @@ obj-$(CONFIG_SOFTMMU) += vhost_net.o obj-$(CONFIG_VHOST_NET) += vhost.o obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/ obj-$(CONFIG_NO_PCI) += pci-stub.o -obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_VGA) += vga.o obj-$(CONFIG_SOFTMMU) += device-hotplug.o obj-$(CONFIG_XEN) += xen_domainbuild.o xen_machine_pv.ohw/device-assignment.c +16
-32@@ -36,7 +36,6 @@#include "pc.h" #include "qemu-error.h" #include "console.h" -#include "device-assignment.h" #include "loader.h" #include "monitor.h" #include "range.h" @@ -143,6 +142,8 @@ typedef struct AssignedDevice {QLIST_ENTRY (AssignedDevice) next; } AssignedDevice; +static void assigned_dev_update_irq_routing (PCIDevice *dev); +static void assigned_dev_load_option_rom (AssignedDevice *dev);static void assigned_dev_unregister_msix_mmio (AssignedDevice *dev);@@ -869,8 +870,13 @@ static int assign_irq(AssignedDevice *dev)int r =0 ;/* Interrupt PIN 0 means don't use INTx */ -if (assigned_dev_pci_read_byte (&dev->dev,PCI_INTERRUPT_PIN ) ==0 ) +if (assigned_dev_pci_read_byte (&dev->dev,PCI_INTERRUPT_PIN ) ==0 ) { +pci_device_set_intx_routing_notifier (&dev->dev,NULL );return 0 ; + } + +pci_device_set_intx_routing_notifier (&dev->dev, + assigned_dev_update_irq_routing); intx_route =pci_device_route_intx_to_irq (&dev->dev,0 );assert (intx_route.mode !=PCI_INTX_INVERTED );@@ -944,43 +950,19 @@ static void deassign_device(AssignedDevice *dev) dev->dev.qdev.id, strerror(-r)); } -#if 0 -AssignedDevInfo *get_assigned_device (int pcibus,int slot) -{ -AssignedDevice *assigned_dev =NULL ; -AssignedDevInfo *adev =NULL ; - - QLIST_FOREACH(adev, &adev_head, next) { - assigned_dev = adev->assigned_dev; -if (pci_bus_num (assigned_dev->dev.bus) == pcibus && -PCI_SLOT (assigned_dev->dev.devfn) == slot) -return adev; - } - -return NULL ; -} -#endif -/* The pci config space got updated. Check if irq numbers have changed * for our devices */ -void assigned_dev_update_irqs (void ) +static void assigned_dev_update_irq_routing (PCIDevice *dev) { -AssignedDevice *dev, *next; +AssignedDevice *assigned_dev =DO_UPCAST (AssignedDevice, dev, dev);Error *err =NULL ;int r; - dev =QLIST_FIRST (&devs); -while (dev) { - next =QLIST_NEXT (dev, next); -if (dev->irq_requested_type &KVM_DEV_IRQ_HOST_INTX ) { - r =assign_irq (dev); -if (r <0 ) { -qdev_unplug (&dev->dev.qdev, &err); -assert (!err); - } - } - dev = next; + r =assign_irq (assigned_dev); +if (r <0 ) { +qdev_unplug (&dev->qdev, &err); +assert (!err); } }@@ -1009,6 +991,7 @@ static void assigned_dev_update_msi(PCIDevice *pci_dev)perror ("assigned_dev_update_msi: deassign irq" ); assigned_dev->irq_requested_type =0 ; +pci_device_set_intx_routing_notifier (pci_dev,NULL ); }if (ctrl_byte &PCI_MSI_FLAGS_ENABLE ) {@@ -1151,6 +1134,7 @@ static void assigned_dev_update_msix(PCIDevice *pci_dev)perror ("assigned_dev_update_msix: deassign irq" ); assigned_dev->irq_requested_type =0 ; +pci_device_set_intx_routing_notifier (pci_dev,NULL ); }if (ctrl_word &PCI_MSIX_FLAGS_ENABLE ) {hw/device-assignment.h deleted +0
-33@@ -1,33 +0,0 @@ -/* -* Copyright (c) 2007, Neocleus Corporation. -* Copyright (c) 2007, Intel Corporation. -* -* This program is free software; you can redistribute it and/or modify it -* under the terms and conditions of the GNU General Public License, -* version 2, as published by the Free Software Foundation. -* -* This program is distributed in the hope it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* You should have received a copy of the GNU General Public License along with -* this program; if not, write to the Free Software Foundation, Inc., 59 Temple -* Place - Suite 330, Boston, MA 02111-1307 USA. -* -* Data structures for storing PCI state -* -* Adapted to kvm by Qumranet -* -* Copyright (c) 2007, Neocleus, Alex Novik ([email protected]) -* Copyright (c) 2007, Neocleus, Guy Zana ([email protected]) -* Copyright (C) 2008, Qumranet, Amit Shah ([email protected]) -* Copyright (C) 2008, Red Hat, Amit Shah ([email protected]) -*/ - -#ifndef __DEVICE_ASSIGNMENT_H__ -#define __DEVICE_ASSIGNMENT_H__ - -void assigned_dev_update_irqs (void ); - -#endif /* __DEVICE_ASSIGNMENT_H__ */ hw/pc.h +0
-3@@ -149,9 +149,6 @@ void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr);extern int no_hpet;/* piix_pci.c */ -/* config space register for IRQ routing */ -#define PIIX_CONFIG_IRQ_ROUTE 0x60 -struct PCII440FXState ;typedef struct PCII440FXState PCII440FXState ;hw/pci.c +0
-11@@ -29,9 +29,6 @@#include "net.h" #include "sysemu.h" #include "loader.h" -#include "hw/pc.h" -#include "kvm.h" -#include "device-assignment.h" #include "range.h" #include "qmp-commands.h" #include "msi.h" @@ -1048,14 +1045,6 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l) d->config[addr + i] = (d->config[addr + i] & ~wmask) | (val & wmask); d->config[addr + i] &= ~(val & w1cmask);/* W1C: Write 1 to Clear */ } - -#ifdef CONFIG_KVM_DEVICE_ASSIGNMENT -if (kvm_enabled () &&kvm_irqchip_in_kernel () && - addr >=PIIX_CONFIG_IRQ_ROUTE && - addr <PIIX_CONFIG_IRQ_ROUTE +4 ) -assigned_dev_update_irqs (); -#endif /* CONFIG_KVM_DEVICE_ASSIGNMENT */ - if (ranges_overlap(addr, l, PCI_BASE_ADDRESS_0, 24) || ranges_overlap(addr, l, PCI_ROM_ADDRESS, 4) || ranges_overlap(addr, l, PCI_ROM_ADDRESS1, 4) ||hw/piix_pci.c +0
-2@@ -250,8 +250,6 @@ static int i440fx_initfn(PCIDevice *dev)return 0 ; } -static PIIX3State *piix3_dev; - static PCIBus *i440fx_common_init(const char *device_name, PCII440FXState **pi440fx_state, int *piix3_devfn,@@ -331,7 +329,6 @@ static PCIBus *i440fx_common_init(const char *device_name, ram_size =255 ; (*pi440fx_state)->dev.config[0x57 ]=ram_size;
Quoted 8 lines
hw/piix_pci.c static PCIBus *i440fx_common_init(const char *device_name, · line 334
Quoted 4 lines
hw/piix_pci.c +0
-1- piix3_dev = piix3;i440fx_update_memory_mappings (f);return b;For vfio I chose to leave the intx routing notifier in place for msi & msix as we can easily ignore it when not using intx. I don't see much advantage to one over the other though.
Probably. When you don't disable, then you have to check in the callback if the IRQ is actually registered, but that's a nit as well.
Quoted 3 lines
Acked-by Alex Williamson <[email protected]>
Thanks,
Jan
Quoted 89 lines · Jan Kiszka
From: Jan Kiszka <[email protected]>
Drop pci_map_irq/piix_get_irq in favor of upstream's new interface. This should also properly model disabling of the line at PCI host controller level.
Signed-off-by Jan Kiszka <[email protected]>--- hw/device-assignment.c | 29 +++++++++++++++++++---------- hw/pc.h | 4 ---- hw/pci.c | 4 ---- hw/pci.h | 2 -- hw/piix_pci.c | 7 ------- 5 files changed, 19 insertions(+), 27 deletions(-)hw/device-assignment.c +16
-8@@ -115,7 +115,7 @@ typedef struct AssignedDevice {AssignedDevRegion v_addrs[PCI_NUM_REGIONS -1 ];PCIDevRegions real_device;int run; -int girq; +PCIINTxRoute intx_route;uint16_t h_segnr;uint8_t h_busnr;uint8_t h_devfn;@@ -865,21 +865,24 @@ static int assign_device(AssignedDevice *dev)static int assign_irq (AssignedDevice *dev) {struct kvm_assigned_irq assigned_irq_data; -int irq, r =0 ; +PCIINTxRoute intx_route; +int r =0 ;/* Interrupt PIN 0 means don't use INTx */ if (assigned_dev_pci_read_byte (&dev->dev,PCI_INTERRUPT_PIN ) ==0 )return 0 ; - irq =pci_map_irq (&dev->dev, dev->intpin); - irq =piix_get_irq (irq); + intx_route =pci_device_route_intx_to_irq (&dev->dev,0 ); +assert (intx_route.mode !=PCI_INTX_INVERTED ); -if (dev->girq == irq) +if (dev->intx_route.mode == intx_route.mode && + dev->intx_route.irq == intx_route.irq) {return r; + }memset (&assigned_irq_data,0 ,sizeof (assigned_irq_data)); assigned_irq_data.assigned_dev_id =calc_assigned_dev_id (dev); - assigned_irq_data.guest_irq = irq; + assigned_irq_data.guest_irq = intx_route.irq;if (dev->irq_requested_type) { assigned_irq_data.flags = dev->irq_requested_type; r =kvm_deassign_irq (kvm_state, &assigned_irq_data);@@ -889,6 +892,11 @@ static int assign_irq(AssignedDevice *dev) dev->irq_requested_type =0 ; } +if (intx_route.mode ==PCI_INTX_DISABLED ) { + dev->intx_route = intx_route; +return 0 ; + } + retry: assigned_irq_data.flags =KVM_DEV_IRQ_GUEST_INTX ; if (dev->features & ASSIGNED_DEVICE_PREFER_MSI_MASK &&@@ -917,7 +925,7 @@ retry:return r; } - dev->girq = irq; + dev->intx_route = intx_route; dev->irq_requested_type = assigned_irq_data.flags;return r; }@@ -1029,7 +1037,7 @@ static void assigned_dev_update_msi(PCIDevice *pci_dev)perror ("assigned_dev_enable_msi: assign irq" ); } - assigned_dev->girq =-1 ; + assigned_dev->intx_route.mode =PCI_INTX_DISABLED ; assigned_dev->irq_requested_type = assigned_irq_data.flags; }else {assign_irq (assigned_dev);
hw/device-assignment.c static void assigned_dev_update_msix(PCIDevice *pci_dev) · line 1171
Quoted 5 lines
hw/device-assignment.c +1
-1@@ -1160,7 +1168,7 @@ static void assigned_dev_update_msix(PCIDevice *pci_dev)return ; } } - assigned_dev->girq =-1 ; + assigned_dev->intx_route.mode =PCI_INTX_DISABLED ;
Should both of these set assigned_dev->intx_route.irq = -1 as well? I don't think it hurts anything this way but we test both mode & irq in assign_irq() and we'll end up calling kvm_deassign_irq() again.
hw/device-assignment.c static int assigned_initfn(struct PCIDevice *pci_dev) · line 1796
Quoted 10 lines
hw/device-assignment.c +2
-1assigned_dev->irq_requested_type = assigned_irq_data.flags; }else {assign_irq (assigned_dev);@@ -1784,7 +1792,8 @@ static int assigned_initfn(struct PCIDevice *pci_dev) e_intx = dev->dev.config[0x3d ] -1 ; dev->intpin = e_intx; dev->run =0 ; - dev->girq =-1 ; + dev->intx_route.mode =PCI_INTX_DISABLED ; + dev->intx_route.irq =-1 ;
And here we set both, so it's a little inconsistent.
Quoted 64 lines
hw/device-assignment.c +0
-0dev->h_segnr = dev->host.domain; dev->h_busnr = dev->host.bus; dev->h_devfn =PCI_DEVFN (dev->host.slot, dev->host.function);hw/pc.h +0
-4@@ -171,10 +171,6 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn,extern PCIDevice *piix4_dev;int piix4_init (PCIBus *bus,ISABus **isa_bus,int devfn); -int piix_get_irq (int pin); - -int ipf_map_irq (PCIDevice *pci_dev,int irq_num); -/* vga.c */ enum vga_retrace_method {VGA_RETRACE_DUMB ,hw/pci.c +0
-4@@ -1089,10 +1089,6 @@ static void pci_set_irq(void *opaque, int irq_num, int level)pci_change_irq_level (pci_dev, irq_num, change); } -int pci_map_irq (PCIDevice *pci_dev,int pin) -{ -return pci_dev->bus->map_irq (pci_dev, pin); -}/* Special hooks used by device assignment */ void pci_bus_set_route_irq_fn (PCIBus *bus,pci_route_irq_fn route_intx_to_irq) {hw/pci.h +0
-2@@ -274,8 +274,6 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num, uint8_t attr, MemoryRegion *memory);pcibus_t pci_get_bar_addr (PCIDevice *pci_dev,int region_num); -int pci_map_irq (PCIDevice *pci_dev,int pin); -int pci_add_capability (PCIDevice *pdev,uint8_t cap_id,uint8_t offset,uint8_t size);hw/piix_pci.c +0
-7@@ -435,13 +435,6 @@ static void piix3_write_config(PCIDevice *dev, } } -int piix_get_irq (int pin) -{ -if (piix3_dev) -return piix3_dev->dev.config[0x60 +pin]; -return 0 ; -} -static void piix3_write_config_xen (PCIDevice *dev,uint32_t address,uint32_t val,int len) {
PATCH v2 1/2 pci-assign: Switch to pci_device_route_intx_to_irq interface
From: Jan Kiszka <[email protected]>
Drop pci_map_irq/piix_get_irq in favor of upstream's new interface. This should also properly model disabling of the line at PCI host controller level.
---
Changes in v2:
- always set intx_route.irq to -1 when disabling
hw/device-assignment.c | 31 +++++++++++++++++++++---------- hw/pc.h | 4 ---- hw/pci.c | 4 ---- hw/pci.h | 2 -- hw/piix_pci.c | 7 ------- 5 files changed, 21 insertions(+), 27 deletions(-)
hw/device-assignment.c +21 -10
@@ -115,7 +115,7 @@ typedef struct AssignedDevice {AssignedDevRegion v_addrs[PCI_NUM_REGIONS -1 ];PCIDevRegions real_device;int run; -int girq; +PCIINTxRoute intx_route;uint16_t h_segnr;uint8_t h_busnr;uint8_t h_devfn;
@@ -865,21 +865,24 @@ static int assign_device(AssignedDevice *dev)static int assign_irq (AssignedDevice *dev) {struct kvm_assigned_irq assigned_irq_data; -int irq, r =0 ; +PCIINTxRoute intx_route; +int r =0 ;/* Interrupt PIN 0 means don't use INTx */ if (assigned_dev_pci_read_byte (&dev->dev,PCI_INTERRUPT_PIN ) ==0 )return 0 ; - irq =pci_map_irq (&dev->dev, dev->intpin); - irq =piix_get_irq (irq); + intx_route =pci_device_route_intx_to_irq (&dev->dev,0 ); +assert (intx_route.mode !=PCI_INTX_INVERTED ); -if (dev->girq == irq) +if (dev->intx_route.mode == intx_route.mode && + dev->intx_route.irq == intx_route.irq) {return r; + }memset (&assigned_irq_data,0 ,sizeof (assigned_irq_data)); assigned_irq_data.assigned_dev_id =calc_assigned_dev_id (dev); - assigned_irq_data.guest_irq = irq; + assigned_irq_data.guest_irq = intx_route.irq;if (dev->irq_requested_type) { assigned_irq_data.flags = dev->irq_requested_type; r =kvm_deassign_irq (kvm_state, &assigned_irq_data);
@@ -889,6 +892,11 @@ static int assign_irq(AssignedDevice *dev) dev->irq_requested_type =0 ; } +if (intx_route.mode ==PCI_INTX_DISABLED ) { + dev->intx_route = intx_route; +return 0 ; + } + retry: assigned_irq_data.flags =KVM_DEV_IRQ_GUEST_INTX ; if (dev->features & ASSIGNED_DEVICE_PREFER_MSI_MASK &&
@@ -917,7 +925,7 @@ retry:return r; } - dev->girq = irq; + dev->intx_route = intx_route; dev->irq_requested_type = assigned_irq_data.flags;return r; }
@@ -1029,7 +1037,8 @@ static void assigned_dev_update_msi(PCIDevice *pci_dev)perror ("assigned_dev_enable_msi: assign irq" ); } - assigned_dev->girq =-1 ; + assigned_dev->intx_route.mode =PCI_INTX_DISABLED ; + assigned_dev->intx_route.irq =-1 ; assigned_dev->irq_requested_type = assigned_irq_data.flags; }else {assign_irq (assigned_dev);
@@ -1160,7 +1169,8 @@ static void assigned_dev_update_msix(PCIDevice *pci_dev)return ; } } - assigned_dev->girq =-1 ; + assigned_dev->intx_route.mode =PCI_INTX_DISABLED ; + assigned_dev->intx_route.irq =-1 ; assigned_dev->irq_requested_type = assigned_irq_data.flags; }else {assign_irq (assigned_dev);
@@ -1784,7 +1794,8 @@ static int assigned_initfn(struct PCIDevice *pci_dev) e_intx = dev->dev.config[0x3d ] -1 ; dev->intpin = e_intx; dev->run =0 ; - dev->girq =-1 ; + dev->intx_route.mode =PCI_INTX_DISABLED ; + dev->intx_route.irq =-1 ; dev->h_segnr = dev->host.domain; dev->h_busnr = dev->host.bus; dev->h_devfn =PCI_DEVFN (dev->host.slot, dev->host.function);
hw/pc.h +0 -4
@@ -171,10 +171,6 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn,extern PCIDevice *piix4_dev;int piix4_init (PCIBus *bus,ISABus **isa_bus,int devfn); -int piix_get_irq (int pin); - -int ipf_map_irq (PCIDevice *pci_dev,int irq_num); -/* vga.c */ enum vga_retrace_method {VGA_RETRACE_DUMB ,
hw/pci.c +0 -4
@@ -1089,10 +1089,6 @@ static void pci_set_irq(void *opaque, int irq_num, int level)pci_change_irq_level (pci_dev, irq_num, change); } -int pci_map_irq (PCIDevice *pci_dev,int pin) -{ -return pci_dev->bus->map_irq (pci_dev, pin); -}/* Special hooks used by device assignment */ void pci_bus_set_route_irq_fn (PCIBus *bus,pci_route_irq_fn route_intx_to_irq) {
hw/pci.h +0 -2
@@ -274,8 +274,6 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num, uint8_t attr, MemoryRegion *memory);pcibus_t pci_get_bar_addr (PCIDevice *pci_dev,int region_num); -int pci_map_irq (PCIDevice *pci_dev,int pin); -int pci_add_capability (PCIDevice *pdev,uint8_t cap_id,uint8_t offset,uint8_t size);
hw/piix_pci.c +0 -7
@@ -435,13 +435,6 @@ static void piix3_write_config(PCIDevice *dev, } } -int piix_get_irq (int pin) -{ -if (piix3_dev) -return piix3_dev->dev.config[0x60 +pin]; -return 0 ; -} -static void piix3_write_config_xen (PCIDevice *dev,uint32_t address,uint32_t val,int len) {
Signature · 1 line
1.7.3.4
Quoted 164 lines · Jan Kiszka
From: Jan Kiszka <[email protected]>
Drop pci_map_irq/piix_get_irq in favor of upstream's new interface. This should also properly model disabling of the line at PCI host controller level.
Signed-off-by Jan Kiszka <[email protected]>---
Changes in v2:
- always set intx_route.irq to -1 when disablinghw/device-assignment.c | 31 +++++++++++++++++++++---------- hw/pc.h | 4 ---- hw/pci.c | 4 ---- hw/pci.h | 2 -- hw/piix_pci.c | 7 ------- 5 files changed, 21 insertions(+), 27 deletions(-)hw/device-assignment.c +21
-10@@ -115,7 +115,7 @@ typedef struct AssignedDevice {AssignedDevRegion v_addrs[PCI_NUM_REGIONS -1 ];PCIDevRegions real_device;int run; -int girq; +PCIINTxRoute intx_route;uint16_t h_segnr;uint8_t h_busnr;uint8_t h_devfn;@@ -865,21 +865,24 @@ static int assign_device(AssignedDevice *dev)static int assign_irq (AssignedDevice *dev) {struct kvm_assigned_irq assigned_irq_data; -int irq, r =0 ; +PCIINTxRoute intx_route; +int r =0 ;/* Interrupt PIN 0 means don't use INTx */ if (assigned_dev_pci_read_byte (&dev->dev,PCI_INTERRUPT_PIN ) ==0 )return 0 ; - irq =pci_map_irq (&dev->dev, dev->intpin); - irq =piix_get_irq (irq); + intx_route =pci_device_route_intx_to_irq (&dev->dev,0 ); +assert (intx_route.mode !=PCI_INTX_INVERTED ); -if (dev->girq == irq) +if (dev->intx_route.mode == intx_route.mode && + dev->intx_route.irq == intx_route.irq) {return r; + }memset (&assigned_irq_data,0 ,sizeof (assigned_irq_data)); assigned_irq_data.assigned_dev_id =calc_assigned_dev_id (dev); - assigned_irq_data.guest_irq = irq; + assigned_irq_data.guest_irq = intx_route.irq;if (dev->irq_requested_type) { assigned_irq_data.flags = dev->irq_requested_type; r =kvm_deassign_irq (kvm_state, &assigned_irq_data);@@ -889,6 +892,11 @@ static int assign_irq(AssignedDevice *dev) dev->irq_requested_type =0 ; } +if (intx_route.mode ==PCI_INTX_DISABLED ) { + dev->intx_route = intx_route; +return 0 ; + } + retry: assigned_irq_data.flags =KVM_DEV_IRQ_GUEST_INTX ; if (dev->features & ASSIGNED_DEVICE_PREFER_MSI_MASK &&@@ -917,7 +925,7 @@ retry:return r; } - dev->girq = irq; + dev->intx_route = intx_route; dev->irq_requested_type = assigned_irq_data.flags;return r; }@@ -1029,7 +1037,8 @@ static void assigned_dev_update_msi(PCIDevice *pci_dev)perror ("assigned_dev_enable_msi: assign irq" ); } - assigned_dev->girq =-1 ; + assigned_dev->intx_route.mode =PCI_INTX_DISABLED ; + assigned_dev->intx_route.irq =-1 ; assigned_dev->irq_requested_type = assigned_irq_data.flags; }else {assign_irq (assigned_dev);@@ -1160,7 +1169,8 @@ static void assigned_dev_update_msix(PCIDevice *pci_dev)return ; } } - assigned_dev->girq =-1 ; + assigned_dev->intx_route.mode =PCI_INTX_DISABLED ; + assigned_dev->intx_route.irq =-1 ; assigned_dev->irq_requested_type = assigned_irq_data.flags; }else {assign_irq (assigned_dev);@@ -1784,7 +1794,8 @@ static int assigned_initfn(struct PCIDevice *pci_dev) e_intx = dev->dev.config[0x3d ] -1 ; dev->intpin = e_intx; dev->run =0 ; - dev->girq =-1 ; + dev->intx_route.mode =PCI_INTX_DISABLED ; + dev->intx_route.irq =-1 ; dev->h_segnr = dev->host.domain; dev->h_busnr = dev->host.bus; dev->h_devfn =PCI_DEVFN (dev->host.slot, dev->host.function);hw/pc.h +0
-4@@ -171,10 +171,6 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn,extern PCIDevice *piix4_dev;int piix4_init (PCIBus *bus,ISABus **isa_bus,int devfn); -int piix_get_irq (int pin); - -int ipf_map_irq (PCIDevice *pci_dev,int irq_num); -/* vga.c */ enum vga_retrace_method {VGA_RETRACE_DUMB ,hw/pci.c +0
-4@@ -1089,10 +1089,6 @@ static void pci_set_irq(void *opaque, int irq_num, int level)pci_change_irq_level (pci_dev, irq_num, change); } -int pci_map_irq (PCIDevice *pci_dev,int pin) -{ -return pci_dev->bus->map_irq (pci_dev, pin); -}/* Special hooks used by device assignment */ void pci_bus_set_route_irq_fn (PCIBus *bus,pci_route_irq_fn route_intx_to_irq) {hw/pci.h +0
-2@@ -274,8 +274,6 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num, uint8_t attr, MemoryRegion *memory);pcibus_t pci_get_bar_addr (PCIDevice *pci_dev,int region_num); -int pci_map_irq (PCIDevice *pci_dev,int pin); -int pci_add_capability (PCIDevice *pdev,uint8_t cap_id,uint8_t offset,uint8_t size);hw/piix_pci.c +0
-0@@ -435,13 +435,6 @@ static void piix3_write_config(PCIDevice *dev, } }
hw/piix_pci.c static void piix3_write_config(PCIDevice *dev, · line 440
Quoted 10 lines
hw/piix_pci.c +0
-7-int piix_get_irq (int pin) -{ -if (piix3_dev) -return piix3_dev->dev.config[0x60 +pin]; -return 0 ; -} -static void piix3_write_config_xen (PCIDevice *dev,uint32_t address,uint32_t val,int len) {
Marcelo Tosatti
AppliedQuoted 11 lines · Jan Kiszka
From: Jan Kiszka <[email protected]>
Drop pci_map_irq/piix_get_irq in favor of upstream's new interface. This should also properly model disabling of the line at PCI host controller level.
Signed-off-by Jan Kiszka <[email protected]>---
Changes in v2:
- always set intx_route.irq to -1 when disabling
Applied, thanks.