Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 94c12cc7 authored by Martin Schwidefsky's avatar Martin Schwidefsky
Browse files

[S390] Inline assembly cleanup.



Major cleanup of all s390 inline assemblies. They now have a common
coding style. Quite a few have been shortened, mainly by using register
asm variables. Use of the EX_TABLE macro helps  as well. The atomic ops,
bit ops and locking inlines new use the Q-constraint if a newer gcc
is used.  That results in slightly better code.

Thanks to Christian Borntraeger for proof reading the changes.

Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 25d83cbf
Loading
Loading
Loading
Loading
+65 −139
Original line number Diff line number Diff line
@@ -104,63 +104,6 @@ struct crypt_s390_query_status {
	u64 low;
};

/*
 * Standard fixup and ex_table sections for crypt_s390 inline functions.
 * label 0: the s390 crypto operation
 * label 1: just after 1 to catch illegal operation exception
 *          (unsupported model)
 * label 6: the return point after fixup
 * label 7: set error value if exception _in_ crypto operation
 * label 8: set error value if illegal operation exception
 * [ret] is the variable to receive the error code
 * [ERR] is the error code value
 */
#ifndef CONFIG_64BIT
#define __crypt_s390_fixup \
	".section .fixup,\"ax\" \n"	\
	"7:	lhi	%0,%h[e1] \n"	\
	"	bras	1,9f \n"	\
	"	.long	6b \n"		\
	"8:	lhi	%0,%h[e2] \n"	\
	"	bras	1,9f \n"	\
	"	.long	6b \n"		\
	"9:	l	1,0(1) \n"	\
	"	br	1 \n"		\
	".previous \n"			\
	".section __ex_table,\"a\" \n"	\
	"	.align	4 \n"		\
	"	.long	0b,7b \n"	\
	"	.long	1b,8b \n"	\
	".previous"
#else /* CONFIG_64BIT */
#define __crypt_s390_fixup \
	".section .fixup,\"ax\" \n"	\
	"7:	lhi	%0,%h[e1] \n"	\
	"	jg	6b \n"		\
	"8:	lhi	%0,%h[e2] \n"	\
	"	jg	6b \n"		\
	".previous\n"			\
	".section __ex_table,\"a\" \n"	\
	"	.align	8 \n"		\
	"	.quad	0b,7b \n"	\
	"	.quad	1b,8b \n"	\
	".previous"
#endif /* CONFIG_64BIT */

/*
 * Standard code for setting the result of s390 crypto instructions.
 * %0: the register which will receive the result
 * [result]: the register containing the result (e.g. second operand length
 * to compute number of processed bytes].
 */
#ifndef CONFIG_64BIT
#define __crypt_s390_set_result \
	"	lr	%0,%[result] \n"
#else /* CONFIG_64BIT */
#define __crypt_s390_set_result \
	"	lgr	%0,%[result] \n"
#endif

/*
 * Executes the KM (CIPHER MESSAGE) operation of the CPU.
 * @param func: the function code passed to KM; see crypt_s390_km_func
@@ -176,28 +119,24 @@ crypt_s390_km(long func, void* param, u8* dest, const u8* src, long src_len)
{
	register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
	register void* __param asm("1") = param;
	register u8* __dest asm("4") = dest;
	register const u8* __src asm("2") = src;
	register long __src_len asm("3") = src_len;
	register u8* __dest asm("4") = dest;
	int ret;

	ret = 0;
	__asm__ __volatile__ (
		"0:	.insn	rre,0xB92E0000,%1,%2 \n" /* KM opcode */
	asm volatile(
		"0:	.insn	rre,0xb92e0000,%3,%1 \n" /* KM opcode */
		"1:	brc	1,0b \n" /* handle partial completion */
		__crypt_s390_set_result
		"6:	\n"
		__crypt_s390_fixup
		: "+d" (ret), "+a" (__dest), "+a" (__src),
		  [result] "+d" (__src_len)
		: [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
		  "a" (__param)
		: "cc", "memory"
	);
	if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
		ret = src_len - ret;
	}
		"	ahi	%0,%h7\n"
		"2:	ahi	%0,%h8\n"
		"3:\n"
		EX_TABLE(0b,3b) EX_TABLE(1b,2b)
		: "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest)
		: "d" (__func), "a" (__param), "0" (-EFAULT),
		  "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
	if (ret < 0)
		return ret;
	return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
}

