Skip to content

Commit

Permalink
sparc32: take ->thread.flags out
Browse files Browse the repository at this point in the history
it was used for two things - dealing with unusual ->kregs for kernel
threads and "emulate unaligned userland accesses for this thread";
the former is killed off by the previous commit, the latter never
had been set in the first place.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
  • Loading branch information
Al Viro committed Jan 4, 2021
1 parent af76525 commit 415ddc3
Show file tree
Hide file tree
Showing 3 changed files with 1 addition and 105 deletions.
5 changes: 0 additions & 5 deletions arch/sparc/include/asm/processor_32.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,10 @@ struct thread_struct {
unsigned long fsr;
unsigned long fpqdepth;
struct fpq fpqueue[16];
unsigned long flags;
mm_segment_t current_ds;
};

#define SPARC_FLAG_KTHREAD 0x1 /* task is a kernel thread */
#define SPARC_FLAG_UNALIGNED 0x2 /* is allowed to do unaligned accesses */

#define INIT_THREAD { \
.flags = SPARC_FLAG_KTHREAD, \
.current_ds = KERNEL_DS, \
.kregs = (struct pt_regs *)(init_stack+THREAD_SIZE)-1 \
}
Expand Down
5 changes: 0 additions & 5 deletions arch/sparc/kernel/process_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,6 @@ void flush_thread(void)
clear_thread_flag(TIF_USEDFPU);
#endif
}

/* This task is no longer a kernel thread. */
current->thread.flags &= ~SPARC_FLAG_KTHREAD;
}

static inline struct sparc_stackf __user *
Expand Down Expand Up @@ -306,7 +303,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg,
extern int nwindows;
unsigned long psr;
memset(new_stack, 0, STACKFRAME_SZ + TRACEREG_SZ);
p->thread.flags |= SPARC_FLAG_KTHREAD;
p->thread.current_ds = KERNEL_DS;
ti->kpc = (((unsigned long) ret_from_kernel_thread) - 0x8);
childregs->u_regs[UREG_G1] = sp; /* function */
Expand All @@ -318,7 +314,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg,
}
memcpy(new_stack, (char *)regs - STACKFRAME_SZ, STACKFRAME_SZ + TRACEREG_SZ);
childregs->u_regs[UREG_FP] = sp;
p->thread.flags &= ~SPARC_FLAG_KTHREAD;
p->thread.current_ds = USER_DS;
ti->kpc = (((unsigned long) ret_from_fork) - 0x8);
ti->kpsr = current->thread.fork_kpsr | PSR_PIL;
Expand Down
96 changes: 1 addition & 95 deletions arch/sparc/kernel/unaligned_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,103 +274,9 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
}
}

static inline int ok_for_user(struct pt_regs *regs, unsigned int insn,
enum direction dir)
{
unsigned int reg;
int size = ((insn >> 19) & 3) == 3 ? 8 : 4;

if ((regs->pc | regs->npc) & 3)
return 0;

/* Must access_ok() in all the necessary places. */
#define WINREG_ADDR(regnum) \
((void __user *)(((unsigned long *)regs->u_regs[UREG_FP])+(regnum)))

reg = (insn >> 25) & 0x1f;
if (reg >= 16) {
if (!access_ok(WINREG_ADDR(reg - 16), size))
return -EFAULT;
}
reg = (insn >> 14) & 0x1f;
if (reg >= 16) {
if (!access_ok(WINREG_ADDR(reg - 16), size))
return -EFAULT;
}
if (!(insn & 0x2000)) {
reg = (insn & 0x1f);
if (reg >= 16) {
if (!access_ok(WINREG_ADDR(reg - 16), size))
return -EFAULT;
}
}
#undef WINREG_ADDR
return 0;
}

static void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn)
{
send_sig_fault(SIGBUS, BUS_ADRALN,
(void __user *)safe_compute_effective_address(regs, insn),
0, current);
}

asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn)
{
enum direction dir;

if(!(current->thread.flags & SPARC_FLAG_UNALIGNED) ||
(((insn >> 30) & 3) != 3))
goto kill_user;
dir = decode_direction(insn);
if(!ok_for_user(regs, insn, dir)) {
goto kill_user;
} else {
int err, size = decode_access_size(insn);
unsigned long addr;

if(floating_point_load_or_store_p(insn)) {
printk("User FPU load/store unaligned unsupported.\n");
goto kill_user;
}

addr = compute_effective_address(regs, insn);
perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, addr);
switch(dir) {
case load:
err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f),
regs),
size, (unsigned long *) addr,
decode_signedness(insn));
break;

case store:
err = do_int_store(((insn>>25)&0x1f), size,
(unsigned long *) addr, regs);
break;

case both:
/*
* This was supported in 2.4. However, we question
* the value of SWAP instruction across word boundaries.
*/
printk("Unaligned SWAP unsupported.\n");
err = -EFAULT;
break;

default:
unaligned_panic("Impossible user unaligned trap.");
goto out;
}
if (err)
goto kill_user;
else
advance(regs);
goto out;
}

kill_user:
user_mna_trap_fault(regs, insn);
out:
;
}

0 comments on commit 415ddc3

Please sign in to comment.