xref: /linux/arch/powerpc/kvm/book3s_xics.c (revision 8b78645c93b5d469e8006d68dbc92edc2640c654)
1bc5ad3f3SBenjamin Herrenschmidt /*
2bc5ad3f3SBenjamin Herrenschmidt  * Copyright 2012 Michael Ellerman, IBM Corporation.
3bc5ad3f3SBenjamin Herrenschmidt  * Copyright 2012 Benjamin Herrenschmidt, IBM Corporation.
4bc5ad3f3SBenjamin Herrenschmidt  *
5bc5ad3f3SBenjamin Herrenschmidt  * This program is free software; you can redistribute it and/or modify
6bc5ad3f3SBenjamin Herrenschmidt  * it under the terms of the GNU General Public License, version 2, as
7bc5ad3f3SBenjamin Herrenschmidt  * published by the Free Software Foundation.
8bc5ad3f3SBenjamin Herrenschmidt  */
9bc5ad3f3SBenjamin Herrenschmidt 
10bc5ad3f3SBenjamin Herrenschmidt #include <linux/kernel.h>
11bc5ad3f3SBenjamin Herrenschmidt #include <linux/kvm_host.h>
12bc5ad3f3SBenjamin Herrenschmidt #include <linux/err.h>
13bc5ad3f3SBenjamin Herrenschmidt #include <linux/gfp.h>
14bc5ad3f3SBenjamin Herrenschmidt 
15bc5ad3f3SBenjamin Herrenschmidt #include <asm/uaccess.h>
16bc5ad3f3SBenjamin Herrenschmidt #include <asm/kvm_book3s.h>
17bc5ad3f3SBenjamin Herrenschmidt #include <asm/kvm_ppc.h>
18bc5ad3f3SBenjamin Herrenschmidt #include <asm/hvcall.h>
19bc5ad3f3SBenjamin Herrenschmidt #include <asm/xics.h>
20bc5ad3f3SBenjamin Herrenschmidt #include <asm/debug.h>
21bc5ad3f3SBenjamin Herrenschmidt 
22bc5ad3f3SBenjamin Herrenschmidt #include <linux/debugfs.h>
23bc5ad3f3SBenjamin Herrenschmidt #include <linux/seq_file.h>
24bc5ad3f3SBenjamin Herrenschmidt 
25bc5ad3f3SBenjamin Herrenschmidt #include "book3s_xics.h"
26bc5ad3f3SBenjamin Herrenschmidt 
27bc5ad3f3SBenjamin Herrenschmidt #if 1
28bc5ad3f3SBenjamin Herrenschmidt #define XICS_DBG(fmt...) do { } while (0)
29bc5ad3f3SBenjamin Herrenschmidt #else
30bc5ad3f3SBenjamin Herrenschmidt #define XICS_DBG(fmt...) trace_printk(fmt)
31bc5ad3f3SBenjamin Herrenschmidt #endif
32bc5ad3f3SBenjamin Herrenschmidt 
33e7d26f28SBenjamin Herrenschmidt #define ENABLE_REALMODE	true
34e7d26f28SBenjamin Herrenschmidt #define DEBUG_REALMODE	false
35e7d26f28SBenjamin Herrenschmidt 
36bc5ad3f3SBenjamin Herrenschmidt /*
37bc5ad3f3SBenjamin Herrenschmidt  * LOCKING
38bc5ad3f3SBenjamin Herrenschmidt  * =======
39bc5ad3f3SBenjamin Herrenschmidt  *
40bc5ad3f3SBenjamin Herrenschmidt  * Each ICS has a mutex protecting the information about the IRQ
41bc5ad3f3SBenjamin Herrenschmidt  * sources and avoiding simultaneous deliveries if the same interrupt.
42bc5ad3f3SBenjamin Herrenschmidt  *
43bc5ad3f3SBenjamin Herrenschmidt  * ICP operations are done via a single compare & swap transaction
44bc5ad3f3SBenjamin Herrenschmidt  * (most ICP state fits in the union kvmppc_icp_state)
45bc5ad3f3SBenjamin Herrenschmidt  */
46bc5ad3f3SBenjamin Herrenschmidt 
47bc5ad3f3SBenjamin Herrenschmidt /*
48bc5ad3f3SBenjamin Herrenschmidt  * TODO
49bc5ad3f3SBenjamin Herrenschmidt  * ====
50bc5ad3f3SBenjamin Herrenschmidt  *
51bc5ad3f3SBenjamin Herrenschmidt  * - To speed up resends, keep a bitmap of "resend" set bits in the
52bc5ad3f3SBenjamin Herrenschmidt  *   ICS
53bc5ad3f3SBenjamin Herrenschmidt  *
54bc5ad3f3SBenjamin Herrenschmidt  * - Speed up server# -> ICP lookup (array ? hash table ?)
55bc5ad3f3SBenjamin Herrenschmidt  *
56bc5ad3f3SBenjamin Herrenschmidt  * - Make ICS lockless as well, or at least a per-interrupt lock or hashed
57bc5ad3f3SBenjamin Herrenschmidt  *   locks array to improve scalability
58bc5ad3f3SBenjamin Herrenschmidt  *
59bc5ad3f3SBenjamin Herrenschmidt  * - ioctl's to save/restore the entire state for snapshot & migration
60bc5ad3f3SBenjamin Herrenschmidt  */
61bc5ad3f3SBenjamin Herrenschmidt 
62bc5ad3f3SBenjamin Herrenschmidt /* -- ICS routines -- */
63bc5ad3f3SBenjamin Herrenschmidt 
64bc5ad3f3SBenjamin Herrenschmidt static void icp_deliver_irq(struct kvmppc_xics *xics, struct kvmppc_icp *icp,
65bc5ad3f3SBenjamin Herrenschmidt 			    u32 new_irq);
66bc5ad3f3SBenjamin Herrenschmidt 
67bc5ad3f3SBenjamin Herrenschmidt static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level)
68bc5ad3f3SBenjamin Herrenschmidt {
69bc5ad3f3SBenjamin Herrenschmidt 	struct ics_irq_state *state;
70bc5ad3f3SBenjamin Herrenschmidt 	struct kvmppc_ics *ics;
71bc5ad3f3SBenjamin Herrenschmidt 	u16 src;
72bc5ad3f3SBenjamin Herrenschmidt 
73bc5ad3f3SBenjamin Herrenschmidt 	XICS_DBG("ics deliver %#x (level: %d)\n", irq, level);
74bc5ad3f3SBenjamin Herrenschmidt 
75bc5ad3f3SBenjamin Herrenschmidt 	ics = kvmppc_xics_find_ics(xics, irq, &src);
76bc5ad3f3SBenjamin Herrenschmidt 	if (!ics) {
77bc5ad3f3SBenjamin Herrenschmidt 		XICS_DBG("ics_deliver_irq: IRQ 0x%06x not found !\n", irq);
78bc5ad3f3SBenjamin Herrenschmidt 		return -EINVAL;
79bc5ad3f3SBenjamin Herrenschmidt 	}
80bc5ad3f3SBenjamin Herrenschmidt 	state = &ics->irq_state[src];
81bc5ad3f3SBenjamin Herrenschmidt 	if (!state->exists)
82bc5ad3f3SBenjamin Herrenschmidt 		return -EINVAL;
83bc5ad3f3SBenjamin Herrenschmidt 
84bc5ad3f3SBenjamin Herrenschmidt 	/*
85bc5ad3f3SBenjamin Herrenschmidt 	 * We set state->asserted locklessly. This should be fine as
86bc5ad3f3SBenjamin Herrenschmidt 	 * we are the only setter, thus concurrent access is undefined
87bc5ad3f3SBenjamin Herrenschmidt 	 * to begin with.
88bc5ad3f3SBenjamin Herrenschmidt 	 */
89bc5ad3f3SBenjamin Herrenschmidt 	if (level == KVM_INTERRUPT_SET_LEVEL)
90bc5ad3f3SBenjamin Herrenschmidt 		state->asserted = 1;
91bc5ad3f3SBenjamin Herrenschmidt 	else if (level == KVM_INTERRUPT_UNSET) {
92bc5ad3f3SBenjamin Herrenschmidt 		state->asserted = 0;
93bc5ad3f3SBenjamin Herrenschmidt 		return 0;
94bc5ad3f3SBenjamin Herrenschmidt 	}
95bc5ad3f3SBenjamin Herrenschmidt 
96bc5ad3f3SBenjamin Herrenschmidt 	/* Attempt delivery */
97bc5ad3f3SBenjamin Herrenschmidt 	icp_deliver_irq(xics, NULL, irq);
98bc5ad3f3SBenjamin Herrenschmidt 
99bc5ad3f3SBenjamin Herrenschmidt 	return 0;
100bc5ad3f3SBenjamin Herrenschmidt }
101bc5ad3f3SBenjamin Herrenschmidt 
102bc5ad3f3SBenjamin Herrenschmidt static void ics_check_resend(struct kvmppc_xics *xics, struct kvmppc_ics *ics,
103bc5ad3f3SBenjamin Herrenschmidt 			     struct kvmppc_icp *icp)
104bc5ad3f3SBenjamin Herrenschmidt {
105bc5ad3f3SBenjamin Herrenschmidt 	int i;
106bc5ad3f3SBenjamin Herrenschmidt 
107bc5ad3f3SBenjamin Herrenschmidt 	mutex_lock(&ics->lock);
108bc5ad3f3SBenjamin Herrenschmidt 
109bc5ad3f3SBenjamin Herrenschmidt 	for (i = 0; i < KVMPPC_XICS_IRQ_PER_ICS; i++) {
110bc5ad3f3SBenjamin Herrenschmidt 		struct ics_irq_state *state = &ics->irq_state[i];
111bc5ad3f3SBenjamin Herrenschmidt 
112bc5ad3f3SBenjamin Herrenschmidt 		if (!state->resend)
113bc5ad3f3SBenjamin Herrenschmidt 			continue;
114bc5ad3f3SBenjamin Herrenschmidt 
115bc5ad3f3SBenjamin Herrenschmidt 		XICS_DBG("resend %#x prio %#x\n", state->number,
116bc5ad3f3SBenjamin Herrenschmidt 			      state->priority);
117bc5ad3f3SBenjamin Herrenschmidt 
118bc5ad3f3SBenjamin Herrenschmidt 		mutex_unlock(&ics->lock);
119bc5ad3f3SBenjamin Herrenschmidt 		icp_deliver_irq(xics, icp, state->number);
120bc5ad3f3SBenjamin Herrenschmidt 		mutex_lock(&ics->lock);
121bc5ad3f3SBenjamin Herrenschmidt 	}
122bc5ad3f3SBenjamin Herrenschmidt 
123bc5ad3f3SBenjamin Herrenschmidt 	mutex_unlock(&ics->lock);
124bc5ad3f3SBenjamin Herrenschmidt }
125bc5ad3f3SBenjamin Herrenschmidt 
126d19bd862SPaul Mackerras static bool write_xive(struct kvmppc_xics *xics, struct kvmppc_ics *ics,
127d19bd862SPaul Mackerras 		       struct ics_irq_state *state,
128d19bd862SPaul Mackerras 		       u32 server, u32 priority, u32 saved_priority)
129d19bd862SPaul Mackerras {
130d19bd862SPaul Mackerras 	bool deliver;
131d19bd862SPaul Mackerras 
132d19bd862SPaul Mackerras 	mutex_lock(&ics->lock);
133d19bd862SPaul Mackerras 
134d19bd862SPaul Mackerras 	state->server = server;
135d19bd862SPaul Mackerras 	state->priority = priority;
136d19bd862SPaul Mackerras 	state->saved_priority = saved_priority;
137d19bd862SPaul Mackerras 	deliver = false;
138d19bd862SPaul Mackerras 	if ((state->masked_pending || state->resend) && priority != MASKED) {
139d19bd862SPaul Mackerras 		state->masked_pending = 0;
140d19bd862SPaul Mackerras 		deliver = true;
141d19bd862SPaul Mackerras 	}
142d19bd862SPaul Mackerras 
143d19bd862SPaul Mackerras 	mutex_unlock(&ics->lock);
144d19bd862SPaul Mackerras 
145d19bd862SPaul Mackerras 	return deliver;
146d19bd862SPaul Mackerras }
147d19bd862SPaul Mackerras 
148bc5ad3f3SBenjamin Herrenschmidt int kvmppc_xics_set_xive(struct kvm *kvm, u32 irq, u32 server, u32 priority)
149bc5ad3f3SBenjamin Herrenschmidt {
150bc5ad3f3SBenjamin Herrenschmidt 	struct kvmppc_xics *xics = kvm->arch.xics;
151bc5ad3f3SBenjamin Herrenschmidt 	struct kvmppc_icp *icp;
152bc5ad3f3SBenjamin Herrenschmidt 	struct kvmppc_ics *ics;
153bc5ad3f3SBenjamin Herrenschmidt 	struct ics_irq_state *state;
154bc5ad3f3SBenjamin Herrenschmidt 	u16 src;
155bc5ad3f3SBenjamin Herrenschmidt 
156bc5ad3f3SBenjamin Herrenschmidt 	if (!xics)
157bc5ad3f3SBenjamin Herrenschmidt 		return -ENODEV;
158bc5ad3f3SBenjamin Herrenschmidt 
159bc5ad3f3SBenjamin Herrenschmidt 	ics = kvmppc_xics_find_ics(xics, irq, &src);
160bc5ad3f3SBenjamin Herrenschmidt 	if (!ics)
161bc5ad3f3SBenjamin Herrenschmidt 		return -EINVAL;
162bc5ad3f3SBenjamin Herrenschmidt 	state = &ics->irq_state[src];
163bc5ad3f3SBenjamin Herrenschmidt 
164bc5ad3f3SBenjamin Herrenschmidt 	icp = kvmppc_xics_find_server(kvm, server);
165bc5ad3f3SBenjamin Herrenschmidt 	if (!icp)
166bc5ad3f3SBenjamin Herrenschmidt 		return -EINVAL;
167bc5ad3f3SBenjamin Herrenschmidt 
168bc5ad3f3SBenjamin Herrenschmidt 	XICS_DBG("set_xive %#x server %#x prio %#x MP:%d RS:%d\n",
169bc5ad3f3SBenjamin Herrenschmidt 		 irq, server, priority,
170bc5ad3f3SBenjamin Herrenschmidt 		 state->masked_pending, state->resend);
171bc5ad3f3SBenjamin Herrenschmidt 
172d19bd862SPaul Mackerras 	if (write_xive(xics, ics, state, server, priority, priority))
173bc5ad3f3SBenjamin Herrenschmidt 		icp_deliver_irq(xics, icp, irq);
174bc5ad3f3SBenjamin Herrenschmidt 
175bc5ad3f3SBenjamin Herrenschmidt 	return 0;
176bc5ad3f3SBenjamin Herrenschmidt }
177bc5ad3f3SBenjamin Herrenschmidt 
178bc5ad3f3SBenjamin Herrenschmidt int kvmppc_xics_get_xive(struct kvm *kvm, u32 irq, u32 *server, u32 *priority)
179bc5ad3f3SBenjamin Herrenschmidt {
180bc5ad3f3SBenjamin Herrenschmidt 	struct kvmppc_xics *xics = kvm->arch.xics;
181bc5ad3f3SBenjamin Herrenschmidt 	struct kvmppc_ics *ics;
182bc5ad3f3SBenjamin Herrenschmidt 	struct ics_irq_state *state;
183bc5ad3f3SBenjamin Herrenschmidt 	u16 src;
184bc5ad3f3SBenjamin Herrenschmidt 
185bc5ad3f3SBenjamin Herrenschmidt 	if (!xics)
186bc5ad3f3SBenjamin Herrenschmidt 		return -ENODEV;
187bc5ad3f3SBenjamin Herrenschmidt 
188bc5ad3f3SBenjamin Herrenschmidt 	ics = kvmppc_xics_find_ics(xics, irq, &src);
189bc5ad3f3SBenjamin Herrenschmidt 	if (!ics)
190bc5ad3f3SBenjamin Herrenschmidt 		return -EINVAL;
191bc5ad3f3SBenjamin Herrenschmidt 	state = &ics->irq_state[src];
192bc5ad3f3SBenjamin Herrenschmidt 
193bc5ad3f3SBenjamin Herrenschmidt 	mutex_lock(&ics->lock);
194bc5ad3f3SBenjamin Herrenschmidt 	*server = state->server;
195bc5ad3f3SBenjamin Herrenschmidt 	*priority = state->priority;
196bc5ad3f3SBenjamin Herrenschmidt 	mutex_unlock(&ics->lock);
197bc5ad3f3SBenjamin Herrenschmidt 
198bc5ad3f3SBenjamin Herrenschmidt 	return 0;
199bc5ad3f3SBenjamin Herrenschmidt }
200bc5ad3f3SBenjamin Herrenschmidt 
201d19bd862SPaul Mackerras int kvmppc_xics_int_on(struct kvm *kvm, u32 irq)
202d19bd862SPaul Mackerras {
203d19bd862SPaul Mackerras 	struct kvmppc_xics *xics = kvm->arch.xics;
204d19bd862SPaul Mackerras 	struct kvmppc_icp *icp;
205d19bd862SPaul Mackerras 	struct kvmppc_ics *ics;
206d19bd862SPaul Mackerras 	struct ics_irq_state *state;
207d19bd862SPaul Mackerras 	u16 src;
208d19bd862SPaul Mackerras 
209d19bd862SPaul Mackerras 	if (!xics)
210d19bd862SPaul Mackerras 		return -ENODEV;
211d19bd862SPaul Mackerras 
212d19bd862SPaul Mackerras 	ics = kvmppc_xics_find_ics(xics, irq, &src);
213d19bd862SPaul Mackerras 	if (!ics)
214d19bd862SPaul Mackerras 		return -EINVAL;
215d19bd862SPaul Mackerras 	state = &ics->irq_state[src];
216d19bd862SPaul Mackerras 
217d19bd862SPaul Mackerras 	icp = kvmppc_xics_find_server(kvm, state->server);
218d19bd862SPaul Mackerras 	if (!icp)
219d19bd862SPaul Mackerras 		return -EINVAL;
220d19bd862SPaul Mackerras 
221d19bd862SPaul Mackerras 	if (write_xive(xics, ics, state, state->server, state->saved_priority,
222d19bd862SPaul Mackerras 		       state->saved_priority))
223d19bd862SPaul Mackerras 		icp_deliver_irq(xics, icp, irq);
224d19bd862SPaul Mackerras 
225d19bd862SPaul Mackerras 	return 0;
226d19bd862SPaul Mackerras }
227d19bd862SPaul Mackerras 
228d19bd862SPaul Mackerras int kvmppc_xics_int_off(struct kvm *kvm, u32 irq)
229d19bd862SPaul Mackerras {
230d19bd862SPaul Mackerras 	struct kvmppc_xics *xics = kvm->arch.xics;
231d19bd862SPaul Mackerras 	struct kvmppc_ics *ics;
232d19bd862SPaul Mackerras 	struct ics_irq_state *state;
233d19bd862SPaul Mackerras 	u16 src;
234d19bd862SPaul Mackerras 
235d19bd862SPaul Mackerras 	if (!xics)
236d19bd862SPaul Mackerras 		return -ENODEV;
237d19bd862SPaul Mackerras 
238d19bd862SPaul Mackerras 	ics = kvmppc_xics_find_ics(xics, irq, &src);
239d19bd862SPaul Mackerras 	if (!ics)
240d19bd862SPaul Mackerras 		return -EINVAL;
241d19bd862SPaul Mackerras 	state = &ics->irq_state[src];
242d19bd862SPaul Mackerras 
243d19bd862SPaul Mackerras 	write_xive(xics, ics, state, state->server, MASKED, state->priority);
244d19bd862SPaul Mackerras 
245d19bd862SPaul Mackerras 	return 0;
246d19bd862SPaul Mackerras }
247d19bd862SPaul Mackerras 
248bc5ad3f3SBenjamin Herrenschmidt /* -- ICP routines, including hcalls -- */
249bc5ad3f3SBenjamin Herrenschmidt 
250bc5ad3f3SBenjamin Herrenschmidt static inline bool icp_try_update(struct kvmppc_icp *icp,
251bc5ad3f3SBenjamin Herrenschmidt 				  union kvmppc_icp_state old,
252bc5ad3f3SBenjamin Herrenschmidt 				  union kvmppc_icp_state new,
253bc5ad3f3SBenjamin Herrenschmidt 				  bool change_self)
254bc5ad3f3SBenjamin Herrenschmidt {
255bc5ad3f3SBenjamin Herrenschmidt 	bool success;
256bc5ad3f3SBenjamin Herrenschmidt 
257bc5ad3f3SBenjamin Herrenschmidt 	/* Calculate new output value */
258bc5ad3f3SBenjamin Herrenschmidt 	new.out_ee = (new.xisr && (new.pending_pri < new.cppr));
259bc5ad3f3SBenjamin Herrenschmidt 
260bc5ad3f3SBenjamin Herrenschmidt 	/* Attempt atomic update */
261bc5ad3f3SBenjamin Herrenschmidt 	success = cmpxchg64(&icp->state.raw, old.raw, new.raw) == old.raw;
262bc5ad3f3SBenjamin Herrenschmidt 	if (!success)
263bc5ad3f3SBenjamin Herrenschmidt 		goto bail;
264bc5ad3f3SBenjamin Herrenschmidt 
265bc5ad3f3SBenjamin Herrenschmidt 	XICS_DBG("UPD [%04x] - C:%02x M:%02x PP: %02x PI:%06x R:%d O:%d\n",
266bc5ad3f3SBenjamin Herrenschmidt 		 icp->server_num,
267bc5ad3f3SBenjamin Herrenschmidt 		 old.cppr, old.mfrr, old.pending_pri, old.xisr,
268bc5ad3f3SBenjamin Herrenschmidt 		 old.need_resend, old.out_ee);
269bc5ad3f3SBenjamin Herrenschmidt 	XICS_DBG("UPD        - C:%02x M:%02x PP: %02x PI:%06x R:%d O:%d\n",
270bc5ad3f3SBenjamin Herrenschmidt 		 new.cppr, new.mfrr, new.pending_pri, new.xisr,
271bc5ad3f3SBenjamin Herrenschmidt 		 new.need_resend, new.out_ee);
272bc5ad3f3SBenjamin Herrenschmidt 	/*
273bc5ad3f3SBenjamin Herrenschmidt 	 * Check for output state update
274bc5ad3f3SBenjamin Herrenschmidt 	 *
275bc5ad3f3SBenjamin Herrenschmidt 	 * Note that this is racy since another processor could be updating
276bc5ad3f3SBenjamin Herrenschmidt 	 * the state already. This is why we never clear the interrupt output
277bc5ad3f3SBenjamin Herrenschmidt 	 * here, we only ever set it. The clear only happens prior to doing
278bc5ad3f3SBenjamin Herrenschmidt 	 * an update and only by the processor itself. Currently we do it
279bc5ad3f3SBenjamin Herrenschmidt 	 * in Accept (H_XIRR) and Up_Cppr (H_XPPR).
280bc5ad3f3SBenjamin Herrenschmidt 	 *
281bc5ad3f3SBenjamin Herrenschmidt 	 * We also do not try to figure out whether the EE state has changed,
282e7d26f28SBenjamin Herrenschmidt 	 * we unconditionally set it if the new state calls for it. The reason
283e7d26f28SBenjamin Herrenschmidt 	 * for that is that we opportunistically remove the pending interrupt
284e7d26f28SBenjamin Herrenschmidt 	 * flag when raising CPPR, so we need to set it back here if an
285e7d26f28SBenjamin Herrenschmidt 	 * interrupt is still pending.
286bc5ad3f3SBenjamin Herrenschmidt 	 */
287bc5ad3f3SBenjamin Herrenschmidt 	if (new.out_ee) {
288bc5ad3f3SBenjamin Herrenschmidt 		kvmppc_book3s_queue_irqprio(icp->vcpu,
289bc5ad3f3SBenjamin Herrenschmidt 					    BOOK3S_INTERRUPT_EXTERNAL_LEVEL);
290bc5ad3f3SBenjamin Herrenschmidt 		if (!change_self)
29154695c30SBenjamin Herrenschmidt 			kvmppc_fast_vcpu_kick(icp->vcpu);
292bc5ad3f3SBenjamin Herrenschmidt 	}
293bc5ad3f3SBenjamin Herrenschmidt  bail:
294bc5ad3f3SBenjamin Herrenschmidt 	return success;
295bc5ad3f3SBenjamin Herrenschmidt }
296bc5ad3f3SBenjamin Herrenschmidt 
297bc5ad3f3SBenjamin Herrenschmidt static void icp_check_resend(struct kvmppc_xics *xics,
298bc5ad3f3SBenjamin Herrenschmidt 			     struct kvmppc_icp *icp)
299bc5ad3f3SBenjamin Herrenschmidt {
300bc5ad3f3SBenjamin Herrenschmidt 	u32 icsid;
301bc5ad3f3SBenjamin Herrenschmidt 
302bc5ad3f3SBenjamin Herrenschmidt 	/* Order this load with the test for need_resend in the caller */
303bc5ad3f3SBenjamin Herrenschmidt 	smp_rmb();
304bc5ad3f3SBenjamin Herrenschmidt 	for_each_set_bit(icsid, icp->resend_map, xics->max_icsid + 1) {
305bc5ad3f3SBenjamin Herrenschmidt 		struct kvmppc_ics *ics = xics->ics[icsid];
306bc5ad3f3SBenjamin Herrenschmidt 
307bc5ad3f3SBenjamin Herrenschmidt 		if (!test_and_clear_bit(icsid, icp->resend_map))
308bc5ad3f3SBenjamin Herrenschmidt 			continue;
309bc5ad3f3SBenjamin Herrenschmidt 		if (!ics)
310bc5ad3f3SBenjamin Herrenschmidt 			continue;
311bc5ad3f3SBenjamin Herrenschmidt 		ics_check_resend(xics, ics, icp);
312bc5ad3f3SBenjamin Herrenschmidt 	}
313bc5ad3f3SBenjamin Herrenschmidt }
314bc5ad3f3SBenjamin Herrenschmidt 
315bc5ad3f3SBenjamin Herrenschmidt static bool icp_try_to_deliver(struct kvmppc_icp *icp, u32 irq, u8 priority,
316bc5ad3f3SBenjamin Herrenschmidt 			       u32 *reject)
317bc5ad3f3SBenjamin Herrenschmidt {
318bc5ad3f3SBenjamin Herrenschmidt 	union kvmppc_icp_state old_state, new_state;
319bc5ad3f3SBenjamin Herrenschmidt 	bool success;
320bc5ad3f3SBenjamin Herrenschmidt 
321bc5ad3f3SBenjamin Herrenschmidt 	XICS_DBG("try deliver %#x(P:%#x) to server %#x\n", irq, priority,
322bc5ad3f3SBenjamin Herrenschmidt 		 icp->server_num);
323bc5ad3f3SBenjamin Herrenschmidt 
324bc5ad3f3SBenjamin Herrenschmidt 	do {
325bc5ad3f3SBenjamin Herrenschmidt 		old_state = new_state = ACCESS_ONCE(icp->state);
326bc5ad3f3SBenjamin Herrenschmidt 
327bc5ad3f3SBenjamin Herrenschmidt 		*reject = 0;
328bc5ad3f3SBenjamin Herrenschmidt 
329bc5ad3f3SBenjamin Herrenschmidt 		/* See if we can deliver */
330bc5ad3f3SBenjamin Herrenschmidt 		success = new_state.cppr > priority &&
331bc5ad3f3SBenjamin Herrenschmidt 			new_state.mfrr > priority &&
332bc5ad3f3SBenjamin Herrenschmidt 			new_state.pending_pri > priority;
333bc5ad3f3SBenjamin Herrenschmidt 
334bc5ad3f3SBenjamin Herrenschmidt 		/*
335bc5ad3f3SBenjamin Herrenschmidt 		 * If we can, check for a rejection and perform the
336bc5ad3f3SBenjamin Herrenschmidt 		 * delivery
337bc5ad3f3SBenjamin Herrenschmidt 		 */
338bc5ad3f3SBenjamin Herrenschmidt 		if (success) {
339bc5ad3f3SBenjamin Herrenschmidt 			*reject = new_state.xisr;
340bc5ad3f3SBenjamin Herrenschmidt 			new_state.xisr = irq;
341bc5ad3f3SBenjamin Herrenschmidt 			new_state.pending_pri = priority;
342bc5ad3f3SBenjamin Herrenschmidt 		} else {
343bc5ad3f3SBenjamin Herrenschmidt 			/*
344bc5ad3f3SBenjamin Herrenschmidt 			 * If we failed to deliver we set need_resend
345bc5ad3f3SBenjamin Herrenschmidt 			 * so a subsequent CPPR state change causes us
346bc5ad3f3SBenjamin Herrenschmidt 			 * to try a new delivery.
347bc5ad3f3SBenjamin Herrenschmidt 			 */
348bc5ad3f3SBenjamin Herrenschmidt 			new_state.need_resend = true;
349bc5ad3f3SBenjamin Herrenschmidt 		}
350bc5ad3f3SBenjamin Herrenschmidt 
351bc5ad3f3SBenjamin Herrenschmidt 	} while (!icp_try_update(icp, old_state, new_state, false));
352bc5ad3f3SBenjamin Herrenschmidt 
353bc5ad3f3SBenjamin Herrenschmidt 	return success;
354bc5ad3f3SBenjamin Herrenschmidt }
355bc5ad3f3SBenjamin Herrenschmidt 
356bc5ad3f3SBenjamin Herrenschmidt static void icp_deliver_irq(struct kvmppc_xics *xics, struct kvmppc_icp *icp,
357bc5ad3f3SBenjamin Herrenschmidt 			    u32 new_irq)
358bc5ad3f3SBenjamin Herrenschmidt {
359bc5ad3f3SBenjamin Herrenschmidt 	struct ics_irq_state *state;
360bc5ad3f3SBenjamin Herrenschmidt 	struct kvmppc_ics *ics;
361bc5ad3f3SBenjamin Herrenschmidt 	u32 reject;
362bc5ad3f3SBenjamin Herrenschmidt 	u16 src;
363bc5ad3f3SBenjamin Herrenschmidt 
364bc5ad3f3SBenjamin Herrenschmidt 	/*
365bc5ad3f3SBenjamin Herrenschmidt 	 * This is used both for initial delivery of an interrupt and
366bc5ad3f3SBenjamin Herrenschmidt 	 * for subsequent rejection.
367bc5ad3f3SBenjamin Herrenschmidt 	 *
368bc5ad3f3SBenjamin Herrenschmidt 	 * Rejection can be racy vs. resends. We have evaluated the
369bc5ad3f3SBenjamin Herrenschmidt 	 * rejection in an atomic ICP transaction which is now complete,
370bc5ad3f3SBenjamin Herrenschmidt 	 * so potentially the ICP can already accept the interrupt again.
371bc5ad3f3SBenjamin Herrenschmidt 	 *
372bc5ad3f3SBenjamin Herrenschmidt 	 * So we need to retry the delivery. Essentially the reject path
373bc5ad3f3SBenjamin Herrenschmidt 	 * boils down to a failed delivery. Always.
374bc5ad3f3SBenjamin Herrenschmidt 	 *
375bc5ad3f3SBenjamin Herrenschmidt 	 * Now the interrupt could also have moved to a different target,
376bc5ad3f3SBenjamin Herrenschmidt 	 * thus we may need to re-do the ICP lookup as well
377bc5ad3f3SBenjamin Herrenschmidt 	 */
378bc5ad3f3SBenjamin Herrenschmidt 
379bc5ad3f3SBenjamin Herrenschmidt  again:
380bc5ad3f3SBenjamin Herrenschmidt 	/* Get the ICS state and lock it */
381bc5ad3f3SBenjamin Herrenschmidt 	ics = kvmppc_xics_find_ics(xics, new_irq, &src);
382bc5ad3f3SBenjamin Herrenschmidt 	if (!ics) {
383bc5ad3f3SBenjamin Herrenschmidt 		XICS_DBG("icp_deliver_irq: IRQ 0x%06x not found !\n", new_irq);
384bc5ad3f3SBenjamin Herrenschmidt 		return;
385bc5ad3f3SBenjamin Herrenschmidt 	}
386bc5ad3f3SBenjamin Herrenschmidt 	state = &ics->irq_state[src];
387bc5ad3f3SBenjamin Herrenschmidt 
388bc5ad3f3SBenjamin Herrenschmidt 	/* Get a lock on the ICS */
389bc5ad3f3SBenjamin Herrenschmidt 	mutex_lock(&ics->lock);
390bc5ad3f3SBenjamin Herrenschmidt 
391bc5ad3f3SBenjamin Herrenschmidt 	/* Get our server */
392bc5ad3f3SBenjamin Herrenschmidt 	if (!icp || state->server != icp->server_num) {
393bc5ad3f3SBenjamin Herrenschmidt 		icp = kvmppc_xics_find_server(xics->kvm, state->server);
394bc5ad3f3SBenjamin Herrenschmidt 		if (!icp) {
395bc5ad3f3SBenjamin Herrenschmidt 			pr_warn("icp_deliver_irq: IRQ 0x%06x server 0x%x not found !\n",
396bc5ad3f3SBenjamin Herrenschmidt 				new_irq, state->server);
397bc5ad3f3SBenjamin Herrenschmidt 			goto out;
398bc5ad3f3SBenjamin Herrenschmidt 		}
399bc5ad3f3SBenjamin Herrenschmidt 	}
400bc5ad3f3SBenjamin Herrenschmidt 
401bc5ad3f3SBenjamin Herrenschmidt 	/* Clear the resend bit of that interrupt */
402bc5ad3f3SBenjamin Herrenschmidt 	state->resend = 0;
403bc5ad3f3SBenjamin Herrenschmidt 
404bc5ad3f3SBenjamin Herrenschmidt 	/*
405bc5ad3f3SBenjamin Herrenschmidt 	 * If masked, bail out
406bc5ad3f3SBenjamin Herrenschmidt 	 *
407bc5ad3f3SBenjamin Herrenschmidt 	 * Note: PAPR doesn't mention anything about masked pending
408bc5ad3f3SBenjamin Herrenschmidt 	 * when doing a resend, only when doing a delivery.
409bc5ad3f3SBenjamin Herrenschmidt 	 *
410bc5ad3f3SBenjamin Herrenschmidt 	 * However that would have the effect of losing a masked
411bc5ad3f3SBenjamin Herrenschmidt 	 * interrupt that was rejected and isn't consistent with
412bc5ad3f3SBenjamin Herrenschmidt 	 * the whole masked_pending business which is about not
413bc5ad3f3SBenjamin Herrenschmidt 	 * losing interrupts that occur while masked.
414bc5ad3f3SBenjamin Herrenschmidt 	 *
415bc5ad3f3SBenjamin Herrenschmidt 	 * I don't differenciate normal deliveries and resends, this
416bc5ad3f3SBenjamin Herrenschmidt 	 * implementation will differ from PAPR and not lose such
417bc5ad3f3SBenjamin Herrenschmidt 	 * interrupts.
418bc5ad3f3SBenjamin Herrenschmidt 	 */
419bc5ad3f3SBenjamin Herrenschmidt 	if (state->priority == MASKED) {
420bc5ad3f3SBenjamin Herrenschmidt 		XICS_DBG("irq %#x masked pending\n", new_irq);
421bc5ad3f3SBenjamin Herrenschmidt 		state->masked_pending = 1;
422bc5ad3f3SBenjamin Herrenschmidt 		goto out;
423bc5ad3f3SBenjamin Herrenschmidt 	}
424bc5ad3f3SBenjamin Herrenschmidt 
425bc5ad3f3SBenjamin Herrenschmidt 	/*
426bc5ad3f3SBenjamin Herrenschmidt 	 * Try the delivery, this will set the need_resend flag
427bc5ad3f3SBenjamin Herrenschmidt 	 * in the ICP as part of the atomic transaction if the
428bc5ad3f3SBenjamin Herrenschmidt 	 * delivery is not possible.
429bc5ad3f3SBenjamin Herrenschmidt 	 *
430bc5ad3f3SBenjamin Herrenschmidt 	 * Note that if successful, the new delivery might have itself
431bc5ad3f3SBenjamin Herrenschmidt 	 * rejected an interrupt that was "delivered" before we took the
432bc5ad3f3SBenjamin Herrenschmidt 	 * icp mutex.
433bc5ad3f3SBenjamin Herrenschmidt 	 *
434bc5ad3f3SBenjamin Herrenschmidt 	 * In this case we do the whole sequence all over again for the
435bc5ad3f3SBenjamin Herrenschmidt 	 * new guy. We cannot assume that the rejected interrupt is less
436bc5ad3f3SBenjamin Herrenschmidt 	 * favored than the new one, and thus doesn't need to be delivered,
437bc5ad3f3SBenjamin Herrenschmidt 	 * because by the time we exit icp_try_to_deliver() the target
438bc5ad3f3SBenjamin Herrenschmidt 	 * processor may well have alrady consumed & completed it, and thus
439bc5ad3f3SBenjamin Herrenschmidt 	 * the rejected interrupt might actually be already acceptable.
440bc5ad3f3SBenjamin Herrenschmidt 	 */
441bc5ad3f3SBenjamin Herrenschmidt 	if (icp_try_to_deliver(icp, new_irq, state->priority, &reject)) {
442bc5ad3f3SBenjamin Herrenschmidt 		/*
443bc5ad3f3SBenjamin Herrenschmidt 		 * Delivery was successful, did we reject somebody else ?
444bc5ad3f3SBenjamin Herrenschmidt 		 */
445bc5ad3f3SBenjamin Herrenschmidt 		if (reject && reject != XICS_IPI) {
446bc5ad3f3SBenjamin Herrenschmidt 			mutex_unlock(&ics->lock);
447bc5ad3f3SBenjamin Herrenschmidt 			new_irq = reject;
448bc5ad3f3SBenjamin Herrenschmidt 			goto again;
449bc5ad3f3SBenjamin Herrenschmidt 		}
450bc5ad3f3SBenjamin Herrenschmidt 	} else {
451bc5ad3f3SBenjamin Herrenschmidt 		/*
452bc5ad3f3SBenjamin Herrenschmidt 		 * We failed to deliver the interrupt we need to set the
453bc5ad3f3SBenjamin Herrenschmidt 		 * resend map bit and mark the ICS state as needing a resend
454bc5ad3f3SBenjamin Herrenschmidt 		 */
455bc5ad3f3SBenjamin Herrenschmidt 		set_bit(ics->icsid, icp->resend_map);
456bc5ad3f3SBenjamin Herrenschmidt 		state->resend = 1;
457bc5ad3f3SBenjamin Herrenschmidt 
458bc5ad3f3SBenjamin Herrenschmidt 		/*
459bc5ad3f3SBenjamin Herrenschmidt 		 * If the need_resend flag got cleared in the ICP some time
460bc5ad3f3SBenjamin Herrenschmidt 		 * between icp_try_to_deliver() atomic update and now, then
461bc5ad3f3SBenjamin Herrenschmidt 		 * we know it might have missed the resend_map bit. So we
462bc5ad3f3SBenjamin Herrenschmidt 		 * retry
463bc5ad3f3SBenjamin Herrenschmidt 		 */
464bc5ad3f3SBenjamin Herrenschmidt 		smp_mb();
465bc5ad3f3SBenjamin Herrenschmidt 		if (!icp->state.need_resend) {
466bc5ad3f3SBenjamin Herrenschmidt 			mutex_unlock(&ics->lock);
467bc5ad3f3SBenjamin Herrenschmidt 			goto again;
468bc5ad3f3SBenjamin Herrenschmidt 		}
469bc5ad3f3SBenjamin Herrenschmidt 	}
470bc5ad3f3SBenjamin Herrenschmidt  out:
471bc5ad3f3SBenjamin Herrenschmidt 	mutex_unlock(&ics->lock);
472bc5ad3f3SBenjamin Herrenschmidt }
473bc5ad3f3SBenjamin Herrenschmidt 
474bc5ad3f3SBenjamin Herrenschmidt static void icp_down_cppr(struct kvmppc_xics *xics, struct kvmppc_icp *icp,
475bc5ad3f3SBenjamin Herrenschmidt 			  u8 new_cppr)
476bc5ad3f3SBenjamin Herrenschmidt {
477bc5ad3f3SBenjamin Herrenschmidt 	union kvmppc_icp_state old_state, new_state;
478bc5ad3f3SBenjamin Herrenschmidt 	bool resend;
479bc5ad3f3SBenjamin Herrenschmidt 
480bc5ad3f3SBenjamin Herrenschmidt 	/*
481bc5ad3f3SBenjamin Herrenschmidt 	 * This handles several related states in one operation:
482bc5ad3f3SBenjamin Herrenschmidt 	 *
483bc5ad3f3SBenjamin Herrenschmidt 	 * ICP State: Down_CPPR
484bc5ad3f3SBenjamin Herrenschmidt 	 *
485bc5ad3f3SBenjamin Herrenschmidt 	 * Load CPPR with new value and if the XISR is 0
486bc5ad3f3SBenjamin Herrenschmidt 	 * then check for resends:
487bc5ad3f3SBenjamin Herrenschmidt 	 *
488bc5ad3f3SBenjamin Herrenschmidt 	 * ICP State: Resend
489bc5ad3f3SBenjamin Herrenschmidt 	 *
490bc5ad3f3SBenjamin Herrenschmidt 	 * If MFRR is more favored than CPPR, check for IPIs
491bc5ad3f3SBenjamin Herrenschmidt 	 * and notify ICS of a potential resend. This is done
492bc5ad3f3SBenjamin Herrenschmidt 	 * asynchronously (when used in real mode, we will have
493bc5ad3f3SBenjamin Herrenschmidt 	 * to exit here).
494bc5ad3f3SBenjamin Herrenschmidt 	 *
495bc5ad3f3SBenjamin Herrenschmidt 	 * We do not handle the complete Check_IPI as documented
496bc5ad3f3SBenjamin Herrenschmidt 	 * here. In the PAPR, this state will be used for both
497bc5ad3f3SBenjamin Herrenschmidt 	 * Set_MFRR and Down_CPPR. However, we know that we aren't
498bc5ad3f3SBenjamin Herrenschmidt 	 * changing the MFRR state here so we don't need to handle
499bc5ad3f3SBenjamin Herrenschmidt 	 * the case of an MFRR causing a reject of a pending irq,
500bc5ad3f3SBenjamin Herrenschmidt 	 * this will have been handled when the MFRR was set in the
501bc5ad3f3SBenjamin Herrenschmidt 	 * first place.
502bc5ad3f3SBenjamin Herrenschmidt 	 *
503bc5ad3f3SBenjamin Herrenschmidt 	 * Thus we don't have to handle rejects, only resends.
504bc5ad3f3SBenjamin Herrenschmidt 	 *
505bc5ad3f3SBenjamin Herrenschmidt 	 * When implementing real mode for HV KVM, resend will lead to
506bc5ad3f3SBenjamin Herrenschmidt 	 * a H_TOO_HARD return and the whole transaction will be handled
507bc5ad3f3SBenjamin Herrenschmidt 	 * in virtual mode.
508bc5ad3f3SBenjamin Herrenschmidt 	 */
509bc5ad3f3SBenjamin Herrenschmidt 	do {
510bc5ad3f3SBenjamin Herrenschmidt 		old_state = new_state = ACCESS_ONCE(icp->state);
511bc5ad3f3SBenjamin Herrenschmidt 
512bc5ad3f3SBenjamin Herrenschmidt 		/* Down_CPPR */
513bc5ad3f3SBenjamin Herrenschmidt 		new_state.cppr = new_cppr;
514bc5ad3f3SBenjamin Herrenschmidt 
515bc5ad3f3SBenjamin Herrenschmidt 		/*
516bc5ad3f3SBenjamin Herrenschmidt 		 * Cut down Resend / Check_IPI / IPI
517bc5ad3f3SBenjamin Herrenschmidt 		 *
518bc5ad3f3SBenjamin Herrenschmidt 		 * The logic is that we cannot have a pending interrupt
519bc5ad3f3SBenjamin Herrenschmidt 		 * trumped by an IPI at this point (see above), so we
520bc5ad3f3SBenjamin Herrenschmidt 		 * know that either the pending interrupt is already an
521bc5ad3f3SBenjamin Herrenschmidt 		 * IPI (in which case we don't care to override it) or
522bc5ad3f3SBenjamin Herrenschmidt 		 * it's either more favored than us or non existent
523bc5ad3f3SBenjamin Herrenschmidt 		 */
524bc5ad3f3SBenjamin Herrenschmidt 		if (new_state.mfrr < new_cppr &&
525bc5ad3f3SBenjamin Herrenschmidt 		    new_state.mfrr <= new_state.pending_pri) {
526bc5ad3f3SBenjamin Herrenschmidt 			WARN_ON(new_state.xisr != XICS_IPI &&
527bc5ad3f3SBenjamin Herrenschmidt 				new_state.xisr != 0);
528bc5ad3f3SBenjamin Herrenschmidt 			new_state.pending_pri = new_state.mfrr;
529bc5ad3f3SBenjamin Herrenschmidt 			new_state.xisr = XICS_IPI;
530bc5ad3f3SBenjamin Herrenschmidt 		}
531bc5ad3f3SBenjamin Herrenschmidt 
532bc5ad3f3SBenjamin Herrenschmidt 		/* Latch/clear resend bit */
533bc5ad3f3SBenjamin Herrenschmidt 		resend = new_state.need_resend;
534bc5ad3f3SBenjamin Herrenschmidt 		new_state.need_resend = 0;
535bc5ad3f3SBenjamin Herrenschmidt 
536bc5ad3f3SBenjamin Herrenschmidt 	} while (!icp_try_update(icp, old_state, new_state, true));
537bc5ad3f3SBenjamin Herrenschmidt 
538bc5ad3f3SBenjamin Herrenschmidt 	/*
539bc5ad3f3SBenjamin Herrenschmidt 	 * Now handle resend checks. Those are asynchronous to the ICP
540bc5ad3f3SBenjamin Herrenschmidt 	 * state update in HW (ie bus transactions) so we can handle them
541bc5ad3f3SBenjamin Herrenschmidt 	 * separately here too
542bc5ad3f3SBenjamin Herrenschmidt 	 */
543bc5ad3f3SBenjamin Herrenschmidt 	if (resend)
544bc5ad3f3SBenjamin Herrenschmidt 		icp_check_resend(xics, icp);
545bc5ad3f3SBenjamin Herrenschmidt }
546bc5ad3f3SBenjamin Herrenschmidt 
547e7d26f28SBenjamin Herrenschmidt static noinline unsigned long kvmppc_h_xirr(struct kvm_vcpu *vcpu)
548bc5ad3f3SBenjamin Herrenschmidt {
549bc5ad3f3SBenjamin Herrenschmidt 	union kvmppc_icp_state old_state, new_state;
550bc5ad3f3SBenjamin Herrenschmidt 	struct kvmppc_icp *icp = vcpu->arch.icp;
551bc5ad3f3SBenjamin Herrenschmidt 	u32 xirr;
552bc5ad3f3SBenjamin Herrenschmidt 
553bc5ad3f3SBenjamin Herrenschmidt 	/* First, remove EE from the processor */
554bc5ad3f3SBenjamin Herrenschmidt 	kvmppc_book3s_dequeue_irqprio(icp->vcpu,
555bc5ad3f3SBenjamin Herrenschmidt 				      BOOK3S_INTERRUPT_EXTERNAL_LEVEL);
556bc5ad3f3SBenjamin Herrenschmidt 
557bc5ad3f3SBenjamin Herrenschmidt 	/*
558bc5ad3f3SBenjamin Herrenschmidt 	 * ICP State: Accept_Interrupt
559bc5ad3f3SBenjamin Herrenschmidt 	 *
560bc5ad3f3SBenjamin Herrenschmidt 	 * Return the pending interrupt (if any) along with the
561bc5ad3f3SBenjamin Herrenschmidt 	 * current CPPR, then clear the XISR & set CPPR to the
562bc5ad3f3SBenjamin Herrenschmidt 	 * pending priority
563bc5ad3f3SBenjamin Herrenschmidt 	 */
564bc5ad3f3SBenjamin Herrenschmidt 	do {
565bc5ad3f3SBenjamin Herrenschmidt 		old_state = new_state = ACCESS_ONCE(icp->state);
566bc5ad3f3SBenjamin Herrenschmidt 
567bc5ad3f3SBenjamin Herrenschmidt 		xirr = old_state.xisr | (((u32)old_state.cppr) << 24);
568bc5ad3f3SBenjamin Herrenschmidt 		if (!old_state.xisr)
569bc5ad3f3SBenjamin Herrenschmidt 			break;
570bc5ad3f3SBenjamin Herrenschmidt 		new_state.cppr = new_state.pending_pri;
571bc5ad3f3SBenjamin Herrenschmidt 		new_state.pending_pri = 0xff;
572bc5ad3f3SBenjamin Herrenschmidt 		new_state.xisr = 0;
573bc5ad3f3SBenjamin Herrenschmidt 
574bc5ad3f3SBenjamin Herrenschmidt 	} while (!icp_try_update(icp, old_state, new_state, true));
575bc5ad3f3SBenjamin Herrenschmidt 
576bc5ad3f3SBenjamin Herrenschmidt 	XICS_DBG("h_xirr vcpu %d xirr %#x\n", vcpu->vcpu_id, xirr);
577bc5ad3f3SBenjamin Herrenschmidt 
578bc5ad3f3SBenjamin Herrenschmidt 	return xirr;
579bc5ad3f3SBenjamin Herrenschmidt }
580bc5ad3f3SBenjamin Herrenschmidt 
581e7d26f28SBenjamin Herrenschmidt static noinline int kvmppc_h_ipi(struct kvm_vcpu *vcpu, unsigned long server,
582bc5ad3f3SBenjamin Herrenschmidt 				 unsigned long mfrr)
583bc5ad3f3SBenjamin Herrenschmidt {
584bc5ad3f3SBenjamin Herrenschmidt 	union kvmppc_icp_state old_state, new_state;
585bc5ad3f3SBenjamin Herrenschmidt 	struct kvmppc_xics *xics = vcpu->kvm->arch.xics;
586bc5ad3f3SBenjamin Herrenschmidt 	struct kvmppc_icp *icp;
587bc5ad3f3SBenjamin Herrenschmidt 	u32 reject;
588bc5ad3f3SBenjamin Herrenschmidt 	bool resend;
589bc5ad3f3SBenjamin Herrenschmidt 	bool local;
590bc5ad3f3SBenjamin Herrenschmidt 
591bc5ad3f3SBenjamin Herrenschmidt 	XICS_DBG("h_ipi vcpu %d to server %lu mfrr %#lx\n",
592bc5ad3f3SBenjamin Herrenschmidt 		 vcpu->vcpu_id, server, mfrr);
593bc5ad3f3SBenjamin Herrenschmidt 
594bc5ad3f3SBenjamin Herrenschmidt 	icp = vcpu->arch.icp;
595bc5ad3f3SBenjamin Herrenschmidt 	local = icp->server_num == server;
596bc5ad3f3SBenjamin Herrenschmidt 	if (!local) {
597bc5ad3f3SBenjamin Herrenschmidt 		icp = kvmppc_xics_find_server(vcpu->kvm, server);
598bc5ad3f3SBenjamin Herrenschmidt 		if (!icp)
599bc5ad3f3SBenjamin Herrenschmidt 			return H_PARAMETER;
600bc5ad3f3SBenjamin Herrenschmidt 	}
601bc5ad3f3SBenjamin Herrenschmidt 
602bc5ad3f3SBenjamin Herrenschmidt 	/*
603bc5ad3f3SBenjamin Herrenschmidt 	 * ICP state: Set_MFRR
604bc5ad3f3SBenjamin Herrenschmidt 	 *
605bc5ad3f3SBenjamin Herrenschmidt 	 * If the CPPR is more favored than the new MFRR, then
606bc5ad3f3SBenjamin Herrenschmidt 	 * nothing needs to be rejected as there can be no XISR to
607bc5ad3f3SBenjamin Herrenschmidt 	 * reject.  If the MFRR is being made less favored then
608bc5ad3f3SBenjamin Herrenschmidt 	 * there might be a previously-rejected interrupt needing
609bc5ad3f3SBenjamin Herrenschmidt 	 * to be resent.
610bc5ad3f3SBenjamin Herrenschmidt 	 *
611bc5ad3f3SBenjamin Herrenschmidt 	 * If the CPPR is less favored, then we might be replacing
612bc5ad3f3SBenjamin Herrenschmidt 	 * an interrupt, and thus need to possibly reject it as in
613bc5ad3f3SBenjamin Herrenschmidt 	 *
614bc5ad3f3SBenjamin Herrenschmidt 	 * ICP state: Check_IPI
615bc5ad3f3SBenjamin Herrenschmidt 	 */
616bc5ad3f3SBenjamin Herrenschmidt 	do {
617bc5ad3f3SBenjamin Herrenschmidt 		old_state = new_state = ACCESS_ONCE(icp->state);
618bc5ad3f3SBenjamin Herrenschmidt 
619bc5ad3f3SBenjamin Herrenschmidt 		/* Set_MFRR */
620bc5ad3f3SBenjamin Herrenschmidt 		new_state.mfrr = mfrr;
621bc5ad3f3SBenjamin Herrenschmidt 
622bc5ad3f3SBenjamin Herrenschmidt 		/* Check_IPI */
623bc5ad3f3SBenjamin Herrenschmidt 		reject = 0;
624bc5ad3f3SBenjamin Herrenschmidt 		resend = false;
625bc5ad3f3SBenjamin Herrenschmidt 		if (mfrr < new_state.cppr) {
626bc5ad3f3SBenjamin Herrenschmidt 			/* Reject a pending interrupt if not an IPI */
627bc5ad3f3SBenjamin Herrenschmidt 			if (mfrr <= new_state.pending_pri)
628bc5ad3f3SBenjamin Herrenschmidt 				reject = new_state.xisr;
629bc5ad3f3SBenjamin Herrenschmidt 			new_state.pending_pri = mfrr;
630bc5ad3f3SBenjamin Herrenschmidt 			new_state.xisr = XICS_IPI;
631bc5ad3f3SBenjamin Herrenschmidt 		}
632bc5ad3f3SBenjamin Herrenschmidt 
633bc5ad3f3SBenjamin Herrenschmidt 		if (mfrr > old_state.mfrr && mfrr > new_state.cppr) {
634bc5ad3f3SBenjamin Herrenschmidt 			resend = new_state.need_resend;
635bc5ad3f3SBenjamin Herrenschmidt 			new_state.need_resend = 0;
636bc5ad3f3SBenjamin Herrenschmidt 		}
637bc5ad3f3SBenjamin Herrenschmidt 	} while (!icp_try_update(icp, old_state, new_state, local));
638bc5ad3f3SBenjamin Herrenschmidt 
639bc5ad3f3SBenjamin Herrenschmidt 	/* Handle reject */
640bc5ad3f3SBenjamin Herrenschmidt 	if (reject && reject != XICS_IPI)
641bc5ad3f3SBenjamin Herrenschmidt 		icp_deliver_irq(xics, icp, reject);
642bc5ad3f3SBenjamin Herrenschmidt 
643bc5ad3f3SBenjamin Herrenschmidt 	/* Handle resend */
644bc5ad3f3SBenjamin Herrenschmidt 	if (resend)
645bc5ad3f3SBenjamin Herrenschmidt 		icp_check_resend(xics, icp);
646bc5ad3f3SBenjamin Herrenschmidt 
647bc5ad3f3SBenjamin Herrenschmidt 	return H_SUCCESS;
648bc5ad3f3SBenjamin Herrenschmidt }
649bc5ad3f3SBenjamin Herrenschmidt 
650e7d26f28SBenjamin Herrenschmidt static noinline void kvmppc_h_cppr(struct kvm_vcpu *vcpu, unsigned long cppr)
651bc5ad3f3SBenjamin Herrenschmidt {
652bc5ad3f3SBenjamin Herrenschmidt 	union kvmppc_icp_state old_state, new_state;
653bc5ad3f3SBenjamin Herrenschmidt 	struct kvmppc_xics *xics = vcpu->kvm->arch.xics;
654bc5ad3f3SBenjamin Herrenschmidt 	struct kvmppc_icp *icp = vcpu->arch.icp;
655bc5ad3f3SBenjamin Herrenschmidt 	u32 reject;
656bc5ad3f3SBenjamin Herrenschmidt 
657bc5ad3f3SBenjamin Herrenschmidt 	XICS_DBG("h_cppr vcpu %d cppr %#lx\n", vcpu->vcpu_id, cppr);
658bc5ad3f3SBenjamin Herrenschmidt 
659bc5ad3f3SBenjamin Herrenschmidt 	/*
660bc5ad3f3SBenjamin Herrenschmidt 	 * ICP State: Set_CPPR
661bc5ad3f3SBenjamin Herrenschmidt 	 *
662bc5ad3f3SBenjamin Herrenschmidt 	 * We can safely compare the new value with the current
663bc5ad3f3SBenjamin Herrenschmidt 	 * value outside of the transaction as the CPPR is only
664bc5ad3f3SBenjamin Herrenschmidt 	 * ever changed by the processor on itself
665bc5ad3f3SBenjamin Herrenschmidt 	 */
666bc5ad3f3SBenjamin Herrenschmidt 	if (cppr > icp->state.cppr)
667bc5ad3f3SBenjamin Herrenschmidt 		icp_down_cppr(xics, icp, cppr);
668bc5ad3f3SBenjamin Herrenschmidt 	else if (cppr == icp->state.cppr)
669bc5ad3f3SBenjamin Herrenschmidt 		return;
670bc5ad3f3SBenjamin Herrenschmidt 
671bc5ad3f3SBenjamin Herrenschmidt 	/*
672bc5ad3f3SBenjamin Herrenschmidt 	 * ICP State: Up_CPPR
673bc5ad3f3SBenjamin Herrenschmidt 	 *
674bc5ad3f3SBenjamin Herrenschmidt 	 * The processor is raising its priority, this can result
675bc5ad3f3SBenjamin Herrenschmidt 	 * in a rejection of a pending interrupt:
676bc5ad3f3SBenjamin Herrenschmidt 	 *
677bc5ad3f3SBenjamin Herrenschmidt 	 * ICP State: Reject_Current
678bc5ad3f3SBenjamin Herrenschmidt 	 *
679bc5ad3f3SBenjamin Herrenschmidt 	 * We can remove EE from the current processor, the update
680bc5ad3f3SBenjamin Herrenschmidt 	 * transaction will set it again if needed
681bc5ad3f3SBenjamin Herrenschmidt 	 */
682bc5ad3f3SBenjamin Herrenschmidt 	kvmppc_book3s_dequeue_irqprio(icp->vcpu,
683bc5ad3f3SBenjamin Herrenschmidt 				      BOOK3S_INTERRUPT_EXTERNAL_LEVEL);
684bc5ad3f3SBenjamin Herrenschmidt 
685bc5ad3f3SBenjamin Herrenschmidt 	do {
686bc5ad3f3SBenjamin Herrenschmidt 		old_state = new_state = ACCESS_ONCE(icp->state);
687bc5ad3f3SBenjamin Herrenschmidt 
688bc5ad3f3SBenjamin Herrenschmidt 		reject = 0;
689bc5ad3f3SBenjamin Herrenschmidt 		new_state.cppr = cppr;
690bc5ad3f3SBenjamin Herrenschmidt 
691bc5ad3f3SBenjamin Herrenschmidt 		if (cppr <= new_state.pending_pri) {
692bc5ad3f3SBenjamin Herrenschmidt 			reject = new_state.xisr;
693bc5ad3f3SBenjamin Herrenschmidt 			new_state.xisr = 0;
694bc5ad3f3SBenjamin Herrenschmidt 			new_state.pending_pri = 0xff;
695bc5ad3f3SBenjamin Herrenschmidt 		}
696bc5ad3f3SBenjamin Herrenschmidt 
697bc5ad3f3SBenjamin Herrenschmidt 	} while (!icp_try_update(icp, old_state, new_state, true));
698bc5ad3f3SBenjamin Herrenschmidt 
699bc5ad3f3SBenjamin Herrenschmidt 	/*
700bc5ad3f3SBenjamin Herrenschmidt 	 * Check for rejects. They are handled by doing a new delivery
701bc5ad3f3SBenjamin Herrenschmidt 	 * attempt (see comments in icp_deliver_irq).
702bc5ad3f3SBenjamin Herrenschmidt 	 */
703bc5ad3f3SBenjamin Herrenschmidt 	if (reject && reject != XICS_IPI)
704bc5ad3f3SBenjamin Herrenschmidt 		icp_deliver_irq(xics, icp, reject);
705bc5ad3f3SBenjamin Herrenschmidt }
706bc5ad3f3SBenjamin Herrenschmidt 
707e7d26f28SBenjamin Herrenschmidt static noinline int kvmppc_h_eoi(struct kvm_vcpu *vcpu, unsigned long xirr)
708bc5ad3f3SBenjamin Herrenschmidt {
709bc5ad3f3SBenjamin Herrenschmidt 	struct kvmppc_xics *xics = vcpu->kvm->arch.xics;
710bc5ad3f3SBenjamin Herrenschmidt 	struct kvmppc_icp *icp = vcpu->arch.icp;
711bc5ad3f3SBenjamin Herrenschmidt 	struct kvmppc_ics *ics;
712bc5ad3f3SBenjamin Herrenschmidt 	struct ics_irq_state *state;
713bc5ad3f3SBenjamin Herrenschmidt 	u32 irq = xirr & 0x00ffffff;
714bc5ad3f3SBenjamin Herrenschmidt 	u16 src;
715bc5ad3f3SBenjamin Herrenschmidt 
716bc5ad3f3SBenjamin Herrenschmidt 	XICS_DBG("h_eoi vcpu %d eoi %#lx\n", vcpu->vcpu_id, xirr);
717bc5ad3f3SBenjamin Herrenschmidt 
718bc5ad3f3SBenjamin Herrenschmidt 	/*
719bc5ad3f3SBenjamin Herrenschmidt 	 * ICP State: EOI
720bc5ad3f3SBenjamin Herrenschmidt 	 *
721bc5ad3f3SBenjamin Herrenschmidt 	 * Note: If EOI is incorrectly used by SW to lower the CPPR
722bc5ad3f3SBenjamin Herrenschmidt 	 * value (ie more favored), we do not check for rejection of
723bc5ad3f3SBenjamin Herrenschmidt 	 * a pending interrupt, this is a SW error and PAPR sepcifies
724bc5ad3f3SBenjamin Herrenschmidt 	 * that we don't have to deal with it.
725bc5ad3f3SBenjamin Herrenschmidt 	 *
726bc5ad3f3SBenjamin Herrenschmidt 	 * The sending of an EOI to the ICS is handled after the
727bc5ad3f3SBenjamin Herrenschmidt 	 * CPPR update
728bc5ad3f3SBenjamin Herrenschmidt 	 *
729bc5ad3f3SBenjamin Herrenschmidt 	 * ICP State: Down_CPPR which we handle
730bc5ad3f3SBenjamin Herrenschmidt 	 * in a separate function as it's shared with H_CPPR.
731bc5ad3f3SBenjamin Herrenschmidt 	 */
732bc5ad3f3SBenjamin Herrenschmidt 	icp_down_cppr(xics, icp, xirr >> 24);
733bc5ad3f3SBenjamin Herrenschmidt 
734bc5ad3f3SBenjamin Herrenschmidt 	/* IPIs have no EOI */
735bc5ad3f3SBenjamin Herrenschmidt 	if (irq == XICS_IPI)
736bc5ad3f3SBenjamin Herrenschmidt 		return H_SUCCESS;
737bc5ad3f3SBenjamin Herrenschmidt 	/*
738bc5ad3f3SBenjamin Herrenschmidt 	 * EOI handling: If the interrupt is still asserted, we need to
739bc5ad3f3SBenjamin Herrenschmidt 	 * resend it. We can take a lockless "peek" at the ICS state here.
740bc5ad3f3SBenjamin Herrenschmidt 	 *
741bc5ad3f3SBenjamin Herrenschmidt 	 * "Message" interrupts will never have "asserted" set
742bc5ad3f3SBenjamin Herrenschmidt 	 */
743bc5ad3f3SBenjamin Herrenschmidt 	ics = kvmppc_xics_find_ics(xics, irq, &src);
744bc5ad3f3SBenjamin Herrenschmidt 	if (!ics) {
745bc5ad3f3SBenjamin Herrenschmidt 		XICS_DBG("h_eoi: IRQ 0x%06x not found !\n", irq);
746bc5ad3f3SBenjamin Herrenschmidt 		return H_PARAMETER;
747bc5ad3f3SBenjamin Herrenschmidt 	}
748bc5ad3f3SBenjamin Herrenschmidt 	state = &ics->irq_state[src];
749bc5ad3f3SBenjamin Herrenschmidt 
750bc5ad3f3SBenjamin Herrenschmidt 	/* Still asserted, resend it */
751bc5ad3f3SBenjamin Herrenschmidt 	if (state->asserted)
752bc5ad3f3SBenjamin Herrenschmidt 		icp_deliver_irq(xics, icp, irq);
753bc5ad3f3SBenjamin Herrenschmidt 
754bc5ad3f3SBenjamin Herrenschmidt 	return H_SUCCESS;
755bc5ad3f3SBenjamin Herrenschmidt }
756bc5ad3f3SBenjamin Herrenschmidt 
757e7d26f28SBenjamin Herrenschmidt static noinline int kvmppc_xics_rm_complete(struct kvm_vcpu *vcpu, u32 hcall)
758e7d26f28SBenjamin Herrenschmidt {
759e7d26f28SBenjamin Herrenschmidt 	struct kvmppc_xics *xics = vcpu->kvm->arch.xics;
760e7d26f28SBenjamin Herrenschmidt 	struct kvmppc_icp *icp = vcpu->arch.icp;
761e7d26f28SBenjamin Herrenschmidt 
762e7d26f28SBenjamin Herrenschmidt 	XICS_DBG("XICS_RM: H_%x completing, act: %x state: %lx tgt: %p\n",
763e7d26f28SBenjamin Herrenschmidt 		 hcall, icp->rm_action, icp->rm_dbgstate.raw, icp->rm_dbgtgt);
764e7d26f28SBenjamin Herrenschmidt 
765e7d26f28SBenjamin Herrenschmidt 	if (icp->rm_action & XICS_RM_KICK_VCPU)
766e7d26f28SBenjamin Herrenschmidt 		kvmppc_fast_vcpu_kick(icp->rm_kick_target);
767e7d26f28SBenjamin Herrenschmidt 	if (icp->rm_action & XICS_RM_CHECK_RESEND)
768e7d26f28SBenjamin Herrenschmidt 		icp_check_resend(xics, icp);
769e7d26f28SBenjamin Herrenschmidt 	if (icp->rm_action & XICS_RM_REJECT)
770e7d26f28SBenjamin Herrenschmidt 		icp_deliver_irq(xics, icp, icp->rm_reject);
771e7d26f28SBenjamin Herrenschmidt 
772e7d26f28SBenjamin Herrenschmidt 	icp->rm_action = 0;
773e7d26f28SBenjamin Herrenschmidt 
774e7d26f28SBenjamin Herrenschmidt 	return H_SUCCESS;
775e7d26f28SBenjamin Herrenschmidt }
776e7d26f28SBenjamin Herrenschmidt 
777bc5ad3f3SBenjamin Herrenschmidt int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 req)
778bc5ad3f3SBenjamin Herrenschmidt {
779e7d26f28SBenjamin Herrenschmidt 	struct kvmppc_xics *xics = vcpu->kvm->arch.xics;
780bc5ad3f3SBenjamin Herrenschmidt 	unsigned long res;
781bc5ad3f3SBenjamin Herrenschmidt 	int rc = H_SUCCESS;
782bc5ad3f3SBenjamin Herrenschmidt 
783bc5ad3f3SBenjamin Herrenschmidt 	/* Check if we have an ICP */
784e7d26f28SBenjamin Herrenschmidt 	if (!xics || !vcpu->arch.icp)
785bc5ad3f3SBenjamin Herrenschmidt 		return H_HARDWARE;
786bc5ad3f3SBenjamin Herrenschmidt 
787e7d26f28SBenjamin Herrenschmidt 	/* Check for real mode returning too hard */
788e7d26f28SBenjamin Herrenschmidt 	if (xics->real_mode)
789e7d26f28SBenjamin Herrenschmidt 		return kvmppc_xics_rm_complete(vcpu, req);
790e7d26f28SBenjamin Herrenschmidt 
791bc5ad3f3SBenjamin Herrenschmidt 	switch (req) {
792bc5ad3f3SBenjamin Herrenschmidt 	case H_XIRR:
793e7d26f28SBenjamin Herrenschmidt 		res = kvmppc_h_xirr(vcpu);
794bc5ad3f3SBenjamin Herrenschmidt 		kvmppc_set_gpr(vcpu, 4, res);
795bc5ad3f3SBenjamin Herrenschmidt 		break;
796bc5ad3f3SBenjamin Herrenschmidt 	case H_CPPR:
797e7d26f28SBenjamin Herrenschmidt 		kvmppc_h_cppr(vcpu, kvmppc_get_gpr(vcpu, 4));
798bc5ad3f3SBenjamin Herrenschmidt 		break;
799bc5ad3f3SBenjamin Herrenschmidt 	case H_EOI:
800e7d26f28SBenjamin Herrenschmidt 		rc = kvmppc_h_eoi(vcpu, kvmppc_get_gpr(vcpu, 4));
801bc5ad3f3SBenjamin Herrenschmidt 		break;
802bc5ad3f3SBenjamin Herrenschmidt 	case H_IPI:
803e7d26f28SBenjamin Herrenschmidt 		rc = kvmppc_h_ipi(vcpu, kvmppc_get_gpr(vcpu, 4),
804bc5ad3f3SBenjamin Herrenschmidt 				  kvmppc_get_gpr(vcpu, 5));
805bc5ad3f3SBenjamin Herrenschmidt 		break;
806bc5ad3f3SBenjamin Herrenschmidt 	}
807bc5ad3f3SBenjamin Herrenschmidt 
808bc5ad3f3SBenjamin Herrenschmidt 	return rc;
809bc5ad3f3SBenjamin Herrenschmidt }
810bc5ad3f3SBenjamin Herrenschmidt 
811bc5ad3f3SBenjamin Herrenschmidt 
812bc5ad3f3SBenjamin Herrenschmidt /* -- Initialisation code etc. -- */
813bc5ad3f3SBenjamin Herrenschmidt 
814bc5ad3f3SBenjamin Herrenschmidt static int xics_debug_show(struct seq_file *m, void *private)
815bc5ad3f3SBenjamin Herrenschmidt {
816bc5ad3f3SBenjamin Herrenschmidt 	struct kvmppc_xics *xics = m->private;
817bc5ad3f3SBenjamin Herrenschmidt 	struct kvm *kvm = xics->kvm;
818bc5ad3f3SBenjamin Herrenschmidt 	struct kvm_vcpu *vcpu;
819bc5ad3f3SBenjamin Herrenschmidt 	int icsid, i;
820bc5ad3f3SBenjamin Herrenschmidt 
821bc5ad3f3SBenjamin Herrenschmidt 	if (!kvm)
822bc5ad3f3SBenjamin Herrenschmidt 		return 0;
823bc5ad3f3SBenjamin Herrenschmidt 
824bc5ad3f3SBenjamin Herrenschmidt 	seq_printf(m, "=========\nICP state\n=========\n");
825bc5ad3f3SBenjamin Herrenschmidt 
826bc5ad3f3SBenjamin Herrenschmidt 	kvm_for_each_vcpu(i, vcpu, kvm) {
827bc5ad3f3SBenjamin Herrenschmidt 		struct kvmppc_icp *icp = vcpu->arch.icp;
828bc5ad3f3SBenjamin Herrenschmidt 		union kvmppc_icp_state state;
829bc5ad3f3SBenjamin Herrenschmidt 
830bc5ad3f3SBenjamin Herrenschmidt 		if (!icp)
831bc5ad3f3SBenjamin Herrenschmidt 			continue;
832bc5ad3f3SBenjamin Herrenschmidt 
833bc5ad3f3SBenjamin Herrenschmidt 		state.raw = ACCESS_ONCE(icp->state.raw);
834bc5ad3f3SBenjamin Herrenschmidt 		seq_printf(m, "cpu server %#lx XIRR:%#x PPRI:%#x CPPR:%#x MFRR:%#x OUT:%d NR:%d\n",
835bc5ad3f3SBenjamin Herrenschmidt 			   icp->server_num, state.xisr,
836bc5ad3f3SBenjamin Herrenschmidt 			   state.pending_pri, state.cppr, state.mfrr,
837bc5ad3f3SBenjamin Herrenschmidt 			   state.out_ee, state.need_resend);
838bc5ad3f3SBenjamin Herrenschmidt 	}
839bc5ad3f3SBenjamin Herrenschmidt 
840bc5ad3f3SBenjamin Herrenschmidt 	for (icsid = 0; icsid <= KVMPPC_XICS_MAX_ICS_ID; icsid++) {
841bc5ad3f3SBenjamin Herrenschmidt 		struct kvmppc_ics *ics = xics->ics[icsid];
842bc5ad3f3SBenjamin Herrenschmidt 
843bc5ad3f3SBenjamin Herrenschmidt 		if (!ics)
844bc5ad3f3SBenjamin Herrenschmidt 			continue;
845bc5ad3f3SBenjamin Herrenschmidt 
846bc5ad3f3SBenjamin Herrenschmidt 		seq_printf(m, "=========\nICS state for ICS 0x%x\n=========\n",
847bc5ad3f3SBenjamin Herrenschmidt 			   icsid);
848bc5ad3f3SBenjamin Herrenschmidt 
849bc5ad3f3SBenjamin Herrenschmidt 		mutex_lock(&ics->lock);
850bc5ad3f3SBenjamin Herrenschmidt 
851bc5ad3f3SBenjamin Herrenschmidt 		for (i = 0; i < KVMPPC_XICS_IRQ_PER_ICS; i++) {
852bc5ad3f3SBenjamin Herrenschmidt 			struct ics_irq_state *irq = &ics->irq_state[i];
853bc5ad3f3SBenjamin Herrenschmidt 
854bc5ad3f3SBenjamin Herrenschmidt 			seq_printf(m, "irq 0x%06x: server %#x prio %#x save prio %#x asserted %d resend %d masked pending %d\n",
855bc5ad3f3SBenjamin Herrenschmidt 				   irq->number, irq->server, irq->priority,
856bc5ad3f3SBenjamin Herrenschmidt 				   irq->saved_priority, irq->asserted,
857bc5ad3f3SBenjamin Herrenschmidt 				   irq->resend, irq->masked_pending);
858bc5ad3f3SBenjamin Herrenschmidt 
859bc5ad3f3SBenjamin Herrenschmidt 		}
860bc5ad3f3SBenjamin Herrenschmidt 		mutex_unlock(&ics->lock);
861bc5ad3f3SBenjamin Herrenschmidt 	}
862bc5ad3f3SBenjamin Herrenschmidt 	return 0;
863bc5ad3f3SBenjamin Herrenschmidt }
864bc5ad3f3SBenjamin Herrenschmidt 
865bc5ad3f3SBenjamin Herrenschmidt static int xics_debug_open(struct inode *inode, struct file *file)
866bc5ad3f3SBenjamin Herrenschmidt {
867bc5ad3f3SBenjamin Herrenschmidt 	return single_open(file, xics_debug_show, inode->i_private);
868bc5ad3f3SBenjamin Herrenschmidt }
869bc5ad3f3SBenjamin Herrenschmidt 
870bc5ad3f3SBenjamin Herrenschmidt static const struct file_operations xics_debug_fops = {
871bc5ad3f3SBenjamin Herrenschmidt 	.open = xics_debug_open,
872bc5ad3f3SBenjamin Herrenschmidt 	.read = seq_read,
873bc5ad3f3SBenjamin Herrenschmidt 	.llseek = seq_lseek,
874bc5ad3f3SBenjamin Herrenschmidt 	.release = single_release,
875bc5ad3f3SBenjamin Herrenschmidt };
876bc5ad3f3SBenjamin Herrenschmidt 
877bc5ad3f3SBenjamin Herrenschmidt static void xics_debugfs_init(struct kvmppc_xics *xics)
878bc5ad3f3SBenjamin Herrenschmidt {
879bc5ad3f3SBenjamin Herrenschmidt 	char *name;
880bc5ad3f3SBenjamin Herrenschmidt 
881bc5ad3f3SBenjamin Herrenschmidt 	name = kasprintf(GFP_KERNEL, "kvm-xics-%p", xics);
882bc5ad3f3SBenjamin Herrenschmidt 	if (!name) {
883bc5ad3f3SBenjamin Herrenschmidt 		pr_err("%s: no memory for name\n", __func__);
884bc5ad3f3SBenjamin Herrenschmidt 		return;
885bc5ad3f3SBenjamin Herrenschmidt 	}
886bc5ad3f3SBenjamin Herrenschmidt 
887bc5ad3f3SBenjamin Herrenschmidt 	xics->dentry = debugfs_create_file(name, S_IRUGO, powerpc_debugfs_root,
888bc5ad3f3SBenjamin Herrenschmidt 					   xics, &xics_debug_fops);
889bc5ad3f3SBenjamin Herrenschmidt 
890bc5ad3f3SBenjamin Herrenschmidt 	pr_debug("%s: created %s\n", __func__, name);
891bc5ad3f3SBenjamin Herrenschmidt 	kfree(name);
892bc5ad3f3SBenjamin Herrenschmidt }
893bc5ad3f3SBenjamin Herrenschmidt 
894bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_ics *kvmppc_xics_create_ics(struct kvm *kvm,
895bc5ad3f3SBenjamin Herrenschmidt 					  struct kvmppc_xics *xics, int irq)
896bc5ad3f3SBenjamin Herrenschmidt {
897bc5ad3f3SBenjamin Herrenschmidt 	struct kvmppc_ics *ics;
898bc5ad3f3SBenjamin Herrenschmidt 	int i, icsid;
899bc5ad3f3SBenjamin Herrenschmidt 
900bc5ad3f3SBenjamin Herrenschmidt 	icsid = irq >> KVMPPC_XICS_ICS_SHIFT;
901bc5ad3f3SBenjamin Herrenschmidt 
902bc5ad3f3SBenjamin Herrenschmidt 	mutex_lock(&kvm->lock);
903bc5ad3f3SBenjamin Herrenschmidt 
904bc5ad3f3SBenjamin Herrenschmidt 	/* ICS already exists - somebody else got here first */
905bc5ad3f3SBenjamin Herrenschmidt 	if (xics->ics[icsid])
906bc5ad3f3SBenjamin Herrenschmidt 		goto out;
907bc5ad3f3SBenjamin Herrenschmidt 
908bc5ad3f3SBenjamin Herrenschmidt 	/* Create the ICS */
909bc5ad3f3SBenjamin Herrenschmidt 	ics = kzalloc(sizeof(struct kvmppc_ics), GFP_KERNEL);
910bc5ad3f3SBenjamin Herrenschmidt 	if (!ics)
911bc5ad3f3SBenjamin Herrenschmidt 		goto out;
912bc5ad3f3SBenjamin Herrenschmidt 
913bc5ad3f3SBenjamin Herrenschmidt 	mutex_init(&ics->lock);
914bc5ad3f3SBenjamin Herrenschmidt 	ics->icsid = icsid;
915bc5ad3f3SBenjamin Herrenschmidt 
916bc5ad3f3SBenjamin Herrenschmidt 	for (i = 0; i < KVMPPC_XICS_IRQ_PER_ICS; i++) {
917bc5ad3f3SBenjamin Herrenschmidt 		ics->irq_state[i].number = (icsid << KVMPPC_XICS_ICS_SHIFT) | i;
918bc5ad3f3SBenjamin Herrenschmidt 		ics->irq_state[i].priority = MASKED;
919bc5ad3f3SBenjamin Herrenschmidt 		ics->irq_state[i].saved_priority = MASKED;
920bc5ad3f3SBenjamin Herrenschmidt 	}
921bc5ad3f3SBenjamin Herrenschmidt 	smp_wmb();
922bc5ad3f3SBenjamin Herrenschmidt 	xics->ics[icsid] = ics;
923bc5ad3f3SBenjamin Herrenschmidt 
924bc5ad3f3SBenjamin Herrenschmidt 	if (icsid > xics->max_icsid)
925bc5ad3f3SBenjamin Herrenschmidt 		xics->max_icsid = icsid;
926bc5ad3f3SBenjamin Herrenschmidt 
927bc5ad3f3SBenjamin Herrenschmidt  out:
928bc5ad3f3SBenjamin Herrenschmidt 	mutex_unlock(&kvm->lock);
929bc5ad3f3SBenjamin Herrenschmidt 	return xics->ics[icsid];
930bc5ad3f3SBenjamin Herrenschmidt }
931bc5ad3f3SBenjamin Herrenschmidt 
932bc5ad3f3SBenjamin Herrenschmidt int kvmppc_xics_create_icp(struct kvm_vcpu *vcpu, unsigned long server_num)
933bc5ad3f3SBenjamin Herrenschmidt {
934bc5ad3f3SBenjamin Herrenschmidt 	struct kvmppc_icp *icp;
935bc5ad3f3SBenjamin Herrenschmidt 
936bc5ad3f3SBenjamin Herrenschmidt 	if (!vcpu->kvm->arch.xics)
937bc5ad3f3SBenjamin Herrenschmidt 		return -ENODEV;
938bc5ad3f3SBenjamin Herrenschmidt 
939bc5ad3f3SBenjamin Herrenschmidt 	if (kvmppc_xics_find_server(vcpu->kvm, server_num))
940bc5ad3f3SBenjamin Herrenschmidt 		return -EEXIST;
941bc5ad3f3SBenjamin Herrenschmidt 
942bc5ad3f3SBenjamin Herrenschmidt 	icp = kzalloc(sizeof(struct kvmppc_icp), GFP_KERNEL);
943bc5ad3f3SBenjamin Herrenschmidt 	if (!icp)
944bc5ad3f3SBenjamin Herrenschmidt 		return -ENOMEM;
945bc5ad3f3SBenjamin Herrenschmidt 
946bc5ad3f3SBenjamin Herrenschmidt 	icp->vcpu = vcpu;
947bc5ad3f3SBenjamin Herrenschmidt 	icp->server_num = server_num;
948bc5ad3f3SBenjamin Herrenschmidt 	icp->state.mfrr = MASKED;
949bc5ad3f3SBenjamin Herrenschmidt 	icp->state.pending_pri = MASKED;
950bc5ad3f3SBenjamin Herrenschmidt 	vcpu->arch.icp = icp;
951bc5ad3f3SBenjamin Herrenschmidt 
952bc5ad3f3SBenjamin Herrenschmidt 	XICS_DBG("created server for vcpu %d\n", vcpu->vcpu_id);
953bc5ad3f3SBenjamin Herrenschmidt 
954bc5ad3f3SBenjamin Herrenschmidt 	return 0;
955bc5ad3f3SBenjamin Herrenschmidt }
956bc5ad3f3SBenjamin Herrenschmidt 
957*8b78645cSPaul Mackerras u64 kvmppc_xics_get_icp(struct kvm_vcpu *vcpu)
958*8b78645cSPaul Mackerras {
959*8b78645cSPaul Mackerras 	struct kvmppc_icp *icp = vcpu->arch.icp;
960*8b78645cSPaul Mackerras 	union kvmppc_icp_state state;
961*8b78645cSPaul Mackerras 
962*8b78645cSPaul Mackerras 	if (!icp)
963*8b78645cSPaul Mackerras 		return 0;
964*8b78645cSPaul Mackerras 	state = icp->state;
965*8b78645cSPaul Mackerras 	return ((u64)state.cppr << KVM_REG_PPC_ICP_CPPR_SHIFT) |
966*8b78645cSPaul Mackerras 		((u64)state.xisr << KVM_REG_PPC_ICP_XISR_SHIFT) |
967*8b78645cSPaul Mackerras 		((u64)state.mfrr << KVM_REG_PPC_ICP_MFRR_SHIFT) |
968*8b78645cSPaul Mackerras 		((u64)state.pending_pri << KVM_REG_PPC_ICP_PPRI_SHIFT);
969*8b78645cSPaul Mackerras }
970*8b78645cSPaul Mackerras 
971*8b78645cSPaul Mackerras int kvmppc_xics_set_icp(struct kvm_vcpu *vcpu, u64 icpval)
972*8b78645cSPaul Mackerras {
973*8b78645cSPaul Mackerras 	struct kvmppc_icp *icp = vcpu->arch.icp;
974*8b78645cSPaul Mackerras 	struct kvmppc_xics *xics = vcpu->kvm->arch.xics;
975*8b78645cSPaul Mackerras 	union kvmppc_icp_state old_state, new_state;
976*8b78645cSPaul Mackerras 	struct kvmppc_ics *ics;
977*8b78645cSPaul Mackerras 	u8 cppr, mfrr, pending_pri;
978*8b78645cSPaul Mackerras 	u32 xisr;
979*8b78645cSPaul Mackerras 	u16 src;
980*8b78645cSPaul Mackerras 	bool resend;
981*8b78645cSPaul Mackerras 
982*8b78645cSPaul Mackerras 	if (!icp || !xics)
983*8b78645cSPaul Mackerras 		return -ENOENT;
984*8b78645cSPaul Mackerras 
985*8b78645cSPaul Mackerras 	cppr = icpval >> KVM_REG_PPC_ICP_CPPR_SHIFT;
986*8b78645cSPaul Mackerras 	xisr = (icpval >> KVM_REG_PPC_ICP_XISR_SHIFT) &
987*8b78645cSPaul Mackerras 		KVM_REG_PPC_ICP_XISR_MASK;
988*8b78645cSPaul Mackerras 	mfrr = icpval >> KVM_REG_PPC_ICP_MFRR_SHIFT;
989*8b78645cSPaul Mackerras 	pending_pri = icpval >> KVM_REG_PPC_ICP_PPRI_SHIFT;
990*8b78645cSPaul Mackerras 
991*8b78645cSPaul Mackerras 	/* Require the new state to be internally consistent */
992*8b78645cSPaul Mackerras 	if (xisr == 0) {
993*8b78645cSPaul Mackerras 		if (pending_pri != 0xff)
994*8b78645cSPaul Mackerras 			return -EINVAL;
995*8b78645cSPaul Mackerras 	} else if (xisr == XICS_IPI) {
996*8b78645cSPaul Mackerras 		if (pending_pri != mfrr || pending_pri >= cppr)
997*8b78645cSPaul Mackerras 			return -EINVAL;
998*8b78645cSPaul Mackerras 	} else {
999*8b78645cSPaul Mackerras 		if (pending_pri >= mfrr || pending_pri >= cppr)
1000*8b78645cSPaul Mackerras 			return -EINVAL;
1001*8b78645cSPaul Mackerras 		ics = kvmppc_xics_find_ics(xics, xisr, &src);
1002*8b78645cSPaul Mackerras 		if (!ics)
1003*8b78645cSPaul Mackerras 			return -EINVAL;
1004*8b78645cSPaul Mackerras 	}
1005*8b78645cSPaul Mackerras 
1006*8b78645cSPaul Mackerras 	new_state.raw = 0;
1007*8b78645cSPaul Mackerras 	new_state.cppr = cppr;
1008*8b78645cSPaul Mackerras 	new_state.xisr = xisr;
1009*8b78645cSPaul Mackerras 	new_state.mfrr = mfrr;
1010*8b78645cSPaul Mackerras 	new_state.pending_pri = pending_pri;
1011*8b78645cSPaul Mackerras 
1012*8b78645cSPaul Mackerras 	/*
1013*8b78645cSPaul Mackerras 	 * Deassert the CPU interrupt request.
1014*8b78645cSPaul Mackerras 	 * icp_try_update will reassert it if necessary.
1015*8b78645cSPaul Mackerras 	 */
1016*8b78645cSPaul Mackerras 	kvmppc_book3s_dequeue_irqprio(icp->vcpu,
1017*8b78645cSPaul Mackerras 				      BOOK3S_INTERRUPT_EXTERNAL_LEVEL);
1018*8b78645cSPaul Mackerras 
1019*8b78645cSPaul Mackerras 	/*
1020*8b78645cSPaul Mackerras 	 * Note that if we displace an interrupt from old_state.xisr,
1021*8b78645cSPaul Mackerras 	 * we don't mark it as rejected.  We expect userspace to set
1022*8b78645cSPaul Mackerras 	 * the state of the interrupt sources to be consistent with
1023*8b78645cSPaul Mackerras 	 * the ICP states (either before or afterwards, which doesn't
1024*8b78645cSPaul Mackerras 	 * matter).  We do handle resends due to CPPR becoming less
1025*8b78645cSPaul Mackerras 	 * favoured because that is necessary to end up with a
1026*8b78645cSPaul Mackerras 	 * consistent state in the situation where userspace restores
1027*8b78645cSPaul Mackerras 	 * the ICS states before the ICP states.
1028*8b78645cSPaul Mackerras 	 */
1029*8b78645cSPaul Mackerras 	do {
1030*8b78645cSPaul Mackerras 		old_state = ACCESS_ONCE(icp->state);
1031*8b78645cSPaul Mackerras 
1032*8b78645cSPaul Mackerras 		if (new_state.mfrr <= old_state.mfrr) {
1033*8b78645cSPaul Mackerras 			resend = false;
1034*8b78645cSPaul Mackerras 			new_state.need_resend = old_state.need_resend;
1035*8b78645cSPaul Mackerras 		} else {
1036*8b78645cSPaul Mackerras 			resend = old_state.need_resend;
1037*8b78645cSPaul Mackerras 			new_state.need_resend = 0;
1038*8b78645cSPaul Mackerras 		}
1039*8b78645cSPaul Mackerras 	} while (!icp_try_update(icp, old_state, new_state, false));
1040*8b78645cSPaul Mackerras 
1041*8b78645cSPaul Mackerras 	if (resend)
1042*8b78645cSPaul Mackerras 		icp_check_resend(xics, icp);
1043*8b78645cSPaul Mackerras 
1044*8b78645cSPaul Mackerras 	return 0;
1045*8b78645cSPaul Mackerras }
1046*8b78645cSPaul Mackerras 
1047bc5ad3f3SBenjamin Herrenschmidt /* -- ioctls -- */
1048bc5ad3f3SBenjamin Herrenschmidt 
1049bc5ad3f3SBenjamin Herrenschmidt int kvm_vm_ioctl_xics_irq(struct kvm *kvm, struct kvm_irq_level *args)
1050bc5ad3f3SBenjamin Herrenschmidt {
1051bc5ad3f3SBenjamin Herrenschmidt 	struct kvmppc_xics *xics;
1052bc5ad3f3SBenjamin Herrenschmidt 	int r;
1053bc5ad3f3SBenjamin Herrenschmidt 
1054bc5ad3f3SBenjamin Herrenschmidt 	/* locking against multiple callers? */
1055bc5ad3f3SBenjamin Herrenschmidt 
1056bc5ad3f3SBenjamin Herrenschmidt 	xics = kvm->arch.xics;
1057bc5ad3f3SBenjamin Herrenschmidt 	if (!xics)
1058bc5ad3f3SBenjamin Herrenschmidt 		return -ENODEV;
1059bc5ad3f3SBenjamin Herrenschmidt 
1060bc5ad3f3SBenjamin Herrenschmidt 	switch (args->level) {
1061bc5ad3f3SBenjamin Herrenschmidt 	case KVM_INTERRUPT_SET:
1062bc5ad3f3SBenjamin Herrenschmidt 	case KVM_INTERRUPT_SET_LEVEL:
1063bc5ad3f3SBenjamin Herrenschmidt 	case KVM_INTERRUPT_UNSET:
1064bc5ad3f3SBenjamin Herrenschmidt 		r = ics_deliver_irq(xics, args->irq, args->level);
1065bc5ad3f3SBenjamin Herrenschmidt 		break;
1066bc5ad3f3SBenjamin Herrenschmidt 	default:
1067bc5ad3f3SBenjamin Herrenschmidt 		r = -EINVAL;
1068bc5ad3f3SBenjamin Herrenschmidt 	}
1069bc5ad3f3SBenjamin Herrenschmidt 
1070bc5ad3f3SBenjamin Herrenschmidt 	return r;
1071bc5ad3f3SBenjamin Herrenschmidt }
1072bc5ad3f3SBenjamin Herrenschmidt 
1073bc5ad3f3SBenjamin Herrenschmidt void kvmppc_xics_free(struct kvmppc_xics *xics)
1074bc5ad3f3SBenjamin Herrenschmidt {
1075bc5ad3f3SBenjamin Herrenschmidt 	int i;
1076bc5ad3f3SBenjamin Herrenschmidt 	struct kvm *kvm = xics->kvm;
1077bc5ad3f3SBenjamin Herrenschmidt 
1078bc5ad3f3SBenjamin Herrenschmidt 	debugfs_remove(xics->dentry);
1079bc5ad3f3SBenjamin Herrenschmidt 
1080bc5ad3f3SBenjamin Herrenschmidt 	if (kvm)
1081bc5ad3f3SBenjamin Herrenschmidt 		kvm->arch.xics = NULL;
1082bc5ad3f3SBenjamin Herrenschmidt 
1083bc5ad3f3SBenjamin Herrenschmidt 	for (i = 0; i <= xics->max_icsid; i++)
1084bc5ad3f3SBenjamin Herrenschmidt 		kfree(xics->ics[i]);
1085bc5ad3f3SBenjamin Herrenschmidt 	kfree(xics);
1086bc5ad3f3SBenjamin Herrenschmidt }
1087bc5ad3f3SBenjamin Herrenschmidt 
1088bc5ad3f3SBenjamin Herrenschmidt int kvm_xics_create(struct kvm *kvm, u32 type)
1089bc5ad3f3SBenjamin Herrenschmidt {
1090bc5ad3f3SBenjamin Herrenschmidt 	struct kvmppc_xics *xics;
1091bc5ad3f3SBenjamin Herrenschmidt 	int ret = 0;
1092bc5ad3f3SBenjamin Herrenschmidt 
1093bc5ad3f3SBenjamin Herrenschmidt 	xics = kzalloc(sizeof(*xics), GFP_KERNEL);
1094bc5ad3f3SBenjamin Herrenschmidt 	if (!xics)
1095bc5ad3f3SBenjamin Herrenschmidt 		return -ENOMEM;
1096bc5ad3f3SBenjamin Herrenschmidt 
1097bc5ad3f3SBenjamin Herrenschmidt 	xics->kvm = kvm;
1098bc5ad3f3SBenjamin Herrenschmidt 
1099bc5ad3f3SBenjamin Herrenschmidt 	/* Already there ? */
1100bc5ad3f3SBenjamin Herrenschmidt 	mutex_lock(&kvm->lock);
1101bc5ad3f3SBenjamin Herrenschmidt 	if (kvm->arch.xics)
1102bc5ad3f3SBenjamin Herrenschmidt 		ret = -EEXIST;
1103bc5ad3f3SBenjamin Herrenschmidt 	else
1104bc5ad3f3SBenjamin Herrenschmidt 		kvm->arch.xics = xics;
1105bc5ad3f3SBenjamin Herrenschmidt 	mutex_unlock(&kvm->lock);
1106bc5ad3f3SBenjamin Herrenschmidt 
1107bc5ad3f3SBenjamin Herrenschmidt 	if (ret)
1108bc5ad3f3SBenjamin Herrenschmidt 		return ret;
1109bc5ad3f3SBenjamin Herrenschmidt 
1110bc5ad3f3SBenjamin Herrenschmidt 	xics_debugfs_init(xics);
1111bc5ad3f3SBenjamin Herrenschmidt 
1112e7d26f28SBenjamin Herrenschmidt #ifdef CONFIG_KVM_BOOK3S_64_HV
1113e7d26f28SBenjamin Herrenschmidt 	if (cpu_has_feature(CPU_FTR_ARCH_206)) {
1114e7d26f28SBenjamin Herrenschmidt 		/* Enable real mode support */
1115e7d26f28SBenjamin Herrenschmidt 		xics->real_mode = ENABLE_REALMODE;
1116e7d26f28SBenjamin Herrenschmidt 		xics->real_mode_dbg = DEBUG_REALMODE;
1117e7d26f28SBenjamin Herrenschmidt 	}
1118e7d26f28SBenjamin Herrenschmidt #endif /* CONFIG_KVM_BOOK3S_64_HV */
1119e7d26f28SBenjamin Herrenschmidt 
1120bc5ad3f3SBenjamin Herrenschmidt 	return 0;
1121bc5ad3f3SBenjamin Herrenschmidt }
1122bc5ad3f3SBenjamin Herrenschmidt 
1123bc5ad3f3SBenjamin Herrenschmidt void kvmppc_xics_free_icp(struct kvm_vcpu *vcpu)
1124bc5ad3f3SBenjamin Herrenschmidt {
1125bc5ad3f3SBenjamin Herrenschmidt 	if (!vcpu->arch.icp)
1126bc5ad3f3SBenjamin Herrenschmidt 		return;
1127bc5ad3f3SBenjamin Herrenschmidt 	kfree(vcpu->arch.icp);
1128bc5ad3f3SBenjamin Herrenschmidt 	vcpu->arch.icp = NULL;
1129bc5ad3f3SBenjamin Herrenschmidt 	vcpu->arch.irq_type = KVMPPC_IRQ_DEFAULT;
1130bc5ad3f3SBenjamin Herrenschmidt }
1131