]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.19.31/powerpc-powernv-don-t-reprogram-slw-image-on-every-kvm-guest-entry-exit.patch
Linux 4.19.31
[thirdparty/kernel/stable-queue.git] / releases / 4.19.31 / powerpc-powernv-don-t-reprogram-slw-image-on-every-kvm-guest-entry-exit.patch
CommitLineData
0cb42a7c
GKH
1From 19f8a5b5be2898573a5e1dc1db93e8d40117606a Mon Sep 17 00:00:00 2001
2From: Paul Mackerras <paulus@ozlabs.org>
3Date: Tue, 12 Feb 2019 11:58:29 +1100
4Subject: powerpc/powernv: Don't reprogram SLW image on every KVM guest entry/exit
5
6From: Paul Mackerras <paulus@ozlabs.org>
7
8commit 19f8a5b5be2898573a5e1dc1db93e8d40117606a upstream.
9
10Commit 24be85a23d1f ("powerpc/powernv: Clear PECE1 in LPCR via stop-api
11only on Hotplug", 2017-07-21) added two calls to opal_slw_set_reg()
12inside pnv_cpu_offline(), with the aim of changing the LPCR value in
13the SLW image to disable wakeups from the decrementer while a CPU is
14offline. However, pnv_cpu_offline() gets called each time a secondary
15CPU thread is woken up to participate in running a KVM guest, that is,
16not just when a CPU is offlined.
17
18Since opal_slw_set_reg() is a very slow operation (with observed
19execution times around 20 milliseconds), this means that an offline
20secondary CPU can often be busy doing the opal_slw_set_reg() call
21when the primary CPU wants to grab all the secondary threads so that
22it can run a KVM guest. This leads to messages like "KVM: couldn't
23grab CPU n" being printed and guest execution failing.
24
25There is no need to reprogram the SLW image on every KVM guest entry
26and exit. So that we do it only when a CPU is really transitioning
27between online and offline, this moves the calls to
28pnv_program_cpu_hotplug_lpcr() into pnv_smp_cpu_kill_self().
29
30Fixes: 24be85a23d1f ("powerpc/powernv: Clear PECE1 in LPCR via stop-api only on Hotplug")
31Cc: stable@vger.kernel.org # v4.14+
32Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
33Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
34Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
35
36---
37 arch/powerpc/include/asm/powernv.h | 2 ++
38 arch/powerpc/platforms/powernv/idle.c | 27 ++-------------------------
39 arch/powerpc/platforms/powernv/smp.c | 25 +++++++++++++++++++++++++
40 3 files changed, 29 insertions(+), 25 deletions(-)
41
42--- a/arch/powerpc/include/asm/powernv.h
43+++ b/arch/powerpc/include/asm/powernv.h
44@@ -23,6 +23,8 @@ extern int pnv_npu2_handle_fault(struct
45 unsigned long *flags, unsigned long *status,
46 int count);
47
48+void pnv_program_cpu_hotplug_lpcr(unsigned int cpu, u64 lpcr_val);
49+
50 void pnv_tm_init(void);
51 #else
52 static inline void powernv_set_nmmu_ptcr(unsigned long ptcr) { }
53--- a/arch/powerpc/platforms/powernv/idle.c
54+++ b/arch/powerpc/platforms/powernv/idle.c
55@@ -458,7 +458,8 @@ EXPORT_SYMBOL_GPL(pnv_power9_force_smt4_
56 #endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */
57
58 #ifdef CONFIG_HOTPLUG_CPU
59-static void pnv_program_cpu_hotplug_lpcr(unsigned int cpu, u64 lpcr_val)
60+
61+void pnv_program_cpu_hotplug_lpcr(unsigned int cpu, u64 lpcr_val)
62 {
63 u64 pir = get_hard_smp_processor_id(cpu);
64
65@@ -481,20 +482,6 @@ unsigned long pnv_cpu_offline(unsigned i
66 {
67 unsigned long srr1;
68 u32 idle_states = pnv_get_supported_cpuidle_states();
69- u64 lpcr_val;
70-
71- /*
72- * We don't want to take decrementer interrupts while we are
73- * offline, so clear LPCR:PECE1. We keep PECE2 (and
74- * LPCR_PECE_HVEE on P9) enabled as to let IPIs in.
75- *
76- * If the CPU gets woken up by a special wakeup, ensure that
77- * the SLW engine sets LPCR with decrementer bit cleared, else
78- * the CPU will come back to the kernel due to a spurious
79- * wakeup.
80- */
81- lpcr_val = mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1;
82- pnv_program_cpu_hotplug_lpcr(cpu, lpcr_val);
83
84 __ppc64_runlatch_off();
85
86@@ -526,16 +513,6 @@ unsigned long pnv_cpu_offline(unsigned i
87
88 __ppc64_runlatch_on();
89
90- /*
91- * Re-enable decrementer interrupts in LPCR.
92- *
93- * Further, we want stop states to be woken up by decrementer
94- * for non-hotplug cases. So program the LPCR via stop api as
95- * well.
96- */
97- lpcr_val = mfspr(SPRN_LPCR) | (u64)LPCR_PECE1;
98- pnv_program_cpu_hotplug_lpcr(cpu, lpcr_val);
99-
100 return srr1;
101 }
102 #endif
103--- a/arch/powerpc/platforms/powernv/smp.c
104+++ b/arch/powerpc/platforms/powernv/smp.c
105@@ -39,6 +39,7 @@
106 #include <asm/cpuidle.h>
107 #include <asm/kexec.h>
108 #include <asm/reg.h>
109+#include <asm/powernv.h>
110
111 #include "powernv.h"
112
113@@ -153,6 +154,7 @@ static void pnv_smp_cpu_kill_self(void)
114 {
115 unsigned int cpu;
116 unsigned long srr1, wmask;
117+ u64 lpcr_val;
118
119 /* Standard hot unplug procedure */
120 /*
121@@ -174,6 +176,19 @@ static void pnv_smp_cpu_kill_self(void)
122 if (cpu_has_feature(CPU_FTR_ARCH_207S))
123 wmask = SRR1_WAKEMASK_P8;
124
125+ /*
126+ * We don't want to take decrementer interrupts while we are
127+ * offline, so clear LPCR:PECE1. We keep PECE2 (and
128+ * LPCR_PECE_HVEE on P9) enabled so as to let IPIs in.
129+ *
130+ * If the CPU gets woken up by a special wakeup, ensure that
131+ * the SLW engine sets LPCR with decrementer bit cleared, else
132+ * the CPU will come back to the kernel due to a spurious
133+ * wakeup.
134+ */
135+ lpcr_val = mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1;
136+ pnv_program_cpu_hotplug_lpcr(cpu, lpcr_val);
137+
138 while (!generic_check_cpu_restart(cpu)) {
139 /*
140 * Clear IPI flag, since we don't handle IPIs while
141@@ -246,6 +261,16 @@ static void pnv_smp_cpu_kill_self(void)
142
143 }
144
145+ /*
146+ * Re-enable decrementer interrupts in LPCR.
147+ *
148+ * Further, we want stop states to be woken up by decrementer
149+ * for non-hotplug cases. So program the LPCR via stop api as
150+ * well.
151+ */
152+ lpcr_val = mfspr(SPRN_LPCR) | (u64)LPCR_PECE1;
153+ pnv_program_cpu_hotplug_lpcr(cpu, lpcr_val);
154+
155 DBG("CPU%d coming online...\n", cpu);
156 }
157