Skip to contentSkip to conversation

pci-assign: Switch to pci_device_route_intx_to_irq interface

PATCH Superseded Jan Kiszka 3 participants 8 messages Aug 3, 2012 – Aug 13, 2012 KVM

lore
Share & tools
lore

Jan Kiszka

author
#0 lore raw

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
index cc39958..d14c327 100644
@@ -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
index a662090..5b36eb5 100644
@@ -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
index 5ef3453..0b22913 100644
@@ -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
index c69af01..4b6ab3d 100644
@@ -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
index a5090cb..355814f 100644
@@ -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
author
#1 lore raw

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
index 30f9ba6..fa8bb08 100644
@@ -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
deleted file mode 100644
index 3fcb804..0000000
@@ -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
index 5b36eb5..31ccb6f 100644
@@ -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
index 0b22913..4d95984 100644
@@ -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
index 355814f..c497a01 100644
@@ -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
Acked-by on v1 2/2
#2 lore raw

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_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
index 30f9ba6..fa8bb08 100644
@@ -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
index d14c327..7a90027 100644
@@ -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
deleted file mode 100644
index 3fcb804..0000000
@@ -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
index 5b36eb5..31ccb6f 100644
@@ -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
index 0b22913..4d95984 100644
@@ -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
index 355814f..c497a01 100644
@@ -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.

author
#3 lore raw

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_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
index 30f9ba6..fa8bb08 100644
@@ -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
index d14c327..7a90027 100644
@@ -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
deleted file mode 100644
index 3fcb804..0000000
@@ -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
index 5b36eb5..31ccb6f 100644
@@ -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
index 0b22913..4d95984 100644
@@ -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
index 355814f..c497a01 100644
@@ -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

Thanks,
Jan

#4 lore raw
In reply to Jan Kiszka
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.

---
 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
index cc39958..d14c327 100644
@@ -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 -1
         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;

And here we set both, so it's a little inconsistent.

Quoted 64 lines
hw/device-assignment.c +0 -0
     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
index a662090..5b36eb5 100644
@@ -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
index 5ef3453..0b22913 100644
@@ -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
index c69af01..4b6ab3d 100644
@@ -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
index a5090cb..355814f 100644
@@ -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)
 {
author
#5 lore raw

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
index cc39958..35fc604 100644
@@ -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
index a662090..5b36eb5 100644
@@ -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
index 5ef3453..0b22913 100644
@@ -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
index c69af01..4b6ab3d 100644
@@ -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
index a5090cb..355814f 100644
@@ -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
Acked-by on v2 1/2
#6 lore raw
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.

---

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
index cc39958..35fc604 100644
@@ -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
index a662090..5b36eb5 100644
@@ -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
index 5ef3453..0b22913 100644
@@ -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
index c69af01..4b6ab3d 100644
@@ -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
index a5090cb..355814f 100644
@@ -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)
 {