linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] MIPS: Remove get_fs/set_fs
@ 2021-03-30 17:26 Thomas Bogendoerfer
  2021-03-30 17:26 ` [PATCH 1/3] MIPS: uaccess: Added __get/__put_kernel_nofault Thomas Bogendoerfer
                   ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Thomas Bogendoerfer @ 2021-03-30 17:26 UTC (permalink / raw)
  To: linux-mips, linux-kernel; +Cc: hch

This series replaces get_fs/set_fs and removes it from MIPS arch code.

Thomas Bogendoerfer (3):
  MIPS: uaccess: Added __get/__put_kernel_nofault
  MIPS: uaccess: Remove get_fs/set_fs call sites
  MIPS: Remove get_fs/set_fs

 arch/mips/Kconfig                   |   1 -
 arch/mips/include/asm/processor.h   |   4 -
 arch/mips/include/asm/thread_info.h |   6 -
 arch/mips/include/asm/uaccess.h     | 244 +++++++++++-----------------
 arch/mips/kernel/asm-offsets.c      |   1 -
 arch/mips/kernel/process.c          |   2 -
 arch/mips/kernel/scall32-o32.S      |   4 +-
 arch/mips/kernel/traps.c            |  72 +++-----
 arch/mips/kernel/unaligned.c        | 197 ++++++++--------------
 arch/mips/lib/memset.S              |   3 -
 arch/mips/lib/strncpy_user.S        |  48 ++----
 arch/mips/lib/strnlen_user.S        |  44 ++---
 12 files changed, 215 insertions(+), 411 deletions(-)

-- 
2.29.2


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/3] MIPS: uaccess: Added __get/__put_kernel_nofault
  2021-03-30 17:26 [PATCH 0/3] MIPS: Remove get_fs/set_fs Thomas Bogendoerfer
@ 2021-03-30 17:26 ` Thomas Bogendoerfer
  2021-03-30 17:48   ` Christoph Hellwig
  2021-03-30 17:26 ` [PATCH 2/3] MIPS: uaccess: Remove get_fs/set_fs call sites Thomas Bogendoerfer
  2021-03-30 17:27 ` [PATCH 3/3] MIPS: Remove get_fs/set_fs Thomas Bogendoerfer
  2 siblings, 1 reply; 12+ messages in thread
From: Thomas Bogendoerfer @ 2021-03-30 17:26 UTC (permalink / raw)
  To: linux-mips, linux-kernel; +Cc: hch

Added __get/__put_kernel_nofault as preparation for removing
get/set_fs.

Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---
 arch/mips/include/asm/uaccess.h | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h
index d273a3857809..c5cab0b8f902 100644
--- a/arch/mips/include/asm/uaccess.h
+++ b/arch/mips/include/asm/uaccess.h
@@ -355,6 +355,18 @@ do {									\
 	(val) = __gu_tmp.t;						\
 }
 
+#define HAVE_GET_KERNEL_NOFAULT
+
+#define __get_kernel_nofault(dst, src, type, err_label)			\
+do {									\
+	int __gu_err;							\
+									\
+	__get_kernel_common(*((type *)(dst)), sizeof(type),		\
+			    (__force type *)(src));			\
+	if (unlikely(__gu_err))						\
+		goto err_label;						\
+} while (0)
+
 #ifndef CONFIG_EVA
 #define __put_kernel_common(ptr, size) __put_user_common(ptr, size)
 #else
@@ -483,6 +495,18 @@ do {									\
 
 extern void __put_user_unknown(void);
 
+#define __put_kernel_nofault(dst, src, type, err_label)			\
+do {									\
+	type __pu_val;					\
+	int __pu_err = 0;						\
+									\
+	__pu_val = *(__force type *)(src);				\
+	__put_kernel_common(((type *)(dst)), sizeof(type));		\
+	if (unlikely(__pu_err))						\
+		goto err_label;						\
+} while (0)
+
+
 /*
  * We're generating jump to subroutines which will be outside the range of
  * jump instructions
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/3] MIPS: uaccess: Remove get_fs/set_fs call sites
  2021-03-30 17:26 [PATCH 0/3] MIPS: Remove get_fs/set_fs Thomas Bogendoerfer
  2021-03-30 17:26 ` [PATCH 1/3] MIPS: uaccess: Added __get/__put_kernel_nofault Thomas Bogendoerfer
