Skip to content

Commit 830999b

Browse files
hfreudehcahca
authored andcommitted
s390/cpacf: Split and rework cpacf query functions
Rework the cpacf query functions to use the correct RRE or RRF instruction formats and set register fields within instructions correctly. Fixes: 1afd43e ("s390/crypto: allow to query all known cpacf functions") Reported-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com> Suggested-by: Heiko Carstens <hca@linux.ibm.com> Suggested-by: Juergen Christ <jchrist@linux.ibm.com> Suggested-by: Holger Dengler <dengler@linux.ibm.com> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Reviewed-by: Holger Dengler <dengler@linux.ibm.com> Reviewed-by: Juergen Christ <jchrist@linux.ibm.com> Cc: <stable@vger.kernel.org> Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
1 parent 24bf80f commit 830999b

File tree

1 file changed

+81
-20
lines changed

1 file changed

+81
-20
lines changed

arch/s390/include/asm/cpacf.h

Lines changed: 81 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -166,28 +166,79 @@
166166

167167
typedef struct { unsigned char bytes[16]; } cpacf_mask_t;
168168

169-
/**
170-
* cpacf_query() - check if a specific CPACF function is available
171-
* @opcode: the opcode of the crypto instruction
172-
* @func: the function code to test for
173-
*
174-
* Executes the query function for the given crypto instruction @opcode
175-
* and checks if @func is available
176-
*
177-
* Returns 1 if @func is available for @opcode, 0 otherwise
178-
*/
179-
static __always_inline void __cpacf_query(unsigned int opcode, cpacf_mask_t *mask)
169+
static __always_inline void __cpacf_query_rre(u32 opc, u8 r1, u8 r2,
170+
cpacf_mask_t *mask)
180171
{
181172
asm volatile(
182-
" lghi 0,0\n" /* query function */
183-
" lgr 1,%[mask]\n"
184-
" spm 0\n" /* pckmo doesn't change the cc */
185-
/* Parameter regs are ignored, but must be nonzero and unique */
186-
"0: .insn rrf,%[opc] << 16,2,4,6,0\n"
187-
" brc 1,0b\n" /* handle partial completion */
188-
: "=m" (*mask)
189-
: [mask] "d" ((unsigned long)mask), [opc] "i" (opcode)
190-
: "cc", "0", "1");
173+
" la %%r1,%[mask]\n"
174+
" xgr %%r0,%%r0\n"
175+
" .insn rre,%[opc] << 16,%[r1],%[r2]\n"
176+
: [mask] "=R" (*mask)
177+
: [opc] "i" (opc),
178+
[r1] "i" (r1), [r2] "i" (r2)
179+
: "cc", "r0", "r1");
180+
}
181+
182+
static __always_inline void __cpacf_query_rrf(u32 opc,
183+
u8 r1, u8 r2, u8 r3, u8 m4,
184+
cpacf_mask_t *mask)
185+
{
186+
asm volatile(
187+
" la %%r1,%[mask]\n"
188+
" xgr %%r0,%%r0\n"
189+
" .insn rrf,%[opc] << 16,%[r1],%[r2],%[r3],%[m4]\n"
190+
: [mask] "=R" (*mask)
191+
: [opc] "i" (opc), [r1] "i" (r1), [r2] "i" (r2),
192+
[r3] "i" (r3), [m4] "i" (m4)
193+
: "cc", "r0", "r1");
194+
}
195+
196+
static __always_inline void __cpacf_query(unsigned int opcode,
197+
cpacf_mask_t *mask)
198+
{
199+
switch (opcode) {
200+
case CPACF_KDSA:
201+
__cpacf_query_rre(CPACF_KDSA, 0, 2, mask);
202+
break;
203+
case CPACF_KIMD:
204+
__cpacf_query_rre(CPACF_KIMD, 0, 2, mask);
205+
break;
206+
case CPACF_KLMD:
207+
__cpacf_query_rre(CPACF_KLMD, 0, 2, mask);
208+
break;
209+
case CPACF_KM:
210+
__cpacf_query_rre(CPACF_KM, 2, 4, mask);
211+
break;
212+
case CPACF_KMA:
213+
__cpacf_query_rrf(CPACF_KMA, 2, 4, 6, 0, mask);
214+
break;
215+
case CPACF_KMAC:
216+
__cpacf_query_rre(CPACF_KMAC, 0, 2, mask);
217+
break;
218+
case CPACF_KMC:
219+
__cpacf_query_rre(CPACF_KMC, 2, 4, mask);
220+
break;
221+
case CPACF_KMCTR:
222+
__cpacf_query_rrf(CPACF_KMCTR, 2, 4, 6, 0, mask);
223+
break;
224+
case CPACF_KMF:
225+
__cpacf_query_rre(CPACF_KMF, 2, 4, mask);
226+
break;
227+
case CPACF_KMO:
228+
__cpacf_query_rre(CPACF_KMO, 2, 4, mask);
229+
break;
230+
case CPACF_PCC:
231+
__cpacf_query_rre(CPACF_PCC, 0, 0, mask);
232+
break;
233+
case CPACF_PCKMO:
234+
__cpacf_query_rre(CPACF_PCKMO, 0, 0, mask);
235+
break;
236+
case CPACF_PRNO:
237+
__cpacf_query_rre(CPACF_PRNO, 2, 4, mask);
238+
break;
239+
default:
240+
BUG();
241+
}
191242
}
192243

193244
static __always_inline int __cpacf_check_opcode(unsigned int opcode)
@@ -215,6 +266,16 @@ static __always_inline int __cpacf_check_opcode(unsigned int opcode)
215266
}
216267
}
217268

269+
/**
270+
* cpacf_query() - check if a specific CPACF function is available
271+
* @opcode: the opcode of the crypto instruction
272+
* @func: the function code to test for
273+
*
274+
* Executes the query function for the given crypto instruction @opcode
275+
* and checks if @func is available
276+
*
277+
* Returns 1 if @func is available for @opcode, 0 otherwise
278+
*/
218279
static __always_inline int cpacf_query(unsigned int opcode, cpacf_mask_t *mask)
219280
{
220281
if (__cpacf_check_opcode(opcode)) {

0 commit comments

Comments
 (0)