/*
@@ -215,28 +154,24 @@ crypt_s390_kmc(long func, void* param, u8* dest, const u8* src, long src_len)
{
	register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
	register void* __param asm("1") = param;
	register u8* __dest asm("4") = dest;
	register const u8* __src asm("2") = src;
	register long __src_len asm("3") = src_len;
	register u8* __dest asm("4") = dest;
	int ret;

	ret = 0;
	__asm__ __volatile__ (
		"0:	.insn	rre,0xB92F0000,%1,%2 \n" /* KMC opcode */
	asm volatile(
		"0:	.insn	rre,0xb92f0000,%3,%1 \n" /* KMC opcode */
		"1:	brc	1,0b \n" /* handle partial completion */
		__crypt_s390_set_result
		"6:	\n"
		__crypt_s390_fixup
		: "+d" (ret), "+a" (__dest), "+a" (__src),
		  [result] "+d" (__src_len)
		: [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
		  "a" (__param)
		: "cc", "memory"
	);
	if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
		ret = src_len - ret;
	}
		"	ahi	%0,%h7\n"
		"2:	ahi	%0,%h8\n"
		"3:\n"
		EX_TABLE(0b,3b) EX_TABLE(1b,2b)
		: "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest)
		: "d" (__func), "a" (__param), "0" (-EFAULT),
		  "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
	if (ret < 0)
		return ret;
	return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
}

/*
@@ -258,22 +193,19 @@ crypt_s390_kimd(long func, void* param, const u8* src, long src_len)
	register long __src_len asm("3") = src_len;
	int ret;

	ret = 0;
	__asm__ __volatile__ (
		"0:	.insn	rre,0xB93E0000,%1,%1 \n" /* KIMD opcode */
		"1:	brc	1,0b \n" /* handle partical completion */
		__crypt_s390_set_result
		"6:	\n"
		__crypt_s390_fixup
		: "+d" (ret), "+a" (__src), [result] "+d" (__src_len)
		: [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
		  "a" (__param)
		: "cc", "memory"
	);
	if (ret >= 0 && (func & CRYPT_S390_FUNC_MASK)){
		ret = src_len - ret;
	}
	asm volatile(
		"0:	.insn	rre,0xb93e0000,%1,%1 \n" /* KIMD opcode */
		"1:	brc	1,0b \n" /* handle partial completion */
		"	ahi	%0,%h6\n"
		"2:	ahi	%0,%h7\n"
		"3:\n"
		EX_TABLE(0b,3b) EX_TABLE(1b,2b)
		: "=d" (ret), "+a" (__src), "+d" (__src_len)
		: "d" (__func), "a" (__param), "0" (-EFAULT),
		  "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
	if (ret < 0)
		return ret;
	return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
}

/*
@@ -294,22 +226,19 @@ crypt_s390_klmd(long func, void* param, const u8* src, long src_len)
	register long __src_len asm("3") = src_len;
	int ret;

	ret = 0;
	__asm__ __volatile__ (
		"0:	.insn	rre,0xB93F0000,%1,%1 \n" /* KLMD opcode */
		"1:	brc	1,0b \n" /* handle partical completion */
		__crypt_s390_set_result
		"6:	\n"
		__crypt_s390_fixup
		: "+d" (ret), "+a" (__src), [result] "+d" (__src_len)
		: [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
		  "a" (__param)
		: "cc", "memory"
	);
	if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
		ret = src_len - ret;
	}
	asm volatile(
		"0:	.insn	rre,0xb93f0000,%1,%1 \n" /* KLMD opcode */
		"1:	brc	1,0b \n" /* handle partial completion */
		"	ahi	%0,%h6\n"
		"2:	ahi	%0,%h7\n"
		"3:\n"
		EX_TABLE(0b,3b) EX_TABLE(1b,2b)
		: "=d" (ret), "+a" (__src), "+d" (__src_len)
		: "d" (__func), "a" (__param), "0" (-EFAULT),
		  "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
	if (ret < 0)
		return ret;
	return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
}

