Commit f2a39c2b authored by Pete Zaitcev's avatar Pete Zaitcev Committed by David S. Miller

[SPARC]: Get sun4c functional again in 2.6.0

Move some elements of task_struct into thread_info so that
these elements are locked into the TLB in the trap handlers
and thus will not cause a watchdog reset.
parent 361d16e2
...@@ -38,12 +38,6 @@ int foo(void) ...@@ -38,12 +38,6 @@ int foo(void)
DEFINE(AOFF_thread_fork_kpsr, DEFINE(AOFF_thread_fork_kpsr,
offsetof(struct thread_struct, fork_kpsr)); offsetof(struct thread_struct, fork_kpsr));
BLANK(); BLANK();
DEFINE(AOFF_thread_w_saved, offsetof(struct thread_struct, w_saved));
DEFINE(AOFF_thread_rwbuf_stkptrs,
offsetof(struct thread_struct, rwbuf_stkptrs));
DEFINE(AOFF_thread_reg_window,
offsetof(struct thread_struct, reg_window));
BLANK();
DEFINE(AOFF_mm_context, offsetof(struct mm_struct, context)); DEFINE(AOFF_mm_context, offsetof(struct mm_struct, context));
/* DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28); */ /* DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28); */
......
...@@ -1907,9 +1907,8 @@ kuw_patch1: ...@@ -1907,9 +1907,8 @@ kuw_patch1:
wr %o5, 0x0, %psr ! re-enable interrupts wr %o5, 0x0, %psr ! re-enable interrupts
WRITE_PAUSE ! burn baby burn WRITE_PAUSE ! burn baby burn
3: 3:
ld [%g6 + TI_TASK], %o4
retl ! return retl ! return
st %g0, [%o4 + AOFF_task_thread + AOFF_thread_w_saved] ! no windows saved st %g0, [%g6 + TI_W_SAVED] ! no windows saved
.align 4 .align 4
.globl C_LABEL(restore_current) .globl C_LABEL(restore_current)
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include <asm/page.h> #include <asm/page.h>
#include <asm/psr.h> #include <asm/psr.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/asm_offsets.h>
#include <asm/winmacro.h> #include <asm/winmacro.h>
#include <asm/asmmacro.h> #include <asm/asmmacro.h>
#include <asm/thread_info.h> #include <asm/thread_info.h>
...@@ -57,7 +56,7 @@ tsetup_7win_patch6: and %g2, 0x7f, %g2 ...@@ -57,7 +56,7 @@ tsetup_7win_patch6: and %g2, 0x7f, %g2
* *
* sethi %hi(trap_setup), %l4 * sethi %hi(trap_setup), %l4
* jmpl %l4 + %lo(trap_setup), %l6 * jmpl %l4 + %lo(trap_setup), %l6
* mov 1, %l4 * nop
*/ */
/* 2 3 4 window number /* 2 3 4 window number
...@@ -156,9 +155,8 @@ trap_setup_from_user: ...@@ -156,9 +155,8 @@ trap_setup_from_user:
and %t_kstack, %curptr, %curptr and %t_kstack, %curptr, %curptr
#endif #endif
/* Clear current->thread.w_saved */ /* Clear current_thread_info->w_saved */
ld [%curptr + TI_TASK], %g2 st %g0, [%curptr + TI_W_SAVED]
st %g0, [%g2 + AOFF_task_thread + AOFF_thread_w_saved]
/* See if we are in the trap window. */ /* See if we are in the trap window. */
andcc %t_twinmask, %t_wim, %g0 andcc %t_twinmask, %t_wim, %g0
...@@ -292,8 +290,7 @@ trap_setup_user_stack_is_bolixed: ...@@ -292,8 +290,7 @@ trap_setup_user_stack_is_bolixed:
/* From user/kernel into invalid window w/bad user /* From user/kernel into invalid window w/bad user
* stack. Save bad user stack, and return to caller. * stack. Save bad user stack, and return to caller.
*/ */
ld [%curptr + TI_TASK], %glob_tmp SAVE_BOLIXED_USER_STACK(curptr, g3)
SAVE_BOLIXED_USER_STACK(glob_tmp, g3)
restore %g0, %g0, %g0 restore %g0, %g0, %g0
jmpl %t_retpc + 0x8, %g0 jmpl %t_retpc + 0x8, %g0
......
...@@ -356,7 +356,7 @@ void exit_thread(void) ...@@ -356,7 +356,7 @@ void exit_thread(void)
void flush_thread(void) void flush_thread(void)
{ {
current->thread.w_saved = 0; current_thread_info()->w_saved = 0;
/* No new signal delivery by default */ /* No new signal delivery by default */
current->thread.new_signal = 0; current->thread.new_signal = 0;
...@@ -490,9 +490,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, ...@@ -490,9 +490,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
ti->kpsr = current->thread.fork_kpsr | PSR_PIL; ti->kpsr = current->thread.fork_kpsr | PSR_PIL;
ti->kwim = current->thread.fork_kwim; ti->kwim = current->thread.fork_kwim;
/* This is used for sun4c only */
atomic_set(&p->thread.refcount, 1);
if(regs->psr & PSR_PS) { if(regs->psr & PSR_PS) {
extern struct pt_regs fake_swapper_regs; extern struct pt_regs fake_swapper_regs;
......
...@@ -72,7 +72,7 @@ static inline void read_sunos_user(struct pt_regs *regs, unsigned long offset, ...@@ -72,7 +72,7 @@ static inline void read_sunos_user(struct pt_regs *regs, unsigned long offset,
struct task_struct *tsk, long *addr) struct task_struct *tsk, long *addr)
{ {
struct pt_regs *cregs = tsk->thread.kregs; struct pt_regs *cregs = tsk->thread.kregs;
struct thread_struct *t = &tsk->thread; struct thread_info *t = tsk->thread_info;
int v; int v;
if(offset >= 1024) if(offset >= 1024)
...@@ -93,16 +93,16 @@ static inline void read_sunos_user(struct pt_regs *regs, unsigned long offset, ...@@ -93,16 +93,16 @@ static inline void read_sunos_user(struct pt_regs *regs, unsigned long offset,
} }
switch(offset) { switch(offset) {
case 0: case 0:
v = tsk->thread_info->ksp; v = t->ksp;
break; break;
case 4: case 4:
v = tsk->thread_info->kpc; v = t->kpc;
break; break;
case 8: case 8:
v = tsk->thread_info->kpsr; v = t->kpsr;
break; break;
case 12: case 12:
v = tsk->thread_info->uwinmask; v = t->uwinmask;
break; break;
case 832: case 832:
v = t->w_saved; v = t->w_saved;
...@@ -167,7 +167,7 @@ static inline void write_sunos_user(struct pt_regs *regs, unsigned long offset, ...@@ -167,7 +167,7 @@ static inline void write_sunos_user(struct pt_regs *regs, unsigned long offset,
struct task_struct *tsk) struct task_struct *tsk)
{ {
struct pt_regs *cregs = tsk->thread.kregs; struct pt_regs *cregs = tsk->thread.kregs;
struct thread_struct *t = &tsk->thread; struct thread_info *t = tsk->thread_info;
unsigned long value = regs->u_regs[UREG_I3]; unsigned long value = regs->u_regs[UREG_I3];
if(offset >= 1024) if(offset >= 1024)
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include <asm/cprefix.h> #include <asm/cprefix.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/asm_offsets.h>
#include <asm/psr.h> #include <asm/psr.h>
#include <asm/asi.h> #include <asm/asi.h>
#include <asm/smp.h> #include <asm/smp.h>
...@@ -87,8 +86,7 @@ ret_trap_continue: ...@@ -87,8 +86,7 @@ ret_trap_continue:
wr %t_psr, 0x0, %psr wr %t_psr, 0x0, %psr
WRITE_PAUSE WRITE_PAUSE
ld [%curptr + TI_TASK], %o5 ld [%curptr + TI_W_SAVED], %twin_tmp1
ld [%o5 + AOFF_task_thread + AOFF_thread_w_saved], %twin_tmp1
orcc %g0, %twin_tmp1, %g0 orcc %g0, %twin_tmp1, %g0
be ret_trap_nobufwins be ret_trap_nobufwins
nop nop
......
...@@ -432,6 +432,7 @@ setup_frame(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *old ...@@ -432,6 +432,7 @@ setup_frame(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *old
int window = 0, err; int window = 0, err;
unsigned long pc = regs->pc; unsigned long pc = regs->pc;
unsigned long npc = regs->npc; unsigned long npc = regs->npc;
struct thread_info *tp = current_thread_info();
void *sig_address; void *sig_address;
int sig_code; int sig_code;
...@@ -459,20 +460,20 @@ setup_frame(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *old ...@@ -459,20 +460,20 @@ setup_frame(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *old
err |= __put_user(regs->psr, &sc->sigc_psr); err |= __put_user(regs->psr, &sc->sigc_psr);
err |= __put_user(regs->u_regs[UREG_G1], &sc->sigc_g1); err |= __put_user(regs->u_regs[UREG_G1], &sc->sigc_g1);
err |= __put_user(regs->u_regs[UREG_I0], &sc->sigc_o0); err |= __put_user(regs->u_regs[UREG_I0], &sc->sigc_o0);
err |= __put_user(current->thread.w_saved, &sc->sigc_oswins); err |= __put_user(tp->w_saved, &sc->sigc_oswins);
if (current->thread.w_saved) if (tp->w_saved)
for (window = 0; window < current->thread.w_saved; window++) { for (window = 0; window < tp->w_saved; window++) {
put_user((char *)current->thread.rwbuf_stkptrs[window], put_user((char *)tp->rwbuf_stkptrs[window],
&sc->sigc_spbuf[window]); &sc->sigc_spbuf[window]);
err |= __copy_to_user(&sc->sigc_wbuf[window], err |= __copy_to_user(&sc->sigc_wbuf[window],
&current->thread.reg_window[window], &tp->reg_window[window],
sizeof(struct reg_window)); sizeof(struct reg_window));
} }
else else
err |= __copy_to_user(sframep, (char *) regs->u_regs[UREG_FP], err |= __copy_to_user(sframep, (char *) regs->u_regs[UREG_FP],
sizeof(struct reg_window)); sizeof(struct reg_window));
current->thread.w_saved = 0; /* So process is allowed to execute. */ tp->w_saved = 0; /* So process is allowed to execute. */
err |= __put_user(signr, &sframep->sig_num); err |= __put_user(signr, &sframep->sig_num);
sig_address = NULL; sig_address = NULL;
...@@ -601,7 +602,7 @@ new_setup_frame(struct k_sigaction *ka, struct pt_regs *regs, ...@@ -601,7 +602,7 @@ new_setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
if (invalid_frame_pointer(sf, sigframe_size)) if (invalid_frame_pointer(sf, sigframe_size))
goto sigill_and_return; goto sigill_and_return;
if (current->thread.w_saved != 0) if (current_thread_info()->w_saved != 0)
goto sigill_and_return; goto sigill_and_return;
/* 2. Save the current process state */ /* 2. Save the current process state */
...@@ -675,7 +676,7 @@ new_setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, ...@@ -675,7 +676,7 @@ new_setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
get_sigframe(&ka->sa, regs, sigframe_size); get_sigframe(&ka->sa, regs, sigframe_size);
if (invalid_frame_pointer(sf, sigframe_size)) if (invalid_frame_pointer(sf, sigframe_size))
goto sigill; goto sigill;
if (current->thread.w_saved != 0) if (current_thread_info()->w_saved != 0)
goto sigill; goto sigill;
err = __put_user(regs->pc, &sf->regs.pc); err = __put_user(regs->pc, &sf->regs.pc);
...@@ -752,6 +753,7 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc, ...@@ -752,6 +753,7 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
svr4_gwindows_t __user *gw; svr4_gwindows_t __user *gw;
svr4_ucontext_t __user *uc; svr4_ucontext_t __user *uc;
svr4_sigset_t setv; svr4_sigset_t setv;
struct thread_info *tp = current_thread_info();
int window = 0, err; int window = 0, err;
synchronize_user_stack(); synchronize_user_stack();
...@@ -808,7 +810,7 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc, ...@@ -808,7 +810,7 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
err |= __put_user(gw, &mc->gwin); err |= __put_user(gw, &mc->gwin);
/* 2. Number of windows to restore at setcontext(): */ /* 2. Number of windows to restore at setcontext(): */
err |= __put_user(current->thread.w_saved, &gw->count); err |= __put_user(tp->w_saved, &gw->count);
/* 3. Save each valid window /* 3. Save each valid window
* Currently, it makes a copy of the windows from the kernel copy. * Currently, it makes a copy of the windows from the kernel copy.
...@@ -821,16 +823,16 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc, ...@@ -821,16 +823,16 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
* These windows are just used in case synchronize_user_stack failed * These windows are just used in case synchronize_user_stack failed
* to flush the user windows. * to flush the user windows.
*/ */
for (window = 0; window < current->thread.w_saved; window++) { for (window = 0; window < tp->w_saved; window++) {
err |= __put_user((int *) &(gw->win[window]), &gw->winptr[window]); err |= __put_user((int *) &(gw->win[window]), &gw->winptr[window]);
err |= __copy_to_user(&gw->win[window], err |= __copy_to_user(&gw->win[window],
&current->thread.reg_window[window], &tp->reg_window[window],
sizeof(svr4_rwindow_t)); sizeof(svr4_rwindow_t));
err |= __put_user(0, gw->winptr[window]); err |= __put_user(0, gw->winptr[window]);
} }
/* 4. We just pay attention to the gw->count field on setcontext */ /* 4. We just pay attention to the gw->count field on setcontext */
current->thread.w_saved = 0; /* So process is allowed to execute. */ tp->w_saved = 0; /* So process is allowed to execute. */
/* Setup the signal information. Solaris expects a bunch of /* Setup the signal information. Solaris expects a bunch of
* information to be passed to the signal handler, we don't provide * information to be passed to the signal handler, we don't provide
...@@ -878,7 +880,7 @@ asmlinkage int svr4_getcontext(svr4_ucontext_t __user *uc, struct pt_regs *regs) ...@@ -878,7 +880,7 @@ asmlinkage int svr4_getcontext(svr4_ucontext_t __user *uc, struct pt_regs *regs)
synchronize_user_stack(); synchronize_user_stack();
if (current->thread.w_saved) if (current_thread_info()->w_saved)
goto sigsegv_and_return; goto sigsegv_and_return;
err = clear_user(uc, sizeof(*uc)); err = clear_user(uc, sizeof(*uc));
...@@ -928,7 +930,6 @@ asmlinkage int svr4_getcontext(svr4_ucontext_t __user *uc, struct pt_regs *regs) ...@@ -928,7 +930,6 @@ asmlinkage int svr4_getcontext(svr4_ucontext_t __user *uc, struct pt_regs *regs)
/* Set the context for a svr4 application, this is Solaris way to sigreturn */ /* Set the context for a svr4 application, this is Solaris way to sigreturn */
asmlinkage int svr4_setcontext(svr4_ucontext_t __user *c, struct pt_regs *regs) asmlinkage int svr4_setcontext(svr4_ucontext_t __user *c, struct pt_regs *regs)
{ {
struct thread_struct *tp = &current->thread;
svr4_gregset_t __user *gr; svr4_gregset_t __user *gr;
unsigned long pc, npc, psr; unsigned long pc, npc, psr;
sigset_t set; sigset_t set;
...@@ -940,8 +941,8 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t __user *c, struct pt_regs *regs) ...@@ -940,8 +941,8 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t __user *c, struct pt_regs *regs)
* svr4_setup_frame when sync_user_windows is done? * svr4_setup_frame when sync_user_windows is done?
*/ */
flush_user_windows(); flush_user_windows();
if (tp->w_saved) if (current_thread_info()->w_saved)
goto sigsegv_and_return; goto sigsegv_and_return;
if (((uint) c) & 3) if (((uint) c) & 3)
......
...@@ -497,7 +497,10 @@ void trap_init(void) ...@@ -497,7 +497,10 @@ void trap_init(void)
TI_KSP != offsetof(struct thread_info, ksp) || TI_KSP != offsetof(struct thread_info, ksp) ||
TI_KPC != offsetof(struct thread_info, kpc) || TI_KPC != offsetof(struct thread_info, kpc) ||
TI_KPSR != offsetof(struct thread_info, kpsr) || TI_KPSR != offsetof(struct thread_info, kpsr) ||
TI_KWIM != offsetof(struct thread_info, kwim)) TI_KWIM != offsetof(struct thread_info, kwim) ||
TI_REG_WINDOW != offsetof(struct thread_info, reg_window) ||
TI_RWIN_SPTRS != offsetof(struct thread_info, rwbuf_stkptrs) ||
TI_W_SAVED != offsetof(struct thread_info, w_saved))
thread_info_offsets_are_bolixed_pete(); thread_info_offsets_are_bolixed_pete();
/* Attach to the address space of init_task. */ /* Attach to the address space of init_task. */
......
...@@ -36,7 +36,7 @@ void flush_user_windows(void) ...@@ -36,7 +36,7 @@ void flush_user_windows(void)
: "g4", "cc"); : "g4", "cc");
} }
static inline void shift_window_buffer(int first_win, int last_win, struct thread_struct *tp) static inline void shift_window_buffer(int first_win, int last_win, struct thread_info *tp)
{ {
int i; int i;
...@@ -57,11 +57,10 @@ static inline void shift_window_buffer(int first_win, int last_win, struct threa ...@@ -57,11 +57,10 @@ static inline void shift_window_buffer(int first_win, int last_win, struct threa
*/ */
void synchronize_user_stack(void) void synchronize_user_stack(void)
{ {
struct thread_struct *tp; struct thread_info *tp = current_thread_info();
int window; int window;
flush_user_windows(); flush_user_windows();
tp = &current->thread;
if(!tp->w_saved) if(!tp->w_saved)
return; return;
...@@ -110,12 +109,11 @@ static inline void copy_aligned_window(void *dest, const void *src) ...@@ -110,12 +109,11 @@ static inline void copy_aligned_window(void *dest, const void *src)
void try_to_clear_window_buffer(struct pt_regs *regs, int who) void try_to_clear_window_buffer(struct pt_regs *regs, int who)
{ {
struct thread_struct *tp; struct thread_info *tp = current_thread_info();
int window; int window;
lock_kernel(); lock_kernel();
flush_user_windows(); flush_user_windows();
tp = &current->thread;
for(window = 0; window < tp->w_saved; window++) { for(window = 0; window < tp->w_saved; window++) {
unsigned long sp = tp->rwbuf_stkptrs[window]; unsigned long sp = tp->rwbuf_stkptrs[window];
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#include <asm/contregs.h> #include <asm/contregs.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/asm_offsets.h>
#include <asm/psr.h> #include <asm/psr.h>
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/asi.h> #include <asm/asi.h>
...@@ -211,20 +210,18 @@ spwin_user_stack_is_bolixed: ...@@ -211,20 +210,18 @@ spwin_user_stack_is_bolixed:
bne spwin_bad_ustack_from_kernel bne spwin_bad_ustack_from_kernel
nop nop
ld [%curptr + TI_TASK], %glob_tmp
/* Oh well, throw this one window into the per-task window /* Oh well, throw this one window into the per-task window
* buffer, the first one. * buffer, the first one.
*/ */
st %sp, [%glob_tmp + AOFF_task_thread + AOFF_thread_rwbuf_stkptrs] st %sp, [%curptr + TI_RWIN_SPTRS]
STORE_WINDOW(glob_tmp + AOFF_task_thread + AOFF_thread_reg_window) STORE_WINDOW(curptr + TI_REG_WINDOW)
restore %g0, %g0, %g0 restore %g0, %g0, %g0
/* LOCATION: Trap Window */ /* LOCATION: Trap Window */
/* Back in the trap window, update winbuffer save count. */ /* Back in the trap window, update winbuffer save count. */
mov 1, %twin_tmp mov 1, %twin_tmp
st %twin_tmp, [%glob_tmp + AOFF_task_thread + AOFF_thread_w_saved] st %twin_tmp, [%curptr + TI_W_SAVED]
/* Compute new user window mask. What we are basically /* Compute new user window mask. What we are basically
* doing is taking two windows, the invalid one at trap * doing is taking two windows, the invalid one at trap
...@@ -275,8 +272,7 @@ spwin_bad_ustack_from_kernel: ...@@ -275,8 +272,7 @@ spwin_bad_ustack_from_kernel:
* a per-process window buffer until we can properly handle * a per-process window buffer until we can properly handle
* this later on. * this later on.
*/ */
ld [%curptr + TI_TASK], %glob_tmp /* Using curptr one last time */ SAVE_BOLIXED_USER_STACK(curptr, glob_tmp)
SAVE_BOLIXED_USER_STACK(glob_tmp, g6) /* ...now using g6 as scratch */
restore %g0, %g0, %g0 restore %g0, %g0, %g0
/* LOCATION: Trap window */ /* LOCATION: Trap window */
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#include <asm/contregs.h> #include <asm/contregs.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/asm_offsets.h>
#include <asm/psr.h> #include <asm/psr.h>
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/asi.h> #include <asm/asi.h>
...@@ -187,8 +186,7 @@ fwin_user_stack_is_bolixed: ...@@ -187,8 +186,7 @@ fwin_user_stack_is_bolixed:
mov 0x1, %g5 mov 0x1, %g5
sll %g5, %g3, %g5 sll %g5, %g3, %g5
st %g5, [%curptr + TI_UWINMASK] ! one live user window still st %g5, [%curptr + TI_UWINMASK] ! one live user window still
ld [%curptr + TI_TASK], %g5 st %g0, [%curptr + TI_W_SAVED] ! no windows in the buffer
st %g0, [%g5 + AOFF_task_thread + AOFF_thread_w_saved] ! no windows in the buffer
wr %t_psr, PSR_ET, %psr ! enable traps wr %t_psr, PSR_ET, %psr ! enable traps
nop nop
......
...@@ -550,7 +550,7 @@ void window_overflow_fault(void) ...@@ -550,7 +550,7 @@ void window_overflow_fault(void)
{ {
unsigned long sp; unsigned long sp;
sp = current->thread.rwbuf_stkptrs[0]; sp = current_thread_info()->rwbuf_stkptrs[0];
if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK))
force_user_fault(sp + 0x38, 1); force_user_fault(sp + 0x38, 1);
force_user_fault(sp, 1); force_user_fault(sp, 1);
......
...@@ -209,7 +209,8 @@ unsigned long __init bootmem_init(unsigned long *pages_avail) ...@@ -209,7 +209,8 @@ unsigned long __init bootmem_init(unsigned long *pages_avail)
if (max_low_pfn > (SRMMU_MAXMEM >> PAGE_SHIFT)) { if (max_low_pfn > (SRMMU_MAXMEM >> PAGE_SHIFT)) {
highstart_pfn = (SRMMU_MAXMEM >> PAGE_SHIFT); highstart_pfn = (SRMMU_MAXMEM >> PAGE_SHIFT);
max_low_pfn = calc_max_low_pfn(); max_low_pfn = calc_max_low_pfn();
printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", calc_highpages()); printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
calc_highpages() >> (20 - PAGE_SHIFT));
} }
#ifdef CONFIG_BLK_DEV_INITRD #ifdef CONFIG_BLK_DEV_INITRD
......
...@@ -1067,23 +1067,21 @@ static void sun4c_free_thread_info(struct thread_info *ti) ...@@ -1067,23 +1067,21 @@ static void sun4c_free_thread_info(struct thread_info *ti)
unsigned long pages = BUCKET_PTE_PAGE(sun4c_get_pte(tiaddr)); unsigned long pages = BUCKET_PTE_PAGE(sun4c_get_pte(tiaddr));
int entry = BUCKET_NUM(tiaddr); int entry = BUCKET_NUM(tiaddr);
if (atomic_dec_and_test(&ti->task->thread.refcount)) { /* We are deleting a mapping, so the flush here is mandatory. */
/* We are deleting a mapping, so the flush here is mandatory. */ sun4c_flush_page(tiaddr);
sun4c_flush_page(tiaddr);
#ifndef CONFIG_SUN4 #ifndef CONFIG_SUN4
sun4c_flush_page(tiaddr + PAGE_SIZE); sun4c_flush_page(tiaddr + PAGE_SIZE);
#endif #endif
sun4c_put_pte(tiaddr, 0); sun4c_put_pte(tiaddr, 0);
#ifndef CONFIG_SUN4 #ifndef CONFIG_SUN4
sun4c_put_pte(tiaddr + PAGE_SIZE, 0); sun4c_put_pte(tiaddr + PAGE_SIZE, 0);
#endif #endif
sun4c_bucket[entry] = BUCKET_EMPTY; sun4c_bucket[entry] = BUCKET_EMPTY;
if (entry < sun4c_lowbucket_avail) if (entry < sun4c_lowbucket_avail)
sun4c_lowbucket_avail = entry; sun4c_lowbucket_avail = entry;
free_pages(pages, THREAD_INFO_ORDER); free_pages(pages, THREAD_INFO_ORDER);
garbage_collect(entry); garbage_collect(entry);
}
} }
static void __init sun4c_init_buckets(void) static void __init sun4c_init_buckets(void)
......
...@@ -56,19 +56,12 @@ typedef struct { ...@@ -56,19 +56,12 @@ typedef struct {
/* The Sparc processor specific thread struct. */ /* The Sparc processor specific thread struct. */
struct thread_struct { struct thread_struct {
struct pt_regs *kregs; struct pt_regs *kregs;
unsigned int _pad1;
/* Special child fork kpsr/kwim values. */ /* Special child fork kpsr/kwim values. */
unsigned long fork_kpsr __attribute__ ((aligned (8))); unsigned long fork_kpsr __attribute__ ((aligned (8)));
unsigned long fork_kwim; unsigned long fork_kwim;
/* A place to store user windows and stack pointers
* when the stack needs inspection.
*/
#define NSWINS 8
struct reg_window reg_window[NSWINS] __attribute__ ((aligned (8)));
unsigned long rwbuf_stkptrs[NSWINS] __attribute__ ((aligned (8)));
unsigned long w_saved;
/* Floating point regs */ /* Floating point regs */
unsigned long float_regs[32] __attribute__ ((aligned (8))); unsigned long float_regs[32] __attribute__ ((aligned (8)));
unsigned long fsr; unsigned long fsr;
...@@ -78,23 +71,16 @@ struct thread_struct { ...@@ -78,23 +71,16 @@ struct thread_struct {
mm_segment_t current_ds; mm_segment_t current_ds;
struct exec core_exec; /* just what it says. */ struct exec core_exec; /* just what it says. */
int new_signal; int new_signal;
atomic_t refcount; /* used for sun4c only */
}; };
#define SPARC_FLAG_KTHREAD 0x1 /* task is a kernel thread */ #define SPARC_FLAG_KTHREAD 0x1 /* task is a kernel thread */
#define SPARC_FLAG_UNALIGNED 0x2 /* is allowed to do unaligned accesses */ #define SPARC_FLAG_UNALIGNED 0x2 /* is allowed to do unaligned accesses */
#define INIT_THREAD { \ #define INIT_THREAD { \
/* kregs, */ \ /* kregs, _pad1, */ \
0, \ 0, 0, \
/* fork_kpsr, fork_kwim */ \ /* fork_kpsr, fork_kwim */ \
0, 0, \ 0, 0, \
/* reg_window */ \
{ { { 0, }, { 0, } }, }, \
/* rwbuf_stkptrs */ \
{ 0, 0, 0, 0, 0, 0, 0, 0, }, \
/* w_saved */ \
0, \
/* FPU regs */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ /* FPU regs */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, \
/* FPU status, FPU qdepth, FPU queue */ \ /* FPU status, FPU qdepth, FPU queue */ \
......
...@@ -16,16 +16,14 @@ ...@@ -16,16 +16,14 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <asm/btfixup.h> #include <asm/btfixup.h>
#include <asm/ptrace.h>
/* /*
* Low level task data. * Low level task data.
* *
* If you change this, change the TI_* offsets below to match. XXX check_asm. * If you change this, change the TI_* offsets below to match.
*
* The uwinmask is a first class citizen among w_saved and friends.
* XXX Is this a good idea? wof.S/wuf.S have to use w_saved anyway,
* so they waste a register on current, and an ld on fetching it.
*/ */
#define NSWINS 8
struct thread_info { struct thread_info {
unsigned long uwinmask; unsigned long uwinmask;
struct task_struct *task; /* main task structure */ struct task_struct *task; /* main task structure */
...@@ -43,6 +41,13 @@ struct thread_info { ...@@ -43,6 +41,13 @@ struct thread_info {
unsigned long kpsr; unsigned long kpsr;
unsigned long kwim; unsigned long kwim;
/* A place to store user windows and stack pointers
* when the stack needs inspection.
*/
struct reg_window reg_window[NSWINS]; /* align for ldd! */
unsigned long rwbuf_stkptrs[NSWINS];
unsigned long w_saved;
struct restart_block restart_block; struct restart_block restart_block;
}; };
...@@ -100,6 +105,7 @@ BTFIXUPDEF_CALL(void, free_thread_info, struct thread_info *) ...@@ -100,6 +105,7 @@ BTFIXUPDEF_CALL(void, free_thread_info, struct thread_info *)
/* /*
* Offsets in thread_info structure, used in assembly code * Offsets in thread_info structure, used in assembly code
* The "#define REGWIN_SZ 0x40" was abolished, so no multiplications.
*/ */
#define TI_UWINMASK 0x00 /* uwinmask */ #define TI_UWINMASK 0x00 /* uwinmask */
#define TI_TASK 0x04 #define TI_TASK 0x04
...@@ -113,7 +119,10 @@ BTFIXUPDEF_CALL(void, free_thread_info, struct thread_info *) ...@@ -113,7 +119,10 @@ BTFIXUPDEF_CALL(void, free_thread_info, struct thread_info *)
#define TI_KPC 0x24 /* kpc (ldd'ed with kpc) */ #define TI_KPC 0x24 /* kpc (ldd'ed with kpc) */
#define TI_KPSR 0x28 /* kpsr */ #define TI_KPSR 0x28 /* kpsr */
#define TI_KWIM 0x2c /* kwim (ldd'ed with kpsr) */ #define TI_KWIM 0x2c /* kwim (ldd'ed with kpsr) */
#define TI_RESTART_BLOCK 0x30 #define TI_REG_WINDOW 0x30
#define TI_RWIN_SPTRS 0x230
#define TI_W_SAVED 0x250
/* #define TI_RESTART_BLOCK 0x25n */ /* Nobody cares */
#define PREEMPT_ACTIVE 0x4000000 #define PREEMPT_ACTIVE 0x4000000
......
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#include <linux/config.h> #include <linux/config.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/psr.h>
/* Store the register window onto the 8-byte aligned area starting /* Store the register window onto the 8-byte aligned area starting
* at %reg. It might be %sp, it might not, we don't care. * at %reg. It might be %sp, it might not, we don't care.
...@@ -91,18 +90,18 @@ ...@@ -91,18 +90,18 @@
STORE_PT_INS(base_reg) STORE_PT_INS(base_reg)
#define SAVE_BOLIXED_USER_STACK(cur_reg, scratch) \ #define SAVE_BOLIXED_USER_STACK(cur_reg, scratch) \
ld [%cur_reg + AOFF_task_thread + AOFF_thread_w_saved], %scratch; \ ld [%cur_reg + TI_W_SAVED], %scratch; \
sll %scratch, 2, %scratch; \ sll %scratch, 2, %scratch; \
add %scratch, %cur_reg, %scratch; \ add %scratch, %cur_reg, %scratch; \
st %sp, [%scratch + AOFF_task_thread + AOFF_thread_rwbuf_stkptrs]; \ st %sp, [%scratch + TI_RWIN_SPTRS]; \
sub %scratch, %cur_reg, %scratch; \ sub %scratch, %cur_reg, %scratch; \
sll %scratch, 4, %scratch; \ sll %scratch, 4, %scratch; \
add %scratch, %cur_reg, %scratch; \ add %scratch, %cur_reg, %scratch; \
STORE_WINDOW(scratch + AOFF_task_thread + AOFF_thread_reg_window); \ STORE_WINDOW(scratch + TI_REG_WINDOW); \
sub %scratch, %cur_reg, %scratch; \ sub %scratch, %cur_reg, %scratch; \
srl %scratch, 6, %scratch; \ srl %scratch, 6, %scratch; \
add %scratch, 1, %scratch; \ add %scratch, 1, %scratch; \
st %scratch, [%cur_reg + AOFF_task_thread + AOFF_thread_w_saved]; st %scratch, [%cur_reg + TI_W_SAVED];
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
#define LOAD_CURRENT4M(dest_reg, idreg) \ #define LOAD_CURRENT4M(dest_reg, idreg) \
......
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