Blob Blame History Raw
From: Heiko Carstens <hca@linux.ibm.com>
Date: Tue, 18 Oct 2022 13:39:43 +0200
Subject: s390/uaccess: add missing EX_TABLE entries to __clear_user(),
  copy_in_user_mvcos(), copy_in_user_mvc(), clear_user_xc() and __strnlen_user()
Git-commit: 4e1b5a86a5edfbefc9396d41b0fc1a2ebd0101b6
Patch-mainline: v6.1-rc3
References: git-fixes

For some exception types the instruction address points behind the
instruction that caused the exception. Take that into account and add
the missing exception table entries.

Cc: <stable@vger.kernel.org>
Reviewed-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
[ ptesarik: These functions are also patched:
  - copy_in_user_mvcos (cf. commit a7a08b275a8bbade798c4bdaad07ade68fe7003c)
  - copy_in_user_mvc (cf. commit a7a08b275a8bbade798c4bdaad07ade68fe7003c)
  - clear_user_xc (cf. commit 4efd417f298bc23bc8b6ac5db5ff79af5ec92ac5)
  - __strnlen_user (cf. commit e93a1cb8d2b3dccd31bde77373c8d5619f0e0a10)
Signed-off-by: Petr Tesarik <ptesarik@suse.com>
---
 arch/s390/lib/uaccess.c |   20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

--- a/arch/s390/lib/uaccess.c
+++ b/arch/s390/lib/uaccess.c
@@ -173,7 +173,7 @@ static inline unsigned long copy_in_user
 	/* FIXME: copy with reduced length. */
 	asm volatile(
 		"0: .insn ss,0xc80000000000,0(%0,%1),0(%2),0\n"
-		"   jz	  2f\n"
+		"4: jz	  2f\n"
 		"1: algr  %0,%3\n"
 		"   slgr  %1,%3\n"
 		"   slgr  %2,%3\n"
@@ -181,6 +181,7 @@ static inline unsigned long copy_in_user
 		"2:slgr  %0,%0\n"
 		"3: \n"
 		EX_TABLE(0b,3b)
+		EX_TABLE(4b,3b)
 		: "+a" (size), "+a" (to), "+a" (from), "+a" (tmp1), "=a" (tmp2)
 		: "d" (reg0) : "cc", "memory");
 	return size;
@@ -199,13 +200,13 @@ static inline unsigned long copy_in_user
 		"   bras  %3,3f\n"
 		"0: aghi  %0,257\n"
 		"1: mvc	  0(1,%1),0(%2)\n"
-		"   la	  %1,1(%1)\n"
+		"7: la	  %1,1(%1)\n"
 		"   la	  %2,1(%2)\n"
 		"   aghi  %0,-1\n"
 		"   jnz	  1b\n"
 		"   j	  5f\n"
 		"2: mvc	  0(256,%1),0(%2)\n"
-		"   la	  %1,256(%1)\n"
+		"8: la	  %1,256(%1)\n"
 		"   la	  %2,256(%2)\n"
 		"3: aghi  %0,-256\n"
 		"   jnm	  2b\n"
@@ -213,6 +214,7 @@ static inline unsigned long copy_in_user
 		"5: slgr  %0,%0\n"
 		"6: sacf  768\n"
 		EX_TABLE(1b,6b) EX_TABLE(2b,0b) EX_TABLE(4b,0b)
+		EX_TABLE(7b,6b) EX_TABLE(8b,0b)
 		: "+a" (size), "+a" (to), "+a" (from), "=a" (tmp1)
 		: : "cc", "memory");
 	return size;
@@ -234,7 +236,7 @@ static inline unsigned long clear_user_m
 	tmp1 = -4096UL;
 	asm volatile(
 		"0: .insn ss,0xc80000000000,0(%0,%1),0(%4),0\n"
-		"   jz	  4f\n"
+		"6: jz	  4f\n"
 		"1: algr  %0,%2\n"
 		"   slgr  %1,%2\n"
 		"   j	  0b\n"
@@ -244,11 +246,11 @@ static inline unsigned long clear_user_m
 		"   clgr  %0,%3\n"	/* copy crosses next page boundary? */
 		"   jnh	  5f\n"
 		"3: .insn ss,0xc80000000000,0(%3,%1),0(%4),0\n"
-		"   slgr  %0,%3\n"
+		"7: slgr  %0,%3\n"
 		"   j	  5f\n"
 		"4: slgr  %0,%0\n"
 		"5:\n"
-		EX_TABLE(0b,2b) EX_TABLE(3b,5b)
+		EX_TABLE(0b,2b) EX_TABLE(6b,2b) EX_TABLE(3b,5b) EX_TABLE(7b,5b)
 		: "+a" (size), "+a" (to), "+a" (tmp1), "=a" (tmp2)
 		: "a" (empty_zero_page), "d" (reg0) : "cc", "memory");
 	return size;
@@ -278,13 +280,14 @@ static inline unsigned long clear_user_x
 		"   slgr  %0,%2\n"
 		"   j     5f\n"
 		"2: xc    0(256,%1),0(%1)\n"
-		"   la    %1,256(%1)\n"
+		"7: la    %1,256(%1)\n"
 		"3: aghi  %0,-256\n"
 		"   jnm   2b\n"
 		"4: ex    %0,0(%3)\n"
 		"5: slgr  %0,%0\n"
 		"6: sacf  768\n"
 		EX_TABLE(1b,6b) EX_TABLE(2b,0b) EX_TABLE(4b,0b)
+		EX_TABLE(7b,0b)
 		: "+a" (size), "+a" (to), "=a" (tmp1), "=a" (tmp2)
 		: : "cc", "memory");
 	return size;
@@ -310,11 +313,12 @@ static inline unsigned long strnlen_user
 		"   slgr  %0,%0\n"
 		"   sacf  256\n"
 		"0: srst  %3,%2\n"
-		"   jo    0b\n"
+		"2: jo    0b\n"
 		"   la    %0,1(%3)\n"	/* strnlen_user results includes \0 */
 		"   slgr  %0,%1\n"
 		"1: sacf  768\n"
 		EX_TABLE(0b,1b)
+		EX_TABLE(2b,1b)
 		: "+a" (size), "+a" (src), "=a" (tmp1), "=a" (tmp2)
 		: "d" (reg0) : "cc", "memory");
 	return size;