/*
@@ -331,22 +260,19 @@ crypt_s390_kmac(long func, void* param, const u8* src, long src_len)
	register long __src_len asm("3") = src_len;
	int ret;

	ret = 0;
	__asm__ __volatile__ (
		"0:	.insn	rre,0xB91E0000,%5,%5 \n" /* KMAC opcode */
		"1:	brc	1,0b \n" /* handle partical completion */
		__crypt_s390_set_result
		"6:	\n"
		__crypt_s390_fixup
		: "+d" (ret), "+a" (__src), [result] "+d" (__src_len)
		: [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
		  "a" (__param)
		: "cc", "memory"
	);
	if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
		ret = src_len - ret;
	}
	asm volatile(
		"0:	.insn	rre,0xb91e0000,%1,%1 \n" /* KLAC opcode */
		"1:	brc	1,0b \n" /* handle partial completion */
		"	ahi	%0,%h6\n"
		"2:	ahi	%0,%h7\n"
		"3:\n"
		EX_TABLE(0b,3b) EX_TABLE(1b,2b)
		: "=d" (ret), "+a" (__src), "+d" (__src_len)
		: "d" (__func), "a" (__param), "0" (-EFAULT),
		  "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
	if (ret < 0)
		return ret;
	return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
}

/**
+7 −16
Original line number Diff line number Diff line
@@ -333,21 +333,13 @@ static int diag204(unsigned long subcode, unsigned long size, void *addr)
	register unsigned long _subcode asm("0") = subcode;
	register unsigned long _size asm("1") = size;

	asm volatile ("   diag    %2,%0,0x204\n"
		      "0: \n" ".section __ex_table,\"a\"\n"
#ifndef __s390x__
		      "    .align 4\n"
		      "    .long  0b,0b\n"
#else
		      "    .align 8\n"
		      "    .quad  0b,0b\n"
#endif
		      ".previous":"+d" (_subcode), "+d"(_size)
		      :"d"(addr)
		      :"memory");
	asm volatile(
		"	diag	%2,%0,0x204\n"
		"0:\n"
		EX_TABLE(0b,0b)
		: "+d" (_subcode), "+d" (_size) : "d" (addr) : "memory");
	if (_subcode)
		return -1;
	else
	return _size;
}

@@ -491,8 +483,7 @@ static void *diag204_store(void)

static void diag224(void *ptr)
{
	asm volatile("   diag    %0,%1,0x224\n"
		     : :"d" (0), "d"(ptr) : "memory");
	asm volatile("diag %0,%1,0x224" : :"d" (0), "d"(ptr) : "memory");
}

static int diag224_get_name_table(void)
+1 −4
Original line number Diff line number Diff line
@@ -544,10 +544,7 @@ sys32_execve(struct pt_regs regs)
		current->ptrace &= ~PT_DTRACE;
		task_unlock(current);
		current->thread.fp_regs.fpc=0;
		__asm__ __volatile__
		        ("sr  0,0\n\t"
		         "sfpc 0,0\n\t"
			 : : :"0");
		asm volatile("sfpc %0,0" : : "d" (0));
	}
        putname(filename);
out:
+30 −53
Original line number Diff line number Diff line
@@ -25,11 +25,8 @@ static char cpcmd_buf[241];
 */
