summaryrefslogtreecommitdiffstats
path: root/arch/nds32
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2022-02-25 11:16:17 +0100
committerArnd Bergmann <arnd@arndb.de>2022-02-25 11:16:58 +0100
commitdd865f090f0382ba9e74dc4fe1008c08a67a6fca (patch)
treef41fbecea37957bdb6246b867e086fc40b5d0d77 /arch/nds32
parentbe92e1ded1d17d68444a793fb07c118ab98b28b5 (diff)
parent967747bbc084b93b54e66f9047d342232314cd25 (diff)
downloadlinux-dd865f090f0382ba9e74dc4fe1008c08a67a6fca.tar.bz2
Merge branch 'set_fs-4' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic into asm-generic
Christoph Hellwig and a few others spent a huge effort on removing set_fs() from most of the important architectures, but about half the other architectures were never completed even though most of them don't actually use set_fs() at all. I did a patch for microblaze at some point, which turned out to be fairly generic, and now ported it to most other architectures, using new generic implementations of access_ok() and __{get,put}_kernel_nocheck(). Three architectures (sparc64, ia64, and sh) needed some extra work, which I also completed. * 'set_fs-4' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic: uaccess: remove CONFIG_SET_FS ia64: remove CONFIG_SET_FS support sh: remove CONFIG_SET_FS support sparc64: remove CONFIG_SET_FS support lib/test_lockup: fix kernel pointer check for separate address spaces uaccess: generalize access_ok() uaccess: fix type mismatch warnings from access_ok() arm64: simplify access_ok() m68k: fix access_ok for coldfire MIPS: use simpler access_ok() MIPS: Handle address errors for accesses above CPU max virtual user address uaccess: add generic __{get,put}_kernel_nofault nios2: drop access_ok() check from __put_user() x86: use more conventional access_ok() definition x86: remove __range_not_ok() sparc64: add __{get,put}_kernel_nofault() nds32: fix access_ok() checks in get/put_user uaccess: fix nios2 and microblaze get_user_8() uaccess: fix integer overflow on access_ok()
Diffstat (limited to 'arch/nds32')
-rw-r--r--arch/nds32/Kconfig1
-rw-r--r--arch/nds32/include/asm/thread_info.h4
-rw-r--r--arch/nds32/include/asm/uaccess.h40
-rw-r--r--arch/nds32/kernel/process.c5
-rw-r--r--arch/nds32/mm/alignment.c3
5 files changed, 20 insertions, 33 deletions
diff --git a/arch/nds32/Kconfig b/arch/nds32/Kconfig
index 4d1421b18734..013249430fa3 100644
--- a/arch/nds32/Kconfig
+++ b/arch/nds32/Kconfig
@@ -44,7 +44,6 @@ config NDS32
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_DYNAMIC_FTRACE
- select SET_FS
select TRACE_IRQFLAGS_SUPPORT
help
Andes(nds32) Linux support.
diff --git a/arch/nds32/include/asm/thread_info.h b/arch/nds32/include/asm/thread_info.h
index d3967ad184f0..bd8f81cf2ce5 100644
--- a/arch/nds32/include/asm/thread_info.h
+++ b/arch/nds32/include/asm/thread_info.h
@@ -16,8 +16,6 @@ struct task_struct;
#include <asm/ptrace.h>
#include <asm/types.h>
-typedef unsigned long mm_segment_t;
-
/*
* low level task data that entry.S needs immediate access to.
* __switch_to() assumes cpu_context follows immediately after cpu_domain.
@@ -25,12 +23,10 @@ typedef unsigned long mm_segment_t;
struct thread_info {
unsigned long flags; /* low level flags */
__s32 preempt_count; /* 0 => preemptable, <0 => bug */
- mm_segment_t addr_limit; /* address limit */
};
#define INIT_THREAD_INFO(tsk) \
{ \
.preempt_count = INIT_PREEMPT_COUNT, \
- .addr_limit = KERNEL_DS, \
}
#define thread_saved_pc(tsk) ((unsigned long)(tsk->thread.cpu_context.pc))
#define thread_saved_fp(tsk) ((unsigned long)(tsk->thread.cpu_context.fp))
diff --git a/arch/nds32/include/asm/uaccess.h b/arch/nds32/include/asm/uaccess.h
index d4cbf069dc22..377548d4451a 100644
--- a/arch/nds32/include/asm/uaccess.h
+++ b/arch/nds32/include/asm/uaccess.h
@@ -11,6 +11,7 @@
#include <asm/errno.h>
#include <asm/memory.h>
#include <asm/types.h>
+#include <asm-generic/access_ok.h>
#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
@@ -33,23 +34,6 @@ struct exception_table_entry {
extern int fixup_exception(struct pt_regs *regs);
-#define KERNEL_DS ((mm_segment_t) { ~0UL })
-#define USER_DS ((mm_segment_t) {TASK_SIZE - 1})
-
-#define get_fs() (current_thread_info()->addr_limit)
-#define user_addr_max get_fs
-
-static inline void set_fs(mm_segment_t fs)
-{
- current_thread_info()->addr_limit = fs;
-}
-
-#define uaccess_kernel() (get_fs() == KERNEL_DS)
-
-#define __range_ok(addr, size) (size <= get_fs() && addr <= (get_fs() -size))
-
-#define access_ok(addr, size) \
- __range_ok((unsigned long)addr, (unsigned long)size)
/*
* Single-value transfer routines. They automatically use the right
* size if we just have the right pointer type. Note that the functions
@@ -70,9 +54,7 @@ static inline void set_fs(mm_segment_t fs)
* versions are void (ie, don't return a value as such).
*/
-#define get_user __get_user \
-
-#define __get_user(x, ptr) \
+#define get_user(x, ptr) \
({ \
long __gu_err = 0; \
__get_user_check((x), (ptr), __gu_err); \
@@ -85,6 +67,14 @@ static inline void set_fs(mm_segment_t fs)
(void)0; \
})
+#define __get_user(x, ptr) \
+({ \
+ long __gu_err = 0; \
+ const __typeof__(*(ptr)) __user *__p = (ptr); \
+ __get_user_err((x), __p, (__gu_err)); \
+ __gu_err; \
+})
+
#define __get_user_check(x, ptr, err) \
({ \
const __typeof__(*(ptr)) __user *__p = (ptr); \
@@ -165,12 +155,18 @@ do { \
: "r"(addr), "i"(-EFAULT) \
: "cc")
-#define put_user __put_user \
+#define put_user(x, ptr) \
+({ \
+ long __pu_err = 0; \
+ __put_user_check((x), (ptr), __pu_err); \
+ __pu_err; \
+})
#define __put_user(x, ptr) \
({ \
long __pu_err = 0; \
- __put_user_err((x), (ptr), __pu_err); \
+ __typeof__(*(ptr)) __user *__p = (ptr); \
+ __put_user_err((x), __p, __pu_err); \
__pu_err; \
})
diff --git a/arch/nds32/kernel/process.c b/arch/nds32/kernel/process.c
index 49fab9e39cbf..d35c1f63fa11 100644
--- a/arch/nds32/kernel/process.c
+++ b/arch/nds32/kernel/process.c
@@ -119,9 +119,8 @@ void show_regs(struct pt_regs *regs)
regs->uregs[7], regs->uregs[6], regs->uregs[5], regs->uregs[4]);
pr_info("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
regs->uregs[3], regs->uregs[2], regs->uregs[1], regs->uregs[0]);
- pr_info(" IRQs o%s Segment %s\n",
- interrupts_enabled(regs) ? "n" : "ff",
- uaccess_kernel() ? "kernel" : "user");
+ pr_info(" IRQs o%s Segment user\n",
+ interrupts_enabled(regs) ? "n" : "ff");
}
EXPORT_SYMBOL(show_regs);
diff --git a/arch/nds32/mm/alignment.c b/arch/nds32/mm/alignment.c
index 1eb7ded6992b..9c2c0a454da8 100644
--- a/arch/nds32/mm/alignment.c
+++ b/arch/nds32/mm/alignment.c
@@ -512,7 +512,6 @@ int do_unaligned_access(unsigned long addr, struct pt_regs *regs)
{
unsigned long inst;
int ret = -EFAULT;
- mm_segment_t seg;
inst = get_inst(regs->ipc);
@@ -520,12 +519,10 @@ int do_unaligned_access(unsigned long addr, struct pt_regs *regs)
"Faulting addr: 0x%08lx, pc: 0x%08lx [inst: 0x%08lx ]\n", addr,
regs->ipc, inst);
- seg = force_uaccess_begin();
if (inst & NDS32_16BIT_INSTRUCTION)
ret = do_16((inst >> 16) & 0xffff, regs);
else
ret = do_32(inst, regs);
- force_uaccess_end(seg);
return ret;
}