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:
Arnd Bergmann 2022-02-11 17:26:42 +01:00
parent a5ad837843
commit 75d4d29549
8 changed files with 21 additions and 61 deletions

View 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

View 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__

View File

@ -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 */

View 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 */

View 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>
/*

View 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;
}

View 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;

View 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);
}
}