@ 2021-03-30 17:26 ` Thomas Bogendoerfer
  2021-03-30 17:49   ` Christoph Hellwig
  2021-03-30 17:27 ` [PATCH 3/3] MIPS: Remove get_fs/set_fs Thomas Bogendoerfer
  2 siblings, 1 reply; 12+ messages in thread
From: Thomas Bogendoerfer @ 2021-03-30 17:26 UTC (permalink / raw)
  To: linux-mips, linux-kernel; +Cc: hch

Use new __get_data macro to access user/kernel for functions, which
are used with user/kernel pointers. Instead of dealing with get_fs/set_fs
this macro uses a parameter to select user/kernel access.

Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---
 arch/mips/include/asm/uaccess.h |  23 ++++
 arch/mips/kernel/traps.c        |  72 ++++--------
 arch/mips/kernel/unaligned.c    | 197 ++++++++++++--------------------
 3 files changed, 116 insertions(+), 176 deletions(-)

diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h
index c5cab0b8f902..8b3a4b992ebc 100644
--- a/arch/mips/include/asm/uaccess.h
+++ b/arch/mips/include/asm/uaccess.h
@@ -355,6 +355,29 @@ do {									\
 	(val) = __gu_tmp.t;						\
 }
 
+#define __get_udata(x, ptr, size)					\
+({									\
+	int __gu_err;							\
+									\
+	__chk_user_ptr(ptr);						\
+	__get_user_common((x), size, ptr);				\
+									\
+	__gu_err;							\
+})
+
+#define __get_kdata(x, ptr, size)					\
+({									\
+	int __gu_err;							\
+									\
+	__get_kernel_common((x), size, ptr);				\
+									\
+	__gu_err;							\
+})
+
+#define __get_data(x, ptr, u)						\
+	(((u) == true) ? __get_udata((x), (ptr), sizeof(*(ptr))) :	\
+			__get_kdata((x), (ptr), sizeof(*(ptr))))
+
 #define HAVE_GET_KERNEL_NOFAULT
 
 #define __get_kernel_nofault(dst, src, type, err_label)			\
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 808b8b61ded1..6561c0c7841d 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -108,7 +108,8 @@ void (*board_bind_eic_interrupt)(int irq, int regset);
 void (*board_ebase_setup)(void);
 void(*board_cache_error_setup)(void);
 
-static void show_raw_backtrace(unsigned long reg29, const char *loglvl)
+static void show_raw_backtrace(unsigned long reg29, const char *loglvl,
+			       bool user)
 {
 	unsigned long *sp = (unsigned long *)(reg29 & ~3);
 	unsigned long addr;
@@ -120,7 +121,7 @@ static void show_raw_backtrace(unsigned long reg29, const char *loglvl)
 	while (!kstack_end(sp)) {
 		unsigned long __user *p =
 			(unsigned long __user *)(unsigned long)sp++;
-		if (__get_user(addr, p)) {
+		if (__get_data(addr, p, user)) {
 			printk("%s (Bad stack address)", loglvl);
 			break;
 		}
@@ -141,7 +142,7 @@ __setup("raw_show_trace", set_raw_show_trace);
 #endif
 
 static void show_backtrace(struct task_struct *task, const struct pt_regs *regs,
-			   const char *loglvl)
+			   const char *loglvl, bool user)
 {
 	unsigned long sp = regs->regs[29];
 	unsigned long ra = regs->regs[31];
@@ -151,7 +152,7 @@ static void show_backtrace(struct task_struct *task, const struct pt_regs *regs,
 		task = current;
 
 	if (raw_show_trace || user_mode(regs) || !__kernel_text_address(pc)) {
-		show_raw_backtrace(sp, loglvl);
+		show_raw_backtrace(sp, loglvl, user);
 		return;
 	}
 	printk("%sCall Trace:\n", loglvl);
@@ -167,7 +168,7 @@ static void show_backtrace(struct task_struct *task, const struct pt_regs *regs,
  * with at least a bit of error checking ...
  */
 static void show_stacktrace(struct task_struct *task,
-	const struct pt_regs *regs, const char *loglvl)
+	const struct pt_regs *regs, const char *loglvl, bool user)
 {
 	const int field = 2 * sizeof(unsigned long);
 	long stackdata;
@@ -186,7 +187,7 @@ static void show_stacktrace(struct task_struct *task,
 			break;
 		}
 
-		if (__get_user(stackdata, sp++)) {
+		if (__get_data(stackdata, sp++, user)) {
 			pr_cont(" (Bad stack address)");
 			break;
 		}
@@ -195,13 +196,12 @@ static void show_stacktrace(struct task_struct *task,
 		i++;
 	}
 	pr_cont("\n");
-	show_backtrace(task, regs, loglvl);
+	show_backtrace(task, regs, loglvl, user);
 }
 
 void show_stack(struct task_struct *task, unsigned long *sp, const char *loglvl)
 {
 	struct pt_regs regs;
-	mm_segment_t old_fs = get_fs();
 
 	regs.cp0_status = KSU_KERNEL;
 	if (sp) {
@@ -217,16 +217,10 @@ void show_stack(struct task_struct *task, unsigned long *sp, const char *loglvl)
 			prepare_frametrace(&regs);
 		}
 	}
-	/*
-	 * show_stack() deals exclusively with kernel mode, so be sure to access
-	 * the stack in the kernel (not user) address space.
-	 */
-	set_fs(KERNEL_DS);
-	show_stacktrace(task, &regs, loglvl);
-	set_fs(old_fs);
+	show_stacktrace(task, &regs, loglvl, false);
 }
 
-static void show_code(unsigned int __user *pc)
+static void show_code(unsigned int __user *pc, bool user)
 {
 	long i;
 	unsigned short __user *pc16 = NULL;
@@ -237,7 +231,8 @@ static void show_code(unsigned int __user *pc)
 		pc16 = (unsigned short __user *)((unsigned long)pc & ~1);
 	for(i = -3 ; i < 6 ; i++) {
 		unsigned int insn;
-		if (pc16 ? __get_user(insn, pc16 + i) : __get_user(insn, pc + i)) {
+		if (pc16 ? __get_data(insn, pc16 + i, user) :
+			   __get_data(insn, pc + i, user)) {
 			pr_cont(" (Bad address in epc)\n");
 			break;
 		}
@@ -356,7 +351,6 @@ void show_regs(struct pt_regs *regs)
 void show_registers(struct pt_regs *regs)
 {
 	const int field = 2 * sizeof(unsigned long);
-	mm_segment_t old_fs = get_fs();
 
 	__show_regs(regs);
 	print_modules();
@@ -371,13 +365,9 @@ void show_registers(struct pt_regs *regs)
 			printk("*HwTLS: %0*lx\n", field, tls);
 	}
 
-	if (!user_mode(regs))
-		/* Necessary for getting the correct stack content */
-		set_fs(KERNEL_DS);
-	show_stacktrace(current, regs, KERN_DEFAULT);
-	show_code((unsigned int __user *) regs->cp0_epc);
+	show_stacktrace(current, regs, KERN_DEFAULT, user_mode(regs));
+	show_code((unsigned int __user *) regs->cp0_epc, user_mode(regs));
 	printk("\n");
-	set_fs(old_fs);
 }
 
 static DEFINE_RAW_SPINLOCK(die_lock);
@@ -1022,18 +1012,14 @@ asmlinkage void do_bp(struct pt_regs *regs)
 	unsigned long epc = msk_isa16_mode(exception_epc(regs));
 	unsigned int opcode, bcode;
 	enum ctx_state prev_state;
-	mm_segment_t seg;
-
-	seg = get_fs();
-	if (!user_mode(regs))
-		set_fs(KERNEL_DS);
+	bool user = user_mode(regs);
 
 	prev_state = exception_enter();
 	current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
 	if (get_isa16_mode(regs->cp0_epc)) {
 		u16 instr[2];
 
-		if (__get_user(instr[0], (u16 __user *)epc))
+		if (__get_data(instr[0], (u16 __user *)epc, user))
 			goto out_sigsegv;
 
 		if (!cpu_has_mmips) {
@@ -1044,13 +1030,13 @@ asmlinkage void do_bp(struct pt_regs *regs)
 			bcode = instr[0] & 0xf;
 		} else {
 			/* 32-bit microMIPS BREAK */
-			if (__get_user(instr[1], (u16 __user *)(epc + 2)))
+			if (__get_data(instr[1], (u16 __user *)(epc + 2), user))
 				goto out_sigsegv;
 			opcode = (instr[0] << 16) | instr[1];
 			bcode = (opcode >> 6) & ((1 << 20) - 1);
 		}
 	} else {
-		if (__get_user(opcode, (unsigned int __user *)epc))
+		if (__get_data(opcode, (unsigned int __user *)epc, user))
 			goto out_sigsegv;
 		bcode = (opcode >> 6) & ((1 << 20) - 1);
 	}
@@ -1100,7 +1086,6 @@ asmlinkage void do_bp(struct pt_regs *regs)
 	do_trap_or_bp(regs, bcode, TRAP_BRKPT, "Break");
 
 out:
-	set_fs(seg);
 	exception_exit(prev_state);
 	return;
 
@@ -1114,25 +1099,21 @@ asmlinkage void do_tr(struct pt_regs *regs)
 	u32 opcode, tcode = 0;
 	enum ctx_state prev_state;
 	u16 instr[2];
-	mm_segment_t seg;
+	bool user = user_mode(regs);
 	unsigned long epc = msk_isa16_mode(exception_epc(regs));
 
-	seg = get_fs();
-	if (!user_mode(regs))
-		set_fs(KERNEL_DS);
-
 	prev_state = exception_enter();
 	current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
 	if (get_isa16_mode(regs->cp0_epc)) {
-		if (__get_user(instr[0], (u16 __user *)(epc + 0)) ||
-		    __get_user(instr[1], (u16 __user *)(epc + 2)))
+		if (__get_data(instr[0], (u16 __user *)(epc + 0), user) ||
+		    __get_data(instr[1], (u16 __user *)(epc + 2), user))
 			goto out_sigsegv;
 		opcode = (instr[0] << 16) | instr[1];
 		/* Immediate versions don't provide a code.  */
 		if (!(opcode & OPCODE))
 			tcode = (opcode >> 12) & ((1 << 4) - 1);
 	} else {
-		if (__get_user(opcode, (u32 __user *)epc))
+		if (__get_data(opcode, (u32 __user *)epc, user))
 			goto out_sigsegv;
 		/* Immediate versions don't provide a code.  */
 		if (!(opcode & OPCODE))
@@ -1142,7 +1123,6 @@ asmlinkage void do_tr(struct pt_regs *regs)
 	do_trap_or_bp(regs, tcode, 0, "Trap");
 
 out:
-	set_fs(seg);
 	exception_exit(prev_state);
 	return;
 
@@ -1591,7 +1571,6 @@ asmlinkage void do_mcheck(struct pt_regs *regs)
 {
 	int multi_match = regs->cp0_status & ST0_TS;
 	enum ctx_state prev_state;
-	mm_segment_t old_fs = get_fs();
 
 	prev_state = exception_enter();
 	show_regs(regs);
@@ -1602,12 +1581,7 @@ asmlinkage void do_mcheck(struct pt_regs *regs)
 		dump_tlb_all();
 	}
 
-	if (!user_mode(regs))
-		set_fs(KERNEL_DS);
-
-	show_code((unsigned int __user *) regs->cp0_epc);
-
-	set_fs(old_fs);
+	show_code((unsigned int __user *) regs->cp0_epc, user_mode(regs));
 
 	/*
 	 * Some chips may have other causes of machine check (e.g. SB1
diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c
index 126a5f3f4e4c..fa005cdee0c7 100644
--- a/arch/mips/kernel/unaligned.c
+++ b/arch/mips/kernel/unaligned.c
@@ -112,9 +112,8 @@ static void emulate_load_store_insn(struct pt_regs *regs,
 	unsigned long origpc, orig31, value;
 	union mips_instruction insn;
 	unsigned int res;
-#ifdef	CONFIG_EVA
-	mm_segment_t seg;
-#endif
+	bool user = user_mode(regs);
+
 	origpc = (unsigned long)pc;
 	orig31 = regs->regs[31];
 
@@ -123,7 +122,7 @@ static void emulate_load_store_insn(struct pt_regs *regs,
 	/*
 	 * This load never faults.
 	 */
-	__get_user(insn.word, pc);
+	__get_data(insn.word, pc, user);
 
 	switch (insn.i_format.opcode) {
 		/*
@@ -163,7 +162,7 @@ static void emulate_load_store_insn(struct pt_regs *regs,
 		if (insn.dsp_format.func == lx_op) {
 			switch (insn.dsp_format.op) {
 			case lwx_op:
-				if (!access_ok(addr, 4))
+				if (user && !access_ok(addr, 4))
 					goto sigbus;
 				LoadW(addr, value, res);
 				if (res)
@@ -172,7 +171,7 @@ static void emulate_load_store_insn(struct pt_regs *regs,
 				regs->regs[insn.dsp_format.rd] = value;
 				break;
 			case lhx_op:
-				if (!access_ok(addr, 2))
+				if (user && !access_ok(addr, 2))
 					goto sigbus;
 				LoadHW(addr, value, res);
 				if (res)
@@ -191,93 +190,66 @@ static void emulate_load_store_insn(struct pt_regs *regs,
 			 * memory, so we need to "switch" the address limit to
 			 * user space, so that address check can work properly.
 			 */
-			seg = force_uaccess_begin();
 			switch (insn.spec3_format.func) {
 			case lhe_op:
-				if (!access_ok(addr, 2)) {
-					force_uaccess_end(seg);
+				if (!access_ok(addr, 2))
 					goto sigbus;
-				}
 				LoadHWE(addr, value, res);
-				if (res) {
-					force_uaccess_end(seg);
+				if (res)
 					goto fault;
-				}
 				compute_return_epc(regs);
 				regs->regs[insn.spec3_format.rt] = value;
 				break;
 			case lwe_op:
-				if (!access_ok(addr, 4)) {
-					force_uaccess_end(seg);
+				if (!access_ok(addr, 4))
 					goto sigbus;
-				}
 				LoadWE(addr, value, res);
-				if (res) {
-					force_uaccess_end(seg);
+				if (res)
 					goto fault;
-				}
 				compute_return_epc(regs);
 				regs->regs[insn.spec3_format.rt] = value;
 				break;
 			case lhue_op:
-				if (!access_ok(addr, 2)) {
-					force_uaccess_end(seg);
+				if (!access_ok(addr, 2))
 					goto sigbus;
-				}
 				LoadHWUE(addr, value, res);
-				if (res) {
-					force_uaccess_end(seg);
+				if (res)
 					goto fault;
-				}
 				compute_return_epc(regs);
 				regs->regs[insn.spec3_format.rt] = value;
 				break;
 			case she_op:
-				if (!access_ok(addr, 2)) {
-					force_uaccess_end(seg);
+				if (!access_ok(addr, 2))
 					goto sigbus;
-				}
 				compute_return_epc(regs);
 				value = regs->regs[insn.spec3_format.rt];
 				StoreHWE(addr, value, res);
-				if (res) {
-					force_uaccess_end(seg);
+				if (res)
 					goto fault;
-				}
 				break;
 			case swe_op:
-				if (!access_ok(addr, 4)) {
-					force_uaccess_end(seg);
+				if (!access_ok(addr, 4))
 					goto sigbus;
-				}
 				compute_return_epc(regs);
 				value = regs->regs[insn.spec3_format.rt];
 				StoreWE(addr, value, res);
-				if (res) {
-					force_uaccess_end(seg);
+				if (res)
 					goto fault;
-				}
 				break;
 			default:
-				force_uaccess_end(seg);
 				goto sigill;
 			}
-			force_uaccess_end(seg);
 		}
 #endif
 		break;
 	case lh_op:
-		if (!access_ok(addr, 2))
+		if (user && !access_ok(addr, 2))
 			goto sigbus;
 
-		if (IS_ENABLED(CONFIG_EVA)) {
-			if (uaccess_kernel())
-				LoadHW(addr, value, res);
-			else
-				LoadHWE(addr, value, res);
-		} else {
+		if (IS_ENABLED(CONFIG_EVA) && user)
+			LoadHWE(addr, value, res);
+		else
 			LoadHW(addr, value, res);
-		}
 
 		if (res)
 			goto fault;
@@ -286,17 +258,13 @@ static void emulate_load_store_insn(struct pt_regs *regs,
 		break;
 
 	case lw_op:
-		if (!access_ok(addr, 4))
+		if (user && !access_ok(addr, 4))
 			goto sigbus;
 
-		if (IS_ENABLED(CONFIG_EVA)) {
-			if (uaccess_kernel())
-				LoadW(addr, value, res);
-			else
-				LoadWE(addr, value, res);
-		} else {
+		if (IS_ENABLED(CONFIG_EVA) && user)
+			LoadWE(addr, value, res);
+		else
 			LoadW(addr, value, res);
-		}
 
 		if (res)
 			goto fault;
@@ -305,17 +273,13 @@ static void emulate_load_store_insn(struct pt_regs *regs,
 		break;
 
 	case lhu_op:
-		if (!access_ok(addr, 2))
+		if (user && !access_ok(addr, 2))
 			goto sigbus;
 
-		if (IS_ENABLED(CONFIG_EVA)) {
-			if (uaccess_kernel())
-				LoadHWU(addr, value, res);
-			else
-				LoadHWUE(addr, value, res);
-		} else {
+		if (IS_ENABLED(CONFIG_EVA) && user)
+			LoadHWUE(addr, value, res);
+		else
 			LoadHWU(addr, value, res);
-		}
 
 		if (res)
 			goto fault;
@@ -332,7 +296,7 @@ static void emulate_load_store_insn(struct pt_regs *regs,
 		 * would blow up, so for now we don't handle unaligned 64-bit
 		 * instructions on 32-bit kernels.
 		 */
-		if (!access_ok(addr, 4))
+		if (user && !access_ok(addr, 4))
 			goto sigbus;
 
 		LoadWU(addr, value, res);
@@ -355,7 +319,7 @@ static void emulate_load_store_insn(struct pt_regs *regs,
 		 * would blow up, so for now we don't handle unaligned 64-bit
 		 * instructions on 32-bit kernels.
 		 */
-		if (!access_ok(addr, 8))
+		if (user && !access_ok(addr, 8))
 			goto sigbus;
 
 		LoadDW(addr, value, res);
@@ -370,40 +334,32 @@ static void emulate_load_store_insn(struct pt_regs *regs,
 		goto sigill;
 
 	case sh_op:
-		if (!access_ok(addr, 2))
+		if (user && !access_ok(addr, 2))
 			goto sigbus;
 
 		compute_return_epc(regs);
 		value = regs->regs[insn.i_format.rt];
 
-		if (IS_ENABLED(CONFIG_EVA)) {
-			if (uaccess_kernel())
-				StoreHW(addr, value, res);
-			else
-				StoreHWE(addr, value, res);
-		} else {
+		if (IS_ENABLED(CONFIG_EVA) && user)
+			StoreHWE(addr, value, res);
+		else
 			StoreHW(addr, value, res);
-		}
 
 		if (res)
 			goto fault;
 		break;
 
 	case sw_op:
-		if (!access_ok(addr, 4))
+		if (user && !access_ok(addr, 4))
 			goto sigbus;
 
 		compute_return_epc(regs);
 		value = regs->regs[insn.i_format.rt];
 
-		if (IS_ENABLED(CONFIG_EVA)) {
-			if (uaccess_kernel())
-				StoreW(addr, value, res);
-			else
-				StoreWE(addr, value, res);
-		} else {
+		if (IS_ENABLED(CONFIG_EVA) && user)
+			StoreWE(addr, value, res);
+		else
 			StoreW(addr, value, res);
-		}
 
 		if (res)
 			goto fault;
@@ -418,7 +374,7 @@ static void emulate_load_store_insn(struct pt_regs *regs,
 		 * would blow up, so for now we don't handle unaligned 64-bit
 		 * instructions on 32-bit kernels.
 		 */
-		if (!access_ok(addr, 8))
+		if (user && !access_ok(addr, 8))
 			goto sigbus;
 
 		compute_return_epc(regs);
@@ -626,6 +582,7 @@ static void emulate_load_store_microMIPS(struct pt_regs *regs,
 	unsigned long origpc, contpc;
 	union mips_instruction insn;
 	struct mm_decoded_insn mminsn;
+	bool user = user_mode(regs);
 
 	origpc = regs->cp0_epc;
 	orig31 = regs->regs[31];
@@ -689,7 +646,7 @@ static void emulate_load_store_microMIPS(struct pt_regs *regs,
 			if (reg == 31)
 				goto sigbus;
 
-			if (!access_ok(addr, 8))
+			if (user && !access_ok(addr, 8))
 				goto sigbus;
 
 			LoadW(addr, value, res);
@@ -708,7 +665,7 @@ static void emulate_load_store_microMIPS(struct pt_regs *regs,
 			if (reg == 31)
 				goto sigbus;
 
-			if (!access_ok(addr, 8))
+			if (user && !access_ok(addr, 8))
 				goto sigbus;
 
 			value = regs->regs[reg];
@@ -728,7 +685,7 @@ static void emulate_load_store_microMIPS(struct pt_regs *regs,
 			if (reg == 31)
 				goto sigbus;
 
-			if (!access_ok(addr, 16))
+			if (user && !access_ok(addr, 16))
 				goto sigbus;
 
 			LoadDW(addr, value, res);
@@ -751,7 +708,7 @@ static void emulate_load_store_microMIPS(struct pt_regs *regs,
 			if (reg == 31)
 				goto sigbus;
 
-			if (!access_ok(addr, 16))
+			if (user && !access_ok(addr, 16))
 				goto sigbus;
 
 			value = regs->regs[reg];
@@ -774,10 +731,10 @@ static void emulate_load_store_microMIPS(struct pt_regs *regs,
 			if ((rvar > 9) || !reg)
 				goto sigill;
 			if (reg & 0x10) {
-				if (!access_ok(addr, 4 * (rvar + 1)))
+				if (user && !access_ok(addr, 4 * (rvar + 1)))
 					goto sigbus;
 			} else {
-				if (!access_ok(addr, 4 * rvar))
+				if (user && !access_ok(addr, 4 * rvar))
 					goto sigbus;
 			}
 			if (rvar == 9)
@@ -810,10 +767,10 @@ static void emulate_load_store_microMIPS(struct pt_regs *regs,
 			if ((rvar > 9) || !reg)
 				goto sigill;
 			if (reg & 0x10) {
-				if (!access_ok(addr, 4 * (rvar + 1)))
+				if (user && !access_ok(addr, 4 * (rvar + 1)))
 					goto sigbus;
 			} else {
-				if (!access_ok(addr, 4 * rvar))
+				if (user && !access_ok(addr, 4 * rvar))
 					goto sigbus;
 			}
 			if (rvar == 9)
@@ -847,10 +804,10 @@ static void emulate_load_store_microMIPS(struct pt_regs *regs,
 			if ((rvar > 9) || !reg)
 				goto sigill;
 			if (reg & 0x10) {
-				if (!access_ok(addr, 8 * (rvar + 1)))
+				if (user && !access_ok(addr, 8 * (rvar + 1)))
 					goto sigbus;
 			} else {
-				if (!access_ok(addr, 8 * rvar))
+				if (user && !access_ok(addr, 8 * rvar))
 					goto sigbus;
 			}
 			if (rvar == 9)
@@ -888,10 +845,10 @@ static void emulate_load_store_microMIPS(struct pt_regs *regs,
 			if ((rvar > 9) || !reg)
 				goto sigill;
 			if (reg & 0x10) {
-				if (!access_ok(addr, 8 * (rvar + 1)))
+				if (user && !access_ok(addr, 8 * (rvar + 1)))
 					goto sigbus;
 			} else {
-				if (!access_ok(addr, 8 * rvar))
+				if (user && !access_ok(addr, 8 * rvar))
 					goto sigbus;
 			}
 			if (rvar == 9)
@@ -1010,7 +967,7 @@ static void emulate_load_store_microMIPS(struct pt_regs *regs,
 		case mm_lwm16_op:
 			reg = insn.mm16_m_format.rlist;
 			rvar = reg + 1;
-			if (!access_ok(addr, 4 * rvar))
+			if (user && !access_ok(addr, 4 * rvar))
 				goto sigbus;
 
 			for (i = 16; rvar; rvar--, i++) {
@@ -1030,7 +987,7 @@ static void emulate_load_store_microMIPS(struct pt_regs *regs,
 		case mm_swm16_op:
 			reg = insn.mm16_m_format.rlist;
 			rvar = reg + 1;
-			if (!access_ok(addr, 4 * rvar))
+			if (user && !access_ok(addr, 4 * rvar))
 				goto sigbus;
 
 			for (i = 16; rvar; rvar--, i++) {
@@ -1084,7 +1041,7 @@ static void emulate_load_store_microMIPS(struct pt_regs *regs,
 	}
 
 loadHW:
-	if (!access_ok(addr, 2))
+	if (user && !access_ok(addr, 2))
 		goto sigbus;
 
 	LoadHW(addr, value, res);
@@ -1094,7 +1051,7 @@ static void emulate_load_store_microMIPS(struct pt_regs *regs,
 	goto success;
 
 loadHWU:
-	if (!access_ok(addr, 2))
+	if (user && !access_ok(addr, 2))
 		goto sigbus;
 
 	LoadHWU(addr, value, res);
@@ -1104,7 +1061,7 @@ static void emulate_load_store_microMIPS(struct pt_regs *regs,
 	goto success;
 
 loadW:
-	if (!access_ok(addr, 4))
+	if (user && !access_ok(addr, 4))
 		goto sigbus;
 
 	LoadW(addr, value, res);
@@ -1122,7 +1079,7 @@ static void emulate_load_store_microMIPS(struct pt_regs *regs,
 	 * would blow up, so for now we don't handle unaligned 64-bit
 	 * instructions on 32-bit kernels.
 	 */
-	if (!access_ok(addr, 4))
+	if (user && !access_ok(addr, 4))
 		goto sigbus;
 
 	LoadWU(addr, value, res);
@@ -1144,7 +1101,7 @@ static void emulate_load_store_microMIPS(struct pt_regs *regs,
 	 * would blow up, so for now we don't handle unaligned 64-bit
 	 * instructions on 32-bit kernels.
 	 */
-	if (!access_ok(addr, 8))
+	if (user && !access_ok(addr, 8))
 		goto sigbus;
 
 	LoadDW(addr, value, res);
@@ -1158,7 +1115,7 @@ static void emulate_load_store_microMIPS(struct pt_regs *regs,
 	goto sigill;
 
 storeHW:
-	if (!access_ok(addr, 2))
+	if (user && !access_ok(addr, 2))
 		goto sigbus;
 
 	value = regs->regs[reg];
@@ -1168,7 +1125,7 @@ static void emulate_load_store_microMIPS(struct pt_regs *regs,
 	goto success;
 
 storeW:
-	if (!access_ok(addr, 4))
+	if (user && !access_ok(addr, 4))
 		goto sigbus;
 
 	value = regs->regs[reg];
@@ -1186,7 +1143,7 @@ static void emulate_load_store_microMIPS(struct pt_regs *regs,
 	 * would blow up, so for now we don't handle unaligned 64-bit
 	 * instructions on 32-bit kernels.
 	 */
-	if (!access_ok(addr, 8))
+	if (user && !access_ok(addr, 8))
 		goto sigbus;
 
 	value = regs->regs[reg];
@@ -1243,6 +1200,7 @@ static void emulate_load_store_MIPS16e(struct pt_regs *regs, void __user * addr)
 	union mips16e_instruction mips16inst, oldinst;
 	unsigned int opcode;
 	int extended = 0;
+	bool user = user_mode(regs);
 
 	origpc = regs->cp0_epc;
 	orig31 = regs->regs[31];
@@ -1344,7 +1302,7 @@ static void emulate_load_store_MIPS16e(struct pt_regs *regs, void __user * addr)
 		goto sigbus;
 
 	case MIPS16e_lh_op:
-		if (!access_ok(addr, 2))
+		if (user && !access_ok(addr, 2))
 			goto sigbus;
 
 		LoadHW(addr, value, res);
@@ -1355,7 +1313,7 @@ static void emulate_load_store_MIPS16e(struct pt_regs *regs, void __user * addr)
 		break;
 
 	case MIPS16e_lhu_op:
-		if (!access_ok(addr, 2))
+		if (user && !access_ok(addr, 2))
 			goto sigbus;
 
 		LoadHWU(addr, value, res);
@@ -1368,7 +1326,7 @@ static void emulate_load_store_MIPS16e(struct pt_regs *regs, void __user * addr)
 	case MIPS16e_lw_op:
 	case MIPS16e_lwpc_op:
 	case MIPS16e_lwsp_op:
-		if (!access_ok(addr, 4))
+		if (user && !access_ok(addr, 4))
 			goto sigbus;
 
 		LoadW(addr, value, res);
@@ -1387,7 +1345,7 @@ static void emulate_load_store_MIPS16e(struct pt_regs *regs, void __user * addr)
 		 * would blow up, so for now we don't handle unaligned 64-bit
 		 * instructions on 32-bit kernels.
 		 */
-		if (!access_ok(addr, 4))
+		if (user && !access_ok(addr, 4))
 			goto sigbus;
 
 		LoadWU(addr, value, res);
@@ -1411,7 +1369,7 @@ static void emulate_load_store_MIPS16e(struct pt_regs *regs, void __user * addr)
 		 * would blow up, so for now we don't handle unaligned 64-bit
 		 * instructions on 32-bit kernels.
 		 */
-		if (!access_ok(addr, 8))
+		if (user && !access_ok(addr, 8))
 			goto sigbus;
 
 		LoadDW(addr, value, res);
@@ -1426,7 +1384,7 @@ static void emulate_load_store_MIPS16e(struct pt_regs *regs, void __user * addr)
 		goto sigill;
 
 	case MIPS16e_sh_op:
-		if (!access_ok(addr, 2))
+		if (user && !access_ok(addr, 2))
 			goto sigbus;
 
 		MIPS16e_compute_return_epc(regs, &oldinst);
@@ -1439,7 +1397,7 @@ static void emulate_load_store_MIPS16e(struct pt_regs *regs, void __user * addr)
 	case MIPS16e_sw_op:
 	case MIPS16e_swsp_op:
 	case MIPS16e_i8_op:	/* actually - MIPS16e_swrasp_func */
-		if (!access_ok(addr, 4))
+		if (user && !access_ok(addr, 4))
 			goto sigbus;
 
 		MIPS16e_compute_return_epc(regs, &oldinst);
@@ -1459,7 +1417,7 @@ static void emulate_load_store_MIPS16e(struct pt_regs *regs, void __user * addr)
 		 * would blow up, so for now we don't handle unaligned 64-bit
 		 * instructions on 32-bit kernels.
 		 */
-		if (!access_ok(addr, 8))
+		if (user && !access_ok(addr, 8))
 			goto sigbus;
 
 		MIPS16e_compute_return_epc(regs, &oldinst);
@@ -1516,7 +1474,6 @@ asmlinkage void do_ade(struct pt_regs *regs)
 {
 	enum ctx_state prev_state;
 	unsigned int __user *pc;
-	mm_segment_t seg;
 
 	prev_state = exception_enter();
 	perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS,
@@ -1551,24 +1508,14 @@ asmlinkage void do_ade(struct pt_regs *regs)
 			show_registers(regs);
 
 		if (cpu_has_mmips) {
-			seg = get_fs();
-			if (!user_mode(regs))
-				set_fs(KERNEL_DS);
 			emulate_load_store_microMIPS(regs,
 				(void __user *)regs->cp0_badvaddr);
-			set_fs(seg);
-
 			return;
 		}
 
 		if (cpu_has_mips16) {
-			seg = get_fs();
-			if (!user_mode(regs))
-				set_fs(KERNEL_DS);
 			emulate_load_store_MIPS16e(regs,
 				(void __user *)regs->cp0_badvaddr);
-			set_fs(seg);
-
 			return;
 		}
 
@@ -1579,11 +1526,7 @@ asmlinkage void do_ade(struct pt_regs *regs)
 		show_registers(regs);
 	pc = (unsigned int __user *)exception_epc(regs);
 
-	seg = get_fs();
-	if (!user_mode(regs))
-		set_fs(KERNEL_DS);
 	emulate_load_store_insn(regs, (void __user *)regs->cp0_badvaddr, pc);
-	set_fs(seg);
 
 	return;
 
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/3] MIPS: Remove get_fs/set_fs
  2021-03-30 17:26 [PATCH 0/3] MIPS: Remove get_fs/set_fs Thomas Bogendoerfer
  2021-03-30 17:26 ` [PATCH 1/3] MIPS: uaccess: Added __get/__put_kernel_nofault Thomas Bogendoerfer
  2021-03-30 17:26 ` [PATCH 2/3] MIPS: uaccess: Remove get_fs/set_fs call sites Thomas Bogendoerfer
@ 2021-03-30 17:27 ` Thomas Bogendoerfer
  2021-03-30 17:54   ` Christoph Hellwig
  2021-03-31  1:38   ` kernel test robot
  2 siblings, 2 replies; 12+ messages in thread
