Commit 9f8b6a6cf0ee78de87ebe1e87f54bec1c1741ef7

Authored by Ingo Molnar

Merge branch 'core' of git://git.kernel.org/pub/scm/linux/kernel/git/rric/oprofile into perf/core

Showing 8 changed files Inline Diff

arch/mips/include/asm/stacktrace.h
1 #ifndef _ASM_STACKTRACE_H 1 #ifndef _ASM_STACKTRACE_H
2 #define _ASM_STACKTRACE_H 2 #define _ASM_STACKTRACE_H
3 3
4 #include <asm/ptrace.h> 4 #include <asm/ptrace.h>
5 5
6 #ifdef CONFIG_KALLSYMS 6 #ifdef CONFIG_KALLSYMS
7 extern int raw_show_trace; 7 extern int raw_show_trace;
8 extern unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, 8 extern unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
9 unsigned long pc, unsigned long *ra); 9 unsigned long pc, unsigned long *ra);
10 extern unsigned long unwind_stack_by_address(unsigned long stack_page,
11 unsigned long *sp,
12 unsigned long pc,
13 unsigned long *ra);
10 #else 14 #else
11 #define raw_show_trace 1 15 #define raw_show_trace 1
12 static inline unsigned long unwind_stack(struct task_struct *task, 16 static inline unsigned long unwind_stack(struct task_struct *task,
13 unsigned long *sp, unsigned long pc, unsigned long *ra) 17 unsigned long *sp, unsigned long pc, unsigned long *ra)
14 { 18 {
15 return 0; 19 return 0;
16 } 20 }
17 #endif 21 #endif
18 22
19 static __always_inline void prepare_frametrace(struct pt_regs *regs) 23 static __always_inline void prepare_frametrace(struct pt_regs *regs)
20 { 24 {
21 #ifndef CONFIG_KALLSYMS 25 #ifndef CONFIG_KALLSYMS
22 /* 26 /*
23 * Remove any garbage that may be in regs (specially func 27 * Remove any garbage that may be in regs (specially func
24 * addresses) to avoid show_raw_backtrace() to report them 28 * addresses) to avoid show_raw_backtrace() to report them
25 */ 29 */
26 memset(regs, 0, sizeof(*regs)); 30 memset(regs, 0, sizeof(*regs));
27 #endif 31 #endif
28 __asm__ __volatile__( 32 __asm__ __volatile__(
29 ".set push\n\t" 33 ".set push\n\t"
30 ".set noat\n\t" 34 ".set noat\n\t"
31 #ifdef CONFIG_64BIT 35 #ifdef CONFIG_64BIT
32 "1: dla $1, 1b\n\t" 36 "1: dla $1, 1b\n\t"
33 "sd $1, %0\n\t" 37 "sd $1, %0\n\t"
34 "sd $29, %1\n\t" 38 "sd $29, %1\n\t"
35 "sd $31, %2\n\t" 39 "sd $31, %2\n\t"
36 #else 40 #else
37 "1: la $1, 1b\n\t" 41 "1: la $1, 1b\n\t"
38 "sw $1, %0\n\t" 42 "sw $1, %0\n\t"
39 "sw $29, %1\n\t" 43 "sw $29, %1\n\t"
40 "sw $31, %2\n\t" 44 "sw $31, %2\n\t"
41 #endif 45 #endif
42 ".set pop\n\t" 46 ".set pop\n\t"
43 : "=m" (regs->cp0_epc), 47 : "=m" (regs->cp0_epc),
44 "=m" (regs->regs[29]), "=m" (regs->regs[31]) 48 "=m" (regs->regs[29]), "=m" (regs->regs[31])
45 : : "memory"); 49 : : "memory");
46 } 50 }
47 51
48 #endif /* _ASM_STACKTRACE_H */ 52 #endif /* _ASM_STACKTRACE_H */
49 53
arch/mips/kernel/process.c
1 /* 1 /*
2 * This file is subject to the terms and conditions of the GNU General Public 2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (C) 1994 - 1999, 2000 by Ralf Baechle and others. 6 * Copyright (C) 1994 - 1999, 2000 by Ralf Baechle and others.
7 * Copyright (C) 2005, 2006 by Ralf Baechle (ralf@linux-mips.org) 7 * Copyright (C) 2005, 2006 by Ralf Baechle (ralf@linux-mips.org)
8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
9 * Copyright (C) 2004 Thiemo Seufer 9 * Copyright (C) 2004 Thiemo Seufer
10 */ 10 */
11 #include <linux/errno.h> 11 #include <linux/errno.h>
12 #include <linux/module.h> 12 #include <linux/module.h>
13 #include <linux/sched.h> 13 #include <linux/sched.h>
14 #include <linux/tick.h> 14 #include <linux/tick.h>
15 #include <linux/kernel.h> 15 #include <linux/kernel.h>
16 #include <linux/mm.h> 16 #include <linux/mm.h>
17 #include <linux/stddef.h> 17 #include <linux/stddef.h>
18 #include <linux/unistd.h> 18 #include <linux/unistd.h>
19 #include <linux/ptrace.h> 19 #include <linux/ptrace.h>
20 #include <linux/mman.h> 20 #include <linux/mman.h>
21 #include <linux/personality.h> 21 #include <linux/personality.h>
22 #include <linux/sys.h> 22 #include <linux/sys.h>
23 #include <linux/user.h> 23 #include <linux/user.h>
24 #include <linux/init.h> 24 #include <linux/init.h>
25 #include <linux/completion.h> 25 #include <linux/completion.h>
26 #include <linux/kallsyms.h> 26 #include <linux/kallsyms.h>
27 #include <linux/random.h> 27 #include <linux/random.h>
28 28
29 #include <asm/asm.h> 29 #include <asm/asm.h>
30 #include <asm/bootinfo.h> 30 #include <asm/bootinfo.h>
31 #include <asm/cpu.h> 31 #include <asm/cpu.h>
32 #include <asm/dsp.h> 32 #include <asm/dsp.h>
33 #include <asm/fpu.h> 33 #include <asm/fpu.h>
34 #include <asm/pgtable.h> 34 #include <asm/pgtable.h>
35 #include <asm/system.h> 35 #include <asm/system.h>
36 #include <asm/mipsregs.h> 36 #include <asm/mipsregs.h>
37 #include <asm/processor.h> 37 #include <asm/processor.h>
38 #include <asm/uaccess.h> 38 #include <asm/uaccess.h>
39 #include <asm/io.h> 39 #include <asm/io.h>
40 #include <asm/elf.h> 40 #include <asm/elf.h>
41 #include <asm/isadep.h> 41 #include <asm/isadep.h>
42 #include <asm/inst.h> 42 #include <asm/inst.h>
43 #include <asm/stacktrace.h> 43 #include <asm/stacktrace.h>
44 44
45 /* 45 /*
46 * The idle thread. There's no useful work to be done, so just try to conserve 46 * The idle thread. There's no useful work to be done, so just try to conserve
47 * power and have a low exit latency (ie sit in a loop waiting for somebody to 47 * power and have a low exit latency (ie sit in a loop waiting for somebody to
48 * say that they'd like to reschedule) 48 * say that they'd like to reschedule)
49 */ 49 */
50 void __noreturn cpu_idle(void) 50 void __noreturn cpu_idle(void)
51 { 51 {
52 int cpu; 52 int cpu;
53 53
54 /* CPU is going idle. */ 54 /* CPU is going idle. */
55 cpu = smp_processor_id(); 55 cpu = smp_processor_id();
56 56
57 /* endless idle loop with no priority at all */ 57 /* endless idle loop with no priority at all */
58 while (1) { 58 while (1) {
59 tick_nohz_stop_sched_tick(1); 59 tick_nohz_stop_sched_tick(1);
60 while (!need_resched() && cpu_online(cpu)) { 60 while (!need_resched() && cpu_online(cpu)) {
61 #ifdef CONFIG_MIPS_MT_SMTC 61 #ifdef CONFIG_MIPS_MT_SMTC
62 extern void smtc_idle_loop_hook(void); 62 extern void smtc_idle_loop_hook(void);
63 63
64 smtc_idle_loop_hook(); 64 smtc_idle_loop_hook();
65 #endif 65 #endif
66 66
67 if (cpu_wait) { 67 if (cpu_wait) {
68 /* Don't trace irqs off for idle */ 68 /* Don't trace irqs off for idle */
69 stop_critical_timings(); 69 stop_critical_timings();
70 (*cpu_wait)(); 70 (*cpu_wait)();
71 start_critical_timings(); 71 start_critical_timings();
72 } 72 }
73 } 73 }
74 #ifdef CONFIG_HOTPLUG_CPU 74 #ifdef CONFIG_HOTPLUG_CPU
75 if (!cpu_online(cpu) && !cpu_isset(cpu, cpu_callin_map) && 75 if (!cpu_online(cpu) && !cpu_isset(cpu, cpu_callin_map) &&
76 (system_state == SYSTEM_RUNNING || 76 (system_state == SYSTEM_RUNNING ||
77 system_state == SYSTEM_BOOTING)) 77 system_state == SYSTEM_BOOTING))
78 play_dead(); 78 play_dead();
79 #endif 79 #endif
80 tick_nohz_restart_sched_tick(); 80 tick_nohz_restart_sched_tick();
81 preempt_enable_no_resched(); 81 preempt_enable_no_resched();
82 schedule(); 82 schedule();
83 preempt_disable(); 83 preempt_disable();
84 } 84 }
85 } 85 }
86 86
87 asmlinkage void ret_from_fork(void); 87 asmlinkage void ret_from_fork(void);
88 88
89 void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) 89 void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
90 { 90 {
91 unsigned long status; 91 unsigned long status;
92 92
93 /* New thread loses kernel privileges. */ 93 /* New thread loses kernel privileges. */
94 status = regs->cp0_status & ~(ST0_CU0|ST0_CU1|ST0_FR|KU_MASK); 94 status = regs->cp0_status & ~(ST0_CU0|ST0_CU1|ST0_FR|KU_MASK);
95 #ifdef CONFIG_64BIT 95 #ifdef CONFIG_64BIT
96 status |= test_thread_flag(TIF_32BIT_REGS) ? 0 : ST0_FR; 96 status |= test_thread_flag(TIF_32BIT_REGS) ? 0 : ST0_FR;
97 #endif 97 #endif
98 status |= KU_USER; 98 status |= KU_USER;
99 regs->cp0_status = status; 99 regs->cp0_status = status;
100 clear_used_math(); 100 clear_used_math();
101 clear_fpu_owner(); 101 clear_fpu_owner();
102 if (cpu_has_dsp) 102 if (cpu_has_dsp)
103 __init_dsp(); 103 __init_dsp();
104 regs->cp0_epc = pc; 104 regs->cp0_epc = pc;
105 regs->regs[29] = sp; 105 regs->regs[29] = sp;
106 current_thread_info()->addr_limit = USER_DS; 106 current_thread_info()->addr_limit = USER_DS;
107 } 107 }
108 108
109 void exit_thread(void) 109 void exit_thread(void)
110 { 110 {
111 } 111 }
112 112
113 void flush_thread(void) 113 void flush_thread(void)
114 { 114 {
115 } 115 }
116 116
117 int copy_thread(unsigned long clone_flags, unsigned long usp, 117 int copy_thread(unsigned long clone_flags, unsigned long usp,
118 unsigned long unused, struct task_struct *p, struct pt_regs *regs) 118 unsigned long unused, struct task_struct *p, struct pt_regs *regs)
119 { 119 {
120 struct thread_info *ti = task_thread_info(p); 120 struct thread_info *ti = task_thread_info(p);
121 struct pt_regs *childregs; 121 struct pt_regs *childregs;
122 unsigned long childksp; 122 unsigned long childksp;
123 p->set_child_tid = p->clear_child_tid = NULL; 123 p->set_child_tid = p->clear_child_tid = NULL;
124 124
125 childksp = (unsigned long)task_stack_page(p) + THREAD_SIZE - 32; 125 childksp = (unsigned long)task_stack_page(p) + THREAD_SIZE - 32;
126 126
127 preempt_disable(); 127 preempt_disable();
128 128
129 if (is_fpu_owner()) 129 if (is_fpu_owner())
130 save_fp(p); 130 save_fp(p);
131 131
132 if (cpu_has_dsp) 132 if (cpu_has_dsp)
133 save_dsp(p); 133 save_dsp(p);
134 134
135 preempt_enable(); 135 preempt_enable();
136 136
137 /* set up new TSS. */ 137 /* set up new TSS. */
138 childregs = (struct pt_regs *) childksp - 1; 138 childregs = (struct pt_regs *) childksp - 1;
139 /* Put the stack after the struct pt_regs. */ 139 /* Put the stack after the struct pt_regs. */
140 childksp = (unsigned long) childregs; 140 childksp = (unsigned long) childregs;
141 *childregs = *regs; 141 *childregs = *regs;
142 childregs->regs[7] = 0; /* Clear error flag */ 142 childregs->regs[7] = 0; /* Clear error flag */
143 143
144 childregs->regs[2] = 0; /* Child gets zero as return value */ 144 childregs->regs[2] = 0; /* Child gets zero as return value */
145 145
146 if (childregs->cp0_status & ST0_CU0) { 146 if (childregs->cp0_status & ST0_CU0) {
147 childregs->regs[28] = (unsigned long) ti; 147 childregs->regs[28] = (unsigned long) ti;
148 childregs->regs[29] = childksp; 148 childregs->regs[29] = childksp;
149 ti->addr_limit = KERNEL_DS; 149 ti->addr_limit = KERNEL_DS;
150 } else { 150 } else {
151 childregs->regs[29] = usp; 151 childregs->regs[29] = usp;
152 ti->addr_limit = USER_DS; 152 ti->addr_limit = USER_DS;
153 } 153 }
154 p->thread.reg29 = (unsigned long) childregs; 154 p->thread.reg29 = (unsigned long) childregs;
155 p->thread.reg31 = (unsigned long) ret_from_fork; 155 p->thread.reg31 = (unsigned long) ret_from_fork;
156 156
157 /* 157 /*
158 * New tasks lose permission to use the fpu. This accelerates context 158 * New tasks lose permission to use the fpu. This accelerates context
159 * switching for most programs since they don't use the fpu. 159 * switching for most programs since they don't use the fpu.
160 */ 160 */
161 p->thread.cp0_status = read_c0_status() & ~(ST0_CU2|ST0_CU1); 161 p->thread.cp0_status = read_c0_status() & ~(ST0_CU2|ST0_CU1);
162 childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); 162 childregs->cp0_status &= ~(ST0_CU2|ST0_CU1);
163 163
164 #ifdef CONFIG_MIPS_MT_SMTC 164 #ifdef CONFIG_MIPS_MT_SMTC
165 /* 165 /*
166 * SMTC restores TCStatus after Status, and the CU bits 166 * SMTC restores TCStatus after Status, and the CU bits
167 * are aliased there. 167 * are aliased there.
168 */ 168 */
169 childregs->cp0_tcstatus &= ~(ST0_CU2|ST0_CU1); 169 childregs->cp0_tcstatus &= ~(ST0_CU2|ST0_CU1);
170 #endif 170 #endif
171 clear_tsk_thread_flag(p, TIF_USEDFPU); 171 clear_tsk_thread_flag(p, TIF_USEDFPU);
172 172
173 #ifdef CONFIG_MIPS_MT_FPAFF 173 #ifdef CONFIG_MIPS_MT_FPAFF
174 clear_tsk_thread_flag(p, TIF_FPUBOUND); 174 clear_tsk_thread_flag(p, TIF_FPUBOUND);
175 #endif /* CONFIG_MIPS_MT_FPAFF */ 175 #endif /* CONFIG_MIPS_MT_FPAFF */
176 176
177 if (clone_flags & CLONE_SETTLS) 177 if (clone_flags & CLONE_SETTLS)
178 ti->tp_value = regs->regs[7]; 178 ti->tp_value = regs->regs[7];
179 179
180 return 0; 180 return 0;
181 } 181 }
182 182
183 /* Fill in the fpu structure for a core dump.. */ 183 /* Fill in the fpu structure for a core dump.. */
184 int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r) 184 int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r)
185 { 185 {
186 memcpy(r, &current->thread.fpu, sizeof(current->thread.fpu)); 186 memcpy(r, &current->thread.fpu, sizeof(current->thread.fpu));
187 187
188 return 1; 188 return 1;
189 } 189 }
190 190
191 void elf_dump_regs(elf_greg_t *gp, struct pt_regs *regs) 191 void elf_dump_regs(elf_greg_t *gp, struct pt_regs *regs)
192 { 192 {
193 int i; 193 int i;
194 194
195 for (i = 0; i < EF_R0; i++) 195 for (i = 0; i < EF_R0; i++)
196 gp[i] = 0; 196 gp[i] = 0;
197 gp[EF_R0] = 0; 197 gp[EF_R0] = 0;
198 for (i = 1; i <= 31; i++) 198 for (i = 1; i <= 31; i++)
199 gp[EF_R0 + i] = regs->regs[i]; 199 gp[EF_R0 + i] = regs->regs[i];
200 gp[EF_R26] = 0; 200 gp[EF_R26] = 0;
201 gp[EF_R27] = 0; 201 gp[EF_R27] = 0;
202 gp[EF_LO] = regs->lo; 202 gp[EF_LO] = regs->lo;
203 gp[EF_HI] = regs->hi; 203 gp[EF_HI] = regs->hi;
204 gp[EF_CP0_EPC] = regs->cp0_epc; 204 gp[EF_CP0_EPC] = regs->cp0_epc;
205 gp[EF_CP0_BADVADDR] = regs->cp0_badvaddr; 205 gp[EF_CP0_BADVADDR] = regs->cp0_badvaddr;
206 gp[EF_CP0_STATUS] = regs->cp0_status; 206 gp[EF_CP0_STATUS] = regs->cp0_status;
207 gp[EF_CP0_CAUSE] = regs->cp0_cause; 207 gp[EF_CP0_CAUSE] = regs->cp0_cause;
208 #ifdef EF_UNUSED0 208 #ifdef EF_UNUSED0
209 gp[EF_UNUSED0] = 0; 209 gp[EF_UNUSED0] = 0;
210 #endif 210 #endif
211 } 211 }
212 212
213 int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs) 213 int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
214 { 214 {
215 elf_dump_regs(*regs, task_pt_regs(tsk)); 215 elf_dump_regs(*regs, task_pt_regs(tsk));
216 return 1; 216 return 1;
217 } 217 }
218 218
219 int dump_task_fpu(struct task_struct *t, elf_fpregset_t *fpr) 219 int dump_task_fpu(struct task_struct *t, elf_fpregset_t *fpr)
220 { 220 {
221 memcpy(fpr, &t->thread.fpu, sizeof(current->thread.fpu)); 221 memcpy(fpr, &t->thread.fpu, sizeof(current->thread.fpu));
222 222
223 return 1; 223 return 1;
224 } 224 }
225 225
226 /* 226 /*
227 * Create a kernel thread 227 * Create a kernel thread
228 */ 228 */
229 static void __noreturn kernel_thread_helper(void *arg, int (*fn)(void *)) 229 static void __noreturn kernel_thread_helper(void *arg, int (*fn)(void *))
230 { 230 {
231 do_exit(fn(arg)); 231 do_exit(fn(arg));
232 } 232 }
233 233
234 long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) 234 long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
235 { 235 {
236 struct pt_regs regs; 236 struct pt_regs regs;
237 237
238 memset(&regs, 0, sizeof(regs)); 238 memset(&regs, 0, sizeof(regs));
239 239
240 regs.regs[4] = (unsigned long) arg; 240 regs.regs[4] = (unsigned long) arg;
241 regs.regs[5] = (unsigned long) fn; 241 regs.regs[5] = (unsigned long) fn;
242 regs.cp0_epc = (unsigned long) kernel_thread_helper; 242 regs.cp0_epc = (unsigned long) kernel_thread_helper;
243 regs.cp0_status = read_c0_status(); 243 regs.cp0_status = read_c0_status();
244 #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) 244 #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
245 regs.cp0_status = (regs.cp0_status & ~(ST0_KUP | ST0_IEP | ST0_IEC)) | 245 regs.cp0_status = (regs.cp0_status & ~(ST0_KUP | ST0_IEP | ST0_IEC)) |
246 ((regs.cp0_status & (ST0_KUC | ST0_IEC)) << 2); 246 ((regs.cp0_status & (ST0_KUC | ST0_IEC)) << 2);
247 #else 247 #else
248 regs.cp0_status |= ST0_EXL; 248 regs.cp0_status |= ST0_EXL;
249 #endif 249 #endif
250 250
251 /* Ok, create the new process.. */ 251 /* Ok, create the new process.. */
252 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL); 252 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
253 } 253 }
254 254
255 /* 255 /*
256 * 256 *
257 */ 257 */
258 struct mips_frame_info { 258 struct mips_frame_info {
259 void *func; 259 void *func;
260 unsigned long func_size; 260 unsigned long func_size;
261 int frame_size; 261 int frame_size;
262 int pc_offset; 262 int pc_offset;
263 }; 263 };
264 264
265 static inline int is_ra_save_ins(union mips_instruction *ip) 265 static inline int is_ra_save_ins(union mips_instruction *ip)
266 { 266 {
267 /* sw / sd $ra, offset($sp) */ 267 /* sw / sd $ra, offset($sp) */
268 return (ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op) && 268 return (ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op) &&
269 ip->i_format.rs == 29 && 269 ip->i_format.rs == 29 &&
270 ip->i_format.rt == 31; 270 ip->i_format.rt == 31;
271 } 271 }
272 272
273 static inline int is_jal_jalr_jr_ins(union mips_instruction *ip) 273 static inline int is_jal_jalr_jr_ins(union mips_instruction *ip)
274 { 274 {
275 if (ip->j_format.opcode == jal_op) 275 if (ip->j_format.opcode == jal_op)
276 return 1; 276 return 1;
277 if (ip->r_format.opcode != spec_op) 277 if (ip->r_format.opcode != spec_op)
278 return 0; 278 return 0;
279 return ip->r_format.func == jalr_op || ip->r_format.func == jr_op; 279 return ip->r_format.func == jalr_op || ip->r_format.func == jr_op;
280 } 280 }
281 281
282 static inline int is_sp_move_ins(union mips_instruction *ip) 282 static inline int is_sp_move_ins(union mips_instruction *ip)
283 { 283 {
284 /* addiu/daddiu sp,sp,-imm */ 284 /* addiu/daddiu sp,sp,-imm */
285 if (ip->i_format.rs != 29 || ip->i_format.rt != 29) 285 if (ip->i_format.rs != 29 || ip->i_format.rt != 29)
286 return 0; 286 return 0;
287 if (ip->i_format.opcode == addiu_op || ip->i_format.opcode == daddiu_op) 287 if (ip->i_format.opcode == addiu_op || ip->i_format.opcode == daddiu_op)
288 return 1; 288 return 1;
289 return 0; 289 return 0;
290 } 290 }
291 291
292 static int get_frame_info(struct mips_frame_info *info) 292 static int get_frame_info(struct mips_frame_info *info)
293 { 293 {
294 union mips_instruction *ip = info->func; 294 union mips_instruction *ip = info->func;
295 unsigned max_insns = info->func_size / sizeof(union mips_instruction); 295 unsigned max_insns = info->func_size / sizeof(union mips_instruction);
296 unsigned i; 296 unsigned i;
297 297
298 info->pc_offset = -1; 298 info->pc_offset = -1;
299 info->frame_size = 0; 299 info->frame_size = 0;
300 300
301 if (!ip) 301 if (!ip)
302 goto err; 302 goto err;
303 303
304 if (max_insns == 0) 304 if (max_insns == 0)
305 max_insns = 128U; /* unknown function size */ 305 max_insns = 128U; /* unknown function size */
306 max_insns = min(128U, max_insns); 306 max_insns = min(128U, max_insns);
307 307
308 for (i = 0; i < max_insns; i++, ip++) { 308 for (i = 0; i < max_insns; i++, ip++) {
309 309
310 if (is_jal_jalr_jr_ins(ip)) 310 if (is_jal_jalr_jr_ins(ip))
311 break; 311 break;
312 if (!info->frame_size) { 312 if (!info->frame_size) {
313 if (is_sp_move_ins(ip)) 313 if (is_sp_move_ins(ip))
314 info->frame_size = - ip->i_format.simmediate; 314 info->frame_size = - ip->i_format.simmediate;
315 continue; 315 continue;
316 } 316 }
317 if (info->pc_offset == -1 && is_ra_save_ins(ip)) { 317 if (info->pc_offset == -1 && is_ra_save_ins(ip)) {
318 info->pc_offset = 318 info->pc_offset =
319 ip->i_format.simmediate / sizeof(long); 319 ip->i_format.simmediate / sizeof(long);
320 break; 320 break;
321 } 321 }
322 } 322 }
323 if (info->frame_size && info->pc_offset >= 0) /* nested */ 323 if (info->frame_size && info->pc_offset >= 0) /* nested */
324 return 0; 324 return 0;
325 if (info->pc_offset < 0) /* leaf */ 325 if (info->pc_offset < 0) /* leaf */
326 return 1; 326 return 1;
327 /* prologue seems boggus... */ 327 /* prologue seems boggus... */
328 err: 328 err:
329 return -1; 329 return -1;
330 } 330 }
331 331
332 static struct mips_frame_info schedule_mfi __read_mostly; 332 static struct mips_frame_info schedule_mfi __read_mostly;
333 333
334 static int __init frame_info_init(void) 334 static int __init frame_info_init(void)
335 { 335 {
336 unsigned long size = 0; 336 unsigned long size = 0;
337 #ifdef CONFIG_KALLSYMS 337 #ifdef CONFIG_KALLSYMS
338 unsigned long ofs; 338 unsigned long ofs;
339 339
340 kallsyms_lookup_size_offset((unsigned long)schedule, &size, &ofs); 340 kallsyms_lookup_size_offset((unsigned long)schedule, &size, &ofs);
341 #endif 341 #endif
342 schedule_mfi.func = schedule; 342 schedule_mfi.func = schedule;
343 schedule_mfi.func_size = size; 343 schedule_mfi.func_size = size;
344 344
345 get_frame_info(&schedule_mfi); 345 get_frame_info(&schedule_mfi);
346 346
347 /* 347 /*
348 * Without schedule() frame info, result given by 348 * Without schedule() frame info, result given by
349 * thread_saved_pc() and get_wchan() are not reliable. 349 * thread_saved_pc() and get_wchan() are not reliable.
350 */ 350 */
351 if (schedule_mfi.pc_offset < 0) 351 if (schedule_mfi.pc_offset < 0)
352 printk("Can't analyze schedule() prologue at %p\n", schedule); 352 printk("Can't analyze schedule() prologue at %p\n", schedule);
353 353
354 return 0; 354 return 0;
355 } 355 }
356 356
357 arch_initcall(frame_info_init); 357 arch_initcall(frame_info_init);
358 358
359 /* 359 /*
360 * Return saved PC of a blocked thread. 360 * Return saved PC of a blocked thread.
361 */ 361 */
362 unsigned long thread_saved_pc(struct task_struct *tsk) 362 unsigned long thread_saved_pc(struct task_struct *tsk)
363 { 363 {
364 struct thread_struct *t = &tsk->thread; 364 struct thread_struct *t = &tsk->thread;
365 365
366 /* New born processes are a special case */ 366 /* New born processes are a special case */
367 if (t->reg31 == (unsigned long) ret_from_fork) 367 if (t->reg31 == (unsigned long) ret_from_fork)
368 return t->reg31; 368 return t->reg31;
369 if (schedule_mfi.pc_offset < 0) 369 if (schedule_mfi.pc_offset < 0)
370 return 0; 370 return 0;
371 return ((unsigned long *)t->reg29)[schedule_mfi.pc_offset]; 371 return ((unsigned long *)t->reg29)[schedule_mfi.pc_offset];
372 } 372 }
373 373
374 374
375 #ifdef CONFIG_KALLSYMS 375 #ifdef CONFIG_KALLSYMS
376 /* used by show_backtrace() */ 376 /* generic stack unwinding function */
377 unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, 377 unsigned long notrace unwind_stack_by_address(unsigned long stack_page,
378 unsigned long pc, unsigned long *ra) 378 unsigned long *sp,
379 unsigned long pc,
380 unsigned long *ra)
379 { 381 {
380 unsigned long stack_page;
381 struct mips_frame_info info; 382 struct mips_frame_info info;
382 unsigned long size, ofs; 383 unsigned long size, ofs;
383 int leaf; 384 int leaf;
384 extern void ret_from_irq(void); 385 extern void ret_from_irq(void);
385 extern void ret_from_exception(void); 386 extern void ret_from_exception(void);
386 387
387 stack_page = (unsigned long)task_stack_page(task);
388 if (!stack_page) 388 if (!stack_page)
389 return 0; 389 return 0;
390 390
391 /* 391 /*
392 * If we reached the bottom of interrupt context, 392 * If we reached the bottom of interrupt context,
393 * return saved pc in pt_regs. 393 * return saved pc in pt_regs.
394 */ 394 */
395 if (pc == (unsigned long)ret_from_irq || 395 if (pc == (unsigned long)ret_from_irq ||
396 pc == (unsigned long)ret_from_exception) { 396 pc == (unsigned long)ret_from_exception) {
397 struct pt_regs *regs; 397 struct pt_regs *regs;
398 if (*sp >= stack_page && 398 if (*sp >= stack_page &&
399 *sp + sizeof(*regs) <= stack_page + THREAD_SIZE - 32) { 399 *sp + sizeof(*regs) <= stack_page + THREAD_SIZE - 32) {
400 regs = (struct pt_regs *)*sp; 400 regs = (struct pt_regs *)*sp;
401 pc = regs->cp0_epc; 401 pc = regs->cp0_epc;
402 if (__kernel_text_address(pc)) { 402 if (__kernel_text_address(pc)) {
403 *sp = regs->regs[29]; 403 *sp = regs->regs[29];
404 *ra = regs->regs[31]; 404 *ra = regs->regs[31];
405 return pc; 405 return pc;
406 } 406 }
407 } 407 }
408 return 0; 408 return 0;
409 } 409 }
410 if (!kallsyms_lookup_size_offset(pc, &size, &ofs)) 410 if (!kallsyms_lookup_size_offset(pc, &size, &ofs))
411 return 0; 411 return 0;
412 /* 412 /*
413 * Return ra if an exception occurred at the first instruction 413 * Return ra if an exception occurred at the first instruction
414 */ 414 */
415 if (unlikely(ofs == 0)) { 415 if (unlikely(ofs == 0)) {
416 pc = *ra; 416 pc = *ra;
417 *ra = 0; 417 *ra = 0;
418 return pc; 418 return pc;
419 } 419 }
420 420
421 info.func = (void *)(pc - ofs); 421 info.func = (void *)(pc - ofs);
422 info.func_size = ofs; /* analyze from start to ofs */ 422 info.func_size = ofs; /* analyze from start to ofs */
423 leaf = get_frame_info(&info); 423 leaf = get_frame_info(&info);
424 if (leaf < 0) 424 if (leaf < 0)
425 return 0; 425 return 0;
426 426
427 if (*sp < stack_page || 427 if (*sp < stack_page ||
428 *sp + info.frame_size > stack_page + THREAD_SIZE - 32) 428 *sp + info.frame_size > stack_page + THREAD_SIZE - 32)
429 return 0; 429 return 0;
430 430
431 if (leaf) 431 if (leaf)
432 /* 432 /*
433 * For some extreme cases, get_frame_info() can 433 * For some extreme cases, get_frame_info() can
434 * consider wrongly a nested function as a leaf 434 * consider wrongly a nested function as a leaf
435 * one. In that cases avoid to return always the 435 * one. In that cases avoid to return always the
436 * same value. 436 * same value.
437 */ 437 */
438 pc = pc != *ra ? *ra : 0; 438 pc = pc != *ra ? *ra : 0;
439 else 439 else
440 pc = ((unsigned long *)(*sp))[info.pc_offset]; 440 pc = ((unsigned long *)(*sp))[info.pc_offset];
441 441
442 *sp += info.frame_size; 442 *sp += info.frame_size;
443 *ra = 0; 443 *ra = 0;
444 return __kernel_text_address(pc) ? pc : 0; 444 return __kernel_text_address(pc) ? pc : 0;
445 }
446 EXPORT_SYMBOL(unwind_stack_by_address);
447
448 /* used by show_backtrace() */
449 unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
450 unsigned long pc, unsigned long *ra)
451 {
452 unsigned long stack_page = (unsigned long)task_stack_page(task);
453 return unwind_stack_by_address(stack_page, sp, pc, ra);
445 } 454 }
446 #endif 455 #endif
447 456
448 /* 457 /*
449 * get_wchan - a maintenance nightmare^W^Wpain in the ass ... 458 * get_wchan - a maintenance nightmare^W^Wpain in the ass ...
450 */ 459 */
451 unsigned long get_wchan(struct task_struct *task) 460 unsigned long get_wchan(struct task_struct *task)
452 { 461 {
453 unsigned long pc = 0; 462 unsigned long pc = 0;
454 #ifdef CONFIG_KALLSYMS 463 #ifdef CONFIG_KALLSYMS
455 unsigned long sp; 464 unsigned long sp;
456 unsigned long ra = 0; 465 unsigned long ra = 0;
457 #endif 466 #endif
458 467
459 if (!task || task == current || task->state == TASK_RUNNING) 468 if (!task || task == current || task->state == TASK_RUNNING)
460 goto out; 469 goto out;
461 if (!task_stack_page(task)) 470 if (!task_stack_page(task))
462 goto out; 471 goto out;
463 472
464 pc = thread_saved_pc(task); 473 pc = thread_saved_pc(task);
465 474
466 #ifdef CONFIG_KALLSYMS 475 #ifdef CONFIG_KALLSYMS
467 sp = task->thread.reg29 + schedule_mfi.frame_size; 476 sp = task->thread.reg29 + schedule_mfi.frame_size;
468 477
469 while (in_sched_functions(pc)) 478 while (in_sched_functions(pc))
470 pc = unwind_stack(task, &sp, pc, &ra); 479 pc = unwind_stack(task, &sp, pc, &ra);
471 #endif 480 #endif
472 481
473 out: 482 out:
474 return pc; 483 return pc;
475 } 484 }
476 485
477 /* 486 /*
478 * Don't forget that the stack pointer must be aligned on a 8 bytes 487 * Don't forget that the stack pointer must be aligned on a 8 bytes
479 * boundary for 32-bits ABI and 16 bytes for 64-bits ABI. 488 * boundary for 32-bits ABI and 16 bytes for 64-bits ABI.
480 */ 489 */
481 unsigned long arch_align_stack(unsigned long sp) 490 unsigned long arch_align_stack(unsigned long sp)
482 { 491 {
483 if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) 492 if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
484 sp -= get_random_int() & ~PAGE_MASK; 493 sp -= get_random_int() & ~PAGE_MASK;
485 494
486 return sp & ALMASK; 495 return sp & ALMASK;
arch/mips/oprofile/Makefile
1 ccflags-y := -Werror 1 ccflags-y := -Werror
2 2
3 obj-$(CONFIG_OPROFILE) += oprofile.o 3 obj-$(CONFIG_OPROFILE) += oprofile.o
4 4
5 DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ 5 DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
6 oprof.o cpu_buffer.o buffer_sync.o \ 6 oprof.o cpu_buffer.o buffer_sync.o \
7 event_buffer.o oprofile_files.o \ 7 event_buffer.o oprofile_files.o \
8 oprofilefs.o oprofile_stats.o \ 8 oprofilefs.o oprofile_stats.o \
9 timer_int.o ) 9 timer_int.o )
10 10
11 oprofile-y := $(DRIVER_OBJS) common.o 11 oprofile-y := $(DRIVER_OBJS) common.o backtrace.o
12 12
13 oprofile-$(CONFIG_CPU_MIPS32) += op_model_mipsxx.o 13 oprofile-$(CONFIG_CPU_MIPS32) += op_model_mipsxx.o
14 oprofile-$(CONFIG_CPU_MIPS64) += op_model_mipsxx.o 14 oprofile-$(CONFIG_CPU_MIPS64) += op_model_mipsxx.o
15 oprofile-$(CONFIG_CPU_R10000) += op_model_mipsxx.o 15 oprofile-$(CONFIG_CPU_R10000) += op_model_mipsxx.o
16 oprofile-$(CONFIG_CPU_SB1) += op_model_mipsxx.o 16 oprofile-$(CONFIG_CPU_SB1) += op_model_mipsxx.o
17 oprofile-$(CONFIG_CPU_RM9000) += op_model_rm9000.o 17 oprofile-$(CONFIG_CPU_RM9000) += op_model_rm9000.o
18 oprofile-$(CONFIG_CPU_LOONGSON2) += op_model_loongson2.o 18 oprofile-$(CONFIG_CPU_LOONGSON2) += op_model_loongson2.o
19 19
arch/mips/oprofile/backtrace.c
File was created 1 #include <linux/oprofile.h>
2 #include <linux/sched.h>
3 #include <linux/mm.h>
4 #include <linux/uaccess.h>
5 #include <asm/ptrace.h>
6 #include <asm/stacktrace.h>
7 #include <linux/stacktrace.h>
8 #include <linux/kernel.h>
9 #include <asm/sections.h>
10 #include <asm/inst.h>
11
12 struct stackframe {
13 unsigned long sp;
14 unsigned long pc;
15 unsigned long ra;
16 };
17
18 static inline int get_mem(unsigned long addr, unsigned long *result)
19 {
20 unsigned long *address = (unsigned long *) addr;
21 if (!access_ok(VERIFY_READ, addr, sizeof(unsigned long)))
22 return -1;
23 if (__copy_from_user_inatomic(result, address, sizeof(unsigned long)))
24 return -3;
25 return 0;
26 }
27
28 /*
29 * These two instruction helpers were taken from process.c
30 */
31 static inline int is_ra_save_ins(union mips_instruction *ip)
32 {
33 /* sw / sd $ra, offset($sp) */
34 return (ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op)
35 && ip->i_format.rs == 29 && ip->i_format.rt == 31;
36 }
37
38 static inline int is_sp_move_ins(union mips_instruction *ip)
39 {
40 /* addiu/daddiu sp,sp,-imm */
41 if (ip->i_format.rs != 29 || ip->i_format.rt != 29)
42 return 0;
43 if (ip->i_format.opcode == addiu_op || ip->i_format.opcode == daddiu_op)
44 return 1;
45 return 0;
46 }
47
48 /*
49 * Looks for specific instructions that mark the end of a function.
50 * This usually means we ran into the code area of the previous function.
51 */
52 static inline int is_end_of_function_marker(union mips_instruction *ip)
53 {
54 /* jr ra */
55 if (ip->r_format.func == jr_op && ip->r_format.rs == 31)
56 return 1;
57 /* lui gp */
58 if (ip->i_format.opcode == lui_op && ip->i_format.rt == 28)
59 return 1;
60 return 0;
61 }
62
63 /*
64 * TODO for userspace stack unwinding:
65 * - handle cases where the stack is adjusted inside a function
66 * (generally doesn't happen)
67 * - find optimal value for max_instr_check
68 * - try to find a way to handle leaf functions
69 */
70
71 static inline int unwind_user_frame(struct stackframe *old_frame,
72 const unsigned int max_instr_check)
73 {
74 struct stackframe new_frame = *old_frame;
75 off_t ra_offset = 0;
76 size_t stack_size = 0;
77 unsigned long addr;
78
79 if (old_frame->pc == 0 || old_frame->sp == 0 || old_frame->ra == 0)
80 return -9;
81
82 for (addr = new_frame.pc; (addr + max_instr_check > new_frame.pc)
83 && (!ra_offset || !stack_size); --addr) {
84 union mips_instruction ip;
85
86 if (get_mem(addr, (unsigned long *) &ip))
87 return -11;
88
89 if (is_sp_move_ins(&ip)) {
90 int stack_adjustment = ip.i_format.simmediate;
91 if (stack_adjustment > 0)
92 /* This marks the end of the previous function,
93 which means we overran. */
94 break;
95 stack_size = (unsigned) stack_adjustment;
96 } else if (is_ra_save_ins(&ip)) {
97 int ra_slot = ip.i_format.simmediate;
98 if (ra_slot < 0)
99 /* This shouldn't happen. */
100 break;
101 ra_offset = ra_slot;
102 } else if (is_end_of_function_marker(&ip))
103 break;
104 }
105
106 if (!ra_offset || !stack_size)
107 return -1;
108
109 if (ra_offset) {
110 new_frame.ra = old_frame->sp + ra_offset;
111 if (get_mem(new_frame.ra, &(new_frame.ra)))
112 return -13;
113 }
114
115 if (stack_size) {
116 new_frame.sp = old_frame->sp + stack_size;
117 if (get_mem(new_frame.sp, &(new_frame.sp)))
118 return -14;
119 }
120
121 if (new_frame.sp > old_frame->sp)
122 return -2;
123
124 new_frame.pc = old_frame->ra;
125 *old_frame = new_frame;
126
127 return 0;
128 }
129
130 static inline void do_user_backtrace(unsigned long low_addr,
131 struct stackframe *frame,
132 unsigned int depth)
133 {
134 const unsigned int max_instr_check = 512;
135 const unsigned long high_addr = low_addr + THREAD_SIZE;
136
137 while (depth-- && !unwind_user_frame(frame, max_instr_check)) {
138 oprofile_add_trace(frame->ra);
139 if (frame->sp < low_addr || frame->sp > high_addr)
140 break;
141 }
142 }
143
144 #ifndef CONFIG_KALLSYMS
145 static inline void do_kernel_backtrace(unsigned long low_addr,
146 struct stackframe *frame,
147 unsigned int depth) { }
148 #else
149 static inline void do_kernel_backtrace(unsigned long low_addr,
150 struct stackframe *frame,
151 unsigned int depth)
152 {
153 while (depth-- && frame->pc) {
154 frame->pc = unwind_stack_by_address(low_addr,
155 &(frame->sp),
156 frame->pc,
157 &(frame->ra));
158 oprofile_add_trace(frame->ra);
159 }
160 }
161 #endif
162
163 void notrace op_mips_backtrace(struct pt_regs *const regs, unsigned int depth)
164 {
165 struct stackframe frame = { .sp = regs->regs[29],
166 .pc = regs->cp0_epc,
167 .ra = regs->regs[31] };
168 const int userspace = user_mode(regs);
169 const unsigned long low_addr = ALIGN(frame.sp, THREAD_SIZE);
170
171 if (userspace)
172 do_user_backtrace(low_addr, &frame, depth);
173 else
174 do_kernel_backtrace(low_addr, &frame, depth);
175 }
176
arch/mips/oprofile/common.c
1 /* 1 /*
2 * This file is subject to the terms and conditions of the GNU General Public 2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (C) 2004, 2005 Ralf Baechle 6 * Copyright (C) 2004, 2005 Ralf Baechle
7 * Copyright (C) 2005 MIPS Technologies, Inc. 7 * Copyright (C) 2005 MIPS Technologies, Inc.
8 */ 8 */
9 #include <linux/compiler.h> 9 #include <linux/compiler.h>
10 #include <linux/errno.h> 10 #include <linux/errno.h>
11 #include <linux/init.h> 11 #include <linux/init.h>
12 #include <linux/oprofile.h> 12 #include <linux/oprofile.h>
13 #include <linux/smp.h> 13 #include <linux/smp.h>
14 #include <asm/cpu-info.h> 14 #include <asm/cpu-info.h>
15 15
16 #include "op_impl.h" 16 #include "op_impl.h"
17 17
18 extern struct op_mips_model op_model_mipsxx_ops __weak; 18 extern struct op_mips_model op_model_mipsxx_ops __weak;
19 extern struct op_mips_model op_model_rm9000_ops __weak; 19 extern struct op_mips_model op_model_rm9000_ops __weak;
20 extern struct op_mips_model op_model_loongson2_ops __weak; 20 extern struct op_mips_model op_model_loongson2_ops __weak;
21 21
22 static struct op_mips_model *model; 22 static struct op_mips_model *model;
23 23
24 static struct op_counter_config ctr[20]; 24 static struct op_counter_config ctr[20];
25 25
26 static int op_mips_setup(void) 26 static int op_mips_setup(void)
27 { 27 {
28 /* Pre-compute the values to stuff in the hardware registers. */ 28 /* Pre-compute the values to stuff in the hardware registers. */
29 model->reg_setup(ctr); 29 model->reg_setup(ctr);
30 30
31 /* Configure the registers on all cpus. */ 31 /* Configure the registers on all cpus. */
32 on_each_cpu(model->cpu_setup, NULL, 1); 32 on_each_cpu(model->cpu_setup, NULL, 1);
33 33
34 return 0; 34 return 0;
35 } 35 }
36 36
37 static int op_mips_create_files(struct super_block *sb, struct dentry *root) 37 static int op_mips_create_files(struct super_block *sb, struct dentry *root)
38 { 38 {
39 int i; 39 int i;
40 40
41 for (i = 0; i < model->num_counters; ++i) { 41 for (i = 0; i < model->num_counters; ++i) {
42 struct dentry *dir; 42 struct dentry *dir;
43 char buf[4]; 43 char buf[4];
44 44
45 snprintf(buf, sizeof buf, "%d", i); 45 snprintf(buf, sizeof buf, "%d", i);
46 dir = oprofilefs_mkdir(sb, root, buf); 46 dir = oprofilefs_mkdir(sb, root, buf);
47 47
48 oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled); 48 oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
49 oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event); 49 oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
50 oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count); 50 oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
51 oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel); 51 oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
52 oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user); 52 oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
53 oprofilefs_create_ulong(sb, dir, "exl", &ctr[i].exl); 53 oprofilefs_create_ulong(sb, dir, "exl", &ctr[i].exl);
54 /* Dummy. */ 54 /* Dummy. */
55 oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask); 55 oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
56 } 56 }
57 57
58 return 0; 58 return 0;
59 } 59 }
60 60
61 static int op_mips_start(void) 61 static int op_mips_start(void)
62 { 62 {
63 on_each_cpu(model->cpu_start, NULL, 1); 63 on_each_cpu(model->cpu_start, NULL, 1);
64 64
65 return 0; 65 return 0;
66 } 66 }
67 67
68 static void op_mips_stop(void) 68 static void op_mips_stop(void)
69 { 69 {
70 /* Disable performance monitoring for all counters. */ 70 /* Disable performance monitoring for all counters. */
71 on_each_cpu(model->cpu_stop, NULL, 1); 71 on_each_cpu(model->cpu_stop, NULL, 1);
72 } 72 }
73 73
74 int __init oprofile_arch_init(struct oprofile_operations *ops) 74 int __init oprofile_arch_init(struct oprofile_operations *ops)
75 { 75 {
76 struct op_mips_model *lmodel = NULL; 76 struct op_mips_model *lmodel = NULL;
77 int res; 77 int res;
78 78
79 switch (current_cpu_type()) { 79 switch (current_cpu_type()) {
80 case CPU_5KC: 80 case CPU_5KC:
81 case CPU_20KC: 81 case CPU_20KC:
82 case CPU_24K: 82 case CPU_24K:
83 case CPU_25KF: 83 case CPU_25KF:
84 case CPU_34K: 84 case CPU_34K:
85 case CPU_1004K: 85 case CPU_1004K:
86 case CPU_74K: 86 case CPU_74K:
87 case CPU_SB1: 87 case CPU_SB1:
88 case CPU_SB1A: 88 case CPU_SB1A:
89 case CPU_R10000: 89 case CPU_R10000:
90 case CPU_R12000: 90 case CPU_R12000:
91 case CPU_R14000: 91 case CPU_R14000:
92 lmodel = &op_model_mipsxx_ops; 92 lmodel = &op_model_mipsxx_ops;
93 break; 93 break;
94 94
95 case CPU_RM9000: 95 case CPU_RM9000:
96 lmodel = &op_model_rm9000_ops; 96 lmodel = &op_model_rm9000_ops;
97 break; 97 break;
98 case CPU_LOONGSON2: 98 case CPU_LOONGSON2:
99 lmodel = &op_model_loongson2_ops; 99 lmodel = &op_model_loongson2_ops;
100 break; 100 break;
101 }; 101 };
102 102
103 if (!lmodel) 103 if (!lmodel)
104 return -ENODEV; 104 return -ENODEV;
105 105
106 res = lmodel->init(); 106 res = lmodel->init();
107 if (res) 107 if (res)
108 return res; 108 return res;
109 109
110 model = lmodel; 110 model = lmodel;
111 111
112 ops->create_files = op_mips_create_files; 112 ops->create_files = op_mips_create_files;
113 ops->setup = op_mips_setup; 113 ops->setup = op_mips_setup;
114 //ops->shutdown = op_mips_shutdown; 114 //ops->shutdown = op_mips_shutdown;
115 ops->start = op_mips_start; 115 ops->start = op_mips_start;
116 ops->stop = op_mips_stop; 116 ops->stop = op_mips_stop;
117 ops->cpu_type = lmodel->cpu_type; 117 ops->cpu_type = lmodel->cpu_type;
118 ops->backtrace = op_mips_backtrace;
118 119
119 printk(KERN_INFO "oprofile: using %s performance monitoring.\n", 120 printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
120 lmodel->cpu_type); 121 lmodel->cpu_type);
121 122
122 return 0; 123 return 0;
123 } 124 }
124 125
125 void oprofile_arch_exit(void) 126 void oprofile_arch_exit(void)
126 { 127 {
127 if (model) 128 if (model)
128 model->exit(); 129 model->exit();
129 } 130 }
130 131
arch/mips/oprofile/op_impl.h
1 /** 1 /**
2 * @file arch/alpha/oprofile/op_impl.h 2 * @file arch/alpha/oprofile/op_impl.h
3 * 3 *
4 * @remark Copyright 2002 OProfile authors 4 * @remark Copyright 2002 OProfile authors
5 * @remark Read the file COPYING 5 * @remark Read the file COPYING
6 * 6 *
7 * @author Richard Henderson <rth@twiddle.net> 7 * @author Richard Henderson <rth@twiddle.net>
8 */ 8 */
9 9
10 #ifndef OP_IMPL_H 10 #ifndef OP_IMPL_H
11 #define OP_IMPL_H 1 11 #define OP_IMPL_H 1
12 12
13 extern int (*perf_irq)(void); 13 extern int (*perf_irq)(void);
14 14
15 /* Per-counter configuration as set via oprofilefs. */ 15 /* Per-counter configuration as set via oprofilefs. */
16 struct op_counter_config { 16 struct op_counter_config {
17 unsigned long enabled; 17 unsigned long enabled;
18 unsigned long event; 18 unsigned long event;
19 unsigned long count; 19 unsigned long count;
20 /* Dummies because I am too lazy to hack the userspace tools. */ 20 /* Dummies because I am too lazy to hack the userspace tools. */
21 unsigned long kernel; 21 unsigned long kernel;
22 unsigned long user; 22 unsigned long user;
23 unsigned long exl; 23 unsigned long exl;
24 unsigned long unit_mask; 24 unsigned long unit_mask;
25 }; 25 };
26 26
27 /* Per-architecture configury and hooks. */ 27 /* Per-architecture configury and hooks. */
28 struct op_mips_model { 28 struct op_mips_model {
29 void (*reg_setup) (struct op_counter_config *); 29 void (*reg_setup) (struct op_counter_config *);
30 void (*cpu_setup) (void *dummy); 30 void (*cpu_setup) (void *dummy);
31 int (*init)(void); 31 int (*init)(void);
32 void (*exit)(void); 32 void (*exit)(void);
33 void (*cpu_start)(void *args); 33 void (*cpu_start)(void *args);
34 void (*cpu_stop)(void *args); 34 void (*cpu_stop)(void *args);
35 char *cpu_type; 35 char *cpu_type;
36 unsigned char num_counters; 36 unsigned char num_counters;
37 }; 37 };
38 38
39 void op_mips_backtrace(struct pt_regs * const regs, unsigned int depth);
40
39 #endif 41 #endif
40 42
arch/x86/oprofile/backtrace.c
1 /** 1 /**
2 * @file backtrace.c 2 * @file backtrace.c
3 * 3 *
4 * @remark Copyright 2002 OProfile authors 4 * @remark Copyright 2002 OProfile authors
5 * @remark Read the file COPYING 5 * @remark Read the file COPYING
6 * 6 *
7 * @author John Levon 7 * @author John Levon
8 * @author David Smith 8 * @author David Smith
9 */ 9 */
10 10
11 #include <linux/oprofile.h> 11 #include <linux/oprofile.h>
12 #include <linux/sched.h> 12 #include <linux/sched.h>
13 #include <linux/mm.h> 13 #include <linux/mm.h>
14 #include <linux/compat.h>
15 #include <linux/highmem.h>
16
14 #include <asm/ptrace.h> 17 #include <asm/ptrace.h>
15 #include <asm/uaccess.h> 18 #include <asm/uaccess.h>
16 #include <asm/stacktrace.h> 19 #include <asm/stacktrace.h>
17 #include <linux/compat.h>
18 20
19 static int backtrace_stack(void *data, char *name) 21 static int backtrace_stack(void *data, char *name)
20 { 22 {
21 /* Yes, we want all stacks */ 23 /* Yes, we want all stacks */
22 return 0; 24 return 0;
23 } 25 }
24 26
25 static void backtrace_address(void *data, unsigned long addr, int reliable) 27 static void backtrace_address(void *data, unsigned long addr, int reliable)
26 { 28 {
27 unsigned int *depth = data; 29 unsigned int *depth = data;
28 30
29 if ((*depth)--) 31 if ((*depth)--)
30 oprofile_add_trace(addr); 32 oprofile_add_trace(addr);
31 } 33 }
32 34
33 static struct stacktrace_ops backtrace_ops = { 35 static struct stacktrace_ops backtrace_ops = {
34 .stack = backtrace_stack, 36 .stack = backtrace_stack,
35 .address = backtrace_address, 37 .address = backtrace_address,
36 .walk_stack = print_context_stack, 38 .walk_stack = print_context_stack,
37 }; 39 };
38 40
41 /* from arch/x86/kernel/cpu/perf_event.c: */
42
43 /*
44 * best effort, GUP based copy_from_user() that assumes IRQ or NMI context
45 */
46 static unsigned long
47 copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
48 {
49 unsigned long offset, addr = (unsigned long)from;
50 unsigned long size, len = 0;
51 struct page *page;
52 void *map;
53 int ret;
54
55 do {
56 ret = __get_user_pages_fast(addr, 1, 0, &page);
57 if (!ret)
58 break;
59
60 offset = addr & (PAGE_SIZE - 1);
61 size = min(PAGE_SIZE - offset, n - len);
62
63 map = kmap_atomic(page);
64 memcpy(to, map+offset, size);
65 kunmap_atomic(map);
66 put_page(page);
67
68 len += size;
69 to += size;
70 addr += size;
71
72 } while (len < n);
73
74 return len;
75 }
76
39 #ifdef CONFIG_COMPAT 77 #ifdef CONFIG_COMPAT
40 static struct stack_frame_ia32 * 78 static struct stack_frame_ia32 *
41 dump_user_backtrace_32(struct stack_frame_ia32 *head) 79 dump_user_backtrace_32(struct stack_frame_ia32 *head)
42 { 80 {
81 /* Also check accessibility of one struct frame_head beyond: */
43 struct stack_frame_ia32 bufhead[2]; 82 struct stack_frame_ia32 bufhead[2];
44 struct stack_frame_ia32 *fp; 83 struct stack_frame_ia32 *fp;
84 unsigned long bytes;
45 85
46 /* Also check accessibility of one struct frame_head beyond */ 86 bytes = copy_from_user_nmi(bufhead, head, sizeof(bufhead));
47 if (!access_ok(VERIFY_READ, head, sizeof(bufhead))) 87 if (bytes != sizeof(bufhead))
48 return NULL; 88 return NULL;
49 if (__copy_from_user_inatomic(bufhead, head, sizeof(bufhead)))
50 return NULL;
51 89
52 fp = (struct stack_frame_ia32 *) compat_ptr(bufhead[0].next_frame); 90 fp = (struct stack_frame_ia32 *) compat_ptr(bufhead[0].next_frame);
53 91
54 oprofile_add_trace(bufhead[0].return_address); 92 oprofile_add_trace(bufhead[0].return_address);
55 93
56 /* frame pointers should strictly progress back up the stack 94 /* frame pointers should strictly progress back up the stack
57 * (towards higher addresses) */ 95 * (towards higher addresses) */
58 if (head >= fp) 96 if (head >= fp)
59 return NULL; 97 return NULL;
60 98
61 return fp; 99 return fp;
62 } 100 }
63 101
64 static inline int 102 static inline int
65 x86_backtrace_32(struct pt_regs * const regs, unsigned int depth) 103 x86_backtrace_32(struct pt_regs * const regs, unsigned int depth)
66 { 104 {
67 struct stack_frame_ia32 *head; 105 struct stack_frame_ia32 *head;
68 106
69 /* User process is 32-bit */ 107 /* User process is 32-bit */
70 if (!current || !test_thread_flag(TIF_IA32)) 108 if (!current || !test_thread_flag(TIF_IA32))
71 return 0; 109 return 0;
72 110
73 head = (struct stack_frame_ia32 *) regs->bp; 111 head = (struct stack_frame_ia32 *) regs->bp;
74 while (depth-- && head) 112 while (depth-- && head)
75 head = dump_user_backtrace_32(head); 113 head = dump_user_backtrace_32(head);
76 114
77 return 1; 115 return 1;
78 } 116 }
79 117
80 #else 118 #else
81 static inline int 119 static inline int
82 x86_backtrace_32(struct pt_regs * const regs, unsigned int depth) 120 x86_backtrace_32(struct pt_regs * const regs, unsigned int depth)
83 { 121 {
84 return 0; 122 return 0;
85 } 123 }
86 #endif /* CONFIG_COMPAT */ 124 #endif /* CONFIG_COMPAT */
87 125
88 static struct stack_frame *dump_user_backtrace(struct stack_frame *head) 126 static struct stack_frame *dump_user_backtrace(struct stack_frame *head)
89 { 127 {
128 /* Also check accessibility of one struct frame_head beyond: */
90 struct stack_frame bufhead[2]; 129 struct stack_frame bufhead[2];
130 unsigned long bytes;
91 131
92 /* Also check accessibility of one struct stack_frame beyond */ 132 bytes = copy_from_user_nmi(bufhead, head, sizeof(bufhead));
93 if (!access_ok(VERIFY_READ, head, sizeof(bufhead))) 133 if (bytes != sizeof(bufhead))
94 return NULL;
95 if (__copy_from_user_inatomic(bufhead, head, sizeof(bufhead)))
96 return NULL; 134 return NULL;
97 135
98 oprofile_add_trace(bufhead[0].return_address); 136 oprofile_add_trace(bufhead[0].return_address);
99 137
100 /* frame pointers should strictly progress back up the stack 138 /* frame pointers should strictly progress back up the stack
101 * (towards higher addresses) */ 139 * (towards higher addresses) */
102 if (head >= bufhead[0].next_frame) 140 if (head >= bufhead[0].next_frame)
103 return NULL; 141 return NULL;
104 142
105 return bufhead[0].next_frame; 143 return bufhead[0].next_frame;
106 } 144 }
107 145
108 void 146 void
109 x86_backtrace(struct pt_regs * const regs, unsigned int depth) 147 x86_backtrace(struct pt_regs * const regs, unsigned int depth)
110 { 148 {
111 struct stack_frame *head = (struct stack_frame *)frame_pointer(regs); 149 struct stack_frame *head = (struct stack_frame *)frame_pointer(regs);
112 150
113 if (!user_mode_vm(regs)) { 151 if (!user_mode_vm(regs)) {
114 unsigned long stack = kernel_stack_pointer(regs); 152 unsigned long stack = kernel_stack_pointer(regs);
115 if (depth) 153 if (depth)
116 dump_trace(NULL, regs, (unsigned long *)stack, 0, 154 dump_trace(NULL, regs, (unsigned long *)stack, 0,
117 &backtrace_ops, &depth); 155 &backtrace_ops, &depth);
118 return; 156 return;
119 } 157 }
120 158
121 if (x86_backtrace_32(regs, depth)) 159 if (x86_backtrace_32(regs, depth))
122 return; 160 return;
arch/x86/oprofile/nmi_int.c
1 /** 1 /**
2 * @file nmi_int.c 2 * @file nmi_int.c
3 * 3 *
4 * @remark Copyright 2002-2009 OProfile authors 4 * @remark Copyright 2002-2009 OProfile authors
5 * @remark Read the file COPYING 5 * @remark Read the file COPYING
6 * 6 *
7 * @author John Levon <levon@movementarian.org> 7 * @author John Levon <levon@movementarian.org>
8 * @author Robert Richter <robert.richter@amd.com> 8 * @author Robert Richter <robert.richter@amd.com>
9 * @author Barry Kasindorf <barry.kasindorf@amd.com> 9 * @author Barry Kasindorf <barry.kasindorf@amd.com>
10 * @author Jason Yeh <jason.yeh@amd.com> 10 * @author Jason Yeh <jason.yeh@amd.com>
11 * @author Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> 11 * @author Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
12 */ 12 */
13 13
14 #include <linux/init.h> 14 #include <linux/init.h>
15 #include <linux/notifier.h> 15 #include <linux/notifier.h>
16 #include <linux/smp.h> 16 #include <linux/smp.h>
17 #include <linux/oprofile.h> 17 #include <linux/oprofile.h>
18 #include <linux/syscore_ops.h> 18 #include <linux/syscore_ops.h>
19 #include <linux/slab.h> 19 #include <linux/slab.h>
20 #include <linux/moduleparam.h> 20 #include <linux/moduleparam.h>
21 #include <linux/kdebug.h> 21 #include <linux/kdebug.h>
22 #include <linux/cpu.h> 22 #include <linux/cpu.h>
23 #include <asm/nmi.h> 23 #include <asm/nmi.h>
24 #include <asm/msr.h> 24 #include <asm/msr.h>
25 #include <asm/apic.h> 25 #include <asm/apic.h>
26 26
27 #include "op_counter.h" 27 #include "op_counter.h"
28 #include "op_x86_model.h" 28 #include "op_x86_model.h"
29 29
30 static struct op_x86_model_spec *model; 30 static struct op_x86_model_spec *model;
31 static DEFINE_PER_CPU(struct op_msrs, cpu_msrs); 31 static DEFINE_PER_CPU(struct op_msrs, cpu_msrs);
32 static DEFINE_PER_CPU(unsigned long, saved_lvtpc); 32 static DEFINE_PER_CPU(unsigned long, saved_lvtpc);
33 33
34 /* must be protected with get_online_cpus()/put_online_cpus(): */ 34 /* must be protected with get_online_cpus()/put_online_cpus(): */
35 static int nmi_enabled; 35 static int nmi_enabled;
36 static int ctr_running; 36 static int ctr_running;
37 37
38 struct op_counter_config counter_config[OP_MAX_COUNTER]; 38 struct op_counter_config counter_config[OP_MAX_COUNTER];
39 39
40 /* common functions */ 40 /* common functions */
41 41
42 u64 op_x86_get_ctrl(struct op_x86_model_spec const *model, 42 u64 op_x86_get_ctrl(struct op_x86_model_spec const *model,
43 struct op_counter_config *counter_config) 43 struct op_counter_config *counter_config)
44 { 44 {
45 u64 val = 0; 45 u64 val = 0;
46 u16 event = (u16)counter_config->event; 46 u16 event = (u16)counter_config->event;
47 47
48 val |= ARCH_PERFMON_EVENTSEL_INT; 48 val |= ARCH_PERFMON_EVENTSEL_INT;
49 val |= counter_config->user ? ARCH_PERFMON_EVENTSEL_USR : 0; 49 val |= counter_config->user ? ARCH_PERFMON_EVENTSEL_USR : 0;
50 val |= counter_config->kernel ? ARCH_PERFMON_EVENTSEL_OS : 0; 50 val |= counter_config->kernel ? ARCH_PERFMON_EVENTSEL_OS : 0;
51 val |= (counter_config->unit_mask & 0xFF) << 8; 51 val |= (counter_config->unit_mask & 0xFF) << 8;
52 counter_config->extra &= (ARCH_PERFMON_EVENTSEL_INV | 52 counter_config->extra &= (ARCH_PERFMON_EVENTSEL_INV |
53 ARCH_PERFMON_EVENTSEL_EDGE | 53 ARCH_PERFMON_EVENTSEL_EDGE |
54 ARCH_PERFMON_EVENTSEL_CMASK); 54 ARCH_PERFMON_EVENTSEL_CMASK);
55 val |= counter_config->extra; 55 val |= counter_config->extra;
56 event &= model->event_mask ? model->event_mask : 0xFF; 56 event &= model->event_mask ? model->event_mask : 0xFF;
57 val |= event & 0xFF; 57 val |= event & 0xFF;
58 val |= (event & 0x0F00) << 24; 58 val |= (event & 0x0F00) << 24;
59 59
60 return val; 60 return val;
61 } 61 }
62 62
63 63
64 static int profile_exceptions_notify(struct notifier_block *self, 64 static int profile_exceptions_notify(struct notifier_block *self,
65 unsigned long val, void *data) 65 unsigned long val, void *data)
66 { 66 {
67 struct die_args *args = (struct die_args *)data; 67 struct die_args *args = (struct die_args *)data;
68 int ret = NOTIFY_DONE; 68 int ret = NOTIFY_DONE;
69 69
70 switch (val) { 70 switch (val) {
71 case DIE_NMI: 71 case DIE_NMI:
72 if (ctr_running) 72 if (ctr_running)
73 model->check_ctrs(args->regs, &__get_cpu_var(cpu_msrs)); 73 model->check_ctrs(args->regs, &__get_cpu_var(cpu_msrs));
74 else if (!nmi_enabled) 74 else if (!nmi_enabled)
75 break; 75 break;
76 else 76 else
77 model->stop(&__get_cpu_var(cpu_msrs)); 77 model->stop(&__get_cpu_var(cpu_msrs));
78 ret = NOTIFY_STOP; 78 ret = NOTIFY_STOP;
79 break; 79 break;
80 default: 80 default:
81 break; 81 break;
82 } 82 }
83 return ret; 83 return ret;
84 } 84 }
85 85
86 static void nmi_cpu_save_registers(struct op_msrs *msrs) 86 static void nmi_cpu_save_registers(struct op_msrs *msrs)
87 { 87 {
88 struct op_msr *counters = msrs->counters; 88 struct op_msr *counters = msrs->counters;
89 struct op_msr *controls = msrs->controls; 89 struct op_msr *controls = msrs->controls;
90 unsigned int i; 90 unsigned int i;
91 91
92 for (i = 0; i < model->num_counters; ++i) { 92 for (i = 0; i < model->num_counters; ++i) {
93 if (counters[i].addr) 93 if (counters[i].addr)
94 rdmsrl(counters[i].addr, counters[i].saved); 94 rdmsrl(counters[i].addr, counters[i].saved);
95 } 95 }
96 96
97 for (i = 0; i < model->num_controls; ++i) { 97 for (i = 0; i < model->num_controls; ++i) {
98 if (controls[i].addr) 98 if (controls[i].addr)
99 rdmsrl(controls[i].addr, controls[i].saved); 99 rdmsrl(controls[i].addr, controls[i].saved);
100 } 100 }
101 } 101 }
102 102
103 static void nmi_cpu_start(void *dummy) 103 static void nmi_cpu_start(void *dummy)
104 { 104 {
105 struct op_msrs const *msrs = &__get_cpu_var(cpu_msrs); 105 struct op_msrs const *msrs = &__get_cpu_var(cpu_msrs);
106 if (!msrs->controls) 106 if (!msrs->controls)
107 WARN_ON_ONCE(1); 107 WARN_ON_ONCE(1);
108 else 108 else
109 model->start(msrs); 109 model->start(msrs);
110 } 110 }
111 111
112 static int nmi_start(void) 112 static int nmi_start(void)
113 { 113 {
114 get_online_cpus(); 114 get_online_cpus();
115 on_each_cpu(nmi_cpu_start, NULL, 1);
116 ctr_running = 1; 115 ctr_running = 1;
116 /* make ctr_running visible to the nmi handler: */
117 smp_mb();
118 on_each_cpu(nmi_cpu_start, NULL, 1);
117 put_online_cpus(); 119 put_online_cpus();
118 return 0; 120 return 0;
119 } 121 }
120 122
121 static void nmi_cpu_stop(void *dummy) 123 static void nmi_cpu_stop(void *dummy)
122 { 124 {
123 struct op_msrs const *msrs = &__get_cpu_var(cpu_msrs); 125 struct op_msrs const *msrs = &__get_cpu_var(cpu_msrs);
124 if (!msrs->controls) 126 if (!msrs->controls)
125 WARN_ON_ONCE(1); 127 WARN_ON_ONCE(1);
126 else 128 else
127 model->stop(msrs); 129 model->stop(msrs);
128 } 130 }
129 131
130 static void nmi_stop(void) 132 static void nmi_stop(void)
131 { 133 {
132 get_online_cpus(); 134 get_online_cpus();
133 on_each_cpu(nmi_cpu_stop, NULL, 1); 135 on_each_cpu(nmi_cpu_stop, NULL, 1);
134 ctr_running = 0; 136 ctr_running = 0;
135 put_online_cpus(); 137 put_online_cpus();
136 } 138 }
137 139
138 #ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX 140 #ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
139 141
140 static DEFINE_PER_CPU(int, switch_index); 142 static DEFINE_PER_CPU(int, switch_index);
141 143
142 static inline int has_mux(void) 144 static inline int has_mux(void)
143 { 145 {
144 return !!model->switch_ctrl; 146 return !!model->switch_ctrl;
145 } 147 }
146 148
147 inline int op_x86_phys_to_virt(int phys) 149 inline int op_x86_phys_to_virt(int phys)
148 { 150 {
149 return __this_cpu_read(switch_index) + phys; 151 return __this_cpu_read(switch_index) + phys;
150 } 152 }
151 153
152 inline int op_x86_virt_to_phys(int virt) 154 inline int op_x86_virt_to_phys(int virt)
153 { 155 {
154 return virt % model->num_counters; 156 return virt % model->num_counters;
155 } 157 }
156 158
157 static void nmi_shutdown_mux(void) 159 static void nmi_shutdown_mux(void)
158 { 160 {
159 int i; 161 int i;
160 162
161 if (!has_mux()) 163 if (!has_mux())
162 return; 164 return;
163 165
164 for_each_possible_cpu(i) { 166 for_each_possible_cpu(i) {
165 kfree(per_cpu(cpu_msrs, i).multiplex); 167 kfree(per_cpu(cpu_msrs, i).multiplex);
166 per_cpu(cpu_msrs, i).multiplex = NULL; 168 per_cpu(cpu_msrs, i).multiplex = NULL;
167 per_cpu(switch_index, i) = 0; 169 per_cpu(switch_index, i) = 0;
168 } 170 }
169 } 171 }
170 172
171 static int nmi_setup_mux(void) 173 static int nmi_setup_mux(void)
172 { 174 {
173 size_t multiplex_size = 175 size_t multiplex_size =
174 sizeof(struct op_msr) * model->num_virt_counters; 176 sizeof(struct op_msr) * model->num_virt_counters;
175 int i; 177 int i;
176 178
177 if (!has_mux()) 179 if (!has_mux())
178 return 1; 180 return 1;
179 181
180 for_each_possible_cpu(i) { 182 for_each_possible_cpu(i) {
181 per_cpu(cpu_msrs, i).multiplex = 183 per_cpu(cpu_msrs, i).multiplex =
182 kzalloc(multiplex_size, GFP_KERNEL); 184 kzalloc(multiplex_size, GFP_KERNEL);
183 if (!per_cpu(cpu_msrs, i).multiplex) 185 if (!per_cpu(cpu_msrs, i).multiplex)
184 return 0; 186 return 0;
185 } 187 }
186 188
187 return 1; 189 return 1;
188 } 190 }
189 191
190 static void nmi_cpu_setup_mux(int cpu, struct op_msrs const * const msrs) 192 static void nmi_cpu_setup_mux(int cpu, struct op_msrs const * const msrs)
191 { 193 {
192 int i; 194 int i;
193 struct op_msr *multiplex = msrs->multiplex; 195 struct op_msr *multiplex = msrs->multiplex;
194 196
195 if (!has_mux()) 197 if (!has_mux())
196 return; 198 return;
197 199
198 for (i = 0; i < model->num_virt_counters; ++i) { 200 for (i = 0; i < model->num_virt_counters; ++i) {
199 if (counter_config[i].enabled) { 201 if (counter_config[i].enabled) {
200 multiplex[i].saved = -(u64)counter_config[i].count; 202 multiplex[i].saved = -(u64)counter_config[i].count;
201 } else { 203 } else {
202 multiplex[i].saved = 0; 204 multiplex[i].saved = 0;
203 } 205 }
204 } 206 }
205 207
206 per_cpu(switch_index, cpu) = 0; 208 per_cpu(switch_index, cpu) = 0;
207 } 209 }
208 210
209 static void nmi_cpu_save_mpx_registers(struct op_msrs *msrs) 211 static void nmi_cpu_save_mpx_registers(struct op_msrs *msrs)
210 { 212 {
211 struct op_msr *counters = msrs->counters; 213 struct op_msr *counters = msrs->counters;
212 struct op_msr *multiplex = msrs->multiplex; 214 struct op_msr *multiplex = msrs->multiplex;
213 int i; 215 int i;
214 216
215 for (i = 0; i < model->num_counters; ++i) { 217 for (i = 0; i < model->num_counters; ++i) {
216 int virt = op_x86_phys_to_virt(i); 218 int virt = op_x86_phys_to_virt(i);
217 if (counters[i].addr) 219 if (counters[i].addr)
218 rdmsrl(counters[i].addr, multiplex[virt].saved); 220 rdmsrl(counters[i].addr, multiplex[virt].saved);
219 } 221 }
220 } 222 }
221 223
222 static void nmi_cpu_restore_mpx_registers(struct op_msrs *msrs) 224 static void nmi_cpu_restore_mpx_registers(struct op_msrs *msrs)
223 { 225 {
224 struct op_msr *counters = msrs->counters; 226 struct op_msr *counters = msrs->counters;
225 struct op_msr *multiplex = msrs->multiplex; 227 struct op_msr *multiplex = msrs->multiplex;
226 int i; 228 int i;
227 229
228 for (i = 0; i < model->num_counters; ++i) { 230 for (i = 0; i < model->num_counters; ++i) {
229 int virt = op_x86_phys_to_virt(i); 231 int virt = op_x86_phys_to_virt(i);
230 if (counters[i].addr) 232 if (counters[i].addr)
231 wrmsrl(counters[i].addr, multiplex[virt].saved); 233 wrmsrl(counters[i].addr, multiplex[virt].saved);
232 } 234 }
233 } 235 }
234 236
235 static void nmi_cpu_switch(void *dummy) 237 static void nmi_cpu_switch(void *dummy)
236 { 238 {
237 int cpu = smp_processor_id(); 239 int cpu = smp_processor_id();
238 int si = per_cpu(switch_index, cpu); 240 int si = per_cpu(switch_index, cpu);
239 struct op_msrs *msrs = &per_cpu(cpu_msrs, cpu); 241 struct op_msrs *msrs = &per_cpu(cpu_msrs, cpu);
240 242
241 nmi_cpu_stop(NULL); 243 nmi_cpu_stop(NULL);
242 nmi_cpu_save_mpx_registers(msrs); 244 nmi_cpu_save_mpx_registers(msrs);
243 245
244 /* move to next set */ 246 /* move to next set */
245 si += model->num_counters; 247 si += model->num_counters;
246 if ((si >= model->num_virt_counters) || (counter_config[si].count == 0)) 248 if ((si >= model->num_virt_counters) || (counter_config[si].count == 0))
247 per_cpu(switch_index, cpu) = 0; 249 per_cpu(switch_index, cpu) = 0;
248 else 250 else
249 per_cpu(switch_index, cpu) = si; 251 per_cpu(switch_index, cpu) = si;
250 252
251 model->switch_ctrl(model, msrs); 253 model->switch_ctrl(model, msrs);
252 nmi_cpu_restore_mpx_registers(msrs); 254 nmi_cpu_restore_mpx_registers(msrs);
253 255
254 nmi_cpu_start(NULL); 256 nmi_cpu_start(NULL);
255 } 257 }
256 258
257 259
258 /* 260 /*
259 * Quick check to see if multiplexing is necessary. 261 * Quick check to see if multiplexing is necessary.
260 * The check should be sufficient since counters are used 262 * The check should be sufficient since counters are used
261 * in ordre. 263 * in ordre.
262 */ 264 */
263 static int nmi_multiplex_on(void) 265 static int nmi_multiplex_on(void)
264 { 266 {
265 return counter_config[model->num_counters].count ? 0 : -EINVAL; 267 return counter_config[model->num_counters].count ? 0 : -EINVAL;
266 } 268 }
267 269
268 static int nmi_switch_event(void) 270 static int nmi_switch_event(void)
269 { 271 {
270 if (!has_mux()) 272 if (!has_mux())
271 return -ENOSYS; /* not implemented */ 273 return -ENOSYS; /* not implemented */
272 if (nmi_multiplex_on() < 0) 274 if (nmi_multiplex_on() < 0)
273 return -EINVAL; /* not necessary */ 275 return -EINVAL; /* not necessary */
274 276
275 get_online_cpus(); 277 get_online_cpus();
276 if (ctr_running) 278 if (ctr_running)
277 on_each_cpu(nmi_cpu_switch, NULL, 1); 279 on_each_cpu(nmi_cpu_switch, NULL, 1);
278 put_online_cpus(); 280 put_online_cpus();
279 281
280 return 0; 282 return 0;
281 } 283 }
282 284
283 static inline void mux_init(struct oprofile_operations *ops) 285 static inline void mux_init(struct oprofile_operations *ops)
284 { 286 {
285 if (has_mux()) 287 if (has_mux())
286 ops->switch_events = nmi_switch_event; 288 ops->switch_events = nmi_switch_event;
287 } 289 }
288 290
289 static void mux_clone(int cpu) 291 static void mux_clone(int cpu)
290 { 292 {
291 if (!has_mux()) 293 if (!has_mux())
292 return; 294 return;
293 295
294 memcpy(per_cpu(cpu_msrs, cpu).multiplex, 296 memcpy(per_cpu(cpu_msrs, cpu).multiplex,
295 per_cpu(cpu_msrs, 0).multiplex, 297 per_cpu(cpu_msrs, 0).multiplex,
296 sizeof(struct op_msr) * model->num_virt_counters); 298 sizeof(struct op_msr) * model->num_virt_counters);
297 } 299 }
298 300
299 #else 301 #else
300 302
301 inline int op_x86_phys_to_virt(int phys) { return phys; } 303 inline int op_x86_phys_to_virt(int phys) { return phys; }
302 inline int op_x86_virt_to_phys(int virt) { return virt; } 304 inline int op_x86_virt_to_phys(int virt) { return virt; }
303 static inline void nmi_shutdown_mux(void) { } 305 static inline void nmi_shutdown_mux(void) { }
304 static inline int nmi_setup_mux(void) { return 1; } 306 static inline int nmi_setup_mux(void) { return 1; }
305 static inline void 307 static inline void
306 nmi_cpu_setup_mux(int cpu, struct op_msrs const * const msrs) { } 308 nmi_cpu_setup_mux(int cpu, struct op_msrs const * const msrs) { }
307 static inline void mux_init(struct oprofile_operations *ops) { } 309 static inline void mux_init(struct oprofile_operations *ops) { }
308 static void mux_clone(int cpu) { } 310 static void mux_clone(int cpu) { }
309 311
310 #endif 312 #endif
311 313
312 static void free_msrs(void) 314 static void free_msrs(void)
313 { 315 {
314 int i; 316 int i;
315 for_each_possible_cpu(i) { 317 for_each_possible_cpu(i) {
316 kfree(per_cpu(cpu_msrs, i).counters); 318 kfree(per_cpu(cpu_msrs, i).counters);
317 per_cpu(cpu_msrs, i).counters = NULL; 319 per_cpu(cpu_msrs, i).counters = NULL;
318 kfree(per_cpu(cpu_msrs, i).controls); 320 kfree(per_cpu(cpu_msrs, i).controls);
319 per_cpu(cpu_msrs, i).controls = NULL; 321 per_cpu(cpu_msrs, i).controls = NULL;
320 } 322 }
321 nmi_shutdown_mux(); 323 nmi_shutdown_mux();
322 } 324 }
323 325
324 static int allocate_msrs(void) 326 static int allocate_msrs(void)
325 { 327 {
326 size_t controls_size = sizeof(struct op_msr) * model->num_controls; 328 size_t controls_size = sizeof(struct op_msr) * model->num_controls;
327 size_t counters_size = sizeof(struct op_msr) * model->num_counters; 329 size_t counters_size = sizeof(struct op_msr) * model->num_counters;
328 330
329 int i; 331 int i;
330 for_each_possible_cpu(i) { 332 for_each_possible_cpu(i) {
331 per_cpu(cpu_msrs, i).counters = kzalloc(counters_size, 333 per_cpu(cpu_msrs, i).counters = kzalloc(counters_size,
332 GFP_KERNEL); 334 GFP_KERNEL);
333 if (!per_cpu(cpu_msrs, i).counters) 335 if (!per_cpu(cpu_msrs, i).counters)
334 goto fail; 336 goto fail;
335 per_cpu(cpu_msrs, i).controls = kzalloc(controls_size, 337 per_cpu(cpu_msrs, i).controls = kzalloc(controls_size,
336 GFP_KERNEL); 338 GFP_KERNEL);
337 if (!per_cpu(cpu_msrs, i).controls) 339 if (!per_cpu(cpu_msrs, i).controls)
338 goto fail; 340 goto fail;
339 } 341 }
340 342
341 if (!nmi_setup_mux()) 343 if (!nmi_setup_mux())
342 goto fail; 344 goto fail;
343 345
344 return 1; 346 return 1;
345 347
346 fail: 348 fail:
347 free_msrs(); 349 free_msrs();
348 return 0; 350 return 0;
349 } 351 }
350 352
351 static void nmi_cpu_setup(void *dummy) 353 static void nmi_cpu_setup(void *dummy)
352 { 354 {
353 int cpu = smp_processor_id(); 355 int cpu = smp_processor_id();
354 struct op_msrs *msrs = &per_cpu(cpu_msrs, cpu); 356 struct op_msrs *msrs = &per_cpu(cpu_msrs, cpu);
355 nmi_cpu_save_registers(msrs); 357 nmi_cpu_save_registers(msrs);
356 spin_lock(&oprofilefs_lock); 358 spin_lock(&oprofilefs_lock);
357 model->setup_ctrs(model, msrs); 359 model->setup_ctrs(model, msrs);
358 nmi_cpu_setup_mux(cpu, msrs); 360 nmi_cpu_setup_mux(cpu, msrs);
359 spin_unlock(&oprofilefs_lock); 361 spin_unlock(&oprofilefs_lock);
360 per_cpu(saved_lvtpc, cpu) = apic_read(APIC_LVTPC); 362 per_cpu(saved_lvtpc, cpu) = apic_read(APIC_LVTPC);
361 apic_write(APIC_LVTPC, APIC_DM_NMI); 363 apic_write(APIC_LVTPC, APIC_DM_NMI);
362 } 364 }
363 365
364 static struct notifier_block profile_exceptions_nb = { 366 static struct notifier_block profile_exceptions_nb = {
365 .notifier_call = profile_exceptions_notify, 367 .notifier_call = profile_exceptions_notify,
366 .next = NULL, 368 .next = NULL,
367 .priority = NMI_LOCAL_LOW_PRIOR, 369 .priority = NMI_LOCAL_LOW_PRIOR,
368 }; 370 };
369 371
370 static void nmi_cpu_restore_registers(struct op_msrs *msrs) 372 static void nmi_cpu_restore_registers(struct op_msrs *msrs)
371 { 373 {
372 struct op_msr *counters = msrs->counters; 374 struct op_msr *counters = msrs->counters;
373 struct op_msr *controls = msrs->controls; 375 struct op_msr *controls = msrs->controls;
374 unsigned int i; 376 unsigned int i;
375 377
376 for (i = 0; i < model->num_controls; ++i) { 378 for (i = 0; i < model->num_controls; ++i) {
377 if (controls[i].addr) 379 if (controls[i].addr)
378 wrmsrl(controls[i].addr, controls[i].saved); 380 wrmsrl(controls[i].addr, controls[i].saved);
379 } 381 }
380 382
381 for (i = 0; i < model->num_counters; ++i) { 383 for (i = 0; i < model->num_counters; ++i) {
382 if (counters[i].addr) 384 if (counters[i].addr)
383 wrmsrl(counters[i].addr, counters[i].saved); 385 wrmsrl(counters[i].addr, counters[i].saved);
384 } 386 }
385 } 387 }
386 388
387 static void nmi_cpu_shutdown(void *dummy) 389 static void nmi_cpu_shutdown(void *dummy)
388 { 390 {
389 unsigned int v; 391 unsigned int v;
390 int cpu = smp_processor_id(); 392 int cpu = smp_processor_id();
391 struct op_msrs *msrs = &per_cpu(cpu_msrs, cpu); 393 struct op_msrs *msrs = &per_cpu(cpu_msrs, cpu);
392 394
393 /* restoring APIC_LVTPC can trigger an apic error because the delivery 395 /* restoring APIC_LVTPC can trigger an apic error because the delivery
394 * mode and vector nr combination can be illegal. That's by design: on 396 * mode and vector nr combination can be illegal. That's by design: on
395 * power on apic lvt contain a zero vector nr which are legal only for 397 * power on apic lvt contain a zero vector nr which are legal only for
396 * NMI delivery mode. So inhibit apic err before restoring lvtpc 398 * NMI delivery mode. So inhibit apic err before restoring lvtpc
397 */ 399 */
398 v = apic_read(APIC_LVTERR); 400 v = apic_read(APIC_LVTERR);
399 apic_write(APIC_LVTERR, v | APIC_LVT_MASKED); 401 apic_write(APIC_LVTERR, v | APIC_LVT_MASKED);
400 apic_write(APIC_LVTPC, per_cpu(saved_lvtpc, cpu)); 402 apic_write(APIC_LVTPC, per_cpu(saved_lvtpc, cpu));
401 apic_write(APIC_LVTERR, v); 403 apic_write(APIC_LVTERR, v);
402 nmi_cpu_restore_registers(msrs); 404 nmi_cpu_restore_registers(msrs);
403 if (model->cpu_down) 405 if (model->cpu_down)
404 model->cpu_down(); 406 model->cpu_down();
405 } 407 }
406 408
407 static void nmi_cpu_up(void *dummy) 409 static void nmi_cpu_up(void *dummy)
408 { 410 {
409 if (nmi_enabled) 411 if (nmi_enabled)
410 nmi_cpu_setup(dummy); 412 nmi_cpu_setup(dummy);
411 if (ctr_running) 413 if (ctr_running)
412 nmi_cpu_start(dummy); 414 nmi_cpu_start(dummy);
413 } 415 }
414 416
415 static void nmi_cpu_down(void *dummy) 417 static void nmi_cpu_down(void *dummy)
416 { 418 {
417 if (ctr_running) 419 if (ctr_running)
418 nmi_cpu_stop(dummy); 420 nmi_cpu_stop(dummy);
419 if (nmi_enabled) 421 if (nmi_enabled)
420 nmi_cpu_shutdown(dummy); 422 nmi_cpu_shutdown(dummy);
421 } 423 }
422 424
423 static int nmi_create_files(struct super_block *sb, struct dentry *root) 425 static int nmi_create_files(struct super_block *sb, struct dentry *root)
424 { 426 {
425 unsigned int i; 427 unsigned int i;
426 428
427 for (i = 0; i < model->num_virt_counters; ++i) { 429 for (i = 0; i < model->num_virt_counters; ++i) {
428 struct dentry *dir; 430 struct dentry *dir;
429 char buf[4]; 431 char buf[4];
430 432
431 /* quick little hack to _not_ expose a counter if it is not 433 /* quick little hack to _not_ expose a counter if it is not
432 * available for use. This should protect userspace app. 434 * available for use. This should protect userspace app.
433 * NOTE: assumes 1:1 mapping here (that counters are organized 435 * NOTE: assumes 1:1 mapping here (that counters are organized
434 * sequentially in their struct assignment). 436 * sequentially in their struct assignment).
435 */ 437 */
436 if (!avail_to_resrv_perfctr_nmi_bit(op_x86_virt_to_phys(i))) 438 if (!avail_to_resrv_perfctr_nmi_bit(op_x86_virt_to_phys(i)))
437 continue; 439 continue;
438 440
439 snprintf(buf, sizeof(buf), "%d", i); 441 snprintf(buf, sizeof(buf), "%d", i);
440 dir = oprofilefs_mkdir(sb, root, buf); 442 dir = oprofilefs_mkdir(sb, root, buf);
441 oprofilefs_create_ulong(sb, dir, "enabled", &counter_config[i].enabled); 443 oprofilefs_create_ulong(sb, dir, "enabled", &counter_config[i].enabled);
442 oprofilefs_create_ulong(sb, dir, "event", &counter_config[i].event); 444 oprofilefs_create_ulong(sb, dir, "event", &counter_config[i].event);
443 oprofilefs_create_ulong(sb, dir, "count", &counter_config[i].count); 445 oprofilefs_create_ulong(sb, dir, "count", &counter_config[i].count);
444 oprofilefs_create_ulong(sb, dir, "unit_mask", &counter_config[i].unit_mask); 446 oprofilefs_create_ulong(sb, dir, "unit_mask", &counter_config[i].unit_mask);
445 oprofilefs_create_ulong(sb, dir, "kernel", &counter_config[i].kernel); 447 oprofilefs_create_ulong(sb, dir, "kernel", &counter_config[i].kernel);
446 oprofilefs_create_ulong(sb, dir, "user", &counter_config[i].user); 448 oprofilefs_create_ulong(sb, dir, "user", &counter_config[i].user);
447 oprofilefs_create_ulong(sb, dir, "extra", &counter_config[i].extra); 449 oprofilefs_create_ulong(sb, dir, "extra", &counter_config[i].extra);
448 } 450 }
449 451
450 return 0; 452 return 0;
451 } 453 }
452 454
453 static int oprofile_cpu_notifier(struct notifier_block *b, unsigned long action, 455 static int oprofile_cpu_notifier(struct notifier_block *b, unsigned long action,
454 void *data) 456 void *data)
455 { 457 {
456 int cpu = (unsigned long)data; 458 int cpu = (unsigned long)data;
457 switch (action) { 459 switch (action) {
458 case CPU_DOWN_FAILED: 460 case CPU_DOWN_FAILED:
459 case CPU_ONLINE: 461 case CPU_ONLINE:
460 smp_call_function_single(cpu, nmi_cpu_up, NULL, 0); 462 smp_call_function_single(cpu, nmi_cpu_up, NULL, 0);
461 break; 463 break;
462 case CPU_DOWN_PREPARE: 464 case CPU_DOWN_PREPARE:
463 smp_call_function_single(cpu, nmi_cpu_down, NULL, 1); 465 smp_call_function_single(cpu, nmi_cpu_down, NULL, 1);
464 break; 466 break;
465 } 467 }
466 return NOTIFY_DONE; 468 return NOTIFY_DONE;
467 } 469 }
468 470
469 static struct notifier_block oprofile_cpu_nb = { 471 static struct notifier_block oprofile_cpu_nb = {
470 .notifier_call = oprofile_cpu_notifier 472 .notifier_call = oprofile_cpu_notifier
471 }; 473 };
472 474
473 static int nmi_setup(void) 475 static int nmi_setup(void)
474 { 476 {
475 int err = 0; 477 int err = 0;
476 int cpu; 478 int cpu;
477 479
478 if (!allocate_msrs()) 480 if (!allocate_msrs())
479 return -ENOMEM; 481 return -ENOMEM;
480 482
481 /* We need to serialize save and setup for HT because the subset 483 /* We need to serialize save and setup for HT because the subset
482 * of msrs are distinct for save and setup operations 484 * of msrs are distinct for save and setup operations
483 */ 485 */
484 486
485 /* Assume saved/restored counters are the same on all CPUs */ 487 /* Assume saved/restored counters are the same on all CPUs */
486 err = model->fill_in_addresses(&per_cpu(cpu_msrs, 0)); 488 err = model->fill_in_addresses(&per_cpu(cpu_msrs, 0));
487 if (err) 489 if (err)
488 goto fail; 490 goto fail;
489 491
490 for_each_possible_cpu(cpu) { 492 for_each_possible_cpu(cpu) {
491 if (!cpu) 493 if (!cpu)
492 continue; 494 continue;
493 495
494 memcpy(per_cpu(cpu_msrs, cpu).counters, 496 memcpy(per_cpu(cpu_msrs, cpu).counters,
495 per_cpu(cpu_msrs, 0).counters, 497 per_cpu(cpu_msrs, 0).counters,
496 sizeof(struct op_msr) * model->num_counters); 498 sizeof(struct op_msr) * model->num_counters);
497 499
498 memcpy(per_cpu(cpu_msrs, cpu).controls, 500 memcpy(per_cpu(cpu_msrs, cpu).controls,
499 per_cpu(cpu_msrs, 0).controls, 501 per_cpu(cpu_msrs, 0).controls,
500 sizeof(struct op_msr) * model->num_controls); 502 sizeof(struct op_msr) * model->num_controls);
501 503
502 mux_clone(cpu); 504 mux_clone(cpu);
503 } 505 }
504 506
505 nmi_enabled = 0; 507 nmi_enabled = 0;
506 ctr_running = 0; 508 ctr_running = 0;
507 barrier(); 509 /* make variables visible to the nmi handler: */
510 smp_mb();
508 err = register_die_notifier(&profile_exceptions_nb); 511 err = register_die_notifier(&profile_exceptions_nb);
509 if (err) 512 if (err)
510 goto fail; 513 goto fail;
511 514
512 get_online_cpus(); 515 get_online_cpus();
513 register_cpu_notifier(&oprofile_cpu_nb); 516 register_cpu_notifier(&oprofile_cpu_nb);
514 on_each_cpu(nmi_cpu_setup, NULL, 1);
515 nmi_enabled = 1; 517 nmi_enabled = 1;
518 /* make nmi_enabled visible to the nmi handler: */
519 smp_mb();
520 on_each_cpu(nmi_cpu_setup, NULL, 1);
516 put_online_cpus(); 521 put_online_cpus();
517 522
518 return 0; 523 return 0;
519 fail: 524 fail:
520 free_msrs(); 525 free_msrs();
521 return err; 526 return err;
522 } 527 }
523 528
524 static void nmi_shutdown(void) 529 static void nmi_shutdown(void)
525 { 530 {
526 struct op_msrs *msrs; 531 struct op_msrs *msrs;
527 532
528 get_online_cpus(); 533 get_online_cpus();
529 unregister_cpu_notifier(&oprofile_cpu_nb); 534 unregister_cpu_notifier(&oprofile_cpu_nb);
530 on_each_cpu(nmi_cpu_shutdown, NULL, 1); 535 on_each_cpu(nmi_cpu_shutdown, NULL, 1);
531 nmi_enabled = 0; 536 nmi_enabled = 0;
532 ctr_running = 0; 537 ctr_running = 0;
533 put_online_cpus(); 538 put_online_cpus();
534 barrier(); 539 /* make variables visible to the nmi handler: */
540 smp_mb();
535 unregister_die_notifier(&profile_exceptions_nb); 541 unregister_die_notifier(&profile_exceptions_nb);
536 msrs = &get_cpu_var(cpu_msrs); 542 msrs = &get_cpu_var(cpu_msrs);
537 model->shutdown(msrs); 543 model->shutdown(msrs);
538 free_msrs(); 544 free_msrs();
539 put_cpu_var(cpu_msrs); 545 put_cpu_var(cpu_msrs);
540 } 546 }
541 547
542 #ifdef CONFIG_PM 548 #ifdef CONFIG_PM
543 549
544 static int nmi_suspend(void) 550 static int nmi_suspend(void)
545 { 551 {
546 /* Only one CPU left, just stop that one */ 552 /* Only one CPU left, just stop that one */
547 if (nmi_enabled == 1) 553 if (nmi_enabled == 1)
548 nmi_cpu_stop(NULL); 554 nmi_cpu_stop(NULL);
549 return 0; 555 return 0;
550 } 556 }
551 557
552 static void nmi_resume(void) 558 static void nmi_resume(void)
553 { 559 {
554 if (nmi_enabled == 1) 560 if (nmi_enabled == 1)
555 nmi_cpu_start(NULL); 561 nmi_cpu_start(NULL);
556 } 562 }
557 563
558 static struct syscore_ops oprofile_syscore_ops = { 564 static struct syscore_ops oprofile_syscore_ops = {
559 .resume = nmi_resume, 565 .resume = nmi_resume,
560 .suspend = nmi_suspend, 566 .suspend = nmi_suspend,
561 }; 567 };
562 568
563 static void __init init_suspend_resume(void) 569 static void __init init_suspend_resume(void)
564 { 570 {
565 register_syscore_ops(&oprofile_syscore_ops); 571 register_syscore_ops(&oprofile_syscore_ops);
566 } 572 }
567 573
568 static void exit_suspend_resume(void) 574 static void exit_suspend_resume(void)
569 { 575 {
570 unregister_syscore_ops(&oprofile_syscore_ops); 576 unregister_syscore_ops(&oprofile_syscore_ops);
571 } 577 }
572 578
573 #else 579 #else
574 580
575 static inline void init_suspend_resume(void) { } 581 static inline void init_suspend_resume(void) { }
576 static inline void exit_suspend_resume(void) { } 582 static inline void exit_suspend_resume(void) { }
577 583
578 #endif /* CONFIG_PM */ 584 #endif /* CONFIG_PM */
579 585
580 static int __init p4_init(char **cpu_type) 586 static int __init p4_init(char **cpu_type)
581 { 587 {
582 __u8 cpu_model = boot_cpu_data.x86_model; 588 __u8 cpu_model = boot_cpu_data.x86_model;
583 589
584 if (cpu_model > 6 || cpu_model == 5) 590 if (cpu_model > 6 || cpu_model == 5)
585 return 0; 591 return 0;
586 592
587 #ifndef CONFIG_SMP 593 #ifndef CONFIG_SMP
588 *cpu_type = "i386/p4"; 594 *cpu_type = "i386/p4";
589 model = &op_p4_spec; 595 model = &op_p4_spec;
590 return 1; 596 return 1;
591 #else 597 #else
592 switch (smp_num_siblings) { 598 switch (smp_num_siblings) {
593 case 1: 599 case 1:
594 *cpu_type = "i386/p4"; 600 *cpu_type = "i386/p4";
595 model = &op_p4_spec; 601 model = &op_p4_spec;
596 return 1; 602 return 1;
597 603
598 case 2: 604 case 2:
599 *cpu_type = "i386/p4-ht"; 605 *cpu_type = "i386/p4-ht";
600 model = &op_p4_ht2_spec; 606 model = &op_p4_ht2_spec;
601 return 1; 607 return 1;
602 } 608 }
603 #endif 609 #endif
604 610
605 printk(KERN_INFO "oprofile: P4 HyperThreading detected with > 2 threads\n"); 611 printk(KERN_INFO "oprofile: P4 HyperThreading detected with > 2 threads\n");
606 printk(KERN_INFO "oprofile: Reverting to timer mode.\n"); 612 printk(KERN_INFO "oprofile: Reverting to timer mode.\n");
607 return 0; 613 return 0;
608 } 614 }
609 615
610 static int force_arch_perfmon; 616 static int force_arch_perfmon;
611 static int force_cpu_type(const char *str, struct kernel_param *kp) 617 static int force_cpu_type(const char *str, struct kernel_param *kp)
612 { 618 {
613 if (!strcmp(str, "arch_perfmon")) { 619 if (!strcmp(str, "arch_perfmon")) {
614 force_arch_perfmon = 1; 620 force_arch_perfmon = 1;
615 printk(KERN_INFO "oprofile: forcing architectural perfmon\n"); 621 printk(KERN_INFO "oprofile: forcing architectural perfmon\n");
616 } 622 }
617 623
618 return 0; 624 return 0;
619 } 625 }
620 module_param_call(cpu_type, force_cpu_type, NULL, NULL, 0); 626 module_param_call(cpu_type, force_cpu_type, NULL, NULL, 0);
621 627
622 static int __init ppro_init(char **cpu_type) 628 static int __init ppro_init(char **cpu_type)
623 { 629 {
624 __u8 cpu_model = boot_cpu_data.x86_model; 630 __u8 cpu_model = boot_cpu_data.x86_model;
625 struct op_x86_model_spec *spec = &op_ppro_spec; /* default */ 631 struct op_x86_model_spec *spec = &op_ppro_spec; /* default */
626 632
627 if (force_arch_perfmon && cpu_has_arch_perfmon) 633 if (force_arch_perfmon && cpu_has_arch_perfmon)
628 return 0; 634 return 0;
629 635
630 /* 636 /*
631 * Documentation on identifying Intel processors by CPU family 637 * Documentation on identifying Intel processors by CPU family
632 * and model can be found in the Intel Software Developer's 638 * and model can be found in the Intel Software Developer's
633 * Manuals (SDM): 639 * Manuals (SDM):
634 * 640 *
635 * http://www.intel.com/products/processor/manuals/ 641 * http://www.intel.com/products/processor/manuals/
636 * 642 *
637 * As of May 2010 the documentation for this was in the: 643 * As of May 2010 the documentation for this was in the:
638 * "Intel 64 and IA-32 Architectures Software Developer's 644 * "Intel 64 and IA-32 Architectures Software Developer's
639 * Manual Volume 3B: System Programming Guide", "Table B-1 645 * Manual Volume 3B: System Programming Guide", "Table B-1
640 * CPUID Signature Values of DisplayFamily_DisplayModel". 646 * CPUID Signature Values of DisplayFamily_DisplayModel".
641 */ 647 */
642 switch (cpu_model) { 648 switch (cpu_model) {
643 case 0 ... 2: 649 case 0 ... 2:
644 *cpu_type = "i386/ppro"; 650 *cpu_type = "i386/ppro";
645 break; 651 break;
646 case 3 ... 5: 652 case 3 ... 5:
647 *cpu_type = "i386/pii"; 653 *cpu_type = "i386/pii";
648 break; 654 break;
649 case 6 ... 8: 655 case 6 ... 8:
650 case 10 ... 11: 656 case 10 ... 11:
651 *cpu_type = "i386/piii"; 657 *cpu_type = "i386/piii";
652 break; 658 break;
653 case 9: 659 case 9:
654 case 13: 660 case 13:
655 *cpu_type = "i386/p6_mobile"; 661 *cpu_type = "i386/p6_mobile";
656 break; 662 break;
657 case 14: 663 case 14:
658 *cpu_type = "i386/core"; 664 *cpu_type = "i386/core";
659 break; 665 break;
660 case 0x0f: 666 case 0x0f:
661 case 0x16: 667 case 0x16:
662 case 0x17: 668 case 0x17:
663 case 0x1d: 669 case 0x1d:
664 *cpu_type = "i386/core_2"; 670 *cpu_type = "i386/core_2";
665 break; 671 break;
666 case 0x1a: 672 case 0x1a:
667 case 0x1e: 673 case 0x1e:
668 case 0x2e: 674 case 0x2e:
669 spec = &op_arch_perfmon_spec; 675 spec = &op_arch_perfmon_spec;
670 *cpu_type = "i386/core_i7"; 676 *cpu_type = "i386/core_i7";
671 break; 677 break;
672 case 0x1c: 678 case 0x1c:
673 *cpu_type = "i386/atom"; 679 *cpu_type = "i386/atom";
674 break; 680 break;
675 default: 681 default:
676 /* Unknown */ 682 /* Unknown */
677 return 0; 683 return 0;
678 } 684 }
679 685
680 model = spec; 686 model = spec;
681 return 1; 687 return 1;
682 } 688 }
683 689
684 int __init op_nmi_init(struct oprofile_operations *ops) 690 int __init op_nmi_init(struct oprofile_operations *ops)
685 { 691 {
686 __u8 vendor = boot_cpu_data.x86_vendor; 692 __u8 vendor = boot_cpu_data.x86_vendor;
687 __u8 family = boot_cpu_data.x86; 693 __u8 family = boot_cpu_data.x86;
688 char *cpu_type = NULL; 694 char *cpu_type = NULL;
689 int ret = 0; 695 int ret = 0;
690 696
691 if (!cpu_has_apic) 697 if (!cpu_has_apic)
692 return -ENODEV; 698 return -ENODEV;
693 699
694 switch (vendor) { 700 switch (vendor) {
695 case X86_VENDOR_AMD: 701 case X86_VENDOR_AMD:
696 /* Needs to be at least an Athlon (or hammer in 32bit mode) */ 702 /* Needs to be at least an Athlon (or hammer in 32bit mode) */
697 703
698 switch (family) { 704 switch (family) {
699 case 6: 705 case 6:
700 cpu_type = "i386/athlon"; 706 cpu_type = "i386/athlon";
701 break; 707 break;
702 case 0xf: 708 case 0xf:
703 /* 709 /*
704 * Actually it could be i386/hammer too, but 710 * Actually it could be i386/hammer too, but
705 * give user space an consistent name. 711 * give user space an consistent name.
706 */ 712 */
707 cpu_type = "x86-64/hammer"; 713 cpu_type = "x86-64/hammer";
708 break; 714 break;
709 case 0x10: 715 case 0x10:
710 cpu_type = "x86-64/family10"; 716 cpu_type = "x86-64/family10";
711 break; 717 break;
712 case 0x11: 718 case 0x11:
713 cpu_type = "x86-64/family11h"; 719 cpu_type = "x86-64/family11h";
714 break; 720 break;
715 case 0x12: 721 case 0x12:
716 cpu_type = "x86-64/family12h"; 722 cpu_type = "x86-64/family12h";
717 break; 723 break;
718 case 0x14: 724 case 0x14:
719 cpu_type = "x86-64/family14h"; 725 cpu_type = "x86-64/family14h";
720 break; 726 break;
721 case 0x15: 727 case 0x15:
722 cpu_type = "x86-64/family15h"; 728 cpu_type = "x86-64/family15h";
723 break; 729 break;
724 default: 730 default:
725 return -ENODEV; 731 return -ENODEV;
726 } 732 }
727 model = &op_amd_spec; 733 model = &op_amd_spec;
728 break; 734 break;
729 735
730 case X86_VENDOR_INTEL: 736 case X86_VENDOR_INTEL:
731 switch (family) { 737 switch (family) {
732 /* Pentium IV */ 738 /* Pentium IV */
733 case 0xf: 739 case 0xf:
734 p4_init(&cpu_type); 740 p4_init(&cpu_type);
735 break; 741 break;
736 742
737 /* A P6-class processor */ 743 /* A P6-class processor */
738 case 6: 744 case 6:
739 ppro_init(&cpu_type); 745 ppro_init(&cpu_type);
740 break; 746 break;
741 747
742 default: 748 default:
743 break; 749 break;
744 } 750 }
745 751
746 if (cpu_type) 752 if (cpu_type)
747 break; 753 break;
748 754
749 if (!cpu_has_arch_perfmon) 755 if (!cpu_has_arch_perfmon)
750 return -ENODEV; 756 return -ENODEV;
751 757
752 /* use arch perfmon as fallback */ 758 /* use arch perfmon as fallback */
753 cpu_type = "i386/arch_perfmon"; 759 cpu_type = "i386/arch_perfmon";
754 model = &op_arch_perfmon_spec; 760 model = &op_arch_perfmon_spec;
755 break; 761 break;
756 762
757 default: 763 default:
758 return -ENODEV; 764 return -ENODEV;
759 } 765 }
760 766
761 /* default values, can be overwritten by model */ 767 /* default values, can be overwritten by model */
762 ops->create_files = nmi_create_files; 768 ops->create_files = nmi_create_files;
763 ops->setup = nmi_setup; 769 ops->setup = nmi_setup;
764 ops->shutdown = nmi_shutdown; 770 ops->shutdown = nmi_shutdown;
765 ops->start = nmi_start; 771 ops->start = nmi_start;
766 ops->stop = nmi_stop; 772 ops->stop = nmi_stop;
767 ops->cpu_type = cpu_type; 773 ops->cpu_type = cpu_type;
768 774
769 if (model->init) 775 if (model->init)
770 ret = model->init(ops); 776 ret = model->init(ops);
771 if (ret) 777 if (ret)
772 return ret; 778 return ret;
773 779
774 if (!model->num_virt_counters) 780 if (!model->num_virt_counters)
775 model->num_virt_counters = model->num_counters; 781 model->num_virt_counters = model->num_counters;
776 782
777 mux_init(ops); 783 mux_init(ops);
778 784
779 init_suspend_resume(); 785 init_suspend_resume();
780 786
781 printk(KERN_INFO "oprofile: using NMI interrupt.\n"); 787 printk(KERN_INFO "oprofile: using NMI interrupt.\n");
782 return 0; 788 return 0;
783 } 789 }
784 790
785 void op_nmi_exit(void) 791 void op_nmi_exit(void)
786 { 792 {
787 exit_suspend_resume(); 793 exit_suspend_resume();