mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-16 18:26:42 +00:00
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: Christoph Hellwig <hch@lst.de> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
parent
a5ad837843
commit
75d4d29549
@ -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
|
||||
|
@ -3,7 +3,6 @@
|
||||
#define __ASM_SH_PROCESSOR_H
|
||||
|
||||
#include <asm/cpu-features.h>
|
||||
#include <asm/segment.h>
|
||||
#include <asm/cache.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
@ -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 */
|
@ -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 */
|
||||
|
@ -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>
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user