From: Thomas Bogendoerfer @ 2021-03-30 17:27 UTC (permalink / raw)
  To: linux-mips, linux-kernel; +Cc: hch

All get_fs/set_fs calls in MIPS code are gone, so remove implementation
of it.  With the clear separation of user/kernel space access we no
longer need the EVA special handling, so get rid of that, too.

Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---
 arch/mips/Kconfig                   |   1 -
 arch/mips/include/asm/processor.h   |   4 -
 arch/mips/include/asm/thread_info.h |   6 -
 arch/mips/include/asm/uaccess.h     | 197 +++++++---------------------
 arch/mips/kernel/asm-offsets.c      |   1 -
 arch/mips/kernel/process.c          |   2 -
 arch/mips/kernel/scall32-o32.S      |   4 +-
 arch/mips/lib/memset.S              |   3 -
 arch/mips/lib/strncpy_user.S        |  48 ++-----
 arch/mips/lib/strnlen_user.S        |  44 ++-----
 10 files changed, 75 insertions(+), 235 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index b72458215d20..70faa0686444 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -93,7 +93,6 @@ config MIPS
 	select PERF_USE_VMALLOC
 	select PCI_MSI_ARCH_FALLBACKS if PCI_MSI
 	select RTC_LIB
-	select SET_FS
 	select SYSCTL_EXCEPTION_TRACE
 	select VIRT_TO_BUS
 	select ARCH_HAS_ELFCORE_COMPAT
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
index 8e69e0a35ee9..0c3550c82b72 100644
--- a/arch/mips/include/asm/processor.h
+++ b/arch/mips/include/asm/processor.h
@@ -221,10 +221,6 @@ struct nlm_cop2_state {
 #define COP2_INIT
 #endif
 
-typedef struct {
-	unsigned long seg;
-} mm_segment_t;
-
 #ifdef CONFIG_CPU_HAS_MSA
 # define ARCH_MIN_TASKALIGN	16
 # define FPU_ALIGN		__aligned(16)
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h
index e2c352da3877..0b17aaa9e012 100644
--- a/arch/mips/include/asm/thread_info.h
+++ b/arch/mips/include/asm/thread_info.h
@@ -28,11 +28,6 @@ struct thread_info {
 	unsigned long		tp_value;	/* thread pointer */
 	__u32			cpu;		/* current CPU */
 	int			preempt_count;	/* 0 => preemptable, <0 => BUG */
-	mm_segment_t		addr_limit;	/*
-						 * thread address space limit:
-						 * 0x7fffffff for user-thead
-						 * 0xffffffff for kernel-thread
-						 */
 	struct pt_regs		*regs;
 	long			syscall;	/* syscall number */
 };
@@ -46,7 +41,6 @@ struct thread_info {
 	.flags		= _TIF_FIXADE,		\
 	.cpu		= 0,			\
 	.preempt_count	= INIT_PREEMPT_COUNT,	\
-	.addr_limit	= KERNEL_DS,		\
 }
 
 /*
diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h
index 8b3a4b992ebc..5b1fd2e97f57 100644
--- a/arch/mips/include/asm/uaccess.h
+++ b/arch/mips/include/asm/uaccess.h
@@ -16,13 +16,6 @@
 #include <asm/asm-eva.h>
 #include <asm/extable.h>
 
-/*
- * The fs value determines whether argument validity checking should be
- * performed or not.  If get_fs() == USER_DS, checking is performed, with
- * get_fs() == KERNEL_DS, checking is bypassed.
- *
- * For historical reasons, these macros are grossly misnamed.
- */
 #ifdef CONFIG_32BIT
 
 #define __UA_LIMIT 0x80000000UL
@@ -49,38 +42,6 @@ extern u64 __ua_limit;
 
 #endif /* CONFIG_64BIT */
 
-/*
- * USER_DS is a bitmask that has the bits set that may not be set in a valid
- * userspace address.  Note that we limit 32-bit userspace to 0x7fff8000 but
- * the arithmetic we're doing only works if the limit is a power of two, so
- * we use 0x80000000 here on 32-bit kernels.  If a process passes an invalid
- * address in this range it's the process's problem, not ours :-)
- */
-
-#define KERNEL_DS	((mm_segment_t) { 0UL })
-#define USER_DS		((mm_segment_t) { __UA_LIMIT })
-
-#define get_fs()	(current_thread_info()->addr_limit)
-#define set_fs(x)	(current_thread_info()->addr_limit = (x))
-
-#define uaccess_kernel()	(get_fs().seg == KERNEL_DS.seg)
-
-/*
- * eva_kernel_access() - determine whether kernel memory access on an EVA system
- *
- * Determines whether memory accesses should be performed to kernel memory
- * on a system using Extended Virtual Addressing (EVA).
- *
- * Return: true if a kernel memory access on an EVA system, else false.
- */
-static inline bool eva_kernel_access(void)
-{
-	if (!IS_ENABLED(CONFIG_EVA))
-		return false;
-
-	return uaccess_kernel();
-}
-
 /*
  * Is a address valid? This does a straightforward calculation rather
  * than tests.
@@ -118,7 +79,7 @@ static inline bool eva_kernel_access(void)
 static inline int __access_ok(const void __user *p, unsigned long size)
 {
 	unsigned long addr = (unsigned long)p;
-	return (get_fs().seg & (addr | (addr + size) | __ua_size(size))) == 0;
+	return (__UA_LIMIT & (addr | (addr + size) | __ua_size(size))) == 0;
 }
 
 #define access_ok(addr, size)					\
@@ -276,12 +237,9 @@ do {									\
 ({									\
 	int __gu_err;							\
 									\
-	if (eva_kernel_access()) {					\
-		__get_kernel_common((x), size, ptr);			\
-	} else {							\
-		__chk_user_ptr(ptr);					\
-		__get_user_common((x), size, ptr);			\
-	}								\
+	__chk_user_ptr(ptr);						\
+	__get_user_common((x), size, ptr);				\
+									\
 	__gu_err;							\
 })
 
@@ -291,11 +249,8 @@ do {									\
 	const __typeof__(*(ptr)) __user * __gu_ptr = (ptr);		\
 									\
 	might_fault();							\
-	if (likely(access_ok( __gu_ptr, size))) {		\
-		if (eva_kernel_access())				\
-			__get_kernel_common((x), size, __gu_ptr);	\
-		else							\
-			__get_user_common((x), size, __gu_ptr);		\
+	if (likely(access_ok(__gu_ptr, size))) {			\
+		__get_user_common((x), size, __gu_ptr);			\
 	} else								\
 		(x) = 0;						\
 									\
@@ -452,12 +407,9 @@ do {									\
 	int __pu_err = 0;						\
 									\
 	__pu_val = (x);							\
-	if (eva_kernel_access()) {					\
-		__put_kernel_common(ptr, size);				\
-	} else {							\
-		__chk_user_ptr(ptr);					\
-		__put_user_common(ptr, size);				\
-	}								\
+	__chk_user_ptr(ptr);						\
+	__put_user_common(ptr, size);					\
+									\
 	__pu_err;							\
 })
 
@@ -468,11 +420,8 @@ do {									\
 	int __pu_err = -EFAULT;						\
 									\
 	might_fault();							\
-	if (likely(access_ok( __pu_addr, size))) {	\
-		if (eva_kernel_access())				\
-			__put_kernel_common(__pu_addr, size);		\
-		else							\
-			__put_user_common(__pu_addr, size);		\
+	if (likely(access_ok(__pu_addr, size))) {			\
+		__put_user_common(__pu_addr, size);			\
 	}								\
 									\
 	__pu_err;							\
@@ -595,15 +544,6 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n);
 	__cu_len_r;							\
 })
 
-#define __invoke_copy_from_kernel(to, from, n)				\
-	__invoke_copy_from(__copy_user, to, from, n)
-
-#define __invoke_copy_to_kernel(to, from, n)				\
-	__invoke_copy_to(__copy_user, to, from, n)
-
-#define ___invoke_copy_in_kernel(to, from, n)				\
-	__invoke_copy_from(__copy_user, to, from, n)
-
 #ifndef CONFIG_EVA
 #define __invoke_copy_from_user(to, from, n)				\
 	__invoke_copy_from(__copy_user, to, from, n)
@@ -642,19 +582,13 @@ extern size_t __copy_in_user_eva(void *__to, const void *__from, size_t __n);
 static inline unsigned long
 raw_copy_to_user(void __user *to, const void *from, unsigned long n)
 {
-	if (eva_kernel_access())
-		return __invoke_copy_to_kernel(to, from, n);
-	else
-		return __invoke_copy_to_user(to, from, n);
+	return __invoke_copy_to_user(to, from, n);
 }
 
 static inline unsigned long
 raw_copy_from_user(void *to, const void __user *from, unsigned long n)
 {
-	if (eva_kernel_access())
-		return __invoke_copy_from_kernel(to, from, n);
-	else
-		return __invoke_copy_from_user(to, from, n);
+	return __invoke_copy_from_user(to, from, n);
 }
 
 #define INLINE_COPY_FROM_USER
@@ -663,13 +597,9 @@ raw_copy_from_user(void *to, const void __user *from, unsigned long n)
 static inline unsigned long
 raw_copy_in_user(void __user*to, const void __user *from, unsigned long n)
 {
-	if (eva_kernel_access())
-		return ___invoke_copy_in_kernel(to, from, n);
-	else
-		return ___invoke_copy_in_user(to, from,	n);
+	return ___invoke_copy_in_user(to, from,	n);
 }
 
-extern __kernel_size_t __bzero_kernel(void __user *addr, __kernel_size_t size);
 extern __kernel_size_t __bzero(void __user *addr, __kernel_size_t size);
 
 /*
@@ -695,28 +625,16 @@ __clear_user(void __user *addr, __kernel_size_t size)
 #define bzero_clobbers "$4", "$5", "$6", __UA_t0, __UA_t1, "$31"
 #endif /* CONFIG_CPU_MICROMIPS */
 
-	if (eva_kernel_access()) {
-		__asm__ __volatile__(
-			"move\t$4, %1\n\t"
-			"move\t$5, $0\n\t"
-			"move\t$6, %2\n\t"
-			__MODULE_JAL(__bzero_kernel)
-			"move\t%0, $6"
-			: "=r" (res)
-			: "r" (addr), "r" (size)
-			: bzero_clobbers);
-	} else {
-		might_fault();
-		__asm__ __volatile__(
-			"move\t$4, %1\n\t"
-			"move\t$5, $0\n\t"
-			"move\t$6, %2\n\t"
-			__MODULE_JAL(__bzero)
-			"move\t%0, $6"
-			: "=r" (res)
-			: "r" (addr), "r" (size)
-			: bzero_clobbers);
-	}
+	might_fault();
+	__asm__ __volatile__(
+		"move\t$4, %1\n\t"
+		"move\t$5, $0\n\t"
+		"move\t$6, %2\n\t"
+		__MODULE_JAL(__bzero)
+		"move\t%0, $6"
+		: "=r" (res)
+		: "r" (addr), "r" (size)
+		: bzero_clobbers);
 
 	return res;
 }