int  __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
{
	const int mask = 0x40000000L;
	unsigned long flags;
	int return_code;
	int return_len;
	int cmdlen;
	unsigned long flags, cmdlen;
	int return_code, return_len;

	spin_lock_irqsave(&cpcmd_lock, flags);
	cmdlen = strlen(cmd);
@@ -38,64 +35,44 @@ int __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
	ASCEBC(cpcmd_buf, cmdlen);

	if (response != NULL && rlen > 0) {
		register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf;
		register unsigned long reg3 asm ("3") = (addr_t) response;
		register unsigned long reg4 asm ("4") = cmdlen | 0x40000000L;
		register unsigned long reg5 asm ("5") = rlen;

		memset(response, 0, rlen);
		asm volatile(
#ifndef CONFIG_64BIT
		asm volatile (	"lra	2,0(%2)\n"
				"lr	4,%3\n"
				"o	4,%6\n"
				"lra	3,0(%4)\n"
				"lr	5,%5\n"
				"diag	2,4,0x8\n"
			"	diag	%2,%0,0x8\n"
			"	brc	8,1f\n"
				"ar	5, %5\n"
				"1: \n"
				"lr	%0,4\n"
				"lr	%1,5\n"
				: "=d" (return_code), "=d" (return_len)
				: "a" (cpcmd_buf), "d" (cmdlen),
				"a" (response), "d" (rlen), "m" (mask)
				: "cc", "2", "3", "4", "5" );
			"	ar	%1,%4\n"
#else /* CONFIG_64BIT */
                asm volatile (	"lrag	2,0(%2)\n"
				"lgr	4,%3\n"
				"o	4,%6\n"
				"lrag	3,0(%4)\n"
				"lgr	5,%5\n"
			"	sam31\n"
				"diag	2,4,0x8\n"
			"	diag	%2,%0,0x8\n"
			"	sam64\n"
			"	brc	8,1f\n"
				"agr	5, %5\n"
				"1: \n"
				"lgr	%0,4\n"
				"lgr	%1,5\n"
				: "=d" (return_code), "=d" (return_len)
				: "a" (cpcmd_buf), "d" (cmdlen),
				"a" (response), "d" (rlen), "m" (mask)
				: "cc", "2", "3", "4", "5" );
			"	agr	%1,%4\n"
#endif /* CONFIG_64BIT */
			"1:\n"
			: "+d" (reg4), "+d" (reg5)
			: "d" (reg2), "d" (reg3), "d" (rlen) : "cc");
		return_code = (int) reg4;
		return_len = (int) reg5;
                EBCASC(response, rlen);
        } else {
		register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf;
		register unsigned long reg3 asm ("3") = cmdlen;
		return_len = 0;
		asm volatile(
#ifndef CONFIG_64BIT
                asm volatile (	"lra	2,0(%1)\n"
				"lr	3,%2\n"
				"diag	2,3,0x8\n"
				"lr	%0,3\n"
				: "=d" (return_code)
				: "a" (cpcmd_buf), "d" (cmdlen)
				: "2", "3"  );
			"	diag	%1,%0,0x8\n"
#else /* CONFIG_64BIT */
                asm volatile (	"lrag	2,0(%1)\n"
				"lgr	3,%2\n"
			"	sam31\n"
				"diag	2,3,0x8\n"
			"	diag	%1,%0,0x8\n"
			"	sam64\n"
				"lgr	%0,3\n"
				: "=d" (return_code)
				: "a" (cpcmd_buf), "d" (cmdlen)
				: "2", "3" );
#endif /* CONFIG_64BIT */
			: "+d" (reg3) : "d" (reg2) : "cc");
		return_code = (int) reg3;
        }
	spin_unlock_irqrestore(&cpcmd_lock, flags);
	if (response_code != NULL)
+6 −15
Original line number Diff line number Diff line
@@ -126,18 +126,9 @@ static int diag308(unsigned long subcode, void *addr)
	asm volatile(
		"	diag	%0,%2,0x308\n"
		"0:\n"
		".section __ex_table,\"a\"\n"
#ifdef CONFIG_64BIT
		"   .align 8\n"
		"   .quad 0b, 0b\n"
#else
		"   .align 4\n"
		"   .long 0b, 0b\n"
#endif
		".previous\n"
		EX_TABLE(0b,0b)
		: "+d" (_addr), "+d" (_rc)
		: "d" (subcode) : "cc", "memory");

	return _rc;
}

Loading