sparc64: remove CONFIG_SET_FS support

sparc64 uses address space identifiers to differentiate between kernel
and user space, using ASI_P for kernel threads but ASI_AIUS for normal
user space, with the option of changing between them.

As nothing really changes the ASI any more, just hardcode ASI_AIUS
everywhere. Kernel threads are not allowed to access __user pointers
anyway.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Arnd Bergmann
2022-02-11 17:19:14 +01:00
parent 5a06fcb15b
commit a5ad837843
9 changed files with 9 additions and 49 deletions

View File

@@ -46,7 +46,6 @@ config SPARC
select LOCKDEP_SMALL if LOCKDEP select LOCKDEP_SMALL if LOCKDEP
select NEED_DMA_MAP_STATE select NEED_DMA_MAP_STATE
select NEED_SG_DMA_LENGTH select NEED_SG_DMA_LENGTH
select SET_FS
select TRACE_IRQFLAGS_SUPPORT select TRACE_IRQFLAGS_SUPPORT
config SPARC32 config SPARC32
@@ -59,6 +58,7 @@ config SPARC32
select HAVE_UID16 select HAVE_UID16
select OLD_SIGACTION select OLD_SIGACTION
select ZONE_DMA select ZONE_DMA
select SET_FS
config SPARC64 config SPARC64
def_bool 64BIT def_bool 64BIT

View File