@@ -730,7 +648,6 @@ __clear_user(void __user *addr, __kernel_size_t size)
 	__cl_size;							\
 })
 
-extern long __strncpy_from_kernel_asm(char *__to, const char __user *__from, long __len);
 extern long __strncpy_from_user_asm(char *__to, const char __user *__from, long __len);
 
 /*
@@ -756,33 +673,23 @@ strncpy_from_user(char *__to, const char __user *__from, long __len)
 {
 	long res;
 
-	if (eva_kernel_access()) {
-		__asm__ __volatile__(
-			"move\t$4, %1\n\t"
-			"move\t$5, %2\n\t"
-			"move\t$6, %3\n\t"
-			__MODULE_JAL(__strncpy_from_kernel_asm)
-			"move\t%0, $2"
-			: "=r" (res)
-			: "r" (__to), "r" (__from), "r" (__len)
-			: "$2", "$3", "$4", "$5", "$6", __UA_t0, "$31", "memory");
-	} else {
-		might_fault();
-		__asm__ __volatile__(
-			"move\t$4, %1\n\t"
-			"move\t$5, %2\n\t"
-			"move\t$6, %3\n\t"
-			__MODULE_JAL(__strncpy_from_user_asm)
-			"move\t%0, $2"
-			: "=r" (res)
-			: "r" (__to), "r" (__from), "r" (__len)
-			: "$2", "$3", "$4", "$5", "$6", __UA_t0, "$31", "memory");
-	}
+	if (!access_ok(__from, __len))
+		return -EFAULT;
+
+	might_fault();
+	__asm__ __volatile__(
+		"move\t$4, %1\n\t"
+		"move\t$5, %2\n\t"
+		"move\t$6, %3\n\t"
+		__MODULE_JAL(__strncpy_from_user_asm)
+		"move\t%0, $2"
+		: "=r" (res)
+		: "r" (__to), "r" (__from), "r" (__len)
+		: "$2", "$3", "$4", "$5", "$6", __UA_t0, "$31", "memory");
 
 	return res;
 }
 
-extern long __strnlen_kernel_asm(const char __user *s, long n);
 extern long __strnlen_user_asm(const char __user *s, long n);
 
 /*
@@ -802,26 +709,18 @@ static inline long strnlen_user(const char __user *s, long n)
 {
 	long res;
 
+	if (!access_ok(s, n))
+		return -0;
+
 	might_fault();
-	if (eva_kernel_access()) {
-		__asm__ __volatile__(
-			"move\t$4, %1\n\t"
-			"move\t$5, %2\n\t"
-			__MODULE_JAL(__strnlen_kernel_asm)
-			"move\t%0, $2"
-			: "=r" (res)
-			: "r" (s), "r" (n)
-			: "$2", "$4", "$5", __UA_t0, "$31");
-	} else {
-		__asm__ __volatile__(
-			"move\t$4, %1\n\t"
-			"move\t$5, %2\n\t"
-			__MODULE_JAL(__strnlen_user_asm)
-			"move\t%0, $2"
-			: "=r" (res)
-			: "r" (s), "r" (n)
-			: "$2", "$4", "$5", __UA_t0, "$31");
-	}
+	__asm__ __volatile__(
+		"move\t$4, %1\n\t"
+		"move\t$5, %2\n\t"
+		__MODULE_JAL(__strnlen_user_asm)
+		"move\t%0, $2"
+		: "=r" (res)
+		: "r" (s), "r" (n)
+		: "$2", "$4", "$5", __UA_t0, "$31");
 
 	return res;
 }
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index aebfda81120a..5735b2cd6f2a 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -98,7 +98,6 @@ void output_thread_info_defines(void)
 	OFFSET(TI_TP_VALUE, thread_info, tp_value);
 	OFFSET(TI_CPU, thread_info, cpu);
 	OFFSET(TI_PRE_COUNT, thread_info, preempt_count);
-	OFFSET(TI_ADDR_LIMIT, thread_info, addr_limit);
 	OFFSET(TI_REGS, thread_info, regs);
 	DEFINE(_THREAD_SIZE, THREAD_SIZE);
 	DEFINE(_THREAD_MASK, THREAD_MASK);
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 7efa0d1a4c2b..bff080db0294 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -124,7 +124,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
 		/* kernel thread */
 		unsigned long status = p->thread.cp0_status;
 		memset(childregs, 0, sizeof(struct pt_regs));
