diff options
| -rw-r--r-- | arch/sparc/include/asm/perfctr.h | 4 | ||||
| -rw-r--r-- | arch/sparc/include/asm/system_64.h | 15 | ||||
| -rw-r--r-- | arch/sparc/include/asm/thread_info_64.h | 25 | ||||
| -rw-r--r-- | arch/sparc/kernel/entry.h | 1 | ||||
| -rw-r--r-- | arch/sparc/kernel/process_64.c | 23 | ||||
| -rw-r--r-- | arch/sparc/kernel/rtrap_64.S | 54 | ||||
| -rw-r--r-- | arch/sparc/kernel/sys32.S | 1 | ||||
| -rw-r--r-- | arch/sparc/kernel/sys_sparc_64.c | 104 | ||||
| -rw-r--r-- | arch/sparc/kernel/syscalls.S | 23 | ||||
| -rw-r--r-- | arch/sparc/kernel/systbls.h | 2 | ||||
| -rw-r--r-- | arch/sparc/kernel/systbls_64.S | 4 | ||||
| -rw-r--r-- | arch/sparc/kernel/traps_64.c | 9 |
12 files changed, 18 insertions, 247 deletions
diff --git a/arch/sparc/include/asm/perfctr.h b/arch/sparc/include/asm/perfctr.h index 836873002b75..8d8720a8770d 100644 --- a/arch/sparc/include/asm/perfctr.h +++ b/arch/sparc/include/asm/perfctr.h | |||
| @@ -10,8 +10,8 @@ | |||
| 10 | * from enumeration below. The meaning of further arguments | 10 | * from enumeration below. The meaning of further arguments |
| 11 | * are determined by the operation code. | 11 | * are determined by the operation code. |
| 12 | * | 12 | * |
| 13 | * int sys_perfctr(int opcode, unsigned long arg0, | 13 | * NOTE: This system call is no longer provided, use the perf_events |
| 14 | * unsigned long arg1, unsigned long arg2) | 14 | * infrastructure. |
| 15 | * | 15 | * |
| 16 | * Pointers which are passed by the user are pointers to 64-bit | 16 | * Pointers which are passed by the user are pointers to 64-bit |
| 17 | * integers. | 17 | * integers. |
diff --git a/arch/sparc/include/asm/system_64.h b/arch/sparc/include/asm/system_64.h index d47a98e66972..d24cfe16afc1 100644 --- a/arch/sparc/include/asm/system_64.h +++ b/arch/sparc/include/asm/system_64.h | |||
| @@ -143,15 +143,7 @@ do { \ | |||
| 143 | * and 2 stores in this critical code path. -DaveM | 143 | * and 2 stores in this critical code path. -DaveM |
| 144 | */ | 144 | */ |
| 145 | #define switch_to(prev, next, last) \ | 145 | #define switch_to(prev, next, last) \ |
| 146 | do { if (test_thread_flag(TIF_PERFCTR)) { \ | 146 | do { flush_tlb_pending(); \ |
| 147 | unsigned long __tmp; \ | ||
| 148 | read_pcr(__tmp); \ | ||
| 149 | current_thread_info()->pcr_reg = __tmp; \ | ||
| 150 | read_pic(__tmp); \ | ||
| 151 | current_thread_info()->kernel_cntd0 += (unsigned int)(__tmp);\ | ||
| 152 | current_thread_info()->kernel_cntd1 += ((__tmp) >> 32); \ | ||
| 153 | } \ | ||
| 154 | flush_tlb_pending(); \ | ||
| 155 | save_and_clear_fpu(); \ | 147 | save_and_clear_fpu(); \ |
| 156 | /* If you are tempted to conditionalize the following */ \ | 148 | /* If you are tempted to conditionalize the following */ \ |
| 157 | /* so that ASI is only written if it changes, think again. */ \ | 149 | /* so that ASI is only written if it changes, think again. */ \ |
| @@ -197,11 +189,6 @@ do { if (test_thread_flag(TIF_PERFCTR)) { \ | |||
| 197 | "l1", "l2", "l3", "l4", "l5", "l6", "l7", \ | 189 | "l1", "l2", "l3", "l4", "l5", "l6", "l7", \ |
| 198 | "i0", "i1", "i2", "i3", "i4", "i5", \ | 190 | "i0", "i1", "i2", "i3", "i4", "i5", \ |
| 199 | "o0", "o1", "o2", "o3", "o4", "o5", "o7"); \ | 191 | "o0", "o1", "o2", "o3", "o4", "o5", "o7"); \ |
| 200 | /* If you fuck with this, update ret_from_syscall code too. */ \ | ||
| 201 | if (test_thread_flag(TIF_PERFCTR)) { \ | ||
| 202 | write_pcr(current_thread_info()->pcr_reg); \ | ||
| 203 | reset_pic(); \ | ||
| 204 | } \ | ||
| 205 | } while(0) | 192 | } while(0) |
| 206 | 193 | ||
| 207 | static inline unsigned long xchg32(__volatile__ unsigned int *m, unsigned int val) | 194 | static inline unsigned long xchg32(__volatile__ unsigned int *m, unsigned int val) |
diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h index 39be9f256e5a..9e2d9447f2ad 100644 --- a/arch/sparc/include/asm/thread_info_64.h +++ b/arch/sparc/include/asm/thread_info_64.h | |||
| @@ -58,11 +58,6 @@ struct thread_info { | |||
| 58 | unsigned long gsr[7]; | 58 | unsigned long gsr[7]; |
| 59 | unsigned long xfsr[7]; | 59 | unsigned long xfsr[7]; |
| 60 | 60 | ||
| 61 | __u64 __user *user_cntd0; | ||
| 62 | __u64 __user *user_cntd1; | ||
| 63 | __u64 kernel_cntd0, kernel_cntd1; | ||
| 64 | __u64 pcr_reg; | ||
| 65 | |||
| 66 | struct restart_block restart_block; | 61 | struct restart_block restart_block; |
| 67 | 62 | ||
| 68 | struct pt_regs *kern_una_regs; | 63 | struct pt_regs *kern_una_regs; |
| @@ -96,15 +91,10 @@ struct thread_info { | |||
| 96 | #define TI_RWIN_SPTRS 0x000003c8 | 91 | #define TI_RWIN_SPTRS 0x000003c8 |
| 97 | #define TI_GSR 0x00000400 | 92 | #define TI_GSR 0x00000400 |
| 98 | #define TI_XFSR 0x00000438 | 93 | #define TI_XFSR 0x00000438 |
| 99 | #define TI_USER_CNTD0 0x00000470 | 94 | #define TI_RESTART_BLOCK 0x00000470 |
| 100 | #define TI_USER_CNTD1 0x00000478 | 95 | #define TI_KUNA_REGS 0x000004a0 |
| 101 | #define TI_KERN_CNTD0 0x00000480 | 96 | #define TI_KUNA_INSN 0x000004a8 |
| 102 | #define TI_KERN_CNTD1 0x00000488 | 97 | #define TI_FPREGS 0x000004c0 |
| 103 | #define TI_PCR 0x00000490 | ||
| 104 | #define TI_RESTART_BLOCK 0x00000498 | ||
| 105 | #define TI_KUNA_REGS 0x000004c8 | ||
| 106 | #define TI_KUNA_INSN 0x000004d0 | ||
| 107 | #define TI_FPREGS 0x00000500 | ||
| 108 | 98 | ||
| 109 | /* We embed this in the uppermost byte of thread_info->flags */ | 99 | /* We embed this in the uppermost byte of thread_info->flags */ |
| 110 | #define FAULT_CODE_WRITE 0x01 /* Write access, implies D-TLB */ | 100 | #define FAULT_CODE_WRITE 0x01 /* Write access, implies D-TLB */ |
| @@ -199,7 +189,7 @@ register struct thread_info *current_thread_info_reg asm("g6"); | |||
| 199 | * | 189 | * |
| 200 | * On trap return we need to test several values: | 190 | * On trap return we need to test several values: |
| 201 | * | 191 | * |
| 202 | * user: need_resched, notify_resume, sigpending, wsaved, perfctr | 192 | * user: need_resched, notify_resume, sigpending, wsaved |
| 203 | * kernel: fpdepth | 193 | * kernel: fpdepth |
| 204 | * | 194 | * |
| 205 | * So to check for work in the kernel case we simply load the fpdepth | 195 | * So to check for work in the kernel case we simply load the fpdepth |
| @@ -220,7 +210,7 @@ register struct thread_info *current_thread_info_reg asm("g6"); | |||
| 220 | #define TIF_NOTIFY_RESUME 1 /* callback before returning to user */ | 210 | #define TIF_NOTIFY_RESUME 1 /* callback before returning to user */ |
| 221 | #define TIF_SIGPENDING 2 /* signal pending */ | 211 | #define TIF_SIGPENDING 2 /* signal pending */ |
| 222 | #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ | 212 | #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ |
| 223 | #define TIF_PERFCTR 4 /* performance counters active */ | 213 | /* flag bit 4 is available */ |
| 224 | #define TIF_UNALIGNED 5 /* allowed to do unaligned accesses */ | 214 | #define TIF_UNALIGNED 5 /* allowed to do unaligned accesses */ |
| 225 | /* flag bit 6 is available */ | 215 | /* flag bit 6 is available */ |
| 226 | #define TIF_32BIT 7 /* 32-bit binary */ | 216 | #define TIF_32BIT 7 /* 32-bit binary */ |
| @@ -241,7 +231,6 @@ register struct thread_info *current_thread_info_reg asm("g6"); | |||
| 241 | #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) | 231 | #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) |
| 242 | #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) | 232 | #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) |
| 243 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) | 233 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) |
| 244 | #define _TIF_PERFCTR (1<<TIF_PERFCTR) | ||
| 245 | #define _TIF_UNALIGNED (1<<TIF_UNALIGNED) | 234 | #define _TIF_UNALIGNED (1<<TIF_UNALIGNED) |
| 246 | #define _TIF_32BIT (1<<TIF_32BIT) | 235 | #define _TIF_32BIT (1<<TIF_32BIT) |
| 247 | #define _TIF_SECCOMP (1<<TIF_SECCOMP) | 236 | #define _TIF_SECCOMP (1<<TIF_SECCOMP) |
| @@ -252,7 +241,7 @@ register struct thread_info *current_thread_info_reg asm("g6"); | |||
| 252 | 241 | ||
| 253 | #define _TIF_USER_WORK_MASK ((0xff << TI_FLAG_WSAVED_SHIFT) | \ | 242 | #define _TIF_USER_WORK_MASK ((0xff << TI_FLAG_WSAVED_SHIFT) | \ |
| 254 | _TIF_DO_NOTIFY_RESUME_MASK | \ | 243 | _TIF_DO_NOTIFY_RESUME_MASK | \ |
| 255 | _TIF_NEED_RESCHED | _TIF_PERFCTR) | 244 | _TIF_NEED_RESCHED) |
| 256 | #define _TIF_DO_NOTIFY_RESUME_MASK (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING) | 245 | #define _TIF_DO_NOTIFY_RESUME_MASK (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING) |
| 257 | 246 | ||
| 258 | /* | 247 | /* |
diff --git a/arch/sparc/kernel/entry.h b/arch/sparc/kernel/entry.h index 4f53a2395ac6..c011b932bb17 100644 --- a/arch/sparc/kernel/entry.h +++ b/arch/sparc/kernel/entry.h | |||
| @@ -48,7 +48,6 @@ extern void __init boot_cpu_id_too_large(int cpu); | |||
| 48 | extern unsigned int dcache_parity_tl1_occurred; | 48 | extern unsigned int dcache_parity_tl1_occurred; |
| 49 | extern unsigned int icache_parity_tl1_occurred; | 49 | extern unsigned int icache_parity_tl1_occurred; |
| 50 | 50 | ||
| 51 | extern asmlinkage void update_perfctrs(void); | ||
| 52 | extern asmlinkage void sparc_breakpoint(struct pt_regs *regs); | 51 | extern asmlinkage void sparc_breakpoint(struct pt_regs *regs); |
| 53 | extern void timer_interrupt(int irq, struct pt_regs *regs); | 52 | extern void timer_interrupt(int irq, struct pt_regs *regs); |
| 54 | 53 | ||
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index cb70476bd8f5..a5cf3864b31f 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c | |||
| @@ -352,12 +352,6 @@ void exit_thread(void) | |||
| 352 | else | 352 | else |
| 353 | t->utraps[0]--; | 353 | t->utraps[0]--; |
| 354 | } | 354 | } |
| 355 | |||
| 356 | if (test_and_clear_thread_flag(TIF_PERFCTR)) { | ||
| 357 | t->user_cntd0 = t->user_cntd1 = NULL; | ||
| 358 | t->pcr_reg = 0; | ||
| 359 | write_pcr(0); | ||
| 360 | } | ||
| 361 | } | 355 | } |
| 362 | 356 | ||
| 363 | void flush_thread(void) | 357 | void flush_thread(void) |
| @@ -371,13 +365,6 @@ void flush_thread(void) | |||
| 371 | 365 | ||
| 372 | set_thread_wsaved(0); | 366 | set_thread_wsaved(0); |
| 373 | 367 | ||
| 374 | /* Turn off performance counters if on. */ | ||
| 375 | if (test_and_clear_thread_flag(TIF_PERFCTR)) { | ||
| 376 | t->user_cntd0 = t->user_cntd1 = NULL; | ||
| 377 | t->pcr_reg = 0; | ||
| 378 | write_pcr(0); | ||
| 379 | } | ||
| 380 | |||
| 381 | /* Clear FPU register state. */ | 368 | /* Clear FPU register state. */ |
| 382 | t->fpsaved[0] = 0; | 369 | t->fpsaved[0] = 0; |
| 383 | 370 | ||
| @@ -591,16 +578,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, | |||
| 591 | t->kregs->u_regs[UREG_FP] = | 578 | t->kregs->u_regs[UREG_FP] = |
| 592 | ((unsigned long) child_sf) - STACK_BIAS; | 579 | ((unsigned long) child_sf) - STACK_BIAS; |
| 593 | 580 | ||
| 594 | /* Special case, if we are spawning a kernel thread from | ||
| 595 | * a userspace task (usermode helper, NFS or similar), we | ||
| 596 | * must disable performance counters in the child because | ||
| 597 | * the address space and protection realm are changing. | ||
| 598 | */ | ||
| 599 | if (t->flags & _TIF_PERFCTR) { | ||
| 600 | t->user_cntd0 = t->user_cntd1 = NULL; | ||
| 601 | t->pcr_reg = 0; | ||
| 602 | t->flags &= ~_TIF_PERFCTR; | ||
| 603 | } | ||
| 604 | t->flags |= ((long)ASI_P << TI_FLAG_CURRENT_DS_SHIFT); | 581 | t->flags |= ((long)ASI_P << TI_FLAG_CURRENT_DS_SHIFT); |
| 605 | t->kregs->u_regs[UREG_G6] = (unsigned long) t; | 582 | t->kregs->u_regs[UREG_G6] = (unsigned long) t; |
| 606 | t->kregs->u_regs[UREG_G4] = (unsigned long) t->task; | 583 | t->kregs->u_regs[UREG_G4] = (unsigned long) t->task; |
diff --git a/arch/sparc/kernel/rtrap_64.S b/arch/sparc/kernel/rtrap_64.S index fd3cee4d117c..e829a42b7139 100644 --- a/arch/sparc/kernel/rtrap_64.S +++ b/arch/sparc/kernel/rtrap_64.S | |||
| @@ -65,48 +65,6 @@ __handle_user_windows: | |||
| 65 | ba,pt %xcc, __handle_user_windows_continue | 65 | ba,pt %xcc, __handle_user_windows_continue |
| 66 | 66 | ||
| 67 | andn %l1, %l4, %l1 | 67 | andn %l1, %l4, %l1 |
| 68 | __handle_perfctrs: | ||
| 69 | call update_perfctrs | ||
| 70 | wrpr %g0, RTRAP_PSTATE, %pstate | ||
| 71 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate | ||
| 72 | ldub [%g6 + TI_WSAVED], %o2 | ||
| 73 | brz,pt %o2, 1f | ||
| 74 | nop | ||
| 75 | /* Redo userwin+sched+sig checks */ | ||
| 76 | call fault_in_user_windows | ||
| 77 | |||
| 78 | wrpr %g0, RTRAP_PSTATE, %pstate | ||
| 79 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate | ||
| 80 | ldx [%g6 + TI_FLAGS], %l0 | ||
| 81 | andcc %l0, _TIF_NEED_RESCHED, %g0 | ||
| 82 | be,pt %xcc, 1f | ||
| 83 | |||
| 84 | nop | ||
| 85 | call schedule | ||
| 86 | wrpr %g0, RTRAP_PSTATE, %pstate | ||
| 87 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate | ||
| 88 | ldx [%g6 + TI_FLAGS], %l0 | ||
| 89 | 1: andcc %l0, _TIF_DO_NOTIFY_RESUME_MASK, %g0 | ||
| 90 | |||
| 91 | be,pt %xcc, __handle_perfctrs_continue | ||
| 92 | sethi %hi(TSTATE_PEF), %o0 | ||
| 93 | mov %l5, %o1 | ||
| 94 | add %sp, PTREGS_OFF, %o0 | ||
| 95 | mov %l0, %o2 | ||
| 96 | call do_notify_resume | ||
| 97 | |||
| 98 | wrpr %g0, RTRAP_PSTATE, %pstate | ||
| 99 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate | ||
| 100 | /* Signal delivery can modify pt_regs tstate, so we must | ||
| 101 | * reload it. | ||
| 102 | */ | ||
| 103 | ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 | ||
| 104 | sethi %hi(0xf << 20), %l4 | ||
| 105 | and %l1, %l4, %l4 | ||
| 106 | andn %l1, %l4, %l1 | ||
| 107 | ba,pt %xcc, __handle_perfctrs_continue | ||
| 108 | |||
| 109 | sethi %hi(TSTATE_PEF), %o0 | ||
| 110 | __handle_userfpu: | 68 | __handle_userfpu: |
| 111 | rd %fprs, %l5 | 69 | rd %fprs, %l5 |
| 112 | andcc %l5, FPRS_FEF, %g0 | 70 | andcc %l5, FPRS_FEF, %g0 |
| @@ -191,9 +149,9 @@ rtrap_no_irq_enable: | |||
| 191 | * take until the next local IRQ before the signal/resched | 149 | * take until the next local IRQ before the signal/resched |
| 192 | * event would be handled. | 150 | * event would be handled. |
| 193 | * | 151 | * |
| 194 | * This also means that if we have to deal with performance | 152 | * This also means that if we have to deal with user |
| 195 | * counters or user windows, we have to redo all of these | 153 | * windows, we have to redo all of these sched+signal checks |
| 196 | * sched+signal checks with IRQs disabled. | 154 | * with IRQs disabled. |
| 197 | */ | 155 | */ |
| 198 | to_user: wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate | 156 | to_user: wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate |
| 199 | wrpr 0, %pil | 157 | wrpr 0, %pil |
| @@ -214,12 +172,8 @@ __handle_signal_continue: | |||
| 214 | brnz,pn %o2, __handle_user_windows | 172 | brnz,pn %o2, __handle_user_windows |
| 215 | nop | 173 | nop |
| 216 | __handle_user_windows_continue: | 174 | __handle_user_windows_continue: |
| 217 | ldx [%g6 + TI_FLAGS], %l5 | ||
| 218 | andcc %l5, _TIF_PERFCTR, %g0 | ||
| 219 | sethi %hi(TSTATE_PEF), %o0 | 175 | sethi %hi(TSTATE_PEF), %o0 |
| 220 | bne,pn %xcc, __handle_perfctrs | 176 | andcc %l1, %o0, %g0 |
| 221 | __handle_perfctrs_continue: | ||
| 222 | andcc %l1, %o0, %g0 | ||
| 223 | 177 | ||
| 224 | /* This fpdepth clear is necessary for non-syscall rtraps only */ | 178 | /* This fpdepth clear is necessary for non-syscall rtraps only */ |
| 225 | user_nowork: | 179 | user_nowork: |
diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S index e7061138c98a..46a76ba3fb4b 100644 --- a/arch/sparc/kernel/sys32.S +++ b/arch/sparc/kernel/sys32.S | |||
| @@ -51,7 +51,6 @@ SIGN1(sys32_exit_group, sys_exit_group, %o0) | |||
| 51 | SIGN1(sys32_wait4, compat_sys_wait4, %o2) | 51 | SIGN1(sys32_wait4, compat_sys_wait4, %o2) |
| 52 | SIGN1(sys32_creat, sys_creat, %o1) | 52 | SIGN1(sys32_creat, sys_creat, %o1) |
| 53 | SIGN1(sys32_mknod, sys_mknod, %o1) | 53 | SIGN1(sys32_mknod, sys_mknod, %o1) |
| 54 | SIGN1(sys32_perfctr, sys_perfctr, %o0) | ||
| 55 | SIGN1(sys32_umount, sys_umount, %o1) | 54 | SIGN1(sys32_umount, sys_umount, %o1) |
| 56 | SIGN1(sys32_signal, sys_signal, %o0) | 55 | SIGN1(sys32_signal, sys_signal, %o0) |
| 57 | SIGN1(sys32_access, sys_access, %o1) | 56 | SIGN1(sys32_access, sys_access, %o1) |
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index d77f54316948..cb1bef6f14b7 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c | |||
| @@ -27,7 +27,6 @@ | |||
| 27 | 27 | ||
| 28 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
| 29 | #include <asm/utrap.h> | 29 | #include <asm/utrap.h> |
| 30 | #include <asm/perfctr.h> | ||
| 31 | #include <asm/unistd.h> | 30 | #include <asm/unistd.h> |
| 32 | 31 | ||
| 33 | #include "entry.h" | 32 | #include "entry.h" |
| @@ -766,109 +765,6 @@ SYSCALL_DEFINE5(rt_sigaction, int, sig, const struct sigaction __user *, act, | |||
| 766 | return ret; | 765 | return ret; |
| 767 | } | 766 | } |
| 768 | 767 | ||
| 769 | /* Invoked by rtrap code to update performance counters in | ||
| 770 | * user space. | ||
| 771 | */ | ||
| 772 | asmlinkage void update_perfctrs(void) | ||
| 773 | { | ||
| 774 | unsigned long pic, tmp; | ||
| 775 | |||
| 776 | read_pic(pic); | ||
| 777 | tmp = (current_thread_info()->kernel_cntd0 += (unsigned int)pic); | ||
| 778 | __put_user(tmp, current_thread_info()->user_cntd0); | ||
| 779 | tmp = (current_thread_info()->kernel_cntd1 += (pic >> 32)); | ||
| 780 | __put_user(tmp, current_thread_info()->user_cntd1); | ||
| 781 | reset_pic(); | ||
| 782 | } | ||
| 783 | |||
| 784 | SYSCALL_DEFINE4(perfctr, int, opcode, unsigned long, arg0, | ||
| 785 | unsigned long, arg1, unsigned long, arg2) | ||
| 786 | { | ||
| 787 | int err = 0; | ||
| 788 | |||
| 789 | switch(opcode) { | ||
| 790 | case PERFCTR_ON: | ||
| 791 | current_thread_info()->pcr_reg = arg2; | ||
| 792 | current_thread_info()->user_cntd0 = (u64 __user *) arg0; | ||
| 793 | current_thread_info()->user_cntd1 = (u64 __user *) arg1; | ||
| 794 | current_thread_info()->kernel_cntd0 = | ||
| 795 | current_thread_info()->kernel_cntd1 = 0; | ||
| 796 | write_pcr(arg2); | ||
| 797 | reset_pic(); | ||
| 798 | set_thread_flag(TIF_PERFCTR); | ||
| 799 | break; | ||
| 800 | |||
| 801 | case PERFCTR_OFF: | ||
| 802 | err = -EINVAL; | ||
| 803 | if (test_thread_flag(TIF_PERFCTR)) { | ||
| 804 | current_thread_info()->user_cntd0 = | ||
| 805 | current_thread_info()->user_cntd1 = NULL; | ||
| 806 | current_thread_info()->pcr_reg = 0; | ||
| 807 | write_pcr(0); | ||
| 808 | clear_thread_flag(TIF_PERFCTR); | ||
| 809 | err = 0; | ||
| 810 | } | ||
| 811 | break; | ||
| 812 | |||
| 813 | case PERFCTR_READ: { | ||
| 814 | unsigned long pic, tmp; | ||
| 815 | |||
| 816 | if (!test_thread_flag(TIF_PERFCTR)) { | ||
| 817 | err = -EINVAL; | ||
| 818 | break; | ||
| 819 | } | ||
| 820 | read_pic(pic); | ||
| 821 | tmp = (current_thread_info()->kernel_cntd0 += (unsigned int)pic); | ||
| 822 | err |= __put_user(tmp, current_thread_info()->user_cntd0); | ||
| 823 | tmp = (current_thread_info()->kernel_cntd1 += (pic >> 32)); | ||
| 824 | err |= __put_user(tmp, current_thread_info()->user_cntd1); | ||
| 825 | reset_pic(); | ||
| 826 | break; | ||
| 827 | } | ||
| 828 | |||
| 829 | case PERFCTR_CLRPIC: | ||
| 830 | if (!test_thread_flag(TIF_PERFCTR)) { | ||
| 831 | err = -EINVAL; | ||
| 832 | break; | ||
| 833 | } | ||
| 834 | current_thread_info()->kernel_cntd0 = | ||
| 835 | current_thread_info()->kernel_cntd1 = 0; | ||
| 836 | reset_pic(); | ||
| 837 | break; | ||
| 838 | |||
| 839 | case PERFCTR_SETPCR: { | ||
| 840 | u64 __user *user_pcr = (u64 __user *)arg0; | ||
| 841 | |||
| 842 | if (!test_thread_flag(TIF_PERFCTR)) { | ||
| 843 | err = -EINVAL; | ||
| 844 | break; | ||
| 845 | } | ||
| 846 | err |= __get_user(current_thread_info()->pcr_reg, user_pcr); | ||
| 847 | write_pcr(current_thread_info()->pcr_reg); | ||
| 848 | current_thread_info()->kernel_cntd0 = | ||
| 849 | current_thread_info()->kernel_cntd1 = 0; | ||
| 850 | reset_pic(); | ||
| 851 | break; | ||
| 852 | } | ||
| 853 | |||
| 854 | case PERFCTR_GETPCR: { | ||
| 855 | u64 __user *user_pcr = (u64 __user *)arg0; | ||
| 856 | |||
| 857 | if (!test_thread_flag(TIF_PERFCTR)) { | ||
| 858 | err = -EINVAL; | ||
| 859 | break; | ||
| 860 | } | ||
| 861 | err |= __put_user(current_thread_info()->pcr_reg, user_pcr); | ||
| 862 | break; | ||
| 863 | } | ||
| 864 | |||
| 865 | default: | ||
| 866 | err = -EINVAL; | ||
| 867 | break; | ||
| 868 | }; | ||
| 869 | return err; | ||
| 870 | } | ||
| 871 | |||
| 872 | /* | 768 | /* |
| 873 | * Do a system call from kernel instead of calling sys_execve so we | 769 | * Do a system call from kernel instead of calling sys_execve so we |
| 874 | * end up with proper pt_regs. | 770 | * end up with proper pt_regs. |
diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S index dc4a458f74dc..1d7e274f3f2b 100644 --- a/arch/sparc/kernel/syscalls.S +++ b/arch/sparc/kernel/syscalls.S | |||
| @@ -110,31 +110,12 @@ sys_clone: | |||
| 110 | 110 | ||
| 111 | .globl ret_from_syscall | 111 | .globl ret_from_syscall |
| 112 | ret_from_syscall: | 112 | ret_from_syscall: |
| 113 | /* Clear current_thread_info()->new_child, and | 113 | /* Clear current_thread_info()->new_child. */ |
| 114 | * check performance counter stuff too. | ||
| 115 | */ | ||
| 116 | stb %g0, [%g6 + TI_NEW_CHILD] | 114 | stb %g0, [%g6 + TI_NEW_CHILD] |
| 117 | ldx [%g6 + TI_FLAGS], %l0 | 115 | ldx [%g6 + TI_FLAGS], %l0 |
| 118 | call schedule_tail | 116 | call schedule_tail |
| 119 | mov %g7, %o0 | 117 | mov %g7, %o0 |
| 120 | andcc %l0, _TIF_PERFCTR, %g0 | 118 | ba,pt %xcc, ret_sys_call |
| 121 | be,pt %icc, 1f | ||
| 122 | nop | ||
| 123 | ldx [%g6 + TI_PCR], %o7 | ||
| 124 | wr %g0, %o7, %pcr | ||
| 125 | |||
| 126 | /* Blackbird errata workaround. See commentary in | ||
| 127 | * smp.c:smp_percpu_timer_interrupt() for more | ||
| 128 | * information. | ||
| 129 | */ | ||
| 130 | ba,pt %xcc, 99f | ||
| 131 | nop | ||
| 132 | |||
| 133 | .align 64 | ||
| 134 | 99: wr %g0, %g0, %pic | ||
| 135 | rd %pic, %g0 | ||
| 136 | |||
| 137 | 1: ba,pt %xcc, ret_sys_call | ||
| 138 | ldx [%sp + PTREGS_OFF + PT_V9_I0], %o0 | 119 | ldx [%sp + PTREGS_OFF + PT_V9_I0], %o0 |
| 139 | 120 | ||
| 140 | .globl sparc_exit | 121 | .globl sparc_exit |
diff --git a/arch/sparc/kernel/systbls.h b/arch/sparc/kernel/systbls.h index d2f999ae2b85..68312fe8da74 100644 --- a/arch/sparc/kernel/systbls.h +++ b/arch/sparc/kernel/systbls.h | |||
| @@ -36,8 +36,6 @@ extern asmlinkage long sys_rt_sigaction(int sig, | |||
| 36 | struct sigaction __user *oact, | 36 | struct sigaction __user *oact, |
| 37 | void __user *restorer, | 37 | void __user *restorer, |
| 38 | size_t sigsetsize); | 38 | size_t sigsetsize); |
| 39 | extern asmlinkage long sys_perfctr(int opcode, unsigned long arg0, | ||
| 40 | unsigned long arg1, unsigned long arg2); | ||
| 41 | 39 | ||
| 42 | extern asmlinkage void sparc64_set_context(struct pt_regs *regs); | 40 | extern asmlinkage void sparc64_set_context(struct pt_regs *regs); |
| 43 | extern asmlinkage void sparc64_get_context(struct pt_regs *regs); | 41 | extern asmlinkage void sparc64_get_context(struct pt_regs *regs); |
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index e575b46bd7a9..17614251fb6d 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S | |||
| @@ -21,7 +21,7 @@ sys_call_table32: | |||
| 21 | /*0*/ .word sys_restart_syscall, sys32_exit, sys_fork, sys_read, sys_write | 21 | /*0*/ .word sys_restart_syscall, sys32_exit, sys_fork, sys_read, sys_write |
| 22 | /*5*/ .word sys32_open, sys_close, sys32_wait4, sys32_creat, sys_link | 22 | /*5*/ .word sys32_open, sys_close, sys32_wait4, sys32_creat, sys_link |
| 23 | /*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys32_mknod | 23 | /*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys32_mknod |
| 24 | /*15*/ .word sys_chmod, sys_lchown16, sys_brk, sys32_perfctr, sys32_lseek | 24 | /*15*/ .word sys_chmod, sys_lchown16, sys_brk, sys_nis_syscall, sys32_lseek |
| 25 | /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16 | 25 | /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16 |
| 26 | /*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys_pause | 26 | /*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys_pause |
| 27 | /*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice | 27 | /*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice |
| @@ -96,7 +96,7 @@ sys_call_table: | |||
| 96 | /*0*/ .word sys_restart_syscall, sparc_exit, sys_fork, sys_read, sys_write | 96 | /*0*/ .word sys_restart_syscall, sparc_exit, sys_fork, sys_read, sys_write |
| 97 | /*5*/ .word sys_open, sys_close, sys_wait4, sys_creat, sys_link | 97 | /*5*/ .word sys_open, sys_close, sys_wait4, sys_creat, sys_link |
| 98 | /*10*/ .word sys_unlink, sys_nis_syscall, sys_chdir, sys_chown, sys_mknod | 98 | /*10*/ .word sys_unlink, sys_nis_syscall, sys_chdir, sys_chown, sys_mknod |
| 99 | /*15*/ .word sys_chmod, sys_lchown, sys_brk, sys_perfctr, sys_lseek | 99 | /*15*/ .word sys_chmod, sys_lchown, sys_brk, sys_nis_syscall, sys_lseek |
| 100 | /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid, sys_getuid | 100 | /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid, sys_getuid |
| 101 | /*25*/ .word sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_nis_syscall | 101 | /*25*/ .word sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_nis_syscall |
| 102 | /*30*/ .word sys_utime, sys_nis_syscall, sys_nis_syscall, sys_access, sys_nice | 102 | /*30*/ .word sys_utime, sys_nis_syscall, sys_nis_syscall, sys_access, sys_nice |
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c index 10f7bb9fc140..bdc05a21908b 100644 --- a/arch/sparc/kernel/traps_64.c +++ b/arch/sparc/kernel/traps_64.c | |||
| @@ -2548,15 +2548,6 @@ void __init trap_init(void) | |||
| 2548 | rwbuf_stkptrs) || | 2548 | rwbuf_stkptrs) || |
| 2549 | TI_GSR != offsetof(struct thread_info, gsr) || | 2549 | TI_GSR != offsetof(struct thread_info, gsr) || |
| 2550 | TI_XFSR != offsetof(struct thread_info, xfsr) || | 2550 | TI_XFSR != offsetof(struct thread_info, xfsr) || |
| 2551 | TI_USER_CNTD0 != offsetof(struct thread_info, | ||
| 2552 | user_cntd0) || | ||
| 2553 | TI_USER_CNTD1 != offsetof(struct thread_info, | ||
| 2554 | user_cntd1) || | ||
| 2555 | TI_KERN_CNTD0 != offsetof(struct thread_info, | ||
| 2556 | kernel_cntd0) || | ||
| 2557 | TI_KERN_CNTD1 != offsetof(struct thread_info, | ||
| 2558 | kernel_cntd1) || | ||
| 2559 | TI_PCR != offsetof(struct thread_info, pcr_reg) || | ||
| 2560 | TI_PRE_COUNT != offsetof(struct thread_info, | 2551 | TI_PRE_COUNT != offsetof(struct thread_info, |
| 2561 | preempt_count) || | 2552 | preempt_count) || |
| 2562 | TI_NEW_CHILD != offsetof(struct thread_info, new_child) || | 2553 | TI_NEW_CHILD != offsetof(struct thread_info, new_child) || |
