sh: remove CONFIG_SET_FS support
authorArnd Bergmann <arnd@arndb.de>
Fri, 11 Feb 2022 16:26:42 +0000 (17:26 +0100)
committerArnd Bergmann <arnd@arndb.de>
Fri, 25 Feb 2022 08:36:06 +0000 (09:36 +0100)
sh uses set_fs/get_fs only in one file, to handle address
errors in both user and kernel memory.

It already has an abstraction to differentiate between I/O
and memory, so adding a third class for kernel memory fits
into the same scheme and lets us kill off CONFIG_SET_FS.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
arch/sh/Kconfig
arch/sh/include/asm/processor.h
arch/sh/include/asm/segment.h [deleted file]
arch/sh/include/asm/thread_info.h
arch/sh/include/asm/uaccess.h
arch/sh/kernel/io_trapped.c
arch/sh/kernel/process_32.c
arch/sh/kernel/traps_32.c

index 2474a04ceac438975fcb0acb8daf730fbbb1edbe..f676e92b7d5bde24995556b2ae88b461a302193d 100644 (file)
@@ -65,7 +65,6 @@ config SUPERH
        select PERF_EVENTS
        select PERF_USE_VMALLOC
        select RTC_LIB
-       select SET_FS
        select SPARSE_IRQ
        select TRACE_IRQFLAGS_SUPPORT
        help
index 3820d698846e0d9fc29b27a300778174c927380b..85a6c1c3c16e70019a8ff55982ffc4bec7dbc9af 100644 (file)
@@ -3,7 +3,6 @@
 #define __ASM_SH_PROCESSOR_H
 
 #include <asm/cpu-features.h>
-#include <asm/segment.h>
 #include <asm/cache.h>
 
 #ifndef __ASSEMBLY__