-		ti->addr_limit = KERNEL_DS;
 		p->thread.reg16 = usp; /* fn */
 		p->thread.reg17 = kthread_arg;
 		p->thread.reg29 = childksp;
@@ -145,7 +144,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
 	childregs->regs[2] = 0; /* Child gets zero as return value */
 	if (usp)
 		childregs->regs[29] = usp;
-	ti->addr_limit = USER_DS;
 
 	p->thread.reg29 = (unsigned long) childregs;
 	p->thread.reg31 = (unsigned long) ret_from_fork;
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index 84e8624e83a2..b1b2e106f711 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -48,10 +48,8 @@ NESTED(handle_sys, PT_SIZE, sp)
 	 * We intentionally keep the kernel stack a little below the top of
 	 * userspace so we don't have to do a slower byte accurate check here.
 	 */
-	lw	t5, TI_ADDR_LIMIT($28)
 	addu	t4, t0, 32
-	and	t5, t4
-	bltz	t5, bad_stack		# -> sp is bad
+	bltz	t4, bad_stack		# -> sp is bad
 
 	/*
 	 * Ok, copy the args from the luser stack to the kernel stack.
diff --git a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S
index d5449e8a3dfc..b0baa3c79fad 100644
--- a/arch/mips/lib/memset.S
+++ b/arch/mips/lib/memset.S
@@ -314,9 +314,6 @@ EXPORT_SYMBOL(memset)
 #ifndef CONFIG_EVA
 FEXPORT(__bzero)
 EXPORT_SYMBOL(__bzero)
-#else
-FEXPORT(__bzero_kernel)
-EXPORT_SYMBOL(__bzero_kernel)
 #endif
 	__BUILD_BZERO LEGACY_MODE
 
diff --git a/arch/mips/lib/strncpy_user.S b/arch/mips/lib/strncpy_user.S
index acdff66bd5d2..556acf684d7b 100644
--- a/arch/mips/lib/strncpy_user.S
+++ b/arch/mips/lib/strncpy_user.S
@@ -29,19 +29,17 @@
  * it happens at most some bytes of the exceptions handlers will be copied.
  */
 
