mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-23 11:39:53 +00:00
piix: do not set irq while loading vmstate
This patch avoids setting an irq while loading the state of the ISA bridge. Because the i8259 has not been deserialized yet, raising an interrupt could bring the system out-of-sync with the migration source. For example, the migration source could have masked the interrupt in the i8259. On the destination, the i8259 device model would not know that yet and would trigger an interrupt in the CPU. This patch eliminates setting the irq and just restores the calculated state fields in post_load function. Interrupt state will be deserialized separately through the IRR field of the i8259. Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
7385b275d9
commit
2c9ecdeb9f
@ -409,7 +409,7 @@ static void piix3_set_irq_pic(PIIX3State *piix3, int pic_irq)
|
||||
(pic_irq * PIIX_NUM_PIRQS))));
|
||||
}
|
||||
|
||||
static void piix3_set_irq_level(PIIX3State *piix3, int pirq, int level)
|
||||
static void piix3_set_irq_level_internal(PIIX3State *piix3, int pirq, int level)
|
||||
{
|
||||
int pic_irq;
|
||||
uint64_t mask;
|
||||
@ -422,6 +422,18 @@ static void piix3_set_irq_level(PIIX3State *piix3, int pirq, int level)
|
||||
mask = 1ULL << ((pic_irq * PIIX_NUM_PIRQS) + pirq);
|
||||
piix3->pic_levels &= ~mask;
|
||||
piix3->pic_levels |= mask * !!level;
|
||||
}
|
||||
|
||||
static void piix3_set_irq_level(PIIX3State *piix3, int pirq, int level)
|
||||
{
|
||||
int pic_irq;
|
||||
|
||||
pic_irq = piix3->dev.config[PIIX_PIRQC + pirq];
|
||||
if (pic_irq >= PIIX_NUM_PIC_IRQS) {
|
||||
return;
|
||||
}
|
||||
|
||||
piix3_set_irq_level_internal(piix3, pirq, level);
|
||||
|
||||
piix3_set_irq_pic(piix3, pic_irq);
|
||||
}
|
||||
@ -527,7 +539,21 @@ static void piix3_reset(void *opaque)
|
||||
static int piix3_post_load(void *opaque, int version_id)
|
||||
{
|
||||
PIIX3State *piix3 = opaque;
|
||||
piix3_update_irq_levels(piix3);
|
||||
int pirq;
|
||||
|
||||
/* Because the i8259 has not been deserialized yet, qemu_irq_raise
|
||||
* might bring the system to a different state than the saved one;
|
||||
* for example, the interrupt could be masked but the i8259 would
|
||||
* not know that yet and would trigger an interrupt in the CPU.
|
||||
*
|
||||
* Here, we update irq levels without raising the interrupt.
|
||||
* Interrupt state will be deserialized separately through the i8259.
|
||||
*/
|
||||
piix3->pic_levels = 0;
|
||||
for (pirq = 0; pirq < PIIX_NUM_PIRQS; pirq++) {
|
||||
piix3_set_irq_level_internal(piix3, pirq,
|
||||
pci_bus_get_irq_level(piix3->dev.bus, pirq));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user