204
204
#define CPACF_KDSA_ENC_EDDSA_SIGN_ED25519 0x30
205
205
#define CPACF_KDSA_ENC_EDDSA_SIGN_ED448 0x34
206
206
207
+ #define CPACF_FC_QUERY 0x00
208
+
207
209
typedef struct { unsigned char bytes [16 ]; } cpacf_mask_t ;
208
210
209
211
/*
@@ -214,80 +216,85 @@ typedef struct { unsigned char bytes[16]; } cpacf_mask_t;
214
216
void __cpacf_bad_opcode (void );
215
217
216
218
static __always_inline void __cpacf_query_rre (u32 opc , u8 r1 , u8 r2 ,
217
- cpacf_mask_t * mask )
219
+ u8 * pb , u8 fc )
218
220
{
219
221
asm volatile (
220
- " la %%r1,%[mask ]\n"
221
- " xgr %%r0,%%r0 \n"
222
+ " la %%r1,%[pb ]\n"
223
+ " lghi %%r0,%[fc] \n"
222
224
" .insn rre,%[opc] << 16,%[r1],%[r2]\n"
223
- : [mask ] "=R" (* mask )
224
- : [opc ] "i" (opc ),
225
+ : [pb ] "=R" (* pb )
226
+ : [opc ] "i" (opc ), [ fc ] "i" ( fc ),
225
227
[r1 ] "i" (r1 ), [r2 ] "i" (r2 )
226
- : "cc" , "r0" , "r1" );
228
+ : "cc" , "memory" , " r0" , "r1" );
227
229
}
228
230
229
- static __always_inline void __cpacf_query_rrf (u32 opc ,
230
- u8 r1 , u8 r2 , u8 r3 , u8 m4 ,
231
- cpacf_mask_t * mask )
231
+ static __always_inline void __cpacf_query_rrf (u32 opc , u8 r1 , u8 r2 , u8 r3 ,
232
+ u8 m4 , u8 * pb , u8 fc )
232
233
{
233
234
asm volatile (
234
- " la %%r1,%[mask ]\n"
235
- " xgr %%r0,%%r0 \n"
235
+ " la %%r1,%[pb ]\n"
236
+ " lghi %%r0,%[fc] \n"
236
237
" .insn rrf,%[opc] << 16,%[r1],%[r2],%[r3],%[m4]\n"
237
- : [mask ] "=R" (* mask )
238
- : [opc ] "i" (opc ), [r1 ] "i" (r1 ), [r2 ] "i" (r2 ),
239
- [r3 ] "i" (r3 ), [m4 ] "i" (m4 )
240
- : "cc" , "r0" , "r1" );
238
+ : [pb ] "=R" (* pb )
239
+ : [opc ] "i" (opc ), [fc ] "i" (fc ), [r1 ] "i" (r1 ),
240
+ [r2 ] "i" ( r2 ), [ r3 ] "i" (r3 ), [m4 ] "i" (m4 )
241
+ : "cc" , "memory" , " r0" , "r1" );
241
242
}
242
243
243
- static __always_inline void __cpacf_query (unsigned int opcode ,
244
- cpacf_mask_t * mask )
244
+ static __always_inline void __cpacf_query_insn (unsigned int opcode , void * pb ,
245
+ u8 fc )
245
246
{
246
247
switch (opcode ) {
247
248
case CPACF_KDSA :
248
- __cpacf_query_rre (CPACF_KDSA , 0 , 2 , mask );
249
+ __cpacf_query_rre (CPACF_KDSA , 0 , 2 , pb , fc );
249
250
break ;
250
251
case CPACF_KIMD :
251
- __cpacf_query_rre (CPACF_KIMD , 0 , 2 , mask );
252
+ __cpacf_query_rre (CPACF_KIMD , 0 , 2 , pb , fc );
252
253
break ;
253
254
case CPACF_KLMD :
254
- __cpacf_query_rre (CPACF_KLMD , 0 , 2 , mask );
255
+ __cpacf_query_rre (CPACF_KLMD , 0 , 2 , pb , fc );
255
256
break ;
256
257
case CPACF_KM :
257
- __cpacf_query_rre (CPACF_KM , 2 , 4 , mask );
258
+ __cpacf_query_rre (CPACF_KM , 2 , 4 , pb , fc );
258
259
break ;
259
260
case CPACF_KMA :
260
- __cpacf_query_rrf (CPACF_KMA , 2 , 4 , 6 , 0 , mask );
261
+ __cpacf_query_rrf (CPACF_KMA , 2 , 4 , 6 , 0 , pb , fc );
261
262
break ;
262
263
case CPACF_KMAC :
263
- __cpacf_query_rre (CPACF_KMAC , 0 , 2 , mask );
264
+ __cpacf_query_rre (CPACF_KMAC , 0 , 2 , pb , fc );
264
265
break ;
265
266
case CPACF_KMC :
266
- __cpacf_query_rre (CPACF_KMC , 2 , 4 , mask );
267
+ __cpacf_query_rre (CPACF_KMC , 2 , 4 , pb , fc );
267
268
break ;
268
269
case CPACF_KMCTR :
269
- __cpacf_query_rrf (CPACF_KMCTR , 2 , 4 , 6 , 0 , mask );
270
+ __cpacf_query_rrf (CPACF_KMCTR , 2 , 4 , 6 , 0 , pb , fc );
270
271
break ;
271
272
case CPACF_KMF :
272
- __cpacf_query_rre (CPACF_KMF , 2 , 4 , mask );
273
+ __cpacf_query_rre (CPACF_KMF , 2 , 4 , pb , fc );
273
274
break ;
274
275
case CPACF_KMO :
275
- __cpacf_query_rre (CPACF_KMO , 2 , 4 , mask );
276
+ __cpacf_query_rre (CPACF_KMO , 2 , 4 , pb , fc );
276
277
break ;
277
278
case CPACF_PCC :
278
- __cpacf_query_rre (CPACF_PCC , 0 , 0 , mask );
279
+ __cpacf_query_rre (CPACF_PCC , 0 , 0 , pb , fc );
279
280
break ;
280
281
case CPACF_PCKMO :
281
- __cpacf_query_rre (CPACF_PCKMO , 0 , 0 , mask );
282
+ __cpacf_query_rre (CPACF_PCKMO , 0 , 0 , pb , fc );
282
283
break ;
283
284
case CPACF_PRNO :
284
- __cpacf_query_rre (CPACF_PRNO , 2 , 4 , mask );
285
+ __cpacf_query_rre (CPACF_PRNO , 2 , 4 , pb , fc );
285
286
break ;
286
287
default :
287
288
__cpacf_bad_opcode ();
288
289
}
289
290
}
290
291
292
+ static __always_inline void __cpacf_query (unsigned int opcode ,
293
+ cpacf_mask_t * mask )
294
+ {
295
+ __cpacf_query_insn (opcode , mask , CPACF_FC_QUERY );
296
+ }
297
+
291
298
static __always_inline int __cpacf_check_opcode (unsigned int opcode )
292
299
{
293
300
switch (opcode ) {
@@ -317,14 +324,15 @@ static __always_inline int __cpacf_check_opcode(unsigned int opcode)
317
324
}
318
325
319
326
/**
320
- * cpacf_query() - check if a specific CPACF function is available
327
+ * cpacf_query() - Query the function code mask for this CPACF opcode
321
328
* @opcode: the opcode of the crypto instruction
322
- * @func: the function code to test for
329
+ * @mask: ptr to struct cpacf_mask_t
323
330
*
324
331
* Executes the query function for the given crypto instruction @opcode
325
332
* and checks if @func is available
326
333
*
327
- * Returns 1 if @func is available for @opcode, 0 otherwise
334
+ * On success 1 is returned and the mask is filled with the function
335
+ * code mask for this CPACF opcode, otherwise 0 is returned.
328
336
*/
329
337
static __always_inline int cpacf_query (unsigned int opcode , cpacf_mask_t * mask )
330
338
{
0 commit comments