@@ -47,10 +47,6 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
typedef struct {
unsigned char seg;
} mm_segment_t;
/* The Sparc processor specific thread struct. */ /* The Sparc processor specific thread struct. */
/* XXX This should die, everything can go into thread_info now. */ /* XXX This should die, everything can go into thread_info now. */
struct thread_struct { struct thread_struct {

View File

@@ -20,10 +20,8 @@ do { \
*/ */
#define switch_to(prev, next, last) \ #define switch_to(prev, next, last) \
do { save_and_clear_fpu(); \ do { save_and_clear_fpu(); \
/* If you are tempted to conditionalize the following */ \
/* so that ASI is only written if it changes, think again. */ \
__asm__ __volatile__("wr %%g0, %0, %%asi" \ __asm__ __volatile__("wr %%g0, %0, %%asi" \
: : "r" (task_thread_info(next)->current_ds));\ : : "r" (ASI_AIUS)); \
trap_block[current_thread_info()->cpu].thread = \ trap_block[current_thread_info()->cpu].thread = \
task_thread_info(next); \ task_thread_info(next); \
__asm__ __volatile__( \ __asm__ __volatile__( \

View File

@@ -46,7 +46,7 @@ struct thread_info {
struct pt_regs *kregs; struct pt_regs *kregs;
int preempt_count; /* 0 => preemptable, <0 => BUG */ int preempt_count; /* 0 => preemptable, <0 => BUG */
__u8 new_child; __u8 new_child;
__u8 current_ds; __u8 __pad;
__u16 cpu; __u16 cpu;
unsigned long *utraps; unsigned long *utraps;
@@ -81,7 +81,6 @@ struct thread_info {
#define TI_KREGS 0x00000028 #define TI_KREGS 0x00000028
#define TI_PRE_COUNT 0x00000030 #define TI_PRE_COUNT 0x00000030
#define TI_NEW_CHILD 0x00000034 #define TI_NEW_CHILD 0x00000034
#define TI_CURRENT_DS 0x00000035
#define TI_CPU 0x00000036 #define TI_CPU 0x00000036
#define TI_UTRAPS 0x00000038 #define TI_UTRAPS 0x00000038
#define TI_REG_WINDOW 0x00000040 #define TI_REG_WINDOW 0x00000040
@@ -116,7 +115,6 @@ struct thread_info {
#define INIT_THREAD_INFO(tsk) \ #define INIT_THREAD_INFO(tsk) \
{ \ { \
.task = &tsk, \ .task = &tsk, \
.current_ds = ASI_P, \
.preempt_count = INIT_PREEMPT_COUNT, \ .preempt_count = INIT_PREEMPT_COUNT, \
.kregs = (struct pt_regs *)(init_stack+THREAD_SIZE)-1 \ .kregs = (struct pt_regs *)(init_stack+THREAD_SIZE)-1 \
} }

View File

@@ -12,33 +12,15 @@
#include <asm/spitfire.h> #include <asm/spitfire.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm-generic/access_ok.h>
/* /*
* Sparc64 is segmented, though more like the M68K than the I386. * Sparc64 is segmented, though more like the M68K than the I386.
* We use the secondary ASI to address user memory, which references a * We use the secondary ASI to address user memory, which references a
* completely different VM map, thus there is zero chance of the user * completely different VM map, thus there is zero chance of the user
* doing something queer and tricking us into poking kernel memory. * doing something queer and tricking us into poking kernel memory.
*
* What is left here is basically what is needed for the other parts of
* the kernel that expect to be able to manipulate, erum, "segments".
* Or perhaps more properly, permissions.
*
* "For historical reasons, these macros are grossly misnamed." -Linus
*/ */
#define KERNEL_DS ((mm_segment_t) { ASI_P })
#define USER_DS ((mm_segment_t) { ASI_AIUS }) /* har har har */
#define get_fs() ((mm_segment_t){(current_thread_info()->current_ds)})
#include <asm-generic/access_ok.h>
#define set_fs(val) \
do { \
current_thread_info()->current_ds = (val).seg; \
__asm__ __volatile__ ("wr %%g0, %0, %%asi" : : "r" ((val).seg)); \
} while(0)
/* /*
* Test whether a block of memory is a valid user space address. * Test whether a block of memory is a valid user space address.
* Returns 0 if the range is valid, nonzero otherwise. * Returns 0 if the range is valid, nonzero otherwise.

View File

@@ -106,18 +106,13 @@ static void show_regwindow32(struct pt_regs *regs)
{ {
struct reg_window32 __user *rw; struct reg_window32 __user *rw;
struct reg_window32 r_w; struct reg_window32 r_w;
mm_segment_t old_fs;
__asm__ __volatile__ ("flushw"); __asm__ __volatile__ ("flushw");
rw = compat_ptr((unsigned int)regs->u_regs[14]); rw = compat_ptr((unsigned int)regs->u_regs[14]);
old_fs = get_fs();
set_fs (USER_DS);
if (copy_from_user (&r_w, rw, sizeof(r_w))) { if (copy_from_user (&r_w, rw, sizeof(r_w))) {
set_fs (old_fs);
return; return;
} }
set_fs (old_fs);
printk("l0: %08x l1: %08x l2: %08x l3: %08x " printk("l0: %08x l1: %08x l2: %08x l3: %08x "
"l4: %08x l5: %08x l6: %08x l7: %08x\n", "l4: %08x l5: %08x l6: %08x l7: %08x\n",
r_w.locals[0], r_w.locals[1], r_w.locals[2], r_w.locals[3], r_w.locals[0], r_w.locals[1], r_w.locals[2], r_w.locals[3],
@@ -136,7 +131,6 @@ static void show_regwindow(struct pt_regs *regs)
struct reg_window __user *rw; struct reg_window __user *rw;
struct reg_window *rwk; struct reg_window *rwk;
struct reg_window r_w; struct reg_window r_w;
mm_segment_t old_fs;
if ((regs->tstate & TSTATE_PRIV) || !(test_thread_flag(TIF_32BIT))) { if ((regs->tstate & TSTATE_PRIV) || !(test_thread_flag(TIF_32BIT))) {
__asm__ __volatile__ ("flushw"); __asm__ __volatile__ ("flushw");
@@ -145,14 +139,10 @@ static void show_regwindow(struct pt_regs *regs)
rwk = (struct reg_window *) rwk = (struct reg_window *)
(regs->u_regs[14] + STACK_BIAS); (regs->u_regs[14] + STACK_BIAS);
if (!(regs->tstate & TSTATE_PRIV)) { if (!(regs->tstate & TSTATE_PRIV)) {
old_fs = get_fs();
set_fs (USER_DS);
if (copy_from_user (&r_w, rw, sizeof(r_w))) { if (copy_from_user (&r_w, rw, sizeof(r_w))) {
set_fs (old_fs);
return; return;
} }
rwk = &r_w; rwk = &r_w;
set_fs (old_fs);
} }
} else { } else {
show_regwindow32(regs); show_regwindow32(regs);
@@ -598,7 +588,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg,
memset(child_trap_frame, 0, child_stack_sz); memset(child_trap_frame, 0, child_stack_sz);
__thread_flag_byte_ptr(t)[TI_FLAG_BYTE_CWP] = __thread_flag_byte_ptr(t)[TI_FLAG_BYTE_CWP] =
(current_pt_regs()->tstate + 1) & TSTATE_CWP; (current_pt_regs()->tstate + 1) & TSTATE_CWP;
t->current_ds = ASI_P;
t->kregs->u_regs[UREG_G1] = sp; /* function */ t->kregs->u_regs[UREG_G1] = sp; /* function */
t->kregs->u_regs[UREG_G2] = arg; t->kregs->u_regs[UREG_G2] = arg;
return 0; return 0;
@@ -613,7 +602,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg,
t->kregs->u_regs[UREG_FP] = sp; t->kregs->u_regs[UREG_FP] = sp;
__thread_flag_byte_ptr(t)[TI_FLAG_BYTE_CWP] = __thread_flag_byte_ptr(t)[TI_FLAG_BYTE_CWP] =
(regs->tstate + 1) & TSTATE_CWP; (regs->tstate + 1) & TSTATE_CWP;
t->current_ds = ASI_AIUS;
if (sp != regs->u_regs[UREG_FP]) { if (sp != regs->u_regs[UREG_FP]) {
unsigned long csp; unsigned long csp;

View File

@@ -2857,8 +2857,6 @@ void __init trap_init(void)
TI_PRE_COUNT != offsetof(struct thread_info, TI_PRE_COUNT != offsetof(struct thread_info,
preempt_count) || preempt_count) ||
TI_NEW_CHILD != offsetof(struct thread_info, new_child) || TI_NEW_CHILD != offsetof(struct thread_info, new_child) ||
TI_CURRENT_DS != offsetof(struct thread_info,
current_ds) ||
TI_KUNA_REGS != offsetof(struct thread_info, TI_KUNA_REGS != offsetof(struct thread_info,
kern_una_regs) || kern_una_regs) ||
TI_KUNA_INSN != offsetof(struct thread_info, TI_KUNA_INSN != offsetof(struct thread_info,

View File

@@ -10,8 +10,7 @@
#include <asm/thread_info.h> #include <asm/thread_info.h>
#define GLOBAL_SPARE %g7 #define GLOBAL_SPARE %g7
#define RESTORE_ASI(TMP) \ #define RESTORE_ASI(TMP) \
ldub [%g6 + TI_CURRENT_DS], TMP; \ wr %g0, ASI_AIUS, %asi
wr TMP, 0x0, %asi;
#else #else
#define GLOBAL_SPARE %g5 #define GLOBAL_SPARE %g5
#define RESTORE_ASI(TMP) \ #define RESTORE_ASI(TMP) \

View File

@@ -709,9 +709,10 @@ static void __init inherit_prom_mappings(void)
void prom_world(int enter) void prom_world(int enter)
{ {
if (!enter) /*
set_fs(get_fs()); * No need to change the address space any more, just flush
* the register windows
*/
__asm__ __volatile__("flushw"); __asm__ __volatile__("flushw");
} }