204204#define CPACF_KDSA_ENC_EDDSA_SIGN_ED25519 0x30
205205#define CPACF_KDSA_ENC_EDDSA_SIGN_ED448 0x34
206206
207+ #define CPACF_FC_QUERY 0x00
208+
207209typedef struct { unsigned char bytes [16 ]; } cpacf_mask_t ;
208210
209211/*
@@ -214,80 +216,85 @@ typedef struct { unsigned char bytes[16]; } cpacf_mask_t;
214216void __cpacf_bad_opcode (void );
215217
216218static __always_inline void __cpacf_query_rre (u32 opc , u8 r1 , u8 r2 ,
217- cpacf_mask_t * mask )
219+ u8 * pb , u8 fc )
218220{
219221 asm volatile (
220- " la %%r1,%[mask ]\n"
221- " xgr %%r0,%%r0 \n"
222+ " la %%r1,%[pb ]\n"
223+ " lghi %%r0,%[fc] \n"
222224 " .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 ),
225227 [r1 ] "i" (r1 ), [r2 ] "i" (r2 )
226- : "cc" , "r0" , "r1" );
228+ : "cc" , "memory" , " r0" , "r1" );
227229}
228230
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 )
232233{
233234 asm volatile (
234- " la %%r1,%[mask ]\n"
235- " xgr %%r0,%%r0 \n"
235+ " la %%r1,%[pb ]\n"
236+ " lghi %%r0,%[fc] \n"
236237 " .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" );
241242}
242243
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 )
245246{
246247 switch (opcode ) {
247248 case CPACF_KDSA :
248- __cpacf_query_rre (CPACF_KDSA , 0 , 2 , mask );
249+ __cpacf_query_rre (CPACF_KDSA , 0 , 2 , pb , fc );
249250 break ;
250251 case CPACF_KIMD :
251- __cpacf_query_rre (CPACF_KIMD , 0 , 2 , mask );
252+ __cpacf_query_rre (CPACF_KIMD , 0 , 2 , pb , fc );
252253 break ;
253254 case CPACF_KLMD :
254- __cpacf_query_rre (CPACF_KLMD , 0 , 2 , mask );
255+ __cpacf_query_rre (CPACF_KLMD , 0 , 2 , pb , fc );
255256 break ;
256257 case CPACF_KM :
257- __cpacf_query_rre (CPACF_KM , 2 , 4 , mask );
258+ __cpacf_query_rre (CPACF_KM , 2 , 4 , pb , fc );
258259 break ;
259260 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 );
261262 break ;
262263 case CPACF_KMAC :
263- __cpacf_query_rre (CPACF_KMAC , 0 , 2 , mask );
264+ __cpacf_query_rre (CPACF_KMAC , 0 , 2 , pb , fc );
264265 break ;
265266 case CPACF_KMC :
266- __cpacf_query_rre (CPACF_KMC , 2 , 4 , mask );
267+ __cpacf_query_rre (CPACF_KMC , 2 , 4 , pb , fc );
267268 break ;
268269 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 );
270271 break ;
271272 case CPACF_KMF :
272- __cpacf_query_rre (CPACF_KMF , 2 , 4 , mask );
273+ __cpacf_query_rre (CPACF_KMF , 2 , 4 , pb , fc );
273274 break ;
274275 case CPACF_KMO :
275- __cpacf_query_rre (CPACF_KMO , 2 , 4 , mask );
276+ __cpacf_query_rre (CPACF_KMO , 2 , 4 , pb , fc );
276277 break ;
277278 case CPACF_PCC :
278- __cpacf_query_rre (CPACF_PCC , 0 , 0 , mask );
279+ __cpacf_query_rre (CPACF_PCC , 0 , 0 , pb , fc );
279280 break ;
280281 case CPACF_PCKMO :
281- __cpacf_query_rre (CPACF_PCKMO , 0 , 0 , mask );
282+ __cpacf_query_rre (CPACF_PCKMO , 0 , 0 , pb , fc );
282283 break ;
283284 case CPACF_PRNO :
284- __cpacf_query_rre (CPACF_PRNO , 2 , 4 , mask );
285+ __cpacf_query_rre (CPACF_PRNO , 2 , 4 , pb , fc );
285286 break ;
286287 default :
287288 __cpacf_bad_opcode ();
288289 }
289290}
290291
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+
291298static __always_inline int __cpacf_check_opcode (unsigned int opcode )
292299{
293300 switch (opcode ) {
@@ -317,14 +324,15 @@ static __always_inline int __cpacf_check_opcode(unsigned int opcode)
317324}
318325
319326/**
320- * cpacf_query() - check if a specific CPACF function is available
327+ * cpacf_query() - Query the function code mask for this CPACF opcode
321328 * @opcode: the opcode of the crypto instruction
322- * @func: the function code to test for
329+ * @mask: ptr to struct cpacf_mask_t
323330 *
324331 * Executes the query function for the given crypto instruction @opcode
325332 * and checks if @func is available
326333 *
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.
328336 */
329337static __always_inline int cpacf_query (unsigned int opcode , cpacf_mask_t * mask )
330338{
0 commit comments