diff --git a/arch/sh/include/asm/segment.h b/arch/sh/include/asm/segment.h
deleted file mode 100644 (file)
index 02e54a3..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __ASM_SH_SEGMENT_H
-#define __ASM_SH_SEGMENT_H
-
-#ifndef __ASSEMBLY__
-
-typedef struct {
-       unsigned long seg;
-} mm_segment_t;
-
-#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
-
-/*
- * 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.
- */
-#define KERNEL_DS      MAKE_MM_SEG(0xFFFFFFFFUL)
-#ifdef CONFIG_MMU
-#define USER_DS                MAKE_MM_SEG(PAGE_OFFSET)
-#else
-#define USER_DS                KERNEL_DS
-#endif
-
-#define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg)
-
-#define get_fs()       (current_thread_info()->addr_limit)
-#define set_fs(x)      (current_thread_info()->addr_limit = (x))
-
-#endif /* __ASSEMBLY__ */
-#endif /* __ASM_SH_SEGMENT_H */
index 598d0184ffeae3c0e713075d6096926d9e001fc0..b119b859a0a38e7cabc2ab60f6ca5e61a30f53f8 100644 (file)
@@ -30,7 +30,6 @@ struct thread_info {
        __u32                   status;         /* thread synchronous flags */
        __u32                   cpu;
        int                     preempt_count; /* 0 => preemptable, <0 => BUG */
-       mm_segment_t            addr_limit;     /* thread address space */
        unsigned long           previous_sp;    /* sp of previous stack in case
                                                   of nested IRQ stacks */
        __u8                    supervisor_stack[0];
@@ -58,7 +57,6 @@ struct thread_info {
        .status         = 0,                    \
        .cpu            = 0,                    \
        .preempt_count  = INIT_PREEMPT_COUNT,   \
-       .addr_limit     = KERNEL_DS,            \
 }
 
 /* how to get the current stack pointer from C */
index ccd219d7485121f0850c0fcebaf9e1fa2aa7cc26..a79609eb14be43606e1ba32677e0d7b8f280cd30 100644 (file)
@@ -2,11 +2,7 @@
 #ifndef __ASM_SH_UACCESS_H
 #define __ASM_SH_UACCESS_H
 
-#include <asm/segment.h>
 #include <asm/extable.h>
-
-#define user_addr_max()        (current_thread_info()->addr_limit.seg)
-
 #include <asm-generic/access_ok.h>
 
 /*
index 004ad0130b103805f4d82f8ed9dc5ffe44209e46..e803b14ef12eac299500df6e532f335f0d3abfb3 100644 (file)
@@ -270,7 +270,6 @@ static struct mem_access trapped_io_access = {
 
 int handle_trapped_io(struct pt_regs *regs, unsigned long address)
 {
-       mm_segment_t oldfs;
        insn_size_t instruction;
        int tmp;
 
@@ -281,16 +280,12 @@ int handle_trapped_io(struct pt_regs *regs, unsigned long address)
 
        WARN_ON(user_mode(regs));
 
-       oldfs = get_fs();
-       set_fs(KERNEL_DS);
-       if (copy_from_user(&instruction, (void *)(regs->pc),
-                          sizeof(instruction))) {
-               set_fs(oldfs);
+       if (copy_from_kernel_nofault(&instruction, (void *)(regs->pc),
+                                    sizeof(instruction))) {
                return 0;
        }
 
        tmp = handle_unaligned_access(instruction, regs,
                                      &trapped_io_access, 1, address);
-       set_fs(oldfs);
        return tmp == 0;
 }
index 1c28e3cddb60dfc63fcf2e5f162d29c23b2c64a5..ca01286a0610004da0ff95862b81e8818055dc3f 100644 (file)
@@ -123,7 +123,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, unsigned long arg,
 #if defined(CONFIG_SH_FPU)
                childregs->sr |= SR_FD;
 #endif
-               ti->addr_limit = KERNEL_DS;
                ti->status &= ~TS_USEDFPU;
                p->thread.fpu_counter = 0;
                return 0;
@@ -132,7 +131,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, unsigned long arg,
 
        if (usp)
                childregs->regs[15] = usp;
-       ti->addr_limit = USER_DS;
 
        if (clone_flags & CLONE_SETTLS)
                childregs->gbr = tls;
index b3c715bc254b26d469c7abda603380442fa8af99..6cdda3a621a1e5775cbd04f7c20755b687ea6f0d 100644 (file)
@@ -75,6 +75,23 @@ static struct mem_access user_mem_access = {
        copy_to_user,
 };
 
+static unsigned long copy_from_kernel_wrapper(void *dst, const void __user *src,
+                                             unsigned long cnt)
+{
+       return copy_from_kernel_nofault(dst, (const void __force *)src, cnt);
+}
+
+static unsigned long copy_to_kernel_wrapper(void __user *dst, const void *src,
+                                           unsigned long cnt)
+{
+       return copy_to_kernel_nofault((void __force *)dst, src, cnt);
+}
+
+static struct mem_access kernel_mem_access = {
+       copy_from_kernel_wrapper,
+       copy_to_kernel_wrapper,
+};
+
 /*
  * handle an instruction that does an unaligned memory access by emulating the
  * desired behaviour
@@ -473,7 +490,6 @@ asmlinkage void do_address_error(struct pt_regs *regs,
                                 unsigned long address)
 {
        unsigned long error_code = 0;
-       mm_segment_t oldfs;
        insn_size_t instruction;
        int tmp;
 
@@ -489,13 +505,10 @@ asmlinkage void do_address_error(struct pt_regs *regs,
                local_irq_enable();
                inc_unaligned_user_access();
 
-               oldfs = force_uaccess_begin();
                if (copy_from_user(&instruction, (insn_size_t __user *)(regs->pc & ~1),
                                   sizeof(instruction))) {
-                       force_uaccess_end(oldfs);
                        goto uspace_segv;
                }
-               force_uaccess_end(oldfs);
 
                /* shout about userspace fixups */
                unaligned_fixups_notify(current, instruction, regs);
@@ -518,11 +531,9 @@ fixup:
                        goto uspace_segv;
                }
 
-               oldfs = force_uaccess_begin();
                tmp = handle_unaligned_access(instruction, regs,
                                              &user_mem_access, 0,
                                              address);
-               force_uaccess_end(oldfs);
 
                if (tmp == 0)
                        return; /* sorted */
@@ -538,21 +549,18 @@ uspace_segv:
                if (regs->pc & 1)
                        die("unaligned program counter", regs, error_code);
 
-               set_fs(KERNEL_DS);
-               if (copy_from_user(&instruction, (void __user *)(regs->pc),
+               if (copy_from_kernel_nofault(&instruction, (void *)(regs->pc),
                                   sizeof(instruction))) {
                        /* Argh. Fault on the instruction itself.
                           This should never happen non-SMP
                        */
-                       set_fs(oldfs);
                        die("insn faulting in do_address_error", regs, 0);
                }
 
                unaligned_fixups_notify(current, instruction, regs);
 
-               handle_unaligned_access(instruction, regs, &user_mem_access,
+               handle_unaligned_access(instruction, regs, &kernel_mem_access,
                                        0, address);
-               set_fs(oldfs);
        }
 }