-	.macro __BUILD_STRNCPY_ASM func
-LEAF(__strncpy_from_\func\()_asm)
-	LONG_L		v0, TI_ADDR_LIMIT($28)	# pointer ok?
-	and		v0, a1
-	bnez		v0, .Lfault\@
-
+LEAF(__strncpy_from_user_asm)
 	move		t0, zero
 	move		v1, a1
-.ifeqs "\func","kernel"
-1:	EX(lbu, v0, (v1), .Lfault\@)
-.else
-1:	EX(lbue, v0, (v1), .Lfault\@)
-.endif
+#ifdef CONFIG_EVA
+	.set push
+	.set eva
+1:	EX(lbue, v0, (v1), .Lfault)
+	.set pop
+#else
+1:	EX(lbu, v0, (v1), .Lfault)
+#endif
 	PTR_ADDIU	v1, 1
 	R10KCBARRIER(0(ra))
 	sb		v0, (a0)
@@ -51,35 +49,17 @@ LEAF(__strncpy_from_\func\()_asm)
 	bne		t0, a2, 1b
 2:	PTR_ADDU	v0, a1, t0
 	xor		v0, a1
-	bltz		v0, .Lfault\@
+	bltz		v0, .Lfault
 	move		v0, t0
 	jr		ra			# return n
