Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[firefly-linux-kernel-4.4.55.git] / arch / s390 / oprofile / init.c
1 /*
2  * S390 Version
3  *   Copyright IBM Corp. 2002, 2011
4  *   Author(s): Thomas Spatzier (tspat@de.ibm.com)
5  *   Author(s): Mahesh Salgaonkar (mahesh@linux.vnet.ibm.com)
6  *   Author(s): Heinz Graalfs (graalfs@linux.vnet.ibm.com)
7  *   Author(s): Andreas Krebbel (krebbel@linux.vnet.ibm.com)
8  *
9  * @remark Copyright 2002-2011 OProfile authors
10  */
11
12 #include <linux/oprofile.h>
13 #include <linux/init.h>
14 #include <linux/errno.h>
15 #include <linux/fs.h>
16 #include <linux/module.h>
17 #include <asm/processor.h>
18
19 #include "../../../drivers/oprofile/oprof.h"
20
21 extern void s390_backtrace(struct pt_regs * const regs, unsigned int depth);
22
23 #ifdef CONFIG_64BIT
24
25 #include "hwsampler.h"
26 #include "op_counter.h"
27
28 #define DEFAULT_INTERVAL        4127518
29
30 #define DEFAULT_SDBT_BLOCKS     1
31 #define DEFAULT_SDB_BLOCKS      511
32
33 static unsigned long oprofile_hw_interval = DEFAULT_INTERVAL;
34 static unsigned long oprofile_min_interval;
35 static unsigned long oprofile_max_interval;
36
37 static unsigned long oprofile_sdbt_blocks = DEFAULT_SDBT_BLOCKS;
38 static unsigned long oprofile_sdb_blocks = DEFAULT_SDB_BLOCKS;
39
40 static int hwsampler_enabled;
41 static int hwsampler_running;   /* start_mutex must be held to change */
42 static int hwsampler_available;
43
44 static struct oprofile_operations timer_ops;
45
46 struct op_counter_config counter_config;
47
48 enum __force_cpu_type {
49         reserved = 0,           /* do not force */
50         timer,
51 };
52 static int force_cpu_type;
53
54 static int set_cpu_type(const char *str, struct kernel_param *kp)
55 {
56         if (!strcmp(str, "timer")) {
57                 force_cpu_type = timer;
58                 printk(KERN_INFO "oprofile: forcing timer to be returned "
59                                  "as cpu type\n");
60         } else {
61                 force_cpu_type = 0;
62         }
63
64         return 0;
65 }
66 module_param_call(cpu_type, set_cpu_type, NULL, NULL, 0);
67 MODULE_PARM_DESC(cpu_type, "Force legacy basic mode sampling"
68                            "(report cpu_type \"timer\"");
69
70 static int oprofile_hwsampler_start(void)
71 {
72         int retval;
73
74         hwsampler_running = hwsampler_enabled;
75
76         if (!hwsampler_running)
77                 return timer_ops.start();
78
79         retval = hwsampler_allocate(oprofile_sdbt_blocks, oprofile_sdb_blocks);
80         if (retval)
81                 return retval;
82
83         retval = hwsampler_start_all(oprofile_hw_interval);
84         if (retval)
85                 hwsampler_deallocate();
86
87         return retval;
88 }
89
90 static void oprofile_hwsampler_stop(void)
91 {
92         if (!hwsampler_running) {
93                 timer_ops.stop();
94                 return;
95         }
96
97         hwsampler_stop_all();
98         hwsampler_deallocate();
99         return;
100 }
101
102 /*
103  * File ops used for:
104  * /dev/oprofile/0/enabled
105  * /dev/oprofile/hwsampling/hwsampler  (cpu_type = timer)
106  */
107
108 static ssize_t hwsampler_read(struct file *file, char __user *buf,
109                 size_t count, loff_t *offset)
110 {
111         return oprofilefs_ulong_to_user(hwsampler_enabled, buf, count, offset);
112 }
113
114 static ssize_t hwsampler_write(struct file *file, char const __user *buf,
115                 size_t count, loff_t *offset)
116 {
117         unsigned long val;
118         int retval;
119
120         if (*offset)
121                 return -EINVAL;
122
123         retval = oprofilefs_ulong_from_user(&val, buf, count);
124         if (retval <= 0)
125                 return retval;
126
127         if (val != 0 && val != 1)
128                 return -EINVAL;
129
130         if (oprofile_started)
131                 /*
132                  * save to do without locking as we set
133                  * hwsampler_running in start() when start_mutex is
134                  * held
135                  */
136                 return -EBUSY;
137
138         hwsampler_enabled = val;
139
140         return count;
141 }
142
143 static const struct file_operations hwsampler_fops = {
144         .read           = hwsampler_read,
145         .write          = hwsampler_write,
146 };
147
148 /*
149  * File ops used for:
150  * /dev/oprofile/0/count
151  * /dev/oprofile/hwsampling/hw_interval  (cpu_type = timer)
152  *
153  * Make sure that the value is within the hardware range.
154  */
155
156 static ssize_t hw_interval_read(struct file *file, char __user *buf,
157                                 size_t count, loff_t *offset)
158 {
159         return oprofilefs_ulong_to_user(oprofile_hw_interval, buf,
160                                         count, offset);
161 }
162
163 static ssize_t hw_interval_write(struct file *file, char const __user *buf,
164                                  size_t count, loff_t *offset)
165 {
166         unsigned long val;
167         int retval;
168
169         if (*offset)
170                 return -EINVAL;
171         retval = oprofilefs_ulong_from_user(&val, buf, count);
172         if (retval <= 0)
173                 return retval;
174         if (val < oprofile_min_interval)
175                 oprofile_hw_interval = oprofile_min_interval;
176         else if (val > oprofile_max_interval)
177                 oprofile_hw_interval = oprofile_max_interval;
178         else
179                 oprofile_hw_interval = val;
180
181         return count;
182 }
183
184 static const struct file_operations hw_interval_fops = {
185         .read           = hw_interval_read,
186         .write          = hw_interval_write,
187 };
188
189 /*
190  * File ops used for:
191  * /dev/oprofile/0/event
192  * Only a single event with number 0 is supported with this counter.
193  *
194  * /dev/oprofile/0/unit_mask
195  * This is a dummy file needed by the user space tools.
196  * No value other than 0 is accepted or returned.
197  */
198
199 static ssize_t hwsampler_zero_read(struct file *file, char __user *buf,
200                                     size_t count, loff_t *offset)
201 {
202         return oprofilefs_ulong_to_user(0, buf, count, offset);
203 }
204
205 static ssize_t hwsampler_zero_write(struct file *file, char const __user *buf,
206                                      size_t count, loff_t *offset)
207 {
208         unsigned long val;
209         int retval;
210
211         if (*offset)
212                 return -EINVAL;
213
214         retval = oprofilefs_ulong_from_user(&val, buf, count);
215         if (retval <= 0)
216                 return retval;
217         if (val != 0)
218                 return -EINVAL;
219         return count;
220 }
221
222 static const struct file_operations zero_fops = {
223         .read           = hwsampler_zero_read,
224         .write          = hwsampler_zero_write,
225 };
226
227 /* /dev/oprofile/0/kernel file ops.  */
228
229 static ssize_t hwsampler_kernel_read(struct file *file, char __user *buf,
230                                      size_t count, loff_t *offset)
231 {
232         return oprofilefs_ulong_to_user(counter_config.kernel,
233                                         buf, count, offset);
234 }
235
236 static ssize_t hwsampler_kernel_write(struct file *file, char const __user *buf,
237                                       size_t count, loff_t *offset)
238 {
239         unsigned long val;
240         int retval;
241
242         if (*offset)
243                 return -EINVAL;
244
245         retval = oprofilefs_ulong_from_user(&val, buf, count);
246         if (retval <= 0)
247                 return retval;
248
249         if (val != 0 && val != 1)
250                 return -EINVAL;
251
252         counter_config.kernel = val;
253
254         return count;
255 }
256
257 static const struct file_operations kernel_fops = {
258         .read           = hwsampler_kernel_read,
259         .write          = hwsampler_kernel_write,
260 };
261
262 /* /dev/oprofile/0/user file ops. */
263
264 static ssize_t hwsampler_user_read(struct file *file, char __user *buf,
265                                    size_t count, loff_t *offset)
266 {
267         return oprofilefs_ulong_to_user(counter_config.user,
268                                         buf, count, offset);
269 }
270
271 static ssize_t hwsampler_user_write(struct file *file, char const __user *buf,
272                                     size_t count, loff_t *offset)
273 {
274         unsigned long val;
275         int retval;
276
277         if (*offset)
278                 return -EINVAL;
279
280         retval = oprofilefs_ulong_from_user(&val, buf, count);
281         if (retval <= 0)
282                 return retval;
283
284         if (val != 0 && val != 1)
285                 return -EINVAL;
286
287         counter_config.user = val;
288
289         return count;
290 }
291
292 static const struct file_operations user_fops = {
293         .read           = hwsampler_user_read,
294         .write          = hwsampler_user_write,
295 };
296
297
298 /*
299  * File ops used for: /dev/oprofile/timer/enabled
300  * The value always has to be the inverted value of hwsampler_enabled. So
301  * no separate variable is created. That way we do not need locking.
302  */
303
304 static ssize_t timer_enabled_read(struct file *file, char __user *buf,
305                                   size_t count, loff_t *offset)
306 {
307         return oprofilefs_ulong_to_user(!hwsampler_enabled, buf, count, offset);
308 }
309
310 static ssize_t timer_enabled_write(struct file *file, char const __user *buf,
311                                    size_t count, loff_t *offset)
312 {
313         unsigned long val;
314         int retval;
315
316         if (*offset)
317                 return -EINVAL;
318
319         retval = oprofilefs_ulong_from_user(&val, buf, count);
320         if (retval <= 0)
321                 return retval;
322
323         if (val != 0 && val != 1)
324                 return -EINVAL;
325
326         /* Timer cannot be disabled without having hardware sampling.  */
327         if (val == 0 && !hwsampler_available)
328                 return -EINVAL;
329
330         if (oprofile_started)
331                 /*
332                  * save to do without locking as we set
333                  * hwsampler_running in start() when start_mutex is
334                  * held
335                  */
336                 return -EBUSY;
337
338         hwsampler_enabled = !val;
339
340         return count;
341 }
342
343 static const struct file_operations timer_enabled_fops = {
344         .read           = timer_enabled_read,
345         .write          = timer_enabled_write,
346 };
347
348
349 static int oprofile_create_hwsampling_files(struct super_block *sb,
350                                             struct dentry *root)
351 {
352         struct dentry *dir;
353
354         dir = oprofilefs_mkdir(sb, root, "timer");
355         if (!dir)
356                 return -EINVAL;
357
358         oprofilefs_create_file(sb, dir, "enabled", &timer_enabled_fops);
359
360         if (!hwsampler_available)
361                 return 0;
362
363         /* reinitialize default values */
364         hwsampler_enabled = 1;
365         counter_config.kernel = 1;
366         counter_config.user = 1;
367
368         if (!force_cpu_type) {
369                 /*
370                  * Create the counter file system.  A single virtual
371                  * counter is created which can be used to
372                  * enable/disable hardware sampling dynamically from
373                  * user space.  The user space will configure a single
374                  * counter with a single event.  The value of 'event'
375                  * and 'unit_mask' are not evaluated by the kernel code
376                  * and can only be set to 0.
377                  */
378
379                 dir = oprofilefs_mkdir(sb, root, "0");
380                 if (!dir)
381                         return -EINVAL;
382
383                 oprofilefs_create_file(sb, dir, "enabled", &hwsampler_fops);
384                 oprofilefs_create_file(sb, dir, "event", &zero_fops);
385                 oprofilefs_create_file(sb, dir, "count", &hw_interval_fops);
386                 oprofilefs_create_file(sb, dir, "unit_mask", &zero_fops);
387                 oprofilefs_create_file(sb, dir, "kernel", &kernel_fops);
388                 oprofilefs_create_file(sb, dir, "user", &user_fops);
389                 oprofilefs_create_ulong(sb, dir, "hw_sdbt_blocks",
390                                         &oprofile_sdbt_blocks);
391
392         } else {
393                 /*
394                  * Hardware sampling can be used but the cpu_type is
395                  * forced to timer in order to deal with legacy user
396                  * space tools.  The /dev/oprofile/hwsampling fs is
397                  * provided in that case.
398                  */
399                 dir = oprofilefs_mkdir(sb, root, "hwsampling");
400                 if (!dir)
401                         return -EINVAL;
402
403                 oprofilefs_create_file(sb, dir, "hwsampler",
404                                        &hwsampler_fops);
405                 oprofilefs_create_file(sb, dir, "hw_interval",
406                                        &hw_interval_fops);
407                 oprofilefs_create_ro_ulong(sb, dir, "hw_min_interval",
408                                            &oprofile_min_interval);
409                 oprofilefs_create_ro_ulong(sb, dir, "hw_max_interval",
410                                            &oprofile_max_interval);
411                 oprofilefs_create_ulong(sb, dir, "hw_sdbt_blocks",
412                                         &oprofile_sdbt_blocks);
413         }
414         return 0;
415 }
416
417 static int oprofile_hwsampler_init(struct oprofile_operations *ops)
418 {
419         /*
420          * Initialize the timer mode infrastructure as well in order
421          * to be able to switch back dynamically.  oprofile_timer_init
422          * is not supposed to fail.
423          */
424         if (oprofile_timer_init(ops))
425                 BUG();
426
427         memcpy(&timer_ops, ops, sizeof(timer_ops));
428         ops->create_files = oprofile_create_hwsampling_files;
429
430         /*
431          * If the user space tools do not support newer cpu types,
432          * the force_cpu_type module parameter
433          * can be used to always return \"timer\" as cpu type.
434          */
435         if (force_cpu_type != timer) {
436                 struct cpuid id;
437
438                 get_cpu_id (&id);
439
440                 switch (id.machine) {
441                 case 0x2097: case 0x2098: ops->cpu_type = "s390/z10"; break;
442                 case 0x2817: case 0x2818: ops->cpu_type = "s390/z196"; break;
443                 case 0x2827: case 0x2828: ops->cpu_type = "s390/zEC12"; break;
444                 default: return -ENODEV;
445                 }
446         }
447
448         if (hwsampler_setup())
449                 return -ENODEV;
450
451         /*
452          * Query the range for the sampling interval from the
453          * hardware.
454          */
455         oprofile_min_interval = hwsampler_query_min_interval();
456         if (oprofile_min_interval == 0)
457                 return -ENODEV;
458         oprofile_max_interval = hwsampler_query_max_interval();
459         if (oprofile_max_interval == 0)
460                 return -ENODEV;
461
462         /* The initial value should be sane */
463         if (oprofile_hw_interval < oprofile_min_interval)
464                 oprofile_hw_interval = oprofile_min_interval;
465         if (oprofile_hw_interval > oprofile_max_interval)
466                 oprofile_hw_interval = oprofile_max_interval;
467
468         printk(KERN_INFO "oprofile: System z hardware sampling "
469                "facility found.\n");
470
471         ops->start = oprofile_hwsampler_start;
472         ops->stop = oprofile_hwsampler_stop;
473
474         return 0;
475 }
476
477 static void oprofile_hwsampler_exit(void)
478 {
479         hwsampler_shutdown();
480 }
481
482 #endif /* CONFIG_64BIT */
483
484 int __init oprofile_arch_init(struct oprofile_operations *ops)
485 {
486         ops->backtrace = s390_backtrace;
487
488 #ifdef CONFIG_64BIT
489
490         /*
491          * -ENODEV is not reported to the caller.  The module itself
492          * will use the timer mode sampling as fallback and this is
493          * always available.
494          */
495         hwsampler_available = oprofile_hwsampler_init(ops) == 0;
496
497         return 0;
498 #else
499         return -ENODEV;
500 #endif
501 }
502
503 void oprofile_arch_exit(void)
504 {
505 #ifdef CONFIG_64BIT
506         oprofile_hwsampler_exit();
507 #endif
508 }