diff options
30 files changed, 149 insertions, 159 deletions
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index 57d1bbd..4bcfe54 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S @@ -1306,6 +1306,8 @@ ret_from_fork: .align 4 .globl linux_sparc_syscall linux_sparc_syscall: + sethi %hi(PSR_SYSCALL), %l4 + or %l0, %l4, %l0 /* Direct access to user regs, must faster. */ cmp %g1, NR_SYSCALLS bgeu linux_sparc_ni_syscall diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c index 36431f3..da48d24 100644 --- a/arch/sparc/kernel/process.c +++ b/arch/sparc/kernel/process.c @@ -638,11 +638,6 @@ asmlinkage int sparc_execve(struct pt_regs *regs) (char __user * __user *)regs->u_regs[base + UREG_I2], regs); putname(filename); - if (error == 0) { - task_lock(current); - current->ptrace &= ~PT_DTRACE; - task_unlock(current); - } out: return error; } diff --git a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c index 7f44ae6..81f3b92 100644 --- a/arch/sparc/kernel/ptrace.c +++ b/arch/sparc/kernel/ptrace.c @@ -170,8 +170,8 @@ static int genregs32_set(struct task_struct *target, switch (pos) { case 32: /* PSR */ psr = regs->psr; - psr &= ~PSR_ICC; - psr |= (reg & PSR_ICC); + psr &= ~(PSR_ICC | PSR_SYSCALL); + psr |= (reg & (PSR_ICC | PSR_SYSCALL)); regs->psr = psr; break; case 33: /* PC */ @@ -441,6 +441,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; default: + if (request == PTRACE_SPARC_DETACH) + request = PTRACE_DETACH; ret = ptrace_request(child, request, addr, data); break; } diff --git a/arch/sparc/kernel/rtrap.S b/arch/sparc/kernel/rtrap.S index 77ca6fd..b27b5b5 100644 --- a/arch/sparc/kernel/rtrap.S +++ b/arch/sparc/kernel/rtrap.S @@ -50,8 +50,9 @@ rtrap_7win_patch5: and %g1, 0x7f, %g1 ret_trap_entry: ret_trap_lockless_ipi: andcc %t_psr, PSR_PS, %g0 + sethi %hi(PSR_SYSCALL), %g1 be 1f - nop + andn %t_psr, %g1, %t_psr wr %t_psr, 0x0, %psr b ret_trap_kernel @@ -73,7 +74,6 @@ signal_p: ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr mov %l5, %o1 - mov %l6, %o2 call do_signal add %sp, STACKFRAME_SZ, %o0 ! pt_regs ptr @@ -81,6 +81,8 @@ signal_p: ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr clr %l6 ret_trap_continue: + sethi %hi(PSR_SYSCALL), %g1 + andn %t_psr, %g1, %t_psr wr %t_psr, 0x0, %psr WRITE_PAUSE @@ -137,8 +139,9 @@ ret_trap_userwins_ok: LOAD_PT_PRIV(sp, t_psr, t_pc, t_npc) or %t_pc, %t_npc, %g2 andcc %g2, 0x3, %g0 + sethi %hi(PSR_SYCALL), %g2 be 1f - nop + andn %t_psr, %g2, %t_psr b ret_trap_unaligned_pc add %sp, STACKFRAME_SZ, %o0 @@ -201,6 +204,8 @@ rtrap_patch5: and %g1, 0xff, %g1 1: LOAD_PT_ALL(sp, t_psr, t_pc, t_npc, g1) 2: + sethi %hi(PSR_SYSCALL), %twin_tmp1 + andn %t_psr, %twin_tmp1, %t_psr wr %t_psr, 0x0, %psr WRITE_PAUSE diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c index 3681579..3fd1df9 100644 --- a/arch/sparc/kernel/signal.c +++ b/arch/sparc/kernel/signal.c @@ -145,6 +145,9 @@ asmlinkage void do_sigreturn(struct pt_regs *regs) regs->psr = (up_psr & ~(PSR_ICC | PSR_EF)) | (regs->psr & (PSR_ICC | PSR_EF)); + /* Prevent syscall restart. */ + pt_regs_clear_syscall(regs); + err |= __get_user(fpu_save, &sf->fpu_save); if (fpu_save) @@ -199,6 +202,9 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs) regs->psr = (regs->psr & ~PSR_ICC) | (psr & PSR_ICC); + /* Prevent syscall restart. */ + pt_regs_clear_syscall(regs); + err |= __get_user(fpu_save, &sf->fpu_save); if (fpu_save) @@ -507,26 +513,36 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, * want to handle. Thus you cannot kill init even with a SIGKILL even by * mistake. */ -asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0, int restart_syscall) +asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0) { - siginfo_t info; - struct sparc_deliver_cookie cookie; struct k_sigaction ka; - int signr; + int restart_syscall; sigset_t *oldset; + siginfo_t info; + int signr; - cookie.restart_syscall = restart_syscall; - cookie.orig_i0 = orig_i0; + if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C)) + restart_syscall = 1; + else + restart_syscall = 0; if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; - signr = get_signal_to_deliver(&info, &ka, regs, &cookie); + signr = get_signal_to_deliver(&info, &ka, regs, NULL); + + /* If the debugger messes with the program counter, it clears + * the software "in syscall" bit, directing us to not perform + * a syscall restart. + */ + if (restart_syscall && !pt_regs_is_syscall(regs)) + restart_syscall = 0; + if (signr > 0) { - if (cookie.restart_syscall) - syscall_restart(cookie.orig_i0, regs, &ka.sa); + if (restart_syscall) + syscall_restart(orig_i0, regs, &ka.sa); handle_signal(signr, &ka, &info, oldset, regs); /* a signal was successfully delivered; the saved @@ -538,16 +554,16 @@ asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0, int rest clear_thread_flag(TIF_RESTORE_SIGMASK); return; } - if (cookie.restart_syscall && + if (restart_syscall && (regs->u_regs[UREG_I0] == ERESTARTNOHAND || regs->u_regs[UREG_I0] == ERESTARTSYS || regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { /* replay the system call when we are done */ - regs->u_regs[UREG_I0] = cookie.orig_i0; + regs->u_regs[UREG_I0] = orig_i0; regs->pc -= 4; regs->npc -= 4; } - if (cookie.restart_syscall && + if (restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->pc -= 4; @@ -599,27 +615,3 @@ do_sys_sigstack(struct sigstack __user *ssptr, struct sigstack __user *ossptr, out: return ret; } - -void ptrace_signal_deliver(struct pt_regs *regs, void *cookie) -{ - struct sparc_deliver_cookie *cp = cookie; - - if (cp->restart_syscall && - (regs->u_regs[UREG_I0] == ERESTARTNOHAND || - regs->u_regs[UREG_I0] == ERESTARTSYS || - regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { - /* replay the system call when we are done */ - regs->u_regs[UREG_I0] = cp->orig_i0; - regs->pc -= 4; - regs->npc -= 4; - cp->restart_syscall = 0; - } - - if (cp->restart_syscall && - regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { - regs->u_regs[UREG_G1] = __NR_restart_syscall; - regs->pc -= 4; - regs->npc -= 4; - cp->restart_syscall = 0; - } -} diff --git a/arch/sparc64/kernel/etrap.S b/arch/sparc64/kernel/etrap.S index b49d3b6..f25e1da 100644 --- a/arch/sparc64/kernel/etrap.S +++ b/arch/sparc64/kernel/etrap.S @@ -27,11 +27,12 @@ .text .align 64 - .globl etrap, etrap_irq, etraptl1 + .globl etrap_syscall, etrap, etrap_irq, etraptl1 etrap: rdpr %pil, %g2 -etrap_irq: - TRAP_LOAD_THREAD_REG(%g6, %g1) +etrap_irq: clr %g3 +etrap_syscall: TRAP_LOAD_THREAD_REG(%g6, %g1) rdpr %tstate, %g1 + or %g1, %g3, %g1 sllx %g2, 20, %g3 andcc %g1, TSTATE_PRIV, %g0 or %g1, %g3, %g1 diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c index e9fc0aa..f6c9fc9 100644 --- a/arch/sparc64/kernel/ptrace.c +++ b/arch/sparc64/kernel/ptrace.c @@ -287,11 +287,11 @@ static int genregs64_set(struct task_struct *target, 32 * sizeof(u64), 33 * sizeof(u64)); if (!ret) { - /* Only the condition codes can be modified - * in the %tstate register. + /* Only the condition codes and the "in syscall" + * state can be modified in the %tstate register. */ - tstate &= (TSTATE_ICC | TSTATE_XCC); - regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC); + tstate &= (TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL); + regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL); regs->tstate |= tstate; } } @@ -657,8 +657,10 @@ static int genregs32_set(struct task_struct *target, switch (pos) { case 32: /* PSR */ tstate = regs->tstate; - tstate &= ~(TSTATE_ICC | TSTATE_XCC); + tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL); tstate |= psr_to_tstate_icc(reg); + if (reg & PSR_SYSCALL) + tstate |= TSTATE_SYSCALL; regs->tstate = tstate; break; case 33: /* PC */ @@ -944,6 +946,8 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, break; default: + if (request == PTRACE_SPARC_DETACH) + request = PTRACE_DETACH; ret = compat_ptrace_request(child, request, addr, data); break; } @@ -1036,6 +1040,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; default: + if (request == PTRACE_SPARC_DETACH) + request = PTRACE_DETACH; ret = ptrace_request(child, request, addr, data); break; } diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S index ecf6753..b9b785f 100644 --- a/arch/sparc64/kernel/rtrap.S +++ b/arch/sparc64/kernel/rtrap.S @@ -257,6 +257,7 @@ rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1 wr %o3, %g0, %y wrpr %l4, 0x0, %pil wrpr %g0, 0x1, %tl + andn %l1, TSTATE_SYSCALL, %l1 wrpr %l1, %g0, %tstate wrpr %l2, %g0, %tpc wrpr %o2, %g0, %tnpc diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c index 07c0443..2378482 100644 --- a/arch/sparc64/kernel/signal.c +++ b/arch/sparc64/kernel/signal.c @@ -333,7 +333,7 @@ void do_rt_sigreturn(struct pt_regs *regs) regs->tnpc = tnpc; /* Prevent syscall restart. */ - pt_regs_clear_trap_type(regs); + pt_regs_clear_syscall(regs); sigdelsetmask(&set, ~_BLOCKABLE); spin_lock_irq(¤t->sighand->siglock); @@ -499,7 +499,7 @@ static inline void handle_signal(unsigned long signr, struct k_sigaction *ka, } static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, - struct sigaction *sa) + struct sigaction *sa) { switch (regs->u_regs[UREG_I0]) { case ERESTART_RESTARTBLOCK: @@ -525,19 +525,17 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, */ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) { - struct signal_deliver_cookie cookie; struct k_sigaction ka; + int restart_syscall; sigset_t *oldset; siginfo_t info; int signr; if (pt_regs_is_syscall(regs) && (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) { - pt_regs_clear_trap_type(regs); - cookie.restart_syscall = 1; + restart_syscall = 1; } else - cookie.restart_syscall = 0; - cookie.orig_i0 = orig_i0; + restart_syscall = 0; if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; @@ -547,16 +545,25 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) #ifdef CONFIG_COMPAT if (test_thread_flag(TIF_32BIT)) { extern void do_signal32(sigset_t *, struct pt_regs *, - struct signal_deliver_cookie *); - do_signal32(oldset, regs, &cookie); + int restart_syscall, + unsigned long orig_i0); + do_signal32(oldset, regs, restart_syscall, orig_i0); return; } #endif - signr = get_signal_to_deliver(&info, &ka, regs, &cookie); + signr = get_signal_to_deliver(&info, &ka, regs, NULL); + + /* If the debugger messes with the program counter, it clears + * the software "in syscall" bit, directing us to not perform + * a syscall restart. + */ + if (restart_syscall && !pt_regs_is_syscall(regs)) + restart_syscall = 0; + if (signr > 0) { - if (cookie.restart_syscall) - syscall_restart(cookie.orig_i0, regs, &ka.sa); + if (restart_syscall) + syscall_restart(orig_i0, regs, &ka.sa); handle_signal(signr, &ka, &info, oldset, regs); /* a signal was successfully delivered; the saved @@ -568,16 +575,16 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) clear_thread_flag(TIF_RESTORE_SIGMASK); return; } - if (cookie.restart_syscall && + if (restart_syscall && (regs->u_regs[UREG_I0] == ERESTARTNOHAND || regs->u_regs[UREG_I0] == ERESTARTSYS || regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { /* replay the system call when we are done */ - regs->u_regs[UREG_I0] = cookie.orig_i0; + regs->u_regs[UREG_I0] = orig_i0; regs->tpc -= 4; regs->tnpc -= 4; } - if (cookie.restart_syscall && + if (restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->tpc -= 4; @@ -598,26 +605,3 @@ void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) do_signal(regs, orig_i0); } - -void ptrace_signal_deliver(struct pt_regs *regs, void *cookie) -{ - struct signal_deliver_cookie *cp = cookie; - - if (cp->restart_syscall && - (regs->u_regs[UREG_I0] == ERESTARTNOHAND || - regs->u_regs[UREG_I0] == ERESTARTSYS || - regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { - /* replay the system call when we are done */ - regs->u_regs[UREG_I0] = cp->orig_i0; - regs->tpc -= 4; - regs->tnpc -= 4; - cp->restart_syscall = 0; - } - if (cp->restart_syscall && - regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { - regs->u_regs[UREG_G1] = __NR_restart_syscall; - regs->tpc -= 4; - regs->tnpc -= 4; - cp->restart_syscall = 0; - } -} diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index 0f6b7b1..3f19e9a 100644 --- a/arch/sparc64/kernel/signal32.c +++ b/arch/sparc64/kernel/signal32.c @@ -269,7 +269,7 @@ void do_sigreturn32(struct pt_regs *regs) regs->tstate |= psr_to_tstate_icc(psr); /* Prevent syscall restart. */ - pt_regs_clear_trap_type(regs); + pt_regs_clear_syscall(regs); err |= __get_user(fpu_save, &sf->fpu_save); if (fpu_save) @@ -355,7 +355,7 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) regs->tstate |= psr_to_tstate_icc(psr); /* Prevent syscall restart. */ - pt_regs_clear_trap_type(regs); + pt_regs_clear_syscall(regs); err |= __get_user(fpu_save, &sf->fpu_save); if (fpu_save) @@ -768,16 +768,24 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs * mistake. */ void do_signal32(sigset_t *oldset, struct pt_regs * regs, - struct signal_deliver_cookie *cookie) + int restart_syscall, unsigned long orig_i0) { struct k_sigaction ka; siginfo_t info; int signr; - signr = get_signal_to_deliver(&info, &ka, regs, cookie); + signr = get_signal_to_deliver(&info, &ka, regs, NULL); + + /* If the debugger messes with the program counter, it clears + * the "in syscall" bit, directing us to not perform a syscall + * restart. + */ + if (restart_syscall && !pt_regs_is_syscall(regs)) + restart_syscall = 0; + if (signr > 0) { - if (cookie->restart_syscall) - syscall_restart32(cookie->orig_i0, regs, &ka.sa); + if (restart_syscall) + syscall_restart32(orig_i0, regs, &ka.sa); handle_signal32(signr, &ka, &info, oldset, regs); /* a signal was successfully delivered; the saved @@ -789,16 +797,16 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs, clear_thread_flag(TIF_RESTORE_SIGMASK); return; } - if (cookie->restart_syscall && + if (restart_syscall && (regs->u_regs[UREG_I0] == ERESTARTNOHAND || regs->u_regs[UREG_I0] == ERESTARTSYS || regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { /* replay the system call when we are done */ - regs->u_regs[UREG_I0] = cookie->orig_i0; + regs->u_regs[UREG_I0] = orig_i0; regs->tpc -= 4; regs->tnpc -= 4; } - if (cookie->restart_syscall && + if (restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->tpc -= 4; diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c index 79f85dc..e721644 100644 --- a/drivers/video/bw2.c +++ b/drivers/video/bw2.c @@ -17,11 +17,9 @@ #include <linux/init.h> #include <linux/fb.h> #include <linux/mm.h> +#include <linux/of_device.h> #include <asm/io.h> -#include <asm/oplib.h> -#include <asm/prom.h> -#include <asm/of_device.h> #include <asm/fbio.h> #include "sbuslib.h" @@ -299,7 +297,7 @@ static int __devinit bw2_probe(struct of_device *op, const struct of_device_id * par->physbase = op->resource[0].start; par->which_io = op->resource[0].flags & IORESOURCE_BITS; - sbusfb_fill_var(&info->var, dp->node, 1); + sbusfb_fill_var(&info->var, dp, 1); linebytes = of_getintprop_default(dp, "linebytes", info->var.xres); diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c index 0db0fec..b17e746 100644 --- a/drivers/video/cg14.c +++ b/drivers/video/cg14.c @@ -17,10 +17,9 @@ #include <linux/fb.h> #include <linux/mm.h> #include <linux/uaccess.h> +#include <linux/of_device.h> #include <asm/io.h> -#include <asm/prom.h> -#include <asm/of_device.h> #include <asm/fbio.h> #include "sbuslib.h" @@ -482,7 +481,7 @@ static int __devinit cg14_probe(struct of_device *op, const struct of_device_id spin_lock_init(&par->lock); - sbusfb_fill_var(&info->var, dp->node, 8); + sbusfb_fill_var(&info->var, dp, 8); info->var.red.length = 8; info->var.green.length = 8; info->var.blue.length = 8; diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c index e31e26a..3aa7b6c 100644 --- a/drivers/video/cg3.c +++ b/drivers/video/cg3.c @@ -17,11 +17,9 @@ #include <linux/init.h> #include <linux/fb.h> #include <linux/mm.h> +#include <linux/of_device.h> #include <asm/io.h> -#include <asm/oplib.h> -#include <asm/prom.h> -#include <asm/of_device.h> #include <asm/fbio.h> #include "sbuslib.h" @@ -373,7 +371,7 @@ static int __devinit cg3_probe(struct of_device *op, par->physbase = op->resource[0].start; par->which_io = op->resource[0].flags & IORESOURCE_BITS; - sbusfb_fill_var(&info->var, dp->node, 8); + sbusfb_fill_var(&info->var, dp, 8); info->var.red.length = 8; info->var.green.length = 8; info->var.blue.length = 8; diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c index 8000bcc..2f64bb3 100644 --- a/drivers/video/cg6.c +++ b/drivers/video/cg6.c @@ -17,9 +17,9 @@ #include <linux/init.h> #include <linux/fb.h> #include <linux/mm.h> +#include <linux/of_device.h> #include <asm/io.h> -#include <asm/of_device.h> #include <asm/fbio.h> #include "sbuslib.h" @@ -728,7 +728,7 @@ static int __devinit cg6_probe(struct of_device *op, par->physbase = op->resource[0].start; par->which_io = op->resource[0].flags & IORESOURCE_BITS; - sbusfb_fill_var(&info->var, dp->node, 8); + sbusfb_fill_var(&info->var, dp, 8); info->var.red.length = 8; info->var.green.length = 8; info->var.blue.length = 8; diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c index 0f42a69..7992b13 100644 --- a/drivers/video/ffb.c +++ b/drivers/video/ffb.c @@ -16,11 +16,10 @@ #include <linux/fb.h> #include <linux/mm.h> #include <linux/timer.h> +#include <linux/of_device.h> #include <asm/io.h> #include <asm/upa.h> -#include <asm/prom.h> -#include <asm/of_device.h> #include <asm/fbio.h> #include "sbuslib.h" @@ -941,7 +940,7 @@ static int __devinit ffb_probe(struct of_device *op, info->screen_base = (char *) par->physbase + FFB_DFB24_POFF; info->pseudo_palette = par->pseudo_palette; - sbusfb_fill_var(&info->var, dp->node, 32); + sbusfb_fill_var(&info->var, dp, 32); par->fbsize = PAGE_ALIGN(info->var.xres * info->var.yres * 4); ffb_fixup_var_rgb(&info->var); diff --git a/drivers/video/leo.c b/drivers/video/leo.c index fb12992..8bc46e9 100644 --- a/drivers/video/leo.c +++ b/drivers/video/leo.c @@ -16,10 +16,9 @@ #include <linux/init.h> #include <linux/fb.h> #include <linux/mm.h> +#include <linux/of_device.h> #include <asm/io.h> -#include <asm/prom.h> -#include <asm/of_device.h> #include <asm/fbio.h> #include "sbuslib.h" @@ -562,7 +561,7 @@ static int __devinit leo_probe(struct of_device *op, const struct of_device_id * par->physbase = op->resource[0].start; par->which_io = op->resource[0].flags & IORESOURCE_BITS; - sbusfb_fill_var(&info->var, dp->node, 32); + sbusfb_fill_var(&info->var, dp, 32); leo_fixup_var_rgb(&info->var); linebytes = of_getintprop_default(dp, "linebytes", diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c index 676ffb0..9e90345 100644 --- a/drivers/video/p9100.c +++ b/drivers/video/p9100.c @@ -15,10 +15,9 @@ #include <linux/init.h> #include <linux/fb.h> #include <linux/mm.h> +#include <linux/of_device.h> #include <asm/io.h> -#include <asm/prom.h> -#include <asm/of_device.h> #include <asm/fbio.h> #include "sbuslib.h" @@ -275,7 +274,7 @@ static int __devinit p9100_probe(struct of_device *op, const struct of_device_id par->physbase = op->resource[2].start; par->which_io = op->resource[2].flags & IORESOURCE_BITS; - sbusfb_fill_var(&info->var, dp->node, 8); + sbusfb_fill_var(&info->var, dp, 8); info->var.red.length = 8; info->var.green.length = 8; info->var.blue.length = 8; diff --git a/drivers/video/sbuslib.c b/drivers/video/sbuslib.c index 4deaac0..37d764a 100644 --- a/drivers/video/sbuslib.c +++ b/drivers/video/sbuslib.c @@ -10,18 +10,19 @@ #include <linux/fb.h> #include <linux/mm.h> #include <linux/uaccess.h> +#include <linux/of_device.h> -#include <asm/oplib.h> #include <asm/fbio.h> #include "sbuslib.h" -void sbusfb_fill_var(struct fb_var_screeninfo *var, int prom_node, int bpp) +void sbusfb_fill_var(struct fb_var_screeninfo *var, struct device_node *dp, + int bpp) { memset(var, 0, sizeof(*var)); - var->xres = prom_getintdefault(prom_node, "width", 1152); - var->yres = prom_getintdefault(prom_node, "height", 900); + var->xres = of_getintprop_default(dp, "width", 1152); + var->yres = of_getintprop_default(dp, "height", 900); var->xres_virtual = var->xres; var->yres_virtual = var->yres; var->bits_per_pixel = bpp; diff --git a/drivers/video/sbuslib.h b/drivers/video/sbuslib.h index 492828c..7ba3250 100644 --- a/drivers/video/sbuslib.h +++ b/drivers/video/sbuslib.h @@ -11,7 +11,8 @@ struct sbus_mmap_map { #define SBUS_MMAP_FBSIZE(n) (-n) #define SBUS_MMAP_EMPTY 0x80000000 -extern void sbusfb_fill_var(struct fb_var_screeninfo *var, int prom_node, int bpp); +extern void sbusfb_fill_var(struct fb_var_screeninfo *var, + struct device_node *dp, int bpp); struct vm_area_struct; extern int sbusfb_mmap_helper(struct sbus_mmap_map *map, unsigned long physbase, unsigned long fbsize, @@ -21,6 +22,6 @@ int sbusfb_ioctl_helper(unsigned long cmd, unsigned long arg, struct fb_info *info, int type, int fb_depth, unsigned long fb_size); int sbusfb_compat_ioctl(struct fb_info *info, unsigned int cmd, - unsigned long arg); + unsigned long arg); #endif /* _SBUSLIB_H */ diff --git a/drivers/video/sunxvr2500.c b/drivers/video/sunxvr2500.c index c3869a9..b1dde09 100644 --- a/drivers/video/sunxvr2500.c +++ b/drivers/video/sunxvr2500.c @@ -9,10 +9,9 @@ #include <linux/fb.h> #include <linux/pci.h> #include <linux/init.h> +#include <linux/of_device.h> #include <asm/io.h> -#include <asm/prom.h> -#include <asm/of_device.h> struct s3d_info { struct fb_info *info; diff --git a/drivers/video/sunxvr500.c b/drivers/video/sunxvr500.c index 71bf3f1..c2ba51b 100644 --- a/drivers/video/sunxvr500.c +++ b/drivers/video/sunxvr500.c @@ -9,10 +9,9 @@ #include <linux/fb.h> #include <linux/pci.h> #include <linux/init.h> +#include <linux/of_device.h> #include <asm/io.h> -#include <asm/prom.h> -#include <asm/of_device.h> /* XXX This device has a 'dev-comm' property which aparently is * XXX a pointer into the openfirmware's address space which is diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c index 44e8c27..2a03f78 100644 --- a/drivers/video/tcx.c +++ b/drivers/video/tcx.c @@ -17,10 +17,9 @@ #include <linux/init.h> #include <linux/fb.h> #include <linux/mm.h> +#include <linux/of_device.h> #include <asm/io.h> -#include <asm/prom.h> -#include <asm/of_device.h> #include <asm/fbio.h> #include "sbuslib.h" @@ -385,7 +384,7 @@ static int __devinit tcx_probe(struct of_device *op, par->lowdepth = (of_find_property(dp, "tcx-8-bit", NULL) != NULL); - sbusfb_fill_var(&info->var, dp->node, 8); + sbusfb_fill_var(&info->var, dp, 8); info->var.red.length = 8; info->var.green.length = 8; info->var.blue.length = 8; diff --git a/include/asm-sparc/psr.h b/include/asm-sparc/psr.h index 19c9780..2139704 100644 --- a/include/asm-sparc/psr.h +++ b/include/asm-sparc/psr.h @@ -25,6 +25,7 @@ #define PSR_PIL 0x00000f00 /* processor interrupt level */ #define PSR_EF 0x00001000 /* enable floating point */ #define PSR_EC 0x00002000 /* enable co-processor */ +#define PSR_SYSCALL 0x00004000 /* inside of a syscall */ #define PSR_LE 0x00008000 /* SuperSparcII little-endian */ #define PSR_ICC 0x00f00000 /* integer condition codes */ #define PSR_C 0x00100000 /* carry bit */ diff --git a/include/asm-sparc/ptrace.h b/include/asm-sparc/ptrace.h index 8201a7b..6b5e6ce 100644 --- a/include/asm-sparc/ptrace.h +++ b/include/asm-sparc/ptrace.h @@ -39,6 +39,16 @@ struct pt_regs { #define UREG_FP UREG_I6 #define UREG_RETPC UREG_I7 +static inline bool pt_regs_is_syscall(struct pt_regs *regs) +{ + return (regs->psr & PSR_SYSCALL); +} + +static inline bool pt_regs_clear_syscall(struct pt_regs *regs) +{ + return (regs->psr &= ~PSR_SYSCALL); +} + /* A register window */ struct reg_window { unsigned long locals[8]; @@ -149,6 +159,7 @@ extern void show_regs(struct pt_regs *); #define SF_XXARG 0x5c /* Stuff for the ptrace system call */ +#define PTRACE_SPARC_DETACH 11 #define PTRACE_GETREGS 12 #define PTRACE_SETREGS 13 #define PTRACE_GETFPREGS 14 diff --git a/include/asm-sparc/signal.h b/include/asm-sparc/signal.h index d03a21c..94071c7 100644 --- a/include/asm-sparc/signal.h +++ b/include/asm-sparc/signal.h @@ -199,13 +199,7 @@ typedef struct sigaltstack { size_t ss_size; } stack_t; -struct sparc_deliver_cookie { - int restart_syscall; - unsigned long orig_i0; -}; - -struct pt_regs; -extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie); +#define ptrace_signal_deliver(regs, cookie) do { } while (0) #endif /* !(__KERNEL__) */ diff --git a/include/asm-sparc64/psrcompat.h b/include/asm-sparc64/psrcompat.h index 5590ce6..3614ca0 100644 --- a/include/asm-sparc64/psrcompat.h +++ b/include/asm-sparc64/psrcompat.h @@ -12,6 +12,7 @@ #define PSR_PIL 0x00000f00 /* processor interrupt level */ #define PSR_EF 0x00001000 /* enable floating point */ #define PSR_EC 0x00002000 /* enable co-processor */ +#define PSR_SYSCALL 0x00004000 /* inside of a syscall */ #define PSR_LE 0x00008000 /* SuperSparcII little-endian */ #define PSR_ICC 0x00f00000 /* integer condition codes */ #define PSR_C 0x00100000 /* carry bit */ @@ -30,6 +31,7 @@ static inline unsigned int tstate_to_psr(unsigned long tstate) PSR_S | ((tstate & TSTATE_ICC) >> 12) | ((tstate & TSTATE_XCC) >> 20) | + ((tstate & TSTATE_SYSCALL) ? PSR_SYSCALL : 0) | PSR_V8PLUS); } diff --git a/include/asm-sparc64/pstate.h b/include/asm-sparc64/pstate.h index f3c4548..949aeba 100644 --- a/include/asm-sparc64/pstate.h +++ b/include/asm-sparc64/pstate.h @@ -62,6 +62,7 @@ #define TSTATE_PRIV _AC(0x0000000000000400,UL) /* Privilege. */ #define TSTATE_IE _AC(0x0000000000000200,UL) /* Interrupt Enable. */ #define TSTATE_AG _AC(0x0000000000000100,UL) /* Alternate Globals.*/ +#define TSTATE_SYSCALL _AC(0x0000000000000020,UL) /* in syscall trap */ #define TSTATE_CWP _AC(0x000000000000001f,UL) /* Curr Win-Pointer. */ /* Floating-Point Registers State Register. diff --git a/include/asm-sparc64/ptrace.h b/include/asm-sparc64/ptrace.h index 714b819..90972a5 100644 --- a/include/asm-sparc64/ptrace.h +++ b/include/asm-sparc64/ptrace.h @@ -42,16 +42,14 @@ static inline int pt_regs_trap_type(struct pt_regs *regs) return regs->magic & 0x1ff; } -static inline int pt_regs_clear_trap_type(struct pt_regs *regs) +static inline bool pt_regs_is_syscall(struct pt_regs *regs) { - return regs->magic &= ~0x1ff; + return (regs->tstate & TSTATE_SYSCALL); } -static inline bool pt_regs_is_syscall(struct pt_regs *regs) +static inline bool pt_regs_clear_syscall(struct pt_regs *regs) { - int tt = pt_regs_trap_type(regs); - - return (tt == 0x110 || tt == 0x111 || tt == 0x16d); + return (regs->tstate &= ~TSTATE_SYSCALL); } struct pt_regs32 { @@ -298,6 +296,7 @@ extern void __show_regs(struct pt_regs *); #define SF_XXARG 0x5c /* Stuff for the ptrace system call */ +#define PTRACE_SPARC_DETACH 11 #define PTRACE_GETREGS 12 #define PTRACE_SETREGS 13 #define PTRACE_GETFPREGS 14 diff --git a/include/asm-sparc64/signal.h b/include/asm-sparc64/signal.h index fa6f467..c49f32d 100644 --- a/include/asm-sparc64/signal.h +++ b/include/asm-sparc64/signal.h @@ -186,13 +186,7 @@ struct k_sigaction { void __user *ka_restorer; }; -struct signal_deliver_cookie { - int restart_syscall; - unsigned long orig_i0; -}; - -struct pt_regs; -extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie); +#define ptrace_signal_deliver(regs, cookie) do { } while (0) #endif /* !(__KERNEL__) */ diff --git a/include/asm-sparc64/ttable.h b/include/asm-sparc64/ttable.h index 1b55538..52d67d3 100644 --- a/include/asm-sparc64/ttable.h +++ b/include/asm-sparc64/ttable.h @@ -91,13 +91,14 @@ nop; #define SYSCALL_TRAP(routine, systbl) \ + rdpr %pil, %g2; \ + mov TSTATE_SYSCALL, %g3; \ sethi %hi(109f), %g7; \ - ba,pt %xcc, etrap; \ + ba,pt %xcc, etrap_syscall; \ 109: or %g7, %lo(109b), %g7; \ sethi %hi(systbl), %l7; \ ba,pt %xcc, routine; \ - or %l7, %lo(systbl), %l7; \ - nop; nop; + or %l7, %lo(systbl), %l7; #define TRAP_UTRAP(handler,lvl) \ mov handler, %g3; \ |