-	END(__strncpy_from_\func\()_asm)
+	END(__strncpy_from_user_asm)
 
-.Lfault\@:
+.Lfault:
 	li		v0, -EFAULT
 	jr		ra
 
 	.section	__ex_table,"a"
-	PTR		1b, .Lfault\@
+	PTR		1b, .Lfault
 	.previous
 
-	.endm
-
-#ifndef CONFIG_EVA
-	/* Set aliases */
-	.global __strncpy_from_user_asm
-	.set __strncpy_from_user_asm, __strncpy_from_kernel_asm
-EXPORT_SYMBOL(__strncpy_from_user_asm)
-#endif
-
-__BUILD_STRNCPY_ASM kernel
-EXPORT_SYMBOL(__strncpy_from_kernel_asm)
-
-#ifdef CONFIG_EVA
-	.set push
-	.set eva
-__BUILD_STRNCPY_ASM user
-	.set pop
-EXPORT_SYMBOL(__strncpy_from_user_asm)
-#endif
+	EXPORT_SYMBOL(__strncpy_from_user_asm)
diff --git a/arch/mips/lib/strnlen_user.S b/arch/mips/lib/strnlen_user.S
index e1bacf5a3abe..92b63f20ec05 100644
--- a/arch/mips/lib/strnlen_user.S
+++ b/arch/mips/lib/strnlen_user.S
@@ -26,12 +26,7 @@
  *	 bytes.	 There's nothing secret there.	On 64-bit accessing beyond
  *	 the maximum is a tad hairier ...
  */
-	.macro __BUILD_STRNLEN_ASM func
-LEAF(__strnlen_\func\()_asm)
-	LONG_L		v0, TI_ADDR_LIMIT($28)	# pointer ok?
-	and		v0, a0
-	bnez		v0, .Lfault\@
-
+LEAF(__strnlen_user_asm)
 	move		v0, a0
 	PTR_ADDU	a1, a0			# stop pointer
 1:
@@ -40,11 +35,14 @@ LEAF(__strnlen_\func\()_asm)
 	li		AT, 1
 #endif
 	beq		v0, a1, 1f		# limit reached?
-.ifeqs "\func", "kernel"
-	EX(lb, t0, (v0), .Lfault\@)
-.else
-	EX(lbe, t0, (v0), .Lfault\@)
-.endif
+#ifdef CONFIG_EVA
+	.set push
+	.set eva
+	EX(lbe, t0, (v0), .Lfault)
+	.set pop
+#else
+	EX(lb, t0, (v0), .Lfault)
+#endif
 	.set		noreorder
 	bnez		t0, 1b
 1:
@@ -57,28 +55,10 @@ LEAF(__strnlen_\func\()_asm)
 	.set		reorder
 	PTR_SUBU	v0, a0
 	jr		ra
-	END(__strnlen_\func\()_asm)
+	END(__strnlen_user_asm)
 
-.Lfault\@:
+.Lfault:
 	move		v0, zero
 	jr		ra
-	.endm
-
-#ifndef CONFIG_EVA
-	/* Set aliases */
-	.global __strnlen_user_asm
-	.set __strnlen_user_asm, __strnlen_kernel_asm
-EXPORT_SYMBOL(__strnlen_user_asm)
-#endif
-
-__BUILD_STRNLEN_ASM kernel
-EXPORT_SYMBOL(__strnlen_kernel_asm)
-
-#ifdef CONFIG_EVA
 
-	.set push
-	.set eva
-__BUILD_STRNLEN_ASM user
-	.set pop
-EXPORT_SYMBOL(__strnlen_user_asm)
-#endif
+	EXPORT_SYMBOL(__strnlen_user_asm)
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/3] MIPS: uaccess: Added __get/__put_kernel_nofault
  2021-03-30 17:26 ` [PATCH 1/3] MIPS: uaccess: Added __get/__put_kernel_nofault Thomas Bogendoerfer
@ 2021-03-30 17:48   ` Christoph Hellwig
  2021-03-30 20:02     ` Thomas Bogendoerfer
  0 siblings, 1 reply; 12+ messages in thread
From: Christoph Hellwig @ 2021-03-30 17:48 UTC (permalink / raw)
  To: Thomas Bogendoerfer; +Cc: linux-mips, linux-kernel, hch

On Tue, Mar 30, 2021 at 07:26:58PM +0200, Thomas Bogendoerfer wrote:
> Added __get/__put_kernel_nofault as preparation for removing
> get/set_fs.

For !CONFIG_EVA __get_user_common is simply defined to
__get_kernel_common, which probably does the wrong thing here
as it would allow access to user space addresses, won't it?

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/3] MIPS: uaccess: Remove get_fs/set_fs call sites
  2021-03-30 17:26 ` [PATCH 2/3] MIPS: uaccess: Remove get_fs/set_fs call sites Thomas Bogendoerfer
@ 2021-03-30 17:49   ` Christoph Hellwig
  2021-03-30 20:02     ` Thomas Bogendoerfer
  2021-03-30 22:10     ` David Laight
  0 siblings, 2 replies; 12+ messages in thread
From: Christoph Hellwig @ 2021-03-30 17:49 UTC (permalink / raw)
  To: Thomas Bogendoerfer; +Cc: linux-mips, linux-kernel, hch

On Tue, Mar 30, 2021 at 07:26:59PM +0200, Thomas Bogendoerfer wrote:
> +#define __get_data(x, ptr, u)						\
> +	(((u) == true) ? __get_udata((x), (ptr), sizeof(*(ptr))) :	\
> +			__get_kdata((x), (ptr), sizeof(*(ptr))))
> +

I'm a little worried about exposing this in uaccess.h.  Can you
have local helpers insted, preferably strongly typed for their
specific use cases?

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/3] MIPS: Remove get_fs/set_fs
  2021-03-30 17:27 ` [PATCH 3/3] MIPS: Remove get_fs/set_fs Thomas Bogendoerfer
@ 2021-03-30 17:54   ` Christoph Hellwig
  2021-03-31 11:41     ` Thomas Bogendoerfer
  2021-03-31  1:38   ` kernel test robot
  1 sibling, 1 reply; 12+ messages in thread
From: Christoph Hellwig @ 2021-03-30 17:54 UTC (permalink / raw)
  To: Thomas Bogendoerfer; +Cc: linux-mips, linux-kernel, hch

> -	if (likely(access_ok( __gu_ptr, size))) {		\
> -		if (eva_kernel_access())				\
> -			__get_kernel_common((x), size, __gu_ptr);	\

FYI, it might be a good idea to fold __{get,put}_kernel_common into
__{get,put}_kernel_nofault now that these are the only callers left.

Similarly __get_user_common and __put_user_common should probably also
go away.

>  static inline unsigned long
>  raw_copy_to_user(void __user *to, const void *from, unsigned long n)
>  {
> +	return __invoke_copy_to_user(to, from, n);

I think __invoke_copy_to_user, __invoke_copy_from_user and
___invoke_copy_in_user can go away now as well.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/3] MIPS: uaccess: Added __get/__put_kernel_nofault
  2021-03-30 17:48   ` Christoph Hellwig
@ 2021-03-30 20:02     ` Thomas Bogendoerfer
  0 siblings, 0 replies; 12+ messages in thread
From: Thomas Bogendoerfer @ 2021-03-30 20:02 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-mips, linux-kernel

On Tue, Mar 30, 2021 at 07:48:35PM +0200, Christoph Hellwig wrote:
> On Tue, Mar 30, 2021 at 07:26:58PM +0200, Thomas Bogendoerfer wrote:
> > Added __get/__put_kernel_nofault as preparation for removing
> > get/set_fs.
> 
> For !CONFIG_EVA __get_user_common is simply defined to
> __get_kernel_common, which probably does the wrong thing here
> as it would allow access to user space addresses, won't it?

it does, so I'm missing a copy_from_kernel_nofault_allowed() function,
which only allows kernel access, right ?

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.                                                [ RFC1925, 2.3 ]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/3] MIPS: uaccess: Remove get_fs/set_fs call sites
  2021-03-30 17:49   ` Christoph Hellwig
@ 2021-03-30 20:02     ` Thomas Bogendoerfer
  2021-03-30 22:10     ` David Laight
  1 sibling, 0 replies; 12+ messages in thread
From: Thomas Bogendoerfer @ 2021-03-30 20:02 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-mips, linux-kernel

On Tue, Mar 30, 2021 at 07:49:43PM +0200, Christoph Hellwig wrote:
> On Tue, Mar 30, 2021 at 07:26:59PM +0200, Thomas Bogendoerfer wrote:
> > +#define __get_data(x, ptr, u)						\
> > +	(((u) == true) ? __get_udata((x), (ptr), sizeof(*(ptr))) :	\
> > +			__get_kdata((x), (ptr), sizeof(*(ptr))))
> > +
> 
> I'm a little worried about exposing this in uaccess.h.  Can you
> have local helpers insted, preferably strongly typed for their
> specific use cases?

sure, no problem.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.                                                [ RFC1925, 2.3 ]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* RE: [PATCH 2/3] MIPS: uaccess: Remove get_fs/set_fs call sites
  2021-03-30 17:49   ` Christoph Hellwig
  2021-03-30 20:02     ` Thomas Bogendoerfer
