Merge tag 'execve-v6.0-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/kees...
[linux-2.6-microblaze.git] / arch / s390 / include / asm / ap.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Adjunct processor (AP) interfaces
4  *
5  * Copyright IBM Corp. 2017
6  *
7  * Author(s): Tony Krowiak <akrowia@linux.vnet.ibm.com>
8  *            Martin Schwidefsky <schwidefsky@de.ibm.com>
9  *            Harald Freudenberger <freude@de.ibm.com>
10  */
11
12 #ifndef _ASM_S390_AP_H_
13 #define _ASM_S390_AP_H_
14
15 #include <linux/io.h>
16 #include <asm/asm-extable.h>
17
18 /**
19  * The ap_qid_t identifier of an ap queue.
20  * If the AP facilities test (APFT) facility is available,
21  * card and queue index are 8 bit values, otherwise
22  * card index is 6 bit and queue index a 4 bit value.
23  */
24 typedef unsigned int ap_qid_t;
25
26 #define AP_MKQID(_card, _queue) (((_card) & 0xff) << 8 | ((_queue) & 0xff))
27 #define AP_QID_CARD(_qid) (((_qid) >> 8) & 0xff)
28 #define AP_QID_QUEUE(_qid) ((_qid) & 0xff)
29
30 /**
31  * struct ap_queue_status - Holds the AP queue status.
32  * @queue_empty: Shows if queue is empty
33  * @replies_waiting: Waiting replies
34  * @queue_full: Is 1 if the queue is full
35  * @irq_enabled: Shows if interrupts are enabled for the AP
36  * @response_code: Holds the 8 bit response code
37  *
38  * The ap queue status word is returned by all three AP functions
39  * (PQAP, NQAP and DQAP).  There's a set of flags in the first
40  * byte, followed by a 1 byte response code.
41  */
42 struct ap_queue_status {
43         unsigned int queue_empty        : 1;
44         unsigned int replies_waiting    : 1;
45         unsigned int queue_full         : 1;
46         unsigned int _pad1              : 4;
47         unsigned int irq_enabled        : 1;
48         unsigned int response_code      : 8;
49         unsigned int _pad2              : 16;
50 };
51
52 /**
53  * ap_intructions_available() - Test if AP instructions are available.
54  *
55  * Returns true if the AP instructions are installed, otherwise false.
56  */
57 static inline bool ap_instructions_available(void)
58 {
59         unsigned long reg0 = AP_MKQID(0, 0);
60         unsigned long reg1 = 0;
61
62         asm volatile(
63                 "       lgr     0,%[reg0]\n"            /* qid into gr0 */
64                 "       lghi    1,0\n"                  /* 0 into gr1 */
65                 "       lghi    2,0\n"                  /* 0 into gr2 */
66                 "       .insn   rre,0xb2af0000,0,0\n"   /* PQAP(TAPQ) */
67                 "0:     la      %[reg1],1\n"            /* 1 into reg1 */
68                 "1:\n"
69                 EX_TABLE(0b, 1b)
70                 : [reg1] "+&d" (reg1)
71                 : [reg0] "d" (reg0)
72                 : "cc", "0", "1", "2");
73         return reg1 != 0;
74 }
75
76 /**
77  * ap_tapq(): Test adjunct processor queue.
78  * @qid: The AP queue number
79  * @info: Pointer to queue descriptor
80  *
81  * Returns AP queue status structure.
82  */
83 static inline struct ap_queue_status ap_tapq(ap_qid_t qid, unsigned long *info)
84 {
85         struct ap_queue_status reg1;
86         unsigned long reg2;
87
88         asm volatile(
89                 "       lgr     0,%[qid]\n"             /* qid into gr0 */
90                 "       lghi    2,0\n"                  /* 0 into gr2 */
91                 "       .insn   rre,0xb2af0000,0,0\n"   /* PQAP(TAPQ) */
92                 "       lgr     %[reg1],1\n"            /* gr1 (status) into reg1 */
93                 "       lgr     %[reg2],2\n"            /* gr2 into reg2 */
94                 : [reg1] "=&d" (reg1), [reg2] "=&d" (reg2)
95                 : [qid] "d" (qid)
96                 : "cc", "0", "1", "2");
97         if (info)
98                 *info = reg2;
99         return reg1;
100 }
101
102 /**
103  * ap_test_queue(): Test adjunct processor queue.
104  * @qid: The AP queue number
105  * @tbit: Test facilities bit
106  * @info: Pointer to queue descriptor
107  *
108  * Returns AP queue status structure.
109  */
110 static inline struct ap_queue_status ap_test_queue(ap_qid_t qid,
111                                                    int tbit,
112                                                    unsigned long *info)
113 {
114         if (tbit)
115                 qid |= 1UL << 23; /* set T bit*/
116         return ap_tapq(qid, info);
117 }
118
119 /**
120  * ap_pqap_rapq(): Reset adjunct processor queue.
121  * @qid: The AP queue number
122  *
123  * Returns AP queue status structure.
124  */
125 static inline struct ap_queue_status ap_rapq(ap_qid_t qid)
126 {
127         unsigned long reg0 = qid | (1UL << 24);  /* fc 1UL is RAPQ */
128         struct ap_queue_status reg1;
129
130         asm volatile(
131                 "       lgr     0,%[reg0]\n"            /* qid arg into gr0 */
132                 "       .insn   rre,0xb2af0000,0,0\n"   /* PQAP(RAPQ) */
133                 "       lgr     %[reg1],1\n"            /* gr1 (status) into reg1 */
134                 : [reg1] "=&d" (reg1)
135                 : [reg0] "d" (reg0)
136                 : "cc", "0", "1");
137         return reg1;
138 }
139
140 /**
141  * ap_pqap_zapq(): Reset and zeroize adjunct processor queue.
142  * @qid: The AP queue number
143  *
144  * Returns AP queue status structure.
145  */
146 static inline struct ap_queue_status ap_zapq(ap_qid_t qid)
147 {
148         unsigned long reg0 = qid | (2UL << 24);  /* fc 2UL is ZAPQ */
149         struct ap_queue_status reg1;
150
151         asm volatile(
152                 "       lgr     0,%[reg0]\n"            /* qid arg into gr0 */
153                 "       .insn   rre,0xb2af0000,0,0\n"   /* PQAP(ZAPQ) */
154                 "       lgr     %[reg1],1\n"            /* gr1 (status) into reg1 */
155                 : [reg1] "=&d" (reg1)
156                 : [reg0] "d" (reg0)
157                 : "cc", "0", "1");
158         return reg1;
159 }
160
161 /**
162  * struct ap_config_info - convenience struct for AP crypto
163  * config info as returned by the ap_qci() function.
164  */
165 struct ap_config_info {
166         unsigned int apsc        : 1;   /* S bit */
167         unsigned int apxa        : 1;   /* N bit */
168         unsigned int qact        : 1;   /* C bit */
169         unsigned int rc8a        : 1;   /* R bit */
170         unsigned char _reserved1 : 4;
171         unsigned char _reserved2[3];
172         unsigned char Na;               /* max # of APs - 1 */
173         unsigned char Nd;               /* max # of Domains - 1 */
174         unsigned char _reserved3[10];
175         unsigned int apm[8];            /* AP ID mask */
176         unsigned int aqm[8];            /* AP (usage) queue mask */
177         unsigned int adm[8];            /* AP (control) domain mask */
178         unsigned char _reserved4[16];
179 } __aligned(8);
180
181 /**
182  * ap_qci(): Get AP configuration data
183  *
184  * Returns 0 on success, or -EOPNOTSUPP.
185  */
186 static inline int ap_qci(struct ap_config_info *config)
187 {
188         unsigned long reg0 = 4UL << 24;  /* fc 4UL is QCI */
189         unsigned long reg1 = -EOPNOTSUPP;
190         struct ap_config_info *reg2 = config;
191
192         asm volatile(
193                 "       lgr     0,%[reg0]\n"            /* QCI fc into gr0 */
194                 "       lgr     2,%[reg2]\n"            /* ptr to config into gr2 */
195                 "       .insn   rre,0xb2af0000,0,0\n"   /* PQAP(QCI) */
196                 "0:     la      %[reg1],0\n"            /* good case, QCI fc available */
197                 "1:\n"
198                 EX_TABLE(0b, 1b)
199                 : [reg1] "+&d" (reg1)
200                 : [reg0] "d" (reg0), [reg2] "d" (reg2)
201                 : "cc", "memory", "0", "2");
202
203         return reg1;
204 }
205
206 /*
207  * struct ap_qirq_ctrl - convenient struct for easy invocation
208  * of the ap_aqic() function. This struct is passed as GR1
209  * parameter to the PQAP(AQIC) instruction. For details please
210  * see the AR documentation.
211  */
212 struct ap_qirq_ctrl {
213         unsigned int _res1 : 8;
214         unsigned int zone  : 8; /* zone info */
215         unsigned int ir    : 1; /* ir flag: enable (1) or disable (0) irq */
216         unsigned int _res2 : 4;
217         unsigned int gisc  : 3; /* guest isc field */
218         unsigned int _res3 : 6;
219         unsigned int gf    : 2; /* gisa format */
220         unsigned int _res4 : 1;
221         unsigned int gisa  : 27;        /* gisa origin */
222         unsigned int _res5 : 1;
223         unsigned int isc   : 3; /* irq sub class */
224 };
225
226 /**
227  * ap_aqic(): Control interruption for a specific AP.
228  * @qid: The AP queue number
229  * @qirqctrl: struct ap_qirq_ctrl (64 bit value)
230  * @pa_ind: Physical address of the notification indicator byte
231  *
232  * Returns AP queue status.
233  */
234 static inline struct ap_queue_status ap_aqic(ap_qid_t qid,
235                                              struct ap_qirq_ctrl qirqctrl,
236                                              phys_addr_t pa_ind)
237 {
238         unsigned long reg0 = qid | (3UL << 24);  /* fc 3UL is AQIC */
239         union {
240                 unsigned long value;
241                 struct ap_qirq_ctrl qirqctrl;
242                 struct ap_queue_status status;
243         } reg1;
244         unsigned long reg2 = pa_ind;
245
246         reg1.qirqctrl = qirqctrl;
247
248         asm volatile(
249                 "       lgr     0,%[reg0]\n"            /* qid param into gr0 */
250                 "       lgr     1,%[reg1]\n"            /* irq ctrl into gr1 */
251                 "       lgr     2,%[reg2]\n"            /* ni addr into gr2 */
252                 "       .insn   rre,0xb2af0000,0,0\n"   /* PQAP(AQIC) */
253                 "       lgr     %[reg1],1\n"            /* gr1 (status) into reg1 */
254                 : [reg1] "+&d" (reg1)
255                 : [reg0] "d" (reg0), [reg2] "d" (reg2)
256                 : "cc", "0", "1", "2");
257
258         return reg1.status;
259 }
260
261 /*
262  * union ap_qact_ap_info - used together with the
263  * ap_aqic() function to provide a convenient way
264  * to handle the ap info needed by the qact function.
265  */
266 union ap_qact_ap_info {
267         unsigned long val;
268         struct {
269                 unsigned int      : 3;
270                 unsigned int mode : 3;
271                 unsigned int      : 26;
272                 unsigned int cat  : 8;
273                 unsigned int      : 8;
274                 unsigned char ver[2];
275         };
276 };
277
278 /**
279  * ap_qact(): Query AP combatibility type.
280  * @qid: The AP queue number
281  * @apinfo: On input the info about the AP queue. On output the
282  *          alternate AP queue info provided by the qact function
283  *          in GR2 is stored in.
284  *
285  * Returns AP queue status. Check response_code field for failures.
286  */
287 static inline struct ap_queue_status ap_qact(ap_qid_t qid, int ifbit,
288                                              union ap_qact_ap_info *apinfo)
289 {
290         unsigned long reg0 = qid | (5UL << 24) | ((ifbit & 0x01) << 22);
291         union {
292                 unsigned long value;
293                 struct ap_queue_status status;
294         } reg1;
295         unsigned long reg2;
296
297         reg1.value = apinfo->val;
298
299         asm volatile(
300                 "       lgr     0,%[reg0]\n"            /* qid param into gr0 */
301                 "       lgr     1,%[reg1]\n"            /* qact in info into gr1 */
302                 "       .insn   rre,0xb2af0000,0,0\n"   /* PQAP(QACT) */
303                 "       lgr     %[reg1],1\n"            /* gr1 (status) into reg1 */
304                 "       lgr     %[reg2],2\n"            /* qact out info into reg2 */
305                 : [reg1] "+&d" (reg1), [reg2] "=&d" (reg2)
306                 : [reg0] "d" (reg0)
307                 : "cc", "0", "1", "2");
308         apinfo->val = reg2;
309         return reg1.status;
310 }
311
312 /**
313  * ap_nqap(): Send message to adjunct processor queue.
314  * @qid: The AP queue number
315  * @psmid: The program supplied message identifier
316  * @msg: The message text
317  * @length: The message length
318  *
319  * Returns AP queue status structure.
320  * Condition code 1 on NQAP can't happen because the L bit is 1.
321  * Condition code 2 on NQAP also means the send is incomplete,
322  * because a segment boundary was reached. The NQAP is repeated.
323  */
324 static inline struct ap_queue_status ap_nqap(ap_qid_t qid,
325                                              unsigned long long psmid,
326                                              void *msg, size_t length)
327 {
328         unsigned long reg0 = qid | 0x40000000UL;  /* 0x4... is last msg part */
329         union register_pair nqap_r1, nqap_r2;
330         struct ap_queue_status reg1;
331
332         nqap_r1.even = (unsigned int)(psmid >> 32);
333         nqap_r1.odd  = psmid & 0xffffffff;
334         nqap_r2.even = (unsigned long)msg;
335         nqap_r2.odd  = (unsigned long)length;
336
337         asm volatile (
338                 "       lgr     0,%[reg0]\n"  /* qid param in gr0 */
339                 "0:     .insn   rre,0xb2ad0000,%[nqap_r1],%[nqap_r2]\n"
340                 "       brc     2,0b\n"       /* handle partial completion */
341                 "       lgr     %[reg1],1\n"  /* gr1 (status) into reg1 */
342                 : [reg0] "+&d" (reg0), [reg1] "=&d" (reg1),
343                   [nqap_r2] "+&d" (nqap_r2.pair)
344                 : [nqap_r1] "d" (nqap_r1.pair)
345                 : "cc", "memory", "0", "1");
346         return reg1;
347 }
348
349 /**
350  * ap_dqap(): Receive message from adjunct processor queue.
351  * @qid: The AP queue number
352  * @psmid: Pointer to program supplied message identifier
353  * @msg: The message text
354  * @length: The message length
355  * @reslength: Resitual length on return
356  * @resgr0: input: gr0 value (only used if != 0), output: resitual gr0 content
357  *
358  * Returns AP queue status structure.
359  * Condition code 1 on DQAP means the receive has taken place
360  * but only partially.  The response is incomplete, hence the
361  * DQAP is repeated.
362  * Condition code 2 on DQAP also means the receive is incomplete,
363  * this time because a segment boundary was reached. Again, the
364  * DQAP is repeated.
365  * Note that gpr2 is used by the DQAP instruction to keep track of
366  * any 'residual' length, in case the instruction gets interrupted.
367  * Hence it gets zeroed before the instruction.
368  * If the message does not fit into the buffer, this function will
369  * return with a truncated message and the reply in the firmware queue
370  * is not removed. This is indicated to the caller with an
371  * ap_queue_status response_code value of all bits on (0xFF) and (if
372  * the reslength ptr is given) the remaining length is stored in
373  * *reslength and (if the resgr0 ptr is given) the updated gr0 value
374  * for further processing of this msg entry is stored in *resgr0. The
375  * caller needs to detect this situation and should invoke ap_dqap
376  * with a valid resgr0 ptr and a value in there != 0 to indicate that
377  * *resgr0 is to be used instead of qid to further process this entry.
378  */
379 static inline struct ap_queue_status ap_dqap(ap_qid_t qid,
380                                              unsigned long long *psmid,
381                                              void *msg, size_t length,
382                                              size_t *reslength,
383                                              unsigned long *resgr0)
384 {
385         unsigned long reg0 = resgr0 && *resgr0 ? *resgr0 : qid | 0x80000000UL;
386         struct ap_queue_status reg1;
387         unsigned long reg2;
388         union register_pair rp1, rp2;
389
390         rp1.even = 0UL;
391         rp1.odd  = 0UL;
392         rp2.even = (unsigned long)msg;
393         rp2.odd  = (unsigned long)length;
394
395         asm volatile(
396                 "       lgr     0,%[reg0]\n"   /* qid param into gr0 */
397                 "       lghi    2,0\n"         /* 0 into gr2 (res length) */
398                 "0:     ltgr    %N[rp2],%N[rp2]\n" /* check buf len */
399                 "       jz      2f\n"          /* go out if buf len is 0 */
400                 "1:     .insn   rre,0xb2ae0000,%[rp1],%[rp2]\n"
401                 "       brc     6,0b\n"        /* handle partial complete */
402                 "2:     lgr     %[reg0],0\n"   /* gr0 (qid + info) into reg0 */
403                 "       lgr     %[reg1],1\n"   /* gr1 (status) into reg1 */
404                 "       lgr     %[reg2],2\n"   /* gr2 (res length) into reg2 */
405                 : [reg0] "+&d" (reg0), [reg1] "=&d" (reg1), [reg2] "=&d" (reg2),
406                   [rp1] "+&d" (rp1.pair), [rp2] "+&d" (rp2.pair)
407                 :
408                 : "cc", "memory", "0", "1", "2");
409
410         if (reslength)
411                 *reslength = reg2;
412         if (reg2 != 0 && rp2.odd == 0) {
413                 /*
414                  * Partially complete, status in gr1 is not set.
415                  * Signal the caller that this dqap is only partially received
416                  * with a special status response code 0xFF and *resgr0 updated
417                  */
418                 reg1.response_code = 0xFF;
419                 if (resgr0)
420                         *resgr0 = reg0;
421         } else {
422                 *psmid = (((unsigned long long)rp1.even) << 32) + rp1.odd;
423                 if (resgr0)
424                         *resgr0 = 0;
425         }
426
427         return reg1;
428 }
429
430 /*
431  * Interface to tell the AP bus code that a configuration
432  * change has happened. The bus code should at least do
433  * an ap bus resource rescan.
434  */
435 #if IS_ENABLED(CONFIG_ZCRYPT)
436 void ap_bus_cfg_chg(void);
437 #else
438 static inline void ap_bus_cfg_chg(void){}
439 #endif
440
441 #endif /* _ASM_S390_AP_H_ */