Blame SOURCES/kvm-ppc-Deassert-the-external-interrupt-pin-in-KVM-on-re.patch

22c213
From 22fc9bd7e7ae0b72c6f6e483eb66cf996f519766 Mon Sep 17 00:00:00 2001
22c213
From: David Gibson <dgibson@redhat.com>
22c213
Date: Tue, 21 Jan 2020 05:16:11 +0000
22c213
Subject: [PATCH 01/15] ppc: Deassert the external interrupt pin in KVM on
22c213
 reset
22c213
MIME-Version: 1.0
22c213
Content-Type: text/plain; charset=UTF-8
22c213
Content-Transfer-Encoding: 8bit
22c213
22c213
RH-Author: David Gibson <dgibson@redhat.com>
22c213
Message-id: <20200121051613.388295-2-dgibson@redhat.com>
22c213
Patchwork-id: 93429
22c213
O-Subject: [RHEL-AV-8.2 qemu-kvm PATCH 1/3] ppc: Deassert the external interrupt pin in KVM on reset
22c213
Bugzilla: 1776638
22c213
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
22c213
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
22c213
RH-Acked-by: Thomas Huth <thuth@redhat.com>
22c213
22c213
From: Greg Kurz <groug@kaod.org>
22c213
22c213
When a CPU is reset, QEMU makes sure no interrupt is pending by clearing
22c213
CPUPPCstate::pending_interrupts in ppc_cpu_reset(). In the case of a
22c213
complete machine emulation, eg. a sPAPR machine, an external interrupt
22c213
request could still be pending in KVM though, eg. an IPI. It will be
22c213
eventually presented to the guest, which is supposed to acknowledge it at
22c213
the interrupt controller. If the interrupt controller is emulated in QEMU,
22c213
either XICS or XIVE, ppc_set_irq() won't deassert the external interrupt
22c213
pin in KVM since it isn't pending anymore for QEMU. When the vCPU re-enters
22c213
the guest, the interrupt request is still pending and the vCPU will try
22c213
again to acknowledge it. This causes an infinite loop and eventually hangs
22c213
the guest.
22c213
22c213
The code has been broken since the beginning. The issue wasn't hit before
22c213
because accel=kvm,kernel-irqchip=off is an awkward setup that never got
22c213
used until recently with the LC92x IBM systems (aka, Boston).
22c213
22c213
Add a ppc_irq_reset() function to do the necessary cleanup, ie. deassert
22c213
the IRQ pins of the CPU in QEMU and most importantly the external interrupt
22c213
pin for this vCPU in KVM.
22c213
22c213
Reported-by: Satheesh Rajendran <sathnaga@linux.vnet.ibm.com>
22c213
Signed-off-by: Greg Kurz <groug@kaod.org>
22c213
Message-Id: <157548861740.3650476.16879693165328764758.stgit@bahia.lan>
22c213
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
22c213
(cherry picked from commit 401774387aeb37f2ada9bb18f7c7e307b21a3e93)
22c213
22c213
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1776638
22c213
22c213
Signed-off-by: David Gibson <dgibson@redhat.com>
22c213
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
22c213
---
22c213
 hw/ppc/ppc.c                    | 8 ++++++++
22c213
 include/hw/ppc/ppc.h            | 2 ++
22c213
 target/ppc/translate_init.inc.c | 1 +
22c213
 3 files changed, 11 insertions(+)
22c213
22c213
diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
22c213
index 52a18eb..d554b64 100644
22c213
--- a/hw/ppc/ppc.c
22c213
+++ b/hw/ppc/ppc.c
22c213
@@ -1510,3 +1510,11 @@ PowerPCCPU *ppc_get_vcpu_by_pir(int pir)
22c213
 
22c213
     return NULL;
22c213
 }
22c213
+
22c213
+void ppc_irq_reset(PowerPCCPU *cpu)
22c213
+{
22c213
+    CPUPPCState *env = &cpu->env;
22c213
+
22c213
+    env->irq_input_state = 0;
22c213
+    kvmppc_set_interrupt(cpu, PPC_INTERRUPT_EXT, 0);
22c213
+}
22c213
diff --git a/include/hw/ppc/ppc.h b/include/hw/ppc/ppc.h
22c213
index 4bdcb8b..5dd7531 100644
22c213
--- a/include/hw/ppc/ppc.h
22c213
+++ b/include/hw/ppc/ppc.h
22c213
@@ -76,6 +76,7 @@ static inline void ppc970_irq_init(PowerPCCPU *cpu) {}
22c213
 static inline void ppcPOWER7_irq_init(PowerPCCPU *cpu) {}
22c213
 static inline void ppcPOWER9_irq_init(PowerPCCPU *cpu) {}
22c213
 static inline void ppce500_irq_init(PowerPCCPU *cpu) {}
22c213
+static inline void ppc_irq_reset(PowerPCCPU *cpu) {}
22c213
 #else
22c213
 void ppc40x_irq_init(PowerPCCPU *cpu);
22c213
 void ppce500_irq_init(PowerPCCPU *cpu);
22c213
@@ -83,6 +84,7 @@ void ppc6xx_irq_init(PowerPCCPU *cpu);
22c213
 void ppc970_irq_init(PowerPCCPU *cpu);
22c213
 void ppcPOWER7_irq_init(PowerPCCPU *cpu);
22c213
 void ppcPOWER9_irq_init(PowerPCCPU *cpu);
22c213
+void ppc_irq_reset(PowerPCCPU *cpu);
22c213
 #endif
22c213
 
22c213
 /* PPC machines for OpenBIOS */
22c213
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
22c213
index ba726de..64a8380 100644
22c213
--- a/target/ppc/translate_init.inc.c
22c213
+++ b/target/ppc/translate_init.inc.c
22c213
@@ -10461,6 +10461,7 @@ static void ppc_cpu_reset(CPUState *s)
22c213
     env->pending_interrupts = 0;
22c213
     s->exception_index = POWERPC_EXCP_NONE;
22c213
     env->error_code = 0;
22c213
+    ppc_irq_reset(cpu);
22c213
 
22c213
     /* tininess for underflow is detected before rounding */
22c213
     set_float_detect_tininess(float_tininess_before_rounding,
22c213
-- 
22c213
1.8.3.1
22c213