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

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