Commit 75d4d295 authored by Arnd Bergmann's avatar Arnd Bergmann

sh: remove CONFIG_SET_FS support

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: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parent a5ad8378
...@@ -65,7 +65,6 @@ config SUPERH ...@@ -65,7 +65,6 @@ config SUPERH
select PERF_EVENTS select PERF_EVENTS
select PERF_USE_VMALLOC select PERF_USE_VMALLOC
select RTC_LIB select RTC_LIB
select SET_FS
select SPARSE_IRQ select SPARSE_IRQ
select TRACE_IRQFLAGS_SUPPORT select TRACE_IRQFLAGS_SUPPORT
help help
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
#define __ASM_SH_PROCESSOR_H #define __ASM_SH_PROCESSOR_H
#include <asm/cpu-features.h> #include <asm/cpu-features.h>
#include <asm/segment.h>
#include <asm/cache.h> #include <asm/cache.h>
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
......
/* 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 */
...@@ -30,7 +30,6 @@ struct thread_info { ...@@ -30,7 +30,6 @@ struct thread_info {
__u32 status; /* thread synchronous flags */ __u32 status; /* thread synchronous flags */
__u32 cpu; __u32 cpu;
int preempt_count; /* 0 => preemptable, <0 => BUG */ 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 unsigned long previous_sp; /* sp of previous stack in case
of nested IRQ stacks */ of nested IRQ stacks */
__u8 supervisor_stack[0]; __u8 supervisor_stack[0];
...@@ -58,7 +57,6 @@ struct thread_info { ...@@ -58,7 +57,6 @@ struct thread_info {
.status = 0, \ .status = 0, \
.cpu = 0, \ .cpu = 0, \
.preempt_count = INIT_PREEMPT_COUNT, \ .preempt_count = INIT_PREEMPT_COUNT, \
.addr_limit = KERNEL_DS, \
} }
/* how to get the current stack pointer from C */ /* how to get the current stack pointer from C */
......
...@@ -2,11 +2,7 @@ ...@@ -2,11 +2,7 @@
#ifndef __ASM_SH_UACCESS_H #ifndef __ASM_SH_UACCESS_H
#define __ASM_SH_UACCESS_H #define __ASM_SH_UACCESS_H
#include <asm/segment.h>
#include <asm/extable.h> #include <asm/extable.h>
#define user_addr_max() (current_thread_info()->addr_limit.seg)
#include <asm-generic/access_ok.h> #include <asm-generic/access_ok.h>
/* /*
......
...@@ -270,7 +270,6 @@ static struct mem_access trapped_io_access = { ...@@ -270,7 +270,6 @@ static struct mem_access trapped_io_access = {
int handle_trapped_io(struct pt_regs *regs, unsigned long address) int handle_trapped_io(struct pt_regs *regs, unsigned long address)
{ {
mm_segment_t oldfs;
insn_size_t instruction; insn_size_t instruction;
int tmp; int tmp;
...@@ -281,16 +280,12 @@ int handle_trapped_io(struct pt_regs *regs, unsigned long address) ...@@ -281,16 +280,12 @@ int handle_trapped_io(struct pt_regs *regs, unsigned long address)
WARN_ON(user_mode(regs)); WARN_ON(user_mode(regs));
oldfs = get_fs(); if (copy_from_kernel_nofault(&instruction, (void *)(regs->pc),
set_fs(KERNEL_DS);
if (copy_from_user(&instruction, (void *)(regs->pc),
sizeof(instruction))) { sizeof(instruction))) {
set_fs(oldfs);
return 0; return 0;
} }
tmp = handle_unaligned_access(instruction, regs, tmp = handle_unaligned_access(instruction, regs,
&trapped_io_access, 1, address); &trapped_io_access, 1, address);
set_fs(oldfs);
return tmp == 0; return tmp == 0;
} }
...@@ -123,7 +123,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, unsigned long arg, ...@@ -123,7 +123,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, unsigned long arg,
#if defined(CONFIG_SH_FPU) #if defined(CONFIG_SH_FPU)
childregs->sr |= SR_FD; childregs->sr |= SR_FD;
#endif #endif
ti->addr_limit = KERNEL_DS;
ti->status &= ~TS_USEDFPU; ti->status &= ~TS_USEDFPU;
p->thread.fpu_counter = 0; p->thread.fpu_counter = 0;
return 0; return 0;
...@@ -132,7 +131,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, unsigned long arg, ...@@ -132,7 +131,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, unsigned long arg,
if (usp) if (usp)
childregs->regs[15] = usp; childregs->regs[15] = usp;
ti->addr_limit = USER_DS;
if (clone_flags & CLONE_SETTLS) if (clone_flags & CLONE_SETTLS)
childregs->gbr = tls; childregs->gbr = tls;
......
...@@ -75,6 +75,23 @@ static struct mem_access user_mem_access = { ...@@ -75,6 +75,23 @@ static struct mem_access user_mem_access = {
copy_to_user, 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 * handle an instruction that does an unaligned memory access by emulating the
* desired behaviour * desired behaviour
...@@ -473,7 +490,6 @@ asmlinkage void do_address_error(struct pt_regs *regs, ...@@ -473,7 +490,6 @@ asmlinkage void do_address_error(struct pt_regs *regs,
unsigned long address) unsigned long address)
{ {
unsigned long error_code = 0; unsigned long error_code = 0;
mm_segment_t oldfs;
insn_size_t instruction; insn_size_t instruction;
int tmp; int tmp;
...@@ -489,13 +505,10 @@ asmlinkage void do_address_error(struct pt_regs *regs, ...@@ -489,13 +505,10 @@ asmlinkage void do_address_error(struct pt_regs *regs,
local_irq_enable(); local_irq_enable();
inc_unaligned_user_access(); inc_unaligned_user_access();
oldfs = force_uaccess_begin();
if (copy_from_user(&instruction, (insn_size_t __user *)(regs->pc & ~1), if (copy_from_user(&instruction, (insn_size_t __user *)(regs->pc & ~1),
sizeof(instruction))) { sizeof(instruction))) {
force_uaccess_end(oldfs);
goto uspace_segv; goto uspace_segv;
} }
force_uaccess_end(oldfs);
/* shout about userspace fixups */ /* shout about userspace fixups */
unaligned_fixups_notify(current, instruction, regs); unaligned_fixups_notify(current, instruction, regs);
...@@ -518,11 +531,9 @@ asmlinkage void do_address_error(struct pt_regs *regs, ...@@ -518,11 +531,9 @@ asmlinkage void do_address_error(struct pt_regs *regs,
goto uspace_segv; goto uspace_segv;
} }
oldfs = force_uaccess_begin();
tmp = handle_unaligned_access(instruction, regs, tmp = handle_unaligned_access(instruction, regs,
&user_mem_access, 0, &user_mem_access, 0,
address); address);
force_uaccess_end(oldfs);
if (tmp == 0) if (tmp == 0)
return; /* sorted */ return; /* sorted */
...@@ -538,21 +549,18 @@ asmlinkage void do_address_error(struct pt_regs *regs, ...@@ -538,21 +549,18 @@ asmlinkage void do_address_error(struct pt_regs *regs,
if (regs->pc & 1) if (regs->pc & 1)
die("unaligned program counter", regs, error_code); die("unaligned program counter", regs, error_code);
set_fs(KERNEL_DS); if (copy_from_kernel_nofault(&instruction, (void *)(regs->pc),
if (copy_from_user(&instruction, (void __user *)(regs->pc),
sizeof(instruction))) { sizeof(instruction))) {
/* Argh. Fault on the instruction itself. /* Argh. Fault on the instruction itself.
This should never happen non-SMP This should never happen non-SMP
*/ */
set_fs(oldfs);
die("insn faulting in do_address_error", regs, 0); die("insn faulting in do_address_error", regs, 0);
} }
unaligned_fixups_notify(current, instruction, regs); unaligned_fixups_notify(current, instruction, regs);
handle_unaligned_access(instruction, regs, &user_mem_access, handle_unaligned_access(instruction, regs, &kernel_mem_access,
0, address); 0, address);
set_fs(oldfs);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment