aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUri Lublin <uril@qumranet.com>2007-11-27 20:56:20 +0200
committerAvi Kivity <avi@qumranet.com>2007-12-11 16:44:11 +0200
commit724834f96fcae096b8a2f51c76e0f0059dfa8871 (patch)
tree12a15121e9d6b88185d2df835238815bfc3e10d1
parentbfb6a9a209d0394c3efb9f241cf48247bed95399 (diff)
Migration: save/load PCI-Bus irq related state.kvm-56rc1
This irq state is being used to decide whether or not an interrupt should be passed to the guest or not. This state can be calculated from all the pci devices on that bus. This commit may be reverted if we decide to calculate the irq related state instead of save/load it. Signed-off-by: Uri Lublin <uril@qumranet.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
-rw-r--r--hw/pci.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/hw/pci.c b/hw/pci.c
index 774a8cf49..825b17b62 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -39,6 +39,7 @@ struct PCIBus {
PCIBus *next;
/* The bus IRQ state is the logical OR of the connected devices.
Keep a count of the number of devices with raised IRQs. */
+ int nirq;
int irq_count[];
};
@@ -49,16 +50,51 @@ target_phys_addr_t pci_mem_base;
static int pci_irq_index;
static PCIBus *first_bus;
+static void pcibus_save(QEMUFile *f, void *opaque)
+{
+ PCIBus *bus = (PCIBus *)opaque;
+ int i;
+
+ qemu_put_be32s(f, &bus->nirq);
+ for (i=0; i<bus->nirq; i++)
+ qemu_put_be32s(f, &bus->irq_count[i]);
+}
+
+static int pcibus_load(QEMUFile *f, void *opaque, int version_id)
+{
+ PCIBus *bus = (PCIBus *)opaque;
+ int i, nirq;
+
+ if (version_id != 1)
+ return -EINVAL;
+
+ qemu_get_be32s(f, &nirq);
+ if (bus->nirq != nirq) {
+ fprintf(stderr, "pcibus_load: nirq mismatch: src=%d dst=%d\n",
+ nirq, bus->nirq);
+ return -EINVAL;
+ }
+
+ for (i=0; i<nirq; i++)
+ qemu_get_be32s(f, &bus->irq_count[i]);
+
+ return 0;
+}
+
PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
qemu_irq *pic, int devfn_min, int nirq)
{
PCIBus *bus;
+ static int nbus = 0;
+
bus = qemu_mallocz(sizeof(PCIBus) + (nirq * sizeof(int)));
bus->set_irq = set_irq;
bus->map_irq = map_irq;
bus->irq_opaque = pic;
bus->devfn_min = devfn_min;
+ bus->nirq = nirq;
first_bus = bus;
+ register_savevm("PCIBUS", nbus++, 1, pcibus_save, pcibus_load, bus);
return bus;
}