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: bsc#1205428 LTC#200501

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>
Signed-off-by: Gerald Schaefer <geraldsc@de.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)
Acked-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
@@ -214,7 +214,7 @@ static inline unsigned long copy_in_user
 	asm volatile(
 		"   lgr	  0,%[spec]\n"
 		"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"
@@ -222,6 +222,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)
 		: [spec] "d" (0x810081UL)
 		: "cc", "memory", "0");
@@ -240,13 +241,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"
@@ -254,6 +255,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;
@@ -275,7 +277,7 @@ static inline unsigned long clear_user_m
 	asm volatile(
 		"   lr	  0,%[spec]\n"
 		"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"
@@ -285,11 +287,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), [spec] "d" (spec.val)
 		: "cc", "memory", "0");
@@ -319,13 +321,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;
@@ -351,11 +354,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)
 		:
 		: "cc", "memory", "0");