[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-ppc] [PATCH v4 2/9] ppc/xics: Fix migration failure with kernel-ir
From: |
Nikunj A Dadhania |
Subject: |
[Qemu-ppc] [PATCH v4 2/9] ppc/xics: Fix migration failure with kernel-irqchip=off |
Date: |
Mon, 19 Sep 2016 11:59:30 +0530 |
With a single cpu VM running with kernel-irqchip=off and a flood ping
running in the guest. Migration fails once in few times.
Found that whenever there is an interrupt (in this case lsi int 3 from
e1000), we raise an interrupt using qemu_irq_pulse() and also see that
the kvm ioctl is complete.
address@hidden:xics_set_irq_lsi set_irq_lsi: srcno 3 [irq 0x1003]
address@hidden:xics_icp_irq cpu 0 trying to deliver irq 0x1003 priority 0x5
address@hidden:xics_icp_raise raising IRQ new XIRR=0xff001003
new pending priority=0x5
After migration on the target side, interrupts(prio 0x5) are rejected as
there is a interrupt pending (pending_priority 0x5). Moreover, we never
get an icp_accept from the guest, so it hangs and crashes.
Basically, resend the irq pulse(lsi) to the guest.
Signed-off-by: Nikunj A Dadhania <address@hidden>
---
hw/intc/xics.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 69162f0..f765b08 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -209,7 +209,7 @@ static const TypeInfo xics_common_info = {
#define CPPR(ss) (((ss)->xirr) >> 24)
static void ics_reject(ICSState *ics, int nr);
-static void ics_resend(ICSState *ics);
+static void ics_resend(ICSState *ics, int server);
static void ics_eoi(ICSState *ics, int nr);
static void icp_check_ipi(XICSState *xics, int server)
@@ -238,7 +238,7 @@ static void icp_resend(XICSState *xics, int server)
if (ss->mfrr < CPPR(ss)) {
icp_check_ipi(xics, server);
}
- ics_resend(xics->ics);
+ ics_resend(xics->ics, server);
}
void icp_set_cppr(XICSState *xics, int server, uint8_t cppr)
@@ -512,13 +512,24 @@ static void ics_reject(ICSState *ics, int nr)
}
}
-static void ics_resend(ICSState *ics)
+static void ics_resend(ICSState *ics, int server)
{
int i;
+ ICPState *ss = ics->xics->ss + server;
+ ICSIRQState *irq;
for (i = 0; i < ics->nr_irqs; i++) {
/* FIXME: filter by server#? */
- if (ics->irqs[i].flags & XICS_FLAGS_IRQ_LSI) {
+ irq = &ics->irqs[i];
+ if (!(irq->flags & XICS_FLAGS_IRQ_MASK)) {
+ continue;
+ }
+
+ if (irq->flags & XICS_FLAGS_IRQ_LSI) {
+ if (irq->status & XICS_STATUS_SENT) {
+ qemu_irq_raise(ss->output);
+ continue;
+ }
resend_lsi(ics, i);
} else {
resend_msi(ics, i);
--
2.7.4