xref: /openbmc/linux/drivers/s390/cio/vfio_ccw_cp.c (revision 0a19e61e6d4c6192077ead760ba0a2d350987d4c)
1*0a19e61eSDong Jia Shi /*
2*0a19e61eSDong Jia Shi  * channel program interfaces
3*0a19e61eSDong Jia Shi  *
4*0a19e61eSDong Jia Shi  * Copyright IBM Corp. 2017
5*0a19e61eSDong Jia Shi  *
6*0a19e61eSDong Jia Shi  * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
7*0a19e61eSDong Jia Shi  *            Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
8*0a19e61eSDong Jia Shi  */
9*0a19e61eSDong Jia Shi 
10*0a19e61eSDong Jia Shi #include <linux/mm.h>
11*0a19e61eSDong Jia Shi #include <linux/slab.h>
12*0a19e61eSDong Jia Shi #include <linux/iommu.h>
13*0a19e61eSDong Jia Shi #include <linux/vfio.h>
14*0a19e61eSDong Jia Shi #include <asm/idals.h>
15*0a19e61eSDong Jia Shi 
16*0a19e61eSDong Jia Shi #include "vfio_ccw_cp.h"
17*0a19e61eSDong Jia Shi 
18*0a19e61eSDong Jia Shi /*
19*0a19e61eSDong Jia Shi  * Max length for ccw chain.
20*0a19e61eSDong Jia Shi  * XXX: Limit to 256, need to check more?
21*0a19e61eSDong Jia Shi  */
22*0a19e61eSDong Jia Shi #define CCWCHAIN_LEN_MAX	256
23*0a19e61eSDong Jia Shi 
24*0a19e61eSDong Jia Shi struct pfn_array {
25*0a19e61eSDong Jia Shi 	unsigned long		pa_iova;
26*0a19e61eSDong Jia Shi 	unsigned long		*pa_iova_pfn;
27*0a19e61eSDong Jia Shi 	unsigned long		*pa_pfn;
28*0a19e61eSDong Jia Shi 	int			pa_nr;
29*0a19e61eSDong Jia Shi };
30*0a19e61eSDong Jia Shi 
31*0a19e61eSDong Jia Shi struct pfn_array_table {
32*0a19e61eSDong Jia Shi 	struct pfn_array	*pat_pa;
33*0a19e61eSDong Jia Shi 	int			pat_nr;
34*0a19e61eSDong Jia Shi };
35*0a19e61eSDong Jia Shi 
36*0a19e61eSDong Jia Shi struct ccwchain {
37*0a19e61eSDong Jia Shi 	struct list_head	next;
38*0a19e61eSDong Jia Shi 	struct ccw1		*ch_ccw;
39*0a19e61eSDong Jia Shi 	/* Guest physical address of the current chain. */
40*0a19e61eSDong Jia Shi 	u64			ch_iova;
41*0a19e61eSDong Jia Shi 	/* Count of the valid ccws in chain. */
42*0a19e61eSDong Jia Shi 	int			ch_len;
43*0a19e61eSDong Jia Shi 	/* Pinned PAGEs for the original data. */
44*0a19e61eSDong Jia Shi 	struct pfn_array_table	*ch_pat;
45*0a19e61eSDong Jia Shi };
46*0a19e61eSDong Jia Shi 
47*0a19e61eSDong Jia Shi /*
48*0a19e61eSDong Jia Shi  * pfn_array_pin() - pin user pages in memory
49*0a19e61eSDong Jia Shi  * @pa: pfn_array on which to perform the operation
50*0a19e61eSDong Jia Shi  * @mdev: the mediated device to perform pin/unpin operations
51*0a19e61eSDong Jia Shi  *
52*0a19e61eSDong Jia Shi  * Attempt to pin user pages in memory.
53*0a19e61eSDong Jia Shi  *
54*0a19e61eSDong Jia Shi  * Usage of pfn_array:
55*0a19e61eSDong Jia Shi  * @pa->pa_iova     starting guest physical I/O address. Assigned by caller.
56*0a19e61eSDong Jia Shi  * @pa->pa_iova_pfn array that stores PFNs of the pages need to pin. Allocated
57*0a19e61eSDong Jia Shi  *                  by caller.
58*0a19e61eSDong Jia Shi  * @pa->pa_pfn      array that receives PFNs of the pages pinned. Allocated by
59*0a19e61eSDong Jia Shi  *                  caller.
60*0a19e61eSDong Jia Shi  * @pa->pa_nr       number of pages from @pa->pa_iova to pin. Assigned by
61*0a19e61eSDong Jia Shi  *                  caller.
62*0a19e61eSDong Jia Shi  *                  number of pages pinned. Assigned by callee.
63*0a19e61eSDong Jia Shi  *
64*0a19e61eSDong Jia Shi  * Returns:
65*0a19e61eSDong Jia Shi  *   Number of pages pinned on success.
66*0a19e61eSDong Jia Shi  *   If @pa->pa_nr is 0 or negative, returns 0.
67*0a19e61eSDong Jia Shi  *   If no pages were pinned, returns -errno.
68*0a19e61eSDong Jia Shi  */
69*0a19e61eSDong Jia Shi static int pfn_array_pin(struct pfn_array *pa, struct device *mdev)
70*0a19e61eSDong Jia Shi {
71*0a19e61eSDong Jia Shi 	int i, ret;
72*0a19e61eSDong Jia Shi 
73*0a19e61eSDong Jia Shi 	if (pa->pa_nr <= 0) {
74*0a19e61eSDong Jia Shi 		pa->pa_nr = 0;
75*0a19e61eSDong Jia Shi 		return 0;
76*0a19e61eSDong Jia Shi 	}
77*0a19e61eSDong Jia Shi 
78*0a19e61eSDong Jia Shi 	pa->pa_iova_pfn[0] = pa->pa_iova >> PAGE_SHIFT;
79*0a19e61eSDong Jia Shi 	for (i = 1; i < pa->pa_nr; i++)
80*0a19e61eSDong Jia Shi 		pa->pa_iova_pfn[i] = pa->pa_iova_pfn[i - 1] + 1;
81*0a19e61eSDong Jia Shi 
82*0a19e61eSDong Jia Shi 	ret = vfio_pin_pages(mdev, pa->pa_iova_pfn, pa->pa_nr,
83*0a19e61eSDong Jia Shi 			     IOMMU_READ | IOMMU_WRITE, pa->pa_pfn);
84*0a19e61eSDong Jia Shi 
85*0a19e61eSDong Jia Shi 	if (ret > 0 && ret != pa->pa_nr) {
86*0a19e61eSDong Jia Shi 		vfio_unpin_pages(mdev, pa->pa_iova_pfn, ret);
87*0a19e61eSDong Jia Shi 		pa->pa_nr = 0;
88*0a19e61eSDong Jia Shi 		return 0;
89*0a19e61eSDong Jia Shi 	}
90*0a19e61eSDong Jia Shi 
91*0a19e61eSDong Jia Shi 	return ret;
92*0a19e61eSDong Jia Shi }
93*0a19e61eSDong Jia Shi 
94*0a19e61eSDong Jia Shi /* Unpin the pages before releasing the memory. */
95*0a19e61eSDong Jia Shi static void pfn_array_unpin_free(struct pfn_array *pa, struct device *mdev)
96*0a19e61eSDong Jia Shi {
97*0a19e61eSDong Jia Shi 	vfio_unpin_pages(mdev, pa->pa_iova_pfn, pa->pa_nr);
98*0a19e61eSDong Jia Shi 	pa->pa_nr = 0;
99*0a19e61eSDong Jia Shi 	kfree(pa->pa_iova_pfn);
100*0a19e61eSDong Jia Shi }
101*0a19e61eSDong Jia Shi 
102*0a19e61eSDong Jia Shi /* Alloc memory for PFNs, then pin pages with them. */
103*0a19e61eSDong Jia Shi static int pfn_array_alloc_pin(struct pfn_array *pa, struct device *mdev,
104*0a19e61eSDong Jia Shi 			       u64 iova, unsigned int len)
105*0a19e61eSDong Jia Shi {
106*0a19e61eSDong Jia Shi 	int ret = 0;
107*0a19e61eSDong Jia Shi 
108*0a19e61eSDong Jia Shi 	if (!len || pa->pa_nr)
109*0a19e61eSDong Jia Shi 		return -EINVAL;
110*0a19e61eSDong Jia Shi 
111*0a19e61eSDong Jia Shi 	pa->pa_iova = iova;
112*0a19e61eSDong Jia Shi 
113*0a19e61eSDong Jia Shi 	pa->pa_nr = ((iova & ~PAGE_MASK) + len + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
114*0a19e61eSDong Jia Shi 	if (!pa->pa_nr)
115*0a19e61eSDong Jia Shi 		return -EINVAL;
116*0a19e61eSDong Jia Shi 
117*0a19e61eSDong Jia Shi 	pa->pa_iova_pfn = kcalloc(pa->pa_nr,
118*0a19e61eSDong Jia Shi 				  sizeof(*pa->pa_iova_pfn) +
119*0a19e61eSDong Jia Shi 				  sizeof(*pa->pa_pfn),
120*0a19e61eSDong Jia Shi 				  GFP_KERNEL);
121*0a19e61eSDong Jia Shi 	if (unlikely(!pa->pa_iova_pfn))
122*0a19e61eSDong Jia Shi 		return -ENOMEM;
123*0a19e61eSDong Jia Shi 	pa->pa_pfn = pa->pa_iova_pfn + pa->pa_nr;
124*0a19e61eSDong Jia Shi 
125*0a19e61eSDong Jia Shi 	ret = pfn_array_pin(pa, mdev);
126*0a19e61eSDong Jia Shi 
127*0a19e61eSDong Jia Shi 	if (ret > 0)
128*0a19e61eSDong Jia Shi 		return ret;
129*0a19e61eSDong Jia Shi 	else if (!ret)
130*0a19e61eSDong Jia Shi 		ret = -EINVAL;
131*0a19e61eSDong Jia Shi 
132*0a19e61eSDong Jia Shi 	kfree(pa->pa_iova_pfn);
133*0a19e61eSDong Jia Shi 
134*0a19e61eSDong Jia Shi 	return ret;
135*0a19e61eSDong Jia Shi }
136*0a19e61eSDong Jia Shi 
137*0a19e61eSDong Jia Shi static int pfn_array_table_init(struct pfn_array_table *pat, int nr)
138*0a19e61eSDong Jia Shi {
139*0a19e61eSDong Jia Shi 	pat->pat_pa = kcalloc(nr, sizeof(*pat->pat_pa), GFP_KERNEL);
140*0a19e61eSDong Jia Shi 	if (unlikely(ZERO_OR_NULL_PTR(pat->pat_pa))) {
141*0a19e61eSDong Jia Shi 		pat->pat_nr = 0;
142*0a19e61eSDong Jia Shi 		return -ENOMEM;
143*0a19e61eSDong Jia Shi 	}
144*0a19e61eSDong Jia Shi 
145*0a19e61eSDong Jia Shi 	pat->pat_nr = nr;
146*0a19e61eSDong Jia Shi 
147*0a19e61eSDong Jia Shi 	return 0;
148*0a19e61eSDong Jia Shi }
149*0a19e61eSDong Jia Shi 
150*0a19e61eSDong Jia Shi static void pfn_array_table_unpin_free(struct pfn_array_table *pat,
151*0a19e61eSDong Jia Shi 				       struct device *mdev)
152*0a19e61eSDong Jia Shi {
153*0a19e61eSDong Jia Shi 	int i;
154*0a19e61eSDong Jia Shi 
155*0a19e61eSDong Jia Shi 	for (i = 0; i < pat->pat_nr; i++)
156*0a19e61eSDong Jia Shi 		pfn_array_unpin_free(pat->pat_pa + i, mdev);
157*0a19e61eSDong Jia Shi 
158*0a19e61eSDong Jia Shi 	if (pat->pat_nr) {
159*0a19e61eSDong Jia Shi 		kfree(pat->pat_pa);
160*0a19e61eSDong Jia Shi 		pat->pat_pa = NULL;
161*0a19e61eSDong Jia Shi 		pat->pat_nr = 0;
162*0a19e61eSDong Jia Shi 	}
163*0a19e61eSDong Jia Shi }
164*0a19e61eSDong Jia Shi 
165*0a19e61eSDong Jia Shi static bool pfn_array_table_iova_pinned(struct pfn_array_table *pat,
166*0a19e61eSDong Jia Shi 					unsigned long iova)
167*0a19e61eSDong Jia Shi {
168*0a19e61eSDong Jia Shi 	struct pfn_array *pa = pat->pat_pa;
169*0a19e61eSDong Jia Shi 	unsigned long iova_pfn = iova >> PAGE_SHIFT;
170*0a19e61eSDong Jia Shi 	int i, j;
171*0a19e61eSDong Jia Shi 
172*0a19e61eSDong Jia Shi 	for (i = 0; i < pat->pat_nr; i++, pa++)
173*0a19e61eSDong Jia Shi 		for (j = 0; j < pa->pa_nr; j++)
174*0a19e61eSDong Jia Shi 			if (pa->pa_iova_pfn[i] == iova_pfn)
175*0a19e61eSDong Jia Shi 				return true;
176*0a19e61eSDong Jia Shi 
177*0a19e61eSDong Jia Shi 	return false;
178*0a19e61eSDong Jia Shi }
179*0a19e61eSDong Jia Shi /* Create the list idal words for a pfn_array_table. */
180*0a19e61eSDong Jia Shi static inline void pfn_array_table_idal_create_words(
181*0a19e61eSDong Jia Shi 	struct pfn_array_table *pat,
182*0a19e61eSDong Jia Shi 	unsigned long *idaws)
183*0a19e61eSDong Jia Shi {
184*0a19e61eSDong Jia Shi 	struct pfn_array *pa;
185*0a19e61eSDong Jia Shi 	int i, j, k;
186*0a19e61eSDong Jia Shi 
187*0a19e61eSDong Jia Shi 	/*
188*0a19e61eSDong Jia Shi 	 * Idal words (execept the first one) rely on the memory being 4k
189*0a19e61eSDong Jia Shi 	 * aligned. If a user virtual address is 4K aligned, then it's
190*0a19e61eSDong Jia Shi 	 * corresponding kernel physical address will also be 4K aligned. Thus
191*0a19e61eSDong Jia Shi 	 * there will be no problem here to simply use the phys to create an
192*0a19e61eSDong Jia Shi 	 * idaw.
193*0a19e61eSDong Jia Shi 	 */
194*0a19e61eSDong Jia Shi 	k = 0;
195*0a19e61eSDong Jia Shi 	for (i = 0; i < pat->pat_nr; i++) {
196*0a19e61eSDong Jia Shi 		pa = pat->pat_pa + i;
197*0a19e61eSDong Jia Shi 		for (j = 0; j < pa->pa_nr; j++) {
198*0a19e61eSDong Jia Shi 			idaws[k] = pa->pa_pfn[j] << PAGE_SHIFT;
199*0a19e61eSDong Jia Shi 			if (k == 0)
200*0a19e61eSDong Jia Shi 				idaws[k] += pa->pa_iova & (PAGE_SIZE - 1);
201*0a19e61eSDong Jia Shi 			k++;
202*0a19e61eSDong Jia Shi 		}
203*0a19e61eSDong Jia Shi 	}
204*0a19e61eSDong Jia Shi }
205*0a19e61eSDong Jia Shi 
206*0a19e61eSDong Jia Shi 
207*0a19e61eSDong Jia Shi /*
208*0a19e61eSDong Jia Shi  * Within the domain (@mdev), copy @n bytes from a guest physical
209*0a19e61eSDong Jia Shi  * address (@iova) to a host physical address (@to).
210*0a19e61eSDong Jia Shi  */
211*0a19e61eSDong Jia Shi static long copy_from_iova(struct device *mdev,
212*0a19e61eSDong Jia Shi 			   void *to, u64 iova,
213*0a19e61eSDong Jia Shi 			   unsigned long n)
214*0a19e61eSDong Jia Shi {
215*0a19e61eSDong Jia Shi 	struct pfn_array pa = {0};
216*0a19e61eSDong Jia Shi 	u64 from;
217*0a19e61eSDong Jia Shi 	int i, ret;
218*0a19e61eSDong Jia Shi 	unsigned long l, m;
219*0a19e61eSDong Jia Shi 
220*0a19e61eSDong Jia Shi 	ret = pfn_array_alloc_pin(&pa, mdev, iova, n);
221*0a19e61eSDong Jia Shi 	if (ret <= 0)
222*0a19e61eSDong Jia Shi 		return ret;
223*0a19e61eSDong Jia Shi 
224*0a19e61eSDong Jia Shi 	l = n;
225*0a19e61eSDong Jia Shi 	for (i = 0; i < pa.pa_nr; i++) {
226*0a19e61eSDong Jia Shi 		from = pa.pa_pfn[i] << PAGE_SHIFT;
227*0a19e61eSDong Jia Shi 		m = PAGE_SIZE;
228*0a19e61eSDong Jia Shi 		if (i == 0) {
229*0a19e61eSDong Jia Shi 			from += iova & (PAGE_SIZE - 1);
230*0a19e61eSDong Jia Shi 			m -= iova & (PAGE_SIZE - 1);
231*0a19e61eSDong Jia Shi 		}
232*0a19e61eSDong Jia Shi 
233*0a19e61eSDong Jia Shi 		m = min(l, m);
234*0a19e61eSDong Jia Shi 		memcpy(to + (n - l), (void *)from, m);
235*0a19e61eSDong Jia Shi 
236*0a19e61eSDong Jia Shi 		l -= m;
237*0a19e61eSDong Jia Shi 		if (l == 0)
238*0a19e61eSDong Jia Shi 			break;
239*0a19e61eSDong Jia Shi 	}
240*0a19e61eSDong Jia Shi 
241*0a19e61eSDong Jia Shi 	pfn_array_unpin_free(&pa, mdev);
242*0a19e61eSDong Jia Shi 
243*0a19e61eSDong Jia Shi 	return l;
244*0a19e61eSDong Jia Shi }
245*0a19e61eSDong Jia Shi 
246*0a19e61eSDong Jia Shi static long copy_ccw_from_iova(struct channel_program *cp,
247*0a19e61eSDong Jia Shi 			       struct ccw1 *to, u64 iova,
248*0a19e61eSDong Jia Shi 			       unsigned long len)
249*0a19e61eSDong Jia Shi {
250*0a19e61eSDong Jia Shi 	return copy_from_iova(cp->mdev, to, iova, len * sizeof(struct ccw1));
251*0a19e61eSDong Jia Shi }
252*0a19e61eSDong Jia Shi 
253*0a19e61eSDong Jia Shi /*
254*0a19e61eSDong Jia Shi  * Helpers to operate ccwchain.
255*0a19e61eSDong Jia Shi  */
256*0a19e61eSDong Jia Shi #define ccw_is_test(_ccw) (((_ccw)->cmd_code & 0x0F) == 0)
257*0a19e61eSDong Jia Shi 
258*0a19e61eSDong Jia Shi #define ccw_is_noop(_ccw) ((_ccw)->cmd_code == CCW_CMD_NOOP)
259*0a19e61eSDong Jia Shi 
260*0a19e61eSDong Jia Shi #define ccw_is_tic(_ccw) ((_ccw)->cmd_code == CCW_CMD_TIC)
261*0a19e61eSDong Jia Shi 
262*0a19e61eSDong Jia Shi #define ccw_is_idal(_ccw) ((_ccw)->flags & CCW_FLAG_IDA)
263*0a19e61eSDong Jia Shi 
264*0a19e61eSDong Jia Shi 
265*0a19e61eSDong Jia Shi #define ccw_is_chain(_ccw) ((_ccw)->flags & (CCW_FLAG_CC | CCW_FLAG_DC))
266*0a19e61eSDong Jia Shi 
267*0a19e61eSDong Jia Shi static struct ccwchain *ccwchain_alloc(struct channel_program *cp, int len)
268*0a19e61eSDong Jia Shi {
269*0a19e61eSDong Jia Shi 	struct ccwchain *chain;
270*0a19e61eSDong Jia Shi 	void *data;
271*0a19e61eSDong Jia Shi 	size_t size;
272*0a19e61eSDong Jia Shi 
273*0a19e61eSDong Jia Shi 	/* Make ccw address aligned to 8. */
274*0a19e61eSDong Jia Shi 	size = ((sizeof(*chain) + 7L) & -8L) +
275*0a19e61eSDong Jia Shi 		sizeof(*chain->ch_ccw) * len +
276*0a19e61eSDong Jia Shi 		sizeof(*chain->ch_pat) * len;
277*0a19e61eSDong Jia Shi 	chain = kzalloc(size, GFP_DMA | GFP_KERNEL);
278*0a19e61eSDong Jia Shi 	if (!chain)
279*0a19e61eSDong Jia Shi 		return NULL;
280*0a19e61eSDong Jia Shi 
281*0a19e61eSDong Jia Shi 	data = (u8 *)chain + ((sizeof(*chain) + 7L) & -8L);
282*0a19e61eSDong Jia Shi 	chain->ch_ccw = (struct ccw1 *)data;
283*0a19e61eSDong Jia Shi 
284*0a19e61eSDong Jia Shi 	data = (u8 *)(chain->ch_ccw) + sizeof(*chain->ch_ccw) * len;
285*0a19e61eSDong Jia Shi 	chain->ch_pat = (struct pfn_array_table *)data;
286*0a19e61eSDong Jia Shi 
287*0a19e61eSDong Jia Shi 	chain->ch_len = len;
288*0a19e61eSDong Jia Shi 
289*0a19e61eSDong Jia Shi 	list_add_tail(&chain->next, &cp->ccwchain_list);
290*0a19e61eSDong Jia Shi 
291*0a19e61eSDong Jia Shi 	return chain;
292*0a19e61eSDong Jia Shi }
293*0a19e61eSDong Jia Shi 
294*0a19e61eSDong Jia Shi static void ccwchain_free(struct ccwchain *chain)
295*0a19e61eSDong Jia Shi {
296*0a19e61eSDong Jia Shi 	list_del(&chain->next);
297*0a19e61eSDong Jia Shi 	kfree(chain);
298*0a19e61eSDong Jia Shi }
299*0a19e61eSDong Jia Shi 
300*0a19e61eSDong Jia Shi /* Free resource for a ccw that allocated memory for its cda. */
301*0a19e61eSDong Jia Shi static void ccwchain_cda_free(struct ccwchain *chain, int idx)
302*0a19e61eSDong Jia Shi {
303*0a19e61eSDong Jia Shi 	struct ccw1 *ccw = chain->ch_ccw + idx;
304*0a19e61eSDong Jia Shi 
305*0a19e61eSDong Jia Shi 	if (!ccw->count)
306*0a19e61eSDong Jia Shi 		return;
307*0a19e61eSDong Jia Shi 
308*0a19e61eSDong Jia Shi 	kfree((void *)(u64)ccw->cda);
309*0a19e61eSDong Jia Shi }
310*0a19e61eSDong Jia Shi 
311*0a19e61eSDong Jia Shi /* Unpin the pages then free the memory resources. */
312*0a19e61eSDong Jia Shi static void cp_unpin_free(struct channel_program *cp)
313*0a19e61eSDong Jia Shi {
314*0a19e61eSDong Jia Shi 	struct ccwchain *chain, *temp;
315*0a19e61eSDong Jia Shi 	int i;
316*0a19e61eSDong Jia Shi 
317*0a19e61eSDong Jia Shi 	list_for_each_entry_safe(chain, temp, &cp->ccwchain_list, next) {
318*0a19e61eSDong Jia Shi 		for (i = 0; i < chain->ch_len; i++) {
319*0a19e61eSDong Jia Shi 			pfn_array_table_unpin_free(chain->ch_pat + i,
320*0a19e61eSDong Jia Shi 						   cp->mdev);
321*0a19e61eSDong Jia Shi 			ccwchain_cda_free(chain, i);
322*0a19e61eSDong Jia Shi 		}
323*0a19e61eSDong Jia Shi 		ccwchain_free(chain);
324*0a19e61eSDong Jia Shi 	}
325*0a19e61eSDong Jia Shi }
326*0a19e61eSDong Jia Shi 
327*0a19e61eSDong Jia Shi /**
328*0a19e61eSDong Jia Shi  * ccwchain_calc_length - calculate the length of the ccw chain.
329*0a19e61eSDong Jia Shi  * @iova: guest physical address of the target ccw chain
330*0a19e61eSDong Jia Shi  * @cp: channel_program on which to perform the operation
331*0a19e61eSDong Jia Shi  *
332*0a19e61eSDong Jia Shi  * This is the chain length not considering any TICs.
333*0a19e61eSDong Jia Shi  * You need to do a new round for each TIC target.
334*0a19e61eSDong Jia Shi  *
335*0a19e61eSDong Jia Shi  * Returns: the length of the ccw chain or -errno.
336*0a19e61eSDong Jia Shi  */
337*0a19e61eSDong Jia Shi static int ccwchain_calc_length(u64 iova, struct channel_program *cp)
338*0a19e61eSDong Jia Shi {
339*0a19e61eSDong Jia Shi 	struct ccw1 *ccw, *p;
340*0a19e61eSDong Jia Shi 	int cnt;
341*0a19e61eSDong Jia Shi 
342*0a19e61eSDong Jia Shi 	/*
343*0a19e61eSDong Jia Shi 	 * Copy current chain from guest to host kernel.
344*0a19e61eSDong Jia Shi 	 * Currently the chain length is limited to CCWCHAIN_LEN_MAX (256).
345*0a19e61eSDong Jia Shi 	 * So copying 2K is enough (safe).
346*0a19e61eSDong Jia Shi 	 */
347*0a19e61eSDong Jia Shi 	p = ccw = kcalloc(CCWCHAIN_LEN_MAX, sizeof(*ccw), GFP_KERNEL);
348*0a19e61eSDong Jia Shi 	if (!ccw)
349*0a19e61eSDong Jia Shi 		return -ENOMEM;
350*0a19e61eSDong Jia Shi 
351*0a19e61eSDong Jia Shi 	cnt = copy_ccw_from_iova(cp, ccw, iova, CCWCHAIN_LEN_MAX);
352*0a19e61eSDong Jia Shi 	if (cnt) {
353*0a19e61eSDong Jia Shi 		kfree(ccw);
354*0a19e61eSDong Jia Shi 		return cnt;
355*0a19e61eSDong Jia Shi 	}
356*0a19e61eSDong Jia Shi 
357*0a19e61eSDong Jia Shi 	cnt = 0;
358*0a19e61eSDong Jia Shi 	do {
359*0a19e61eSDong Jia Shi 		cnt++;
360*0a19e61eSDong Jia Shi 
361*0a19e61eSDong Jia Shi 		if ((!ccw_is_chain(ccw)) && (!ccw_is_tic(ccw)))
362*0a19e61eSDong Jia Shi 			break;
363*0a19e61eSDong Jia Shi 
364*0a19e61eSDong Jia Shi 		ccw++;
365*0a19e61eSDong Jia Shi 	} while (cnt < CCWCHAIN_LEN_MAX + 1);
366*0a19e61eSDong Jia Shi 
367*0a19e61eSDong Jia Shi 	if (cnt == CCWCHAIN_LEN_MAX + 1)
368*0a19e61eSDong Jia Shi 		cnt = -EINVAL;
369*0a19e61eSDong Jia Shi 
370*0a19e61eSDong Jia Shi 	kfree(p);
371*0a19e61eSDong Jia Shi 	return cnt;
372*0a19e61eSDong Jia Shi }
373*0a19e61eSDong Jia Shi 
374*0a19e61eSDong Jia Shi static int tic_target_chain_exists(struct ccw1 *tic, struct channel_program *cp)
375*0a19e61eSDong Jia Shi {
376*0a19e61eSDong Jia Shi 	struct ccwchain *chain;
377*0a19e61eSDong Jia Shi 	u32 ccw_head, ccw_tail;
378*0a19e61eSDong Jia Shi 
379*0a19e61eSDong Jia Shi 	list_for_each_entry(chain, &cp->ccwchain_list, next) {
380*0a19e61eSDong Jia Shi 		ccw_head = chain->ch_iova;
381*0a19e61eSDong Jia Shi 		ccw_tail = ccw_head + (chain->ch_len - 1) * sizeof(struct ccw1);
382*0a19e61eSDong Jia Shi 
383*0a19e61eSDong Jia Shi 		if ((ccw_head <= tic->cda) && (tic->cda <= ccw_tail))
384*0a19e61eSDong Jia Shi 			return 1;
385*0a19e61eSDong Jia Shi 	}
386*0a19e61eSDong Jia Shi 
387*0a19e61eSDong Jia Shi 	return 0;
388*0a19e61eSDong Jia Shi }
389*0a19e61eSDong Jia Shi 
390*0a19e61eSDong Jia Shi static int ccwchain_loop_tic(struct ccwchain *chain,
391*0a19e61eSDong Jia Shi 			     struct channel_program *cp);
392*0a19e61eSDong Jia Shi 
393*0a19e61eSDong Jia Shi static int ccwchain_handle_tic(struct ccw1 *tic, struct channel_program *cp)
394*0a19e61eSDong Jia Shi {
395*0a19e61eSDong Jia Shi 	struct ccwchain *chain;
396*0a19e61eSDong Jia Shi 	int len, ret;
397*0a19e61eSDong Jia Shi 
398*0a19e61eSDong Jia Shi 	/* May transfer to an existing chain. */
399*0a19e61eSDong Jia Shi 	if (tic_target_chain_exists(tic, cp))
400*0a19e61eSDong Jia Shi 		return 0;
401*0a19e61eSDong Jia Shi 
402*0a19e61eSDong Jia Shi 	/* Get chain length. */
403*0a19e61eSDong Jia Shi 	len = ccwchain_calc_length(tic->cda, cp);
404*0a19e61eSDong Jia Shi 	if (len < 0)
405*0a19e61eSDong Jia Shi 		return len;
406*0a19e61eSDong Jia Shi 
407*0a19e61eSDong Jia Shi 	/* Need alloc a new chain for this one. */
408*0a19e61eSDong Jia Shi 	chain = ccwchain_alloc(cp, len);
409*0a19e61eSDong Jia Shi 	if (!chain)
410*0a19e61eSDong Jia Shi 		return -ENOMEM;
411*0a19e61eSDong Jia Shi 	chain->ch_iova = tic->cda;
412*0a19e61eSDong Jia Shi 
413*0a19e61eSDong Jia Shi 	/* Copy the new chain from user. */
414*0a19e61eSDong Jia Shi 	ret = copy_ccw_from_iova(cp, chain->ch_ccw, tic->cda, len);
415*0a19e61eSDong Jia Shi 	if (ret) {
416*0a19e61eSDong Jia Shi 		ccwchain_free(chain);
417*0a19e61eSDong Jia Shi 		return ret;
418*0a19e61eSDong Jia Shi 	}
419*0a19e61eSDong Jia Shi 
420*0a19e61eSDong Jia Shi 	/* Loop for tics on this new chain. */
421*0a19e61eSDong Jia Shi 	return ccwchain_loop_tic(chain, cp);
422*0a19e61eSDong Jia Shi }
423*0a19e61eSDong Jia Shi 
424*0a19e61eSDong Jia Shi /* Loop for TICs. */
425*0a19e61eSDong Jia Shi static int ccwchain_loop_tic(struct ccwchain *chain, struct channel_program *cp)
426*0a19e61eSDong Jia Shi {
427*0a19e61eSDong Jia Shi 	struct ccw1 *tic;
428*0a19e61eSDong Jia Shi 	int i, ret;
429*0a19e61eSDong Jia Shi 
430*0a19e61eSDong Jia Shi 	for (i = 0; i < chain->ch_len; i++) {
431*0a19e61eSDong Jia Shi 		tic = chain->ch_ccw + i;
432*0a19e61eSDong Jia Shi 
433*0a19e61eSDong Jia Shi 		if (!ccw_is_tic(tic))
434*0a19e61eSDong Jia Shi 			continue;
435*0a19e61eSDong Jia Shi 
436*0a19e61eSDong Jia Shi 		ret = ccwchain_handle_tic(tic, cp);
437*0a19e61eSDong Jia Shi 		if (ret)
438*0a19e61eSDong Jia Shi 			return ret;
439*0a19e61eSDong Jia Shi 	}
440*0a19e61eSDong Jia Shi 
441*0a19e61eSDong Jia Shi 	return 0;
442*0a19e61eSDong Jia Shi }
443*0a19e61eSDong Jia Shi 
444*0a19e61eSDong Jia Shi static int ccwchain_fetch_tic(struct ccwchain *chain,
445*0a19e61eSDong Jia Shi 			      int idx,
446*0a19e61eSDong Jia Shi 			      struct channel_program *cp)
447*0a19e61eSDong Jia Shi {
448*0a19e61eSDong Jia Shi 	struct ccw1 *ccw = chain->ch_ccw + idx;
449*0a19e61eSDong Jia Shi 	struct ccwchain *iter;
450*0a19e61eSDong Jia Shi 	u32 ccw_head, ccw_tail;
451*0a19e61eSDong Jia Shi 
452*0a19e61eSDong Jia Shi 	list_for_each_entry(iter, &cp->ccwchain_list, next) {
453*0a19e61eSDong Jia Shi 		ccw_head = iter->ch_iova;
454*0a19e61eSDong Jia Shi 		ccw_tail = ccw_head + (iter->ch_len - 1) * sizeof(struct ccw1);
455*0a19e61eSDong Jia Shi 
456*0a19e61eSDong Jia Shi 		if ((ccw_head <= ccw->cda) && (ccw->cda <= ccw_tail)) {
457*0a19e61eSDong Jia Shi 			ccw->cda = (__u32) (addr_t) (iter->ch_ccw +
458*0a19e61eSDong Jia Shi 						     (ccw->cda - ccw_head));
459*0a19e61eSDong Jia Shi 			return 0;
460*0a19e61eSDong Jia Shi 		}
461*0a19e61eSDong Jia Shi 	}
462*0a19e61eSDong Jia Shi 
463*0a19e61eSDong Jia Shi 	return -EFAULT;
464*0a19e61eSDong Jia Shi }
465*0a19e61eSDong Jia Shi 
466*0a19e61eSDong Jia Shi static int ccwchain_fetch_direct(struct ccwchain *chain,
467*0a19e61eSDong Jia Shi 				 int idx,
468*0a19e61eSDong Jia Shi 				 struct channel_program *cp)
469*0a19e61eSDong Jia Shi {
470*0a19e61eSDong Jia Shi 	struct ccw1 *ccw;
471*0a19e61eSDong Jia Shi 	struct pfn_array_table *pat;
472*0a19e61eSDong Jia Shi 	unsigned long *idaws;
473*0a19e61eSDong Jia Shi 	int idaw_nr;
474*0a19e61eSDong Jia Shi 
475*0a19e61eSDong Jia Shi 	ccw = chain->ch_ccw + idx;
476*0a19e61eSDong Jia Shi 
477*0a19e61eSDong Jia Shi 	/*
478*0a19e61eSDong Jia Shi 	 * Pin data page(s) in memory.
479*0a19e61eSDong Jia Shi 	 * The number of pages actually is the count of the idaws which will be
480*0a19e61eSDong Jia Shi 	 * needed when translating a direct ccw to a idal ccw.
481*0a19e61eSDong Jia Shi 	 */
482*0a19e61eSDong Jia Shi 	pat = chain->ch_pat + idx;
483*0a19e61eSDong Jia Shi 	if (pfn_array_table_init(pat, 1))
484*0a19e61eSDong Jia Shi 		return -ENOMEM;
485*0a19e61eSDong Jia Shi 	idaw_nr = pfn_array_alloc_pin(pat->pat_pa, cp->mdev,
486*0a19e61eSDong Jia Shi 				      ccw->cda, ccw->count);
487*0a19e61eSDong Jia Shi 	if (idaw_nr < 0)
488*0a19e61eSDong Jia Shi 		return idaw_nr;
489*0a19e61eSDong Jia Shi 
490*0a19e61eSDong Jia Shi 	/* Translate this direct ccw to a idal ccw. */
491*0a19e61eSDong Jia Shi 	idaws = kcalloc(idaw_nr, sizeof(*idaws), GFP_DMA | GFP_KERNEL);
492*0a19e61eSDong Jia Shi 	if (!idaws) {
493*0a19e61eSDong Jia Shi 		pfn_array_table_unpin_free(pat, cp->mdev);
494*0a19e61eSDong Jia Shi 		return -ENOMEM;
495*0a19e61eSDong Jia Shi 	}
496*0a19e61eSDong Jia Shi 	ccw->cda = (__u32) virt_to_phys(idaws);
497*0a19e61eSDong Jia Shi 	ccw->flags |= CCW_FLAG_IDA;
498*0a19e61eSDong Jia Shi 
499*0a19e61eSDong Jia Shi 	pfn_array_table_idal_create_words(pat, idaws);
500*0a19e61eSDong Jia Shi 
501*0a19e61eSDong Jia Shi 	return 0;
502*0a19e61eSDong Jia Shi }
503*0a19e61eSDong Jia Shi 
504*0a19e61eSDong Jia Shi static int ccwchain_fetch_idal(struct ccwchain *chain,
505*0a19e61eSDong Jia Shi 			       int idx,
506*0a19e61eSDong Jia Shi 			       struct channel_program *cp)
507*0a19e61eSDong Jia Shi {
508*0a19e61eSDong Jia Shi 	struct ccw1 *ccw;
509*0a19e61eSDong Jia Shi 	struct pfn_array_table *pat;
510*0a19e61eSDong Jia Shi 	unsigned long *idaws;
511*0a19e61eSDong Jia Shi 	u64 idaw_iova;
512*0a19e61eSDong Jia Shi 	unsigned int idaw_nr, idaw_len;
513*0a19e61eSDong Jia Shi 	int i, ret;
514*0a19e61eSDong Jia Shi 
515*0a19e61eSDong Jia Shi 	ccw = chain->ch_ccw + idx;
516*0a19e61eSDong Jia Shi 
517*0a19e61eSDong Jia Shi 	/* Calculate size of idaws. */
518*0a19e61eSDong Jia Shi 	ret = copy_from_iova(cp->mdev, &idaw_iova, ccw->cda, sizeof(idaw_iova));
519*0a19e61eSDong Jia Shi 	if (ret)
520*0a19e61eSDong Jia Shi 		return ret;
521*0a19e61eSDong Jia Shi 	idaw_nr = idal_nr_words((void *)(idaw_iova), ccw->count);
522*0a19e61eSDong Jia Shi 	idaw_len = idaw_nr * sizeof(*idaws);
523*0a19e61eSDong Jia Shi 
524*0a19e61eSDong Jia Shi 	/* Pin data page(s) in memory. */
525*0a19e61eSDong Jia Shi 	pat = chain->ch_pat + idx;
526*0a19e61eSDong Jia Shi 	ret = pfn_array_table_init(pat, idaw_nr);
527*0a19e61eSDong Jia Shi 	if (ret)
528*0a19e61eSDong Jia Shi 		return ret;
529*0a19e61eSDong Jia Shi 
530*0a19e61eSDong Jia Shi 	/* Translate idal ccw to use new allocated idaws. */
531*0a19e61eSDong Jia Shi 	idaws = kzalloc(idaw_len, GFP_DMA | GFP_KERNEL);
532*0a19e61eSDong Jia Shi 	if (!idaws) {
533*0a19e61eSDong Jia Shi 		ret = -ENOMEM;
534*0a19e61eSDong Jia Shi 		goto out_unpin;
535*0a19e61eSDong Jia Shi 	}
536*0a19e61eSDong Jia Shi 
537*0a19e61eSDong Jia Shi 	ret = copy_from_iova(cp->mdev, idaws, ccw->cda, idaw_len);
538*0a19e61eSDong Jia Shi 	if (ret)
539*0a19e61eSDong Jia Shi 		goto out_free_idaws;
540*0a19e61eSDong Jia Shi 
541*0a19e61eSDong Jia Shi 	ccw->cda = virt_to_phys(idaws);
542*0a19e61eSDong Jia Shi 
543*0a19e61eSDong Jia Shi 	for (i = 0; i < idaw_nr; i++) {
544*0a19e61eSDong Jia Shi 		idaw_iova = *(idaws + i);
545*0a19e61eSDong Jia Shi 		if (IS_ERR_VALUE(idaw_iova)) {
546*0a19e61eSDong Jia Shi 			ret = -EFAULT;
547*0a19e61eSDong Jia Shi 			goto out_free_idaws;
548*0a19e61eSDong Jia Shi 		}
549*0a19e61eSDong Jia Shi 
550*0a19e61eSDong Jia Shi 		ret = pfn_array_alloc_pin(pat->pat_pa + i, cp->mdev,
551*0a19e61eSDong Jia Shi 					  idaw_iova, 1);
552*0a19e61eSDong Jia Shi 		if (ret < 0)
553*0a19e61eSDong Jia Shi 			goto out_free_idaws;
554*0a19e61eSDong Jia Shi 	}
555*0a19e61eSDong Jia Shi 
556*0a19e61eSDong Jia Shi 	pfn_array_table_idal_create_words(pat, idaws);
557*0a19e61eSDong Jia Shi 
558*0a19e61eSDong Jia Shi 	return 0;
559*0a19e61eSDong Jia Shi 
560*0a19e61eSDong Jia Shi out_free_idaws:
561*0a19e61eSDong Jia Shi 	kfree(idaws);
562*0a19e61eSDong Jia Shi out_unpin:
563*0a19e61eSDong Jia Shi 	pfn_array_table_unpin_free(pat, cp->mdev);
564*0a19e61eSDong Jia Shi 	return ret;
565*0a19e61eSDong Jia Shi }
566*0a19e61eSDong Jia Shi 
567*0a19e61eSDong Jia Shi /*
568*0a19e61eSDong Jia Shi  * Fetch one ccw.
569*0a19e61eSDong Jia Shi  * To reduce memory copy, we'll pin the cda page in memory,
570*0a19e61eSDong Jia Shi  * and to get rid of the cda 2G limitiaion of ccw1, we'll translate
571*0a19e61eSDong Jia Shi  * direct ccws to idal ccws.
572*0a19e61eSDong Jia Shi  */
573*0a19e61eSDong Jia Shi static int ccwchain_fetch_one(struct ccwchain *chain,
574*0a19e61eSDong Jia Shi 			      int idx,
575*0a19e61eSDong Jia Shi 			      struct channel_program *cp)
576*0a19e61eSDong Jia Shi {
577*0a19e61eSDong Jia Shi 	struct ccw1 *ccw = chain->ch_ccw + idx;
578*0a19e61eSDong Jia Shi 
579*0a19e61eSDong Jia Shi 	if (ccw_is_test(ccw) || ccw_is_noop(ccw))
580*0a19e61eSDong Jia Shi 		return 0;
581*0a19e61eSDong Jia Shi 
582*0a19e61eSDong Jia Shi 	if (ccw_is_tic(ccw))
583*0a19e61eSDong Jia Shi 		return ccwchain_fetch_tic(chain, idx, cp);
584*0a19e61eSDong Jia Shi 
585*0a19e61eSDong Jia Shi 	if (ccw_is_idal(ccw))
586*0a19e61eSDong Jia Shi 		return ccwchain_fetch_idal(chain, idx, cp);
587*0a19e61eSDong Jia Shi 
588*0a19e61eSDong Jia Shi 	return ccwchain_fetch_direct(chain, idx, cp);
589*0a19e61eSDong Jia Shi }
590*0a19e61eSDong Jia Shi 
591*0a19e61eSDong Jia Shi /**
592*0a19e61eSDong Jia Shi  * cp_init() - allocate ccwchains for a channel program.
593*0a19e61eSDong Jia Shi  * @cp: channel_program on which to perform the operation
594*0a19e61eSDong Jia Shi  * @mdev: the mediated device to perform pin/unpin operations
595*0a19e61eSDong Jia Shi  * @orb: control block for the channel program from the guest
596*0a19e61eSDong Jia Shi  *
597*0a19e61eSDong Jia Shi  * This creates one or more ccwchain(s), and copies the raw data of
598*0a19e61eSDong Jia Shi  * the target channel program from @orb->cmd.iova to the new ccwchain(s).
599*0a19e61eSDong Jia Shi  *
600*0a19e61eSDong Jia Shi  * Limitations:
601*0a19e61eSDong Jia Shi  * 1. Supports only prefetch enabled mode.
602*0a19e61eSDong Jia Shi  * 2. Supports idal(c64) ccw chaining.
603*0a19e61eSDong Jia Shi  * 3. Supports 4k idaw.
604*0a19e61eSDong Jia Shi  *
605*0a19e61eSDong Jia Shi  * Returns:
606*0a19e61eSDong Jia Shi  *   %0 on success and a negative error value on failure.
607*0a19e61eSDong Jia Shi  */
608*0a19e61eSDong Jia Shi int cp_init(struct channel_program *cp, struct device *mdev, union orb *orb)
609*0a19e61eSDong Jia Shi {
610*0a19e61eSDong Jia Shi 	u64 iova = orb->cmd.cpa;
611*0a19e61eSDong Jia Shi 	struct ccwchain *chain;
612*0a19e61eSDong Jia Shi 	int len, ret;
613*0a19e61eSDong Jia Shi 
614*0a19e61eSDong Jia Shi 	/*
615*0a19e61eSDong Jia Shi 	 * XXX:
616*0a19e61eSDong Jia Shi 	 * Only support prefetch enable mode now.
617*0a19e61eSDong Jia Shi 	 * Only support 64bit addressing idal.
618*0a19e61eSDong Jia Shi 	 * Only support 4k IDAW.
619*0a19e61eSDong Jia Shi 	 * Only support ccw1.
620*0a19e61eSDong Jia Shi 	 */
621*0a19e61eSDong Jia Shi 	if (!orb->cmd.pfch || !orb->cmd.c64 || orb->cmd.i2k || !orb->cmd.fmt)
622*0a19e61eSDong Jia Shi 		return -EOPNOTSUPP;
623*0a19e61eSDong Jia Shi 
624*0a19e61eSDong Jia Shi 	INIT_LIST_HEAD(&cp->ccwchain_list);
625*0a19e61eSDong Jia Shi 	memcpy(&cp->orb, orb, sizeof(*orb));
626*0a19e61eSDong Jia Shi 	cp->mdev = mdev;
627*0a19e61eSDong Jia Shi 
628*0a19e61eSDong Jia Shi 	/* Get chain length. */
629*0a19e61eSDong Jia Shi 	len = ccwchain_calc_length(iova, cp);
630*0a19e61eSDong Jia Shi 	if (len < 0)
631*0a19e61eSDong Jia Shi 		return len;
632*0a19e61eSDong Jia Shi 
633*0a19e61eSDong Jia Shi 	/* Alloc mem for the head chain. */
634*0a19e61eSDong Jia Shi 	chain = ccwchain_alloc(cp, len);
635*0a19e61eSDong Jia Shi 	if (!chain)
636*0a19e61eSDong Jia Shi 		return -ENOMEM;
637*0a19e61eSDong Jia Shi 	chain->ch_iova = iova;
638*0a19e61eSDong Jia Shi 
639*0a19e61eSDong Jia Shi 	/* Copy the head chain from guest. */
640*0a19e61eSDong Jia Shi 	ret = copy_ccw_from_iova(cp, chain->ch_ccw, iova, len);
641*0a19e61eSDong Jia Shi 	if (ret) {
642*0a19e61eSDong Jia Shi 		ccwchain_free(chain);
643*0a19e61eSDong Jia Shi 		return ret;
644*0a19e61eSDong Jia Shi 	}
645*0a19e61eSDong Jia Shi 
646*0a19e61eSDong Jia Shi 	/* Now loop for its TICs. */
647*0a19e61eSDong Jia Shi 	ret = ccwchain_loop_tic(chain, cp);
648*0a19e61eSDong Jia Shi 	if (ret)
649*0a19e61eSDong Jia Shi 		cp_unpin_free(cp);
650*0a19e61eSDong Jia Shi 
651*0a19e61eSDong Jia Shi 	return ret;
652*0a19e61eSDong Jia Shi }
653*0a19e61eSDong Jia Shi 
654*0a19e61eSDong Jia Shi 
655*0a19e61eSDong Jia Shi /**
656*0a19e61eSDong Jia Shi  * cp_free() - free resources for channel program.
657*0a19e61eSDong Jia Shi  * @cp: channel_program on which to perform the operation
658*0a19e61eSDong Jia Shi  *
659*0a19e61eSDong Jia Shi  * This unpins the memory pages and frees the memory space occupied by
660*0a19e61eSDong Jia Shi  * @cp, which must have been returned by a previous call to cp_init().
661*0a19e61eSDong Jia Shi  * Otherwise, undefined behavior occurs.
662*0a19e61eSDong Jia Shi  */
663*0a19e61eSDong Jia Shi void cp_free(struct channel_program *cp)
664*0a19e61eSDong Jia Shi {
665*0a19e61eSDong Jia Shi 	cp_unpin_free(cp);
666*0a19e61eSDong Jia Shi }
667*0a19e61eSDong Jia Shi 
668*0a19e61eSDong Jia Shi /**
669*0a19e61eSDong Jia Shi  * cp_prefetch() - translate a guest physical address channel program to
670*0a19e61eSDong Jia Shi  *                 a real-device runnable channel program.
671*0a19e61eSDong Jia Shi  * @cp: channel_program on which to perform the operation
672*0a19e61eSDong Jia Shi  *
673*0a19e61eSDong Jia Shi  * This function translates the guest-physical-address channel program
674*0a19e61eSDong Jia Shi  * and stores the result to ccwchain list. @cp must have been
675*0a19e61eSDong Jia Shi  * initialized by a previous call with cp_init(). Otherwise, undefined
676*0a19e61eSDong Jia Shi  * behavior occurs.
677*0a19e61eSDong Jia Shi  *
678*0a19e61eSDong Jia Shi  * The S/390 CCW Translation APIS (prefixed by 'cp_') are introduced
679*0a19e61eSDong Jia Shi  * as helpers to do ccw chain translation inside the kernel. Basically
680*0a19e61eSDong Jia Shi  * they accept a channel program issued by a virtual machine, and
681*0a19e61eSDong Jia Shi  * translate the channel program to a real-device runnable channel
682*0a19e61eSDong Jia Shi  * program.
683*0a19e61eSDong Jia Shi  *
684*0a19e61eSDong Jia Shi  * These APIs will copy the ccws into kernel-space buffers, and update
685*0a19e61eSDong Jia Shi  * the guest phsical addresses with their corresponding host physical
686*0a19e61eSDong Jia Shi  * addresses.  Then channel I/O device drivers could issue the
687*0a19e61eSDong Jia Shi  * translated channel program to real devices to perform an I/O
688*0a19e61eSDong Jia Shi  * operation.
689*0a19e61eSDong Jia Shi  *
690*0a19e61eSDong Jia Shi  * These interfaces are designed to support translation only for
691*0a19e61eSDong Jia Shi  * channel programs, which are generated and formatted by a
692*0a19e61eSDong Jia Shi  * guest. Thus this will make it possible for things like VFIO to
693*0a19e61eSDong Jia Shi  * leverage the interfaces to passthrough a channel I/O mediated
694*0a19e61eSDong Jia Shi  * device in QEMU.
695*0a19e61eSDong Jia Shi  *
696*0a19e61eSDong Jia Shi  * We support direct ccw chaining by translating them to idal ccws.
697*0a19e61eSDong Jia Shi  *
698*0a19e61eSDong Jia Shi  * Returns:
699*0a19e61eSDong Jia Shi  *   %0 on success and a negative error value on failure.
700*0a19e61eSDong Jia Shi  */
701*0a19e61eSDong Jia Shi int cp_prefetch(struct channel_program *cp)
702*0a19e61eSDong Jia Shi {
703*0a19e61eSDong Jia Shi 	struct ccwchain *chain;
704*0a19e61eSDong Jia Shi 	int len, idx, ret;
705*0a19e61eSDong Jia Shi 
706*0a19e61eSDong Jia Shi 	list_for_each_entry(chain, &cp->ccwchain_list, next) {
707*0a19e61eSDong Jia Shi 		len = chain->ch_len;
708*0a19e61eSDong Jia Shi 		for (idx = 0; idx < len; idx++) {
709*0a19e61eSDong Jia Shi 			ret = ccwchain_fetch_one(chain, idx, cp);
710*0a19e61eSDong Jia Shi 			if (ret)
711*0a19e61eSDong Jia Shi 				return ret;
712*0a19e61eSDong Jia Shi 		}
713*0a19e61eSDong Jia Shi 	}
714*0a19e61eSDong Jia Shi 
715*0a19e61eSDong Jia Shi 	return 0;
716*0a19e61eSDong Jia Shi }
717*0a19e61eSDong Jia Shi 
718*0a19e61eSDong Jia Shi /**
719*0a19e61eSDong Jia Shi  * cp_get_orb() - get the orb of the channel program
720*0a19e61eSDong Jia Shi  * @cp: channel_program on which to perform the operation
721*0a19e61eSDong Jia Shi  * @intparm: new intparm for the returned orb
722*0a19e61eSDong Jia Shi  * @lpm: candidate value of the logical-path mask for the returned orb
723*0a19e61eSDong Jia Shi  *
724*0a19e61eSDong Jia Shi  * This function returns the address of the updated orb of the channel
725*0a19e61eSDong Jia Shi  * program. Channel I/O device drivers could use this orb to issue a
726*0a19e61eSDong Jia Shi  * ssch.
727*0a19e61eSDong Jia Shi  */
728*0a19e61eSDong Jia Shi union orb *cp_get_orb(struct channel_program *cp, u32 intparm, u8 lpm)
729*0a19e61eSDong Jia Shi {
730*0a19e61eSDong Jia Shi 	union orb *orb;
731*0a19e61eSDong Jia Shi 	struct ccwchain *chain;
732*0a19e61eSDong Jia Shi 	struct ccw1 *cpa;
733*0a19e61eSDong Jia Shi 
734*0a19e61eSDong Jia Shi 	orb = &cp->orb;
735*0a19e61eSDong Jia Shi 
736*0a19e61eSDong Jia Shi 	orb->cmd.intparm = intparm;
737*0a19e61eSDong Jia Shi 	orb->cmd.fmt = 1;
738*0a19e61eSDong Jia Shi 	orb->cmd.key = PAGE_DEFAULT_KEY >> 4;
739*0a19e61eSDong Jia Shi 
740*0a19e61eSDong Jia Shi 	if (orb->cmd.lpm == 0)
741*0a19e61eSDong Jia Shi 		orb->cmd.lpm = lpm;
742*0a19e61eSDong Jia Shi 
743*0a19e61eSDong Jia Shi 	chain = list_first_entry(&cp->ccwchain_list, struct ccwchain, next);
744*0a19e61eSDong Jia Shi 	cpa = chain->ch_ccw;
745*0a19e61eSDong Jia Shi 	orb->cmd.cpa = (__u32) __pa(cpa);
746*0a19e61eSDong Jia Shi 
747*0a19e61eSDong Jia Shi 	return orb;
748*0a19e61eSDong Jia Shi }
749*0a19e61eSDong Jia Shi 
750*0a19e61eSDong Jia Shi /**
751*0a19e61eSDong Jia Shi  * cp_update_scsw() - update scsw for a channel program.
752*0a19e61eSDong Jia Shi  * @cp: channel_program on which to perform the operation
753*0a19e61eSDong Jia Shi  * @scsw: I/O results of the channel program and also the target to be
754*0a19e61eSDong Jia Shi  *        updated
755*0a19e61eSDong Jia Shi  *
756*0a19e61eSDong Jia Shi  * @scsw contains the I/O results of the channel program that pointed
757*0a19e61eSDong Jia Shi  * to by @cp. However what @scsw->cpa stores is a host physical
758*0a19e61eSDong Jia Shi  * address, which is meaningless for the guest, which is waiting for
759*0a19e61eSDong Jia Shi  * the I/O results.
760*0a19e61eSDong Jia Shi  *
761*0a19e61eSDong Jia Shi  * This function updates @scsw->cpa to its coressponding guest physical
762*0a19e61eSDong Jia Shi  * address.
763*0a19e61eSDong Jia Shi  */
764*0a19e61eSDong Jia Shi void cp_update_scsw(struct channel_program *cp, union scsw *scsw)
765*0a19e61eSDong Jia Shi {
766*0a19e61eSDong Jia Shi 	struct ccwchain *chain;
767*0a19e61eSDong Jia Shi 	u32 cpa = scsw->cmd.cpa;
768*0a19e61eSDong Jia Shi 	u32 ccw_head, ccw_tail;
769*0a19e61eSDong Jia Shi 
770*0a19e61eSDong Jia Shi 	/*
771*0a19e61eSDong Jia Shi 	 * LATER:
772*0a19e61eSDong Jia Shi 	 * For now, only update the cmd.cpa part. We may need to deal with
773*0a19e61eSDong Jia Shi 	 * other portions of the schib as well, even if we don't return them
774*0a19e61eSDong Jia Shi 	 * in the ioctl directly. Path status changes etc.
775*0a19e61eSDong Jia Shi 	 */
776*0a19e61eSDong Jia Shi 	list_for_each_entry(chain, &cp->ccwchain_list, next) {
777*0a19e61eSDong Jia Shi 		ccw_head = (u32)(u64)chain->ch_ccw;
778*0a19e61eSDong Jia Shi 		ccw_tail = (u32)(u64)(chain->ch_ccw + chain->ch_len - 1);
779*0a19e61eSDong Jia Shi 
780*0a19e61eSDong Jia Shi 		if ((ccw_head <= cpa) && (cpa <= ccw_tail)) {
781*0a19e61eSDong Jia Shi 			/*
782*0a19e61eSDong Jia Shi 			 * (cpa - ccw_head) is the offset value of the host
783*0a19e61eSDong Jia Shi 			 * physical ccw to its chain head.
784*0a19e61eSDong Jia Shi 			 * Adding this value to the guest physical ccw chain
785*0a19e61eSDong Jia Shi 			 * head gets us the guest cpa.
786*0a19e61eSDong Jia Shi 			 */
787*0a19e61eSDong Jia Shi 			cpa = chain->ch_iova + (cpa - ccw_head);
788*0a19e61eSDong Jia Shi 			break;
789*0a19e61eSDong Jia Shi 		}
790*0a19e61eSDong Jia Shi 	}
791*0a19e61eSDong Jia Shi 
792*0a19e61eSDong Jia Shi 	scsw->cmd.cpa = cpa;
793*0a19e61eSDong Jia Shi }
794*0a19e61eSDong Jia Shi 
795*0a19e61eSDong Jia Shi /**
796*0a19e61eSDong Jia Shi  * cp_iova_pinned() - check if an iova is pinned for a ccw chain.
797*0a19e61eSDong Jia Shi  * @cmd: ccwchain command on which to perform the operation
798*0a19e61eSDong Jia Shi  * @iova: the iova to check
799*0a19e61eSDong Jia Shi  *
800*0a19e61eSDong Jia Shi  * If the @iova is currently pinned for the ccw chain, return true;
801*0a19e61eSDong Jia Shi  * else return false.
802*0a19e61eSDong Jia Shi  */
803*0a19e61eSDong Jia Shi bool cp_iova_pinned(struct channel_program *cp, u64 iova)
804*0a19e61eSDong Jia Shi {
805*0a19e61eSDong Jia Shi 	struct ccwchain *chain;
806*0a19e61eSDong Jia Shi 	int i;
807*0a19e61eSDong Jia Shi 
808*0a19e61eSDong Jia Shi 	list_for_each_entry(chain, &cp->ccwchain_list, next) {
809*0a19e61eSDong Jia Shi 		for (i = 0; i < chain->ch_len; i++)
810*0a19e61eSDong Jia Shi 			if (pfn_array_table_iova_pinned(chain->ch_pat + i,
811*0a19e61eSDong Jia Shi 							iova))
812*0a19e61eSDong Jia Shi 				return true;
813*0a19e61eSDong Jia Shi 	}
814*0a19e61eSDong Jia Shi 
815*0a19e61eSDong Jia Shi 	return false;
816*0a19e61eSDong Jia Shi }
817