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) || |