hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/arch/powerpc/kvm/book3s_xive_template.c
....@@ -1,9 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright 2017 Benjamin Herrenschmidt, IBM Corporation
3
- *
4
- * This program is free software; you can redistribute it and/or modify
5
- * it under the terms of the GNU General Public License, version 2, as
6
- * published by the Free Software Foundation.
74 */
85
96 /* File to be included by other .c files */
....@@ -60,6 +57,9 @@
6057 static u8 GLUE(X_PFX,esb_load)(struct xive_irq_data *xd, u32 offset)
6158 {
6259 u64 val;
60
+
61
+ if (offset == XIVE_ESB_SET_PQ_10 && xd->flags & XIVE_IRQ_FLAG_STORE_EOI)
62
+ offset |= XIVE_ESB_LD_ST_MO;
6363
6464 if (xd->flags & XIVE_IRQ_FLAG_SHIFT_BUG)
6565 offset |= offset << 4;
....@@ -130,24 +130,14 @@
130130 */
131131 prio = ffs(pending) - 1;
132132
133
- /*
134
- * If the most favoured prio we found pending is less
135
- * favored (or equal) than a pending IPI, we return
136
- * the IPI instead.
137
- *
138
- * Note: If pending was 0 and mfrr is 0xff, we will
139
- * not spurriously take an IPI because mfrr cannot
140
- * then be smaller than cppr.
141
- */
142
- if (prio >= xc->mfrr && xc->mfrr < xc->cppr) {
143
- prio = xc->mfrr;
144
- hirq = XICS_IPI;
133
+ /* Don't scan past the guest cppr */
134
+ if (prio >= xc->cppr || prio > 7) {
135
+ if (xc->mfrr < xc->cppr) {
136
+ prio = xc->mfrr;
137
+ hirq = XICS_IPI;
138
+ }
145139 break;
146140 }
147
-
148
- /* Don't scan past the guest cppr */
149
- if (prio >= xc->cppr || prio > 7)
150
- break;
151141
152142 /* Grab queue and pointers */
153143 q = &xc->queues[prio];
....@@ -184,9 +174,12 @@
184174 * been set and another occurrence of the IPI will trigger.
185175 */
186176 if (hirq == XICS_IPI || (prio == 0 && !qpage)) {
187
- if (scan_type == scan_fetch)
177
+ if (scan_type == scan_fetch) {
188178 GLUE(X_PFX,source_eoi)(xc->vp_ipi,
189179 &xc->vp_ipi_data);
180
+ q->idx = idx;
181
+ q->toggle = toggle;
182
+ }
190183 /* Loop back on same queue with updated idx/toggle */
191184 #ifdef XIVE_RUNTIME_CHECKS
192185 WARN_ON(hirq && hirq != XICS_IPI);
....@@ -199,31 +192,40 @@
199192 if (hirq == XICS_DUMMY)
200193 goto skip_ipi;
201194
195
+ /* Clear the pending bit if the queue is now empty */
196
+ if (!hirq) {
197
+ pending &= ~(1 << prio);
198
+
199
+ /*
200
+ * Check if the queue count needs adjusting due to
201
+ * interrupts being moved away.
202
+ */
203
+ if (atomic_read(&q->pending_count)) {
204
+ int p = atomic_xchg(&q->pending_count, 0);
205
+ if (p) {
206
+#ifdef XIVE_RUNTIME_CHECKS
207
+ WARN_ON(p > atomic_read(&q->count));
208
+#endif
209
+ atomic_sub(p, &q->count);
210
+ }
211
+ }
212
+ }
213
+
214
+ /*
215
+ * If the most favoured prio we found pending is less
216
+ * favored (or equal) than a pending IPI, we return
217
+ * the IPI instead.
218
+ */
219
+ if (prio >= xc->mfrr && xc->mfrr < xc->cppr) {
220
+ prio = xc->mfrr;
221
+ hirq = XICS_IPI;
222
+ break;
223
+ }
224
+
202225 /* If fetching, update queue pointers */
203226 if (scan_type == scan_fetch) {
204227 q->idx = idx;
205228 q->toggle = toggle;
206
- }
207
-
208
- /* Something found, stop searching */
209
- if (hirq)
210
- break;
211
-
212
- /* Clear the pending bit on the now empty queue */
213
- pending &= ~(1 << prio);
214
-
215
- /*
216
- * Check if the queue count needs adjusting due to
217
- * interrupts being moved away.
218
- */
219
- if (atomic_read(&q->pending_count)) {
220
- int p = atomic_xchg(&q->pending_count, 0);
221
- if (p) {
222
-#ifdef XIVE_RUNTIME_CHECKS
223
- WARN_ON(p > atomic_read(&q->count));
224
-#endif
225
- atomic_sub(p, &q->count);
226
- }
227229 }
228230 }
229231
....@@ -279,14 +281,6 @@
279281
280282 /* First collect pending bits from HW */
281283 GLUE(X_PFX,ack_pending)(xc);
282
-
283
- /*
284
- * Cleanup the old-style bits if needed (they may have been
285
- * set by pull or an escalation interrupts).
286
- */
287
- if (test_bit(BOOK3S_IRQPRIO_EXTERNAL, &vcpu->arch.pending_exceptions))
288
- clear_bit(BOOK3S_IRQPRIO_EXTERNAL_LEVEL,
289
- &vcpu->arch.pending_exceptions);
290284
291285 pr_devel(" new pending=0x%02x hw_cppr=%d cppr=%d\n",
292286 xc->pending, xc->hw_cppr, xc->cppr);