@ 2021-03-30 22:10     ` David Laight
  1 sibling, 0 replies; 12+ messages in thread
From: David Laight @ 2021-03-30 22:10 UTC (permalink / raw)
  To: 'Christoph Hellwig', Thomas Bogendoerfer; +Cc: linux-mips, linux-kernel

From: Christoph Hellwig
> Sent: 30 March 2021 18:50
> 
> On Tue, Mar 30, 2021 at 07:26:59PM +0200, Thomas Bogendoerfer wrote:
> > +#define __get_data(x, ptr, u)						\
> > +	(((u) == true) ? __get_udata((x), (ptr), sizeof(*(ptr))) :	\
> > +			__get_kdata((x), (ptr), sizeof(*(ptr))))
> > +
> 
> I'm a little worried about exposing this in uaccess.h.  Can you
> have local helpers insted, preferably strongly typed for their
> specific use cases?

For things that aren't performance critical it may be worth
using a structure that contains both a kernel and user address
(one of which will be NULL) and passing the offset as a separate
parameter.

(That might have been better for the socket option buffer.)

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/3] MIPS: Remove get_fs/set_fs
  2021-03-30 17:27 ` [PATCH 3/3] MIPS: Remove get_fs/set_fs Thomas Bogendoerfer
  2021-03-30 17:54   ` Christoph Hellwig
@ 2021-03-31  1:38   ` kernel test robot
  1 sibling, 0 replies; 12+ messages in thread
From: kernel test robot @ 2021-03-31  1:38 UTC (permalink / raw)
  To: Thomas Bogendoerfer, linux-mips, linux-kernel; +Cc: kbuild-all, hch

[-- Attachment #1: Type: text/plain, Size: 5078 bytes --]

Hi Thomas,

I love your patch! Yet something to improve:

[auto build test ERROR on next-20210330]
[cannot apply to linux/master hch-configfs/for-next linus/master v5.12-rc5 v5.12-rc4 v5.12-rc3 v5.12-rc5]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Thomas-Bogendoerfer/MIPS-Remove-get_fs-set_fs/20210331-013005
base:    4143e05b7b171902f4938614c2a68821e1af46bc
config: mips-allyesconfig (attached as .config)
compiler: mips-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/628cb4a48f0f31c44bfc3a41b0bad05ba8b8ed3b
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Thomas-Bogendoerfer/MIPS-Remove-get_fs-set_fs/20210331-013005
        git checkout 628cb4a48f0f31c44bfc3a41b0bad05ba8b8ed3b
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=mips 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   arch/mips/kernel/ftrace.c: In function 'ftrace_modify_code_2':
>> arch/mips/kernel/ftrace.c:105:11: error: implicit declaration of function 'get_fs'; did you mean 'sget_fc'? [-Werror=implicit-function-declaration]
     105 |  old_fs = get_fs();
         |           ^~~~~~
         |           sget_fc
>> arch/mips/kernel/ftrace.c:105:11: error: incompatible types when assigning to type 'mm_segment_t' {aka 'struct <anonymous>'} from type 'int'
>> arch/mips/kernel/ftrace.c:106:2: error: implicit declaration of function 'set_fs'; did you mean 'sget_fc'? [-Werror=implicit-function-declaration]
     106 |  set_fs(KERNEL_DS);
         |  ^~~~~~
         |  sget_fc
>> arch/mips/kernel/ftrace.c:106:9: error: 'KERNEL_DS' undeclared (first use in this function); did you mean 'KERNFS_NS'?
     106 |  set_fs(KERNEL_DS);
         |         ^~~~~~~~~
         |         KERNFS_NS
   arch/mips/kernel/ftrace.c:106:9: note: each undeclared identifier is reported only once for each function it appears in
   arch/mips/kernel/ftrace.c: In function 'ftrace_modify_code_2r':
   arch/mips/kernel/ftrace.c:129:11: error: incompatible types when assigning to type 'mm_segment_t' {aka 'struct <anonymous>'} from type 'int'
     129 |  old_fs = get_fs();
         |           ^~~~~~
   arch/mips/kernel/ftrace.c:130:9: error: 'KERNEL_DS' undeclared (first use in this function); did you mean 'KERNFS_NS'?
     130 |  set_fs(KERNEL_DS);
         |         ^~~~~~~~~
         |         KERNFS_NS
   arch/mips/kernel/ftrace.c: At top level:
   arch/mips/kernel/ftrace.c:313:6: warning: no previous prototype for 'prepare_ftrace_return' [-Wmissing-prototypes]
     313 | void prepare_ftrace_return(unsigned long *parent_ra_addr, unsigned long self_ra,
         |      ^~~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors


vim +105 arch/mips/kernel/ftrace.c

538f19526e40ce Wu Zhangjin    2009-11-20   87  
58b69401c797e4 Al Cooper      2013-01-16   88  #ifndef CONFIG_64BIT
58b69401c797e4 Al Cooper      2013-01-16   89  static int ftrace_modify_code_2(unsigned long ip, unsigned int new_code1,
58b69401c797e4 Al Cooper      2013-01-16   90  				unsigned int new_code2)
58b69401c797e4 Al Cooper      2013-01-16   91  {
58b69401c797e4 Al Cooper      2013-01-16   92  	int faulted;
dce0e7d54a7104 Petri Gynther  2014-07-23   93  	mm_segment_t old_fs;
58b69401c797e4 Al Cooper      2013-01-16   94  
58b69401c797e4 Al Cooper      2013-01-16   95  	safe_store_code(new_code1, ip, faulted);
58b69401c797e4 Al Cooper      2013-01-16   96  	if (unlikely(faulted))
58b69401c797e4 Al Cooper      2013-01-16   97  		return -EFAULT;
dce0e7d54a7104 Petri Gynther  2014-07-23   98  
dce0e7d54a7104 Petri Gynther  2014-07-23   99  	ip += 4;
dce0e7d54a7104 Petri Gynther  2014-07-23  100  	safe_store_code(new_code2, ip, faulted);
dce0e7d54a7104 Petri Gynther  2014-07-23  101  	if (unlikely(faulted))
dce0e7d54a7104 Petri Gynther  2014-07-23  102  		return -EFAULT;
dce0e7d54a7104 Petri Gynther  2014-07-23  103  
dce0e7d54a7104 Petri Gynther  2014-07-23  104  	ip -= 4;
dce0e7d54a7104 Petri Gynther  2014-07-23 @105  	old_fs = get_fs();
736706bee32982 Linus Torvalds 2019-03-04 @106  	set_fs(KERNEL_DS);
dce0e7d54a7104 Petri Gynther  2014-07-23  107  	flush_icache_range(ip, ip + 8);
dce0e7d54a7104 Petri Gynther  2014-07-23  108  	set_fs(old_fs);
dce0e7d54a7104 Petri Gynther  2014-07-23  109  
dce0e7d54a7104 Petri Gynther  2014-07-23  110  	return 0;
dce0e7d54a7104 Petri Gynther  2014-07-23  111  }
dce0e7d54a7104 Petri Gynther  2014-07-23  112  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 70698 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/3] MIPS: Remove get_fs/set_fs
  2021-03-30 17:54   ` Christoph Hellwig
@ 2021-03-31 11:41     ` Thomas Bogendoerfer
  0 siblings, 0 replies; 12+ messages in thread
From: Thomas Bogendoerfer @ 2021-03-31 11:41 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-mips, linux-kernel

On Tue, Mar 30, 2021 at 07:54:17PM +0200, Christoph Hellwig wrote:
> > -	if (likely(access_ok( __gu_ptr, size))) {		\
> > -		if (eva_kernel_access())				\
> > -			__get_kernel_common((x), size, __gu_ptr);	\
> 
> FYI, it might be a good idea to fold __{get,put}_kernel_common into
> __{get,put}_kernel_nofault now that these are the only callers left.

__get_data macro used it, but I rewrote it, so I could fold in
__get/__put_kernel_common.

> Similarly __get_user_common and __put_user_common should probably also
> go away.

__get_user_common is used 3 times and __put_user_common twice. So I
left them as they are.

> >  static inline unsigned long
> >  raw_copy_to_user(void __user *to, const void *from, unsigned long n)
> >  {
> > +	return __invoke_copy_to_user(to, from, n);
> 
> I think __invoke_copy_to_user, __invoke_copy_from_user and
> ___invoke_copy_in_user can go away now as well.

done.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.                                                [ RFC1925, 2.3 ]

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2021-03-31 11:47 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-30 17:26 [PATCH 0/3] MIPS: Remove get_fs/set_fs Thomas Bogendoerfer
2021-03-30 17:26 ` [PATCH 1/3] MIPS: uaccess: Added __get/__put_kernel_nofault Thomas Bogendoerfer
2021-03-30 17:48   ` Christoph Hellwig
2021-03-30 20:02     ` Thomas Bogendoerfer
2021-03-30 17:26 ` [PATCH 2/3] MIPS: uaccess: Remove get_fs/set_fs call sites Thomas Bogendoerfer
2021-03-30 17:49   ` Christoph Hellwig
2021-03-30 20:02     ` Thomas Bogendoerfer
2021-03-30 22:10     ` David Laight
2021-03-30 17:27 ` [PATCH 3/3] MIPS: Remove get_fs/set_fs Thomas Bogendoerfer
2021-03-30 17:54   ` Christoph Hellwig
2021-03-31 11:41     ` Thomas Bogendoerfer
2021-03-31  1:38   ` kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).