1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include <linux/module.h>
23#include <linux/kernel.h>
24#include <linux/sched.h>
25#include <linux/interrupt.h>
26#include <linux/proc_fs.h>
27#include <linux/seq_file.h>
28#include <linux/init.h>
29#include <linux/vmalloc.h>
30#include <linux/mm.h>
31#include <linux/sysctl.h>
32#include <linux/list.h>
33#include <linux/file.h>
34#include <linux/poll.h>
35#include <linux/vfs.h>
36#include <linux/smp.h>
37#include <linux/pagemap.h>
38#include <linux/mount.h>
39#include <linux/bitops.h>
40#include <linux/capability.h>
41#include <linux/rcupdate.h>
42#include <linux/completion.h>
43
44#include <asm/errno.h>
45#include <asm/intrinsics.h>
46#include <asm/page.h>
47#include <asm/perfmon.h>
48#include <asm/processor.h>
49#include <asm/signal.h>
50#include <asm/system.h>
51#include <asm/uaccess.h>
52#include <asm/delay.h>
53
54#ifdef CONFIG_PERFMON
55
56
57
58#define PFM_CTX_UNLOADED 1
59#define PFM_CTX_LOADED 2
60#define PFM_CTX_MASKED 3
61#define PFM_CTX_ZOMBIE 4
62
63#define PFM_INVALID_ACTIVATION (~0UL)
64
65#define PFM_NUM_PMC_REGS 64
66#define PFM_NUM_PMD_REGS 64
67
68
69
70
71#define PFM_MAX_MSGS 32
72#define PFM_CTXQ_EMPTY(g) ((g)->ctx_msgq_head == (g)->ctx_msgq_tail)
73
74
75
76
77
78
79
80
81
82
83
84
85#define PFM_REG_NOTIMPL 0x0
86#define PFM_REG_IMPL 0x1
87#define PFM_REG_END 0x2
88#define PFM_REG_MONITOR (0x1<<4|PFM_REG_IMPL)
89#define PFM_REG_COUNTING (0x2<<4|PFM_REG_MONITOR)
90#define PFM_REG_CONTROL (0x4<<4|PFM_REG_IMPL)
91#define PFM_REG_CONFIG (0x8<<4|PFM_REG_IMPL)
92#define PFM_REG_BUFFER (0xc<<4|PFM_REG_IMPL)
93
94#define PMC_IS_LAST(i) (pmu_conf->pmc_desc[i].type & PFM_REG_END)
95#define PMD_IS_LAST(i) (pmu_conf->pmd_desc[i].type & PFM_REG_END)
96
97#define PMC_OVFL_NOTIFY(ctx, i) ((ctx)->ctx_pmds[i].flags & PFM_REGFL_OVFL_NOTIFY)
98
99
100#define PMC_IS_IMPL(i) (i< PMU_MAX_PMCS && (pmu_conf->pmc_desc[i].type & PFM_REG_IMPL))
101#define PMD_IS_IMPL(i) (i< PMU_MAX_PMDS && (pmu_conf->pmd_desc[i].type & PFM_REG_IMPL))
102
103
104#define PMD_IS_COUNTING(i) ((pmu_conf->pmd_desc[i].type & PFM_REG_COUNTING) == PFM_REG_COUNTING)
105#define PMC_IS_COUNTING(i) ((pmu_conf->pmc_desc[i].type & PFM_REG_COUNTING) == PFM_REG_COUNTING)
106#define PMC_IS_MONITOR(i) ((pmu_conf->pmc_desc[i].type & PFM_REG_MONITOR) == PFM_REG_MONITOR)
107#define PMC_IS_CONTROL(i) ((pmu_conf->pmc_desc[i].type & PFM_REG_CONTROL) == PFM_REG_CONTROL)
108
109#define PMC_DFL_VAL(i) pmu_conf->pmc_desc[i].default_value
110#define PMC_RSVD_MASK(i) pmu_conf->pmc_desc[i].reserved_mask
111#define PMD_PMD_DEP(i) pmu_conf->pmd_desc[i].dep_pmd[0]
112#define PMC_PMD_DEP(i) pmu_conf->pmc_desc[i].dep_pmd[0]
113
114#define PFM_NUM_IBRS IA64_NUM_DBG_REGS
115#define PFM_NUM_DBRS IA64_NUM_DBG_REGS
116
117#define CTX_OVFL_NOBLOCK(c) ((c)->ctx_fl_block == 0)
118#define CTX_HAS_SMPL(c) ((c)->ctx_fl_is_sampling)
119#define PFM_CTX_TASK(h) (h)->ctx_task
120
121#define PMU_PMC_OI 5
122
123
124#define CTX_USED_PMD(ctx, mask) (ctx)->ctx_used_pmds[0] |= (mask)
125#define CTX_IS_USED_PMD(ctx, c) (((ctx)->ctx_used_pmds[0] & (1UL << (c))) != 0UL)
126
127#define CTX_USED_MONITOR(ctx, mask) (ctx)->ctx_used_monitors[0] |= (mask)
128
129#define CTX_USED_IBR(ctx,n) (ctx)->ctx_used_ibrs[(n)>>6] |= 1UL<< ((n) % 64)
130#define CTX_USED_DBR(ctx,n) (ctx)->ctx_used_dbrs[(n)>>6] |= 1UL<< ((n) % 64)
131#define CTX_USES_DBREGS(ctx) (((pfm_context_t *)(ctx))->ctx_fl_using_dbreg==1)
132#define PFM_CODE_RR 0
133#define PFM_DATA_RR 1
134
135#define PFM_CPUINFO_CLEAR(v) pfm_get_cpu_var(pfm_syst_info) &= ~(v)
136#define PFM_CPUINFO_SET(v) pfm_get_cpu_var(pfm_syst_info) |= (v)
137#define PFM_CPUINFO_GET() pfm_get_cpu_var(pfm_syst_info)
138
139#define RDEP(x) (1UL<<(x))
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159#define PROTECT_CTX(c, f) \
160 do { \
161 DPRINT(("spinlock_irq_save ctx %p by [%d]\n", c, task_pid_nr(current))); \
162 spin_lock_irqsave(&(c)->ctx_lock, f); \
163 DPRINT(("spinlocked ctx %p by [%d]\n", c, task_pid_nr(current))); \
164 } while(0)
165
166#define UNPROTECT_CTX(c, f) \
167 do { \
168 DPRINT(("spinlock_irq_restore ctx %p by [%d]\n", c, task_pid_nr(current))); \
169 spin_unlock_irqrestore(&(c)->ctx_lock, f); \
170 } while(0)
171
172#define PROTECT_CTX_NOPRINT(c, f) \
173 do { \
174 spin_lock_irqsave(&(c)->ctx_lock, f); \
175 } while(0)
176
177
178#define UNPROTECT_CTX_NOPRINT(c, f) \
179 do { \
180 spin_unlock_irqrestore(&(c)->ctx_lock, f); \
181 } while(0)
182
183
184#define PROTECT_CTX_NOIRQ(c) \
185 do { \
186 spin_lock(&(c)->ctx_lock); \
187 } while(0)
188
189#define UNPROTECT_CTX_NOIRQ(c) \
190 do { \
191 spin_unlock(&(c)->ctx_lock); \
192 } while(0)
193
194
195#ifdef CONFIG_SMP
196
197#define GET_ACTIVATION() pfm_get_cpu_var(pmu_activation_number)
198#define INC_ACTIVATION() pfm_get_cpu_var(pmu_activation_number)++
199#define SET_ACTIVATION(c) (c)->ctx_last_activation = GET_ACTIVATION()
200
201#else
202#define SET_ACTIVATION(t) do {} while(0)
203#define GET_ACTIVATION(t) do {} while(0)
204#define INC_ACTIVATION(t) do {} while(0)
205#endif
206
207#define SET_PMU_OWNER(t, c) do { pfm_get_cpu_var(pmu_owner) = (t); pfm_get_cpu_var(pmu_ctx) = (c); } while(0)
208#define GET_PMU_OWNER() pfm_get_cpu_var(pmu_owner)
209#define GET_PMU_CTX() pfm_get_cpu_var(pmu_ctx)
210
211#define LOCK_PFS(g) spin_lock_irqsave(&pfm_sessions.pfs_lock, g)
212#define UNLOCK_PFS(g) spin_unlock_irqrestore(&pfm_sessions.pfs_lock, g)
213
214#define PFM_REG_RETFLAG_SET(flags, val) do { flags &= ~PFM_REG_RETFL_MASK; flags |= (val); } while(0)
215
216
217
218
219#define PMC0_HAS_OVFL(cmp0) (cmp0 & ~0x1UL)
220
221#define PFMFS_MAGIC 0xa0b4d889
222
223
224
225
226#define PFM_DEBUGGING 1
227#ifdef PFM_DEBUGGING
228#define DPRINT(a) \
229 do { \
230 if (unlikely(pfm_sysctl.debug >0)) { printk("%s.%d: CPU%d [%d] ", __func__, __LINE__, smp_processor_id(), task_pid_nr(current)); printk a; } \
231 } while (0)
232
233#define DPRINT_ovfl(a) \
234 do { \
235 if (unlikely(pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0)) { printk("%s.%d: CPU%d [%d] ", __func__, __LINE__, smp_processor_id(), task_pid_nr(current)); printk a; } \
236 } while (0)
237#endif
238
239
240
241
242
243
244typedef struct {
245 unsigned long val;
246 unsigned long lval;
247 unsigned long long_reset;
248 unsigned long short_reset;
249 unsigned long reset_pmds[4];
250 unsigned long smpl_pmds[4];
251 unsigned long seed;
252 unsigned long mask;
253 unsigned int flags;
254 unsigned long eventid;
255} pfm_counter_t;
256
257
258
259
260typedef struct {
261 unsigned int block:1;
262 unsigned int system:1;
263 unsigned int using_dbreg:1;
264 unsigned int is_sampling:1;
265 unsigned int excl_idle:1;
266 unsigned int going_zombie:1;
267 unsigned int trap_reason:2;
268 unsigned int no_msg:1;
269 unsigned int can_restart:1;
270 unsigned int reserved:22;
271} pfm_context_flags_t;
272
273#define PFM_TRAP_REASON_NONE 0x0
274#define PFM_TRAP_REASON_BLOCK 0x1
275#define PFM_TRAP_REASON_RESET 0x2
276
277
278
279
280
281
282typedef struct pfm_context {
283 spinlock_t ctx_lock;
284
285 pfm_context_flags_t ctx_flags;
286 unsigned int ctx_state;
287
288 struct task_struct *ctx_task;
289
290 unsigned long ctx_ovfl_regs[4];
291
292 struct completion ctx_restart_done;
293
294 unsigned long ctx_used_pmds[4];
295 unsigned long ctx_all_pmds[4];
296 unsigned long ctx_reload_pmds[4];
297
298 unsigned long ctx_all_pmcs[4];
299 unsigned long ctx_reload_pmcs[4];
300 unsigned long ctx_used_monitors[4];
301
302 unsigned long ctx_pmcs[PFM_NUM_PMC_REGS];
303
304 unsigned int ctx_used_ibrs[1];
305 unsigned int ctx_used_dbrs[1];
306 unsigned long ctx_dbrs[IA64_NUM_DBG_REGS];
307 unsigned long ctx_ibrs[IA64_NUM_DBG_REGS];
308
309 pfm_counter_t ctx_pmds[PFM_NUM_PMD_REGS];
310
311 unsigned long th_pmcs[PFM_NUM_PMC_REGS];
312 unsigned long th_pmds[PFM_NUM_PMD_REGS];
313
314 u64 ctx_saved_psr_up;
315
316 unsigned long ctx_last_activation;
317 unsigned int ctx_last_cpu;
318 unsigned int ctx_cpu;
319
320 int ctx_fd;
321 pfm_ovfl_arg_t ctx_ovfl_arg;
322
323 pfm_buffer_fmt_t *ctx_buf_fmt;
324 void *ctx_smpl_hdr;
325 unsigned long ctx_smpl_size;
326 void *ctx_smpl_vaddr;
327
328 wait_queue_head_t ctx_msgq_wait;
329 pfm_msg_t ctx_msgq[PFM_MAX_MSGS];
330 int ctx_msgq_head;
331 int ctx_msgq_tail;
332 struct fasync_struct *ctx_async_queue;
333
334 wait_queue_head_t ctx_zombieq;
335} pfm_context_t;
336
337
338
339
340
341#define PFM_IS_FILE(f) ((f)->f_op == &pfm_file_ops)
342
343#define PFM_GET_CTX(t) ((pfm_context_t *)(t)->thread.pfm_context)
344
345#ifdef CONFIG_SMP
346#define SET_LAST_CPU(ctx, v) (ctx)->ctx_last_cpu = (v)
347#define GET_LAST_CPU(ctx) (ctx)->ctx_last_cpu
348#else
349#define SET_LAST_CPU(ctx, v) do {} while(0)
350#define GET_LAST_CPU(ctx) do {} while(0)
351#endif
352
353
354#define ctx_fl_block ctx_flags.block
355#define ctx_fl_system ctx_flags.system
356#define ctx_fl_using_dbreg ctx_flags.using_dbreg
357#define ctx_fl_is_sampling ctx_flags.is_sampling
358#define ctx_fl_excl_idle ctx_flags.excl_idle
359#define ctx_fl_going_zombie ctx_flags.going_zombie
360#define ctx_fl_trap_reason ctx_flags.trap_reason
361#define ctx_fl_no_msg ctx_flags.no_msg
362#define ctx_fl_can_restart ctx_flags.can_restart
363
364#define PFM_SET_WORK_PENDING(t, v) do { (t)->thread.pfm_needs_checking = v; } while(0);
365#define PFM_GET_WORK_PENDING(t) (t)->thread.pfm_needs_checking
366
367
368
369
370
371typedef struct {
372 spinlock_t pfs_lock;
373
374 unsigned int pfs_task_sessions;
375 unsigned int pfs_sys_sessions;
376 unsigned int pfs_sys_use_dbregs;
377 unsigned int pfs_ptrace_use_dbregs;
378 struct task_struct *pfs_sys_session[NR_CPUS];
379} pfm_session_t;
380
381
382
383
384
385
386typedef int (*pfm_reg_check_t)(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
387typedef struct {
388 unsigned int type;
389 int pm_pos;
390 unsigned long default_value;
391 unsigned long reserved_mask;
392 pfm_reg_check_t read_check;
393 pfm_reg_check_t write_check;
394 unsigned long dep_pmd[4];
395 unsigned long dep_pmc[4];
396} pfm_reg_desc_t;
397
398
399#define PMC_PM(cnum, val) (((val) >> (pmu_conf->pmc_desc[cnum].pm_pos)) & 0x1)
400
401
402
403
404
405
406
407
408
409
410
411
412
413typedef struct {
414 unsigned long ovfl_val;
415
416 pfm_reg_desc_t *pmc_desc;
417 pfm_reg_desc_t *pmd_desc;
418
419 unsigned int num_pmcs;
420 unsigned int num_pmds;
421 unsigned long impl_pmcs[4];
422 unsigned long impl_pmds[4];
423
424 char *pmu_name;
425 unsigned int pmu_family;
426 unsigned int flags;
427 unsigned int num_ibrs;
428 unsigned int num_dbrs;
429 unsigned int num_counters;
430 int (*probe)(void);
431 unsigned int use_rr_dbregs:1;
432} pmu_config_t;
433
434
435
436#define PFM_PMU_IRQ_RESEND 1
437
438
439
440
441typedef struct {
442 unsigned long ibr_mask:56;
443 unsigned long ibr_plm:4;
444 unsigned long ibr_ig:3;
445 unsigned long ibr_x:1;
446} ibr_mask_reg_t;
447
448typedef struct {
449 unsigned long dbr_mask:56;
450 unsigned long dbr_plm:4;
451 unsigned long dbr_ig:2;
452 unsigned long dbr_w:1;
453 unsigned long dbr_r:1;
454} dbr_mask_reg_t;
455
456typedef union {
457 unsigned long val;
458 ibr_mask_reg_t ibr;
459 dbr_mask_reg_t dbr;
460} dbreg_t;
461
462
463
464
465
466typedef struct {
467 int (*cmd_func)(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs);
468 char *cmd_name;
469 int cmd_flags;
470 unsigned int cmd_narg;
471 size_t cmd_argsize;
472 int (*cmd_getsize)(void *arg, size_t *sz);
473} pfm_cmd_desc_t;
474
475#define PFM_CMD_FD 0x01
476#define PFM_CMD_ARG_READ 0x02
477#define PFM_CMD_ARG_RW 0x04
478#define PFM_CMD_STOP 0x08
479
480
481#define PFM_CMD_NAME(cmd) pfm_cmd_tab[(cmd)].cmd_name
482#define PFM_CMD_READ_ARG(cmd) (pfm_cmd_tab[(cmd)].cmd_flags & PFM_CMD_ARG_READ)
483#define PFM_CMD_RW_ARG(cmd) (pfm_cmd_tab[(cmd)].cmd_flags & PFM_CMD_ARG_RW)
484#define PFM_CMD_USE_FD(cmd) (pfm_cmd_tab[(cmd)].cmd_flags & PFM_CMD_FD)
485#define PFM_CMD_STOPPED(cmd) (pfm_cmd_tab[(cmd)].cmd_flags & PFM_CMD_STOP)
486
487#define PFM_CMD_ARG_MANY -1
488
489typedef struct {
490 unsigned long pfm_spurious_ovfl_intr_count;
491 unsigned long pfm_replay_ovfl_intr_count;
492 unsigned long pfm_ovfl_intr_count;
493 unsigned long pfm_ovfl_intr_cycles;
494 unsigned long pfm_ovfl_intr_cycles_min;
495 unsigned long pfm_ovfl_intr_cycles_max;
496 unsigned long pfm_smpl_handler_calls;
497 unsigned long pfm_smpl_handler_cycles;
498 char pad[SMP_CACHE_BYTES] ____cacheline_aligned;
499} pfm_stats_t;
500
501
502
503
504static pfm_stats_t pfm_stats[NR_CPUS];
505static pfm_session_t pfm_sessions;
506
507static DEFINE_SPINLOCK(pfm_alt_install_check);
508static pfm_intr_handler_desc_t *pfm_alt_intr_handler;
509
510static struct proc_dir_entry *perfmon_dir;
511static pfm_uuid_t pfm_null_uuid = {0,};
512
513static spinlock_t pfm_buffer_fmt_lock;
514static LIST_HEAD(pfm_buffer_fmt_list);
515
516static pmu_config_t *pmu_conf;
517
518
519pfm_sysctl_t pfm_sysctl;
520EXPORT_SYMBOL(pfm_sysctl);
521
522static ctl_table pfm_ctl_table[]={
523 {
524 .ctl_name = CTL_UNNUMBERED,
525 .procname = "debug",
526 .data = &pfm_sysctl.debug,
527 .maxlen = sizeof(int),
528 .mode = 0666,
529 .proc_handler = &proc_dointvec,
530 },
531 {
532 .ctl_name = CTL_UNNUMBERED,
533 .procname = "debug_ovfl",
534 .data = &pfm_sysctl.debug_ovfl,
535 .maxlen = sizeof(int),
536 .mode = 0666,
537 .proc_handler = &proc_dointvec,
538 },
539 {
540 .ctl_name = CTL_UNNUMBERED,
541 .procname = "fastctxsw",
542 .data = &pfm_sysctl.fastctxsw,
543 .maxlen = sizeof(int),
544 .mode = 0600,
545 .proc_handler = &proc_dointvec,
546 },
547 {
548 .ctl_name = CTL_UNNUMBERED,
549 .procname = "expert_mode",
550 .data = &pfm_sysctl.expert_mode,
551 .maxlen = sizeof(int),
552 .mode = 0600,
553 .proc_handler = &proc_dointvec,
554 },
555 {}
556};
557static ctl_table pfm_sysctl_dir[] = {
558 {
559 .ctl_name = CTL_UNNUMBERED,
560 .procname = "perfmon",
561 .mode = 0555,
562 .child = pfm_ctl_table,
563 },
564 {}
565};
566static ctl_table pfm_sysctl_root[] = {
567 {
568 .ctl_name = CTL_KERN,
569 .procname = "kernel",
570 .mode = 0555,
571 .child = pfm_sysctl_dir,
572 },
573 {}
574};
575static struct ctl_table_header *pfm_sysctl_header;
576
577static int pfm_context_unload(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs);
578
579#define pfm_get_cpu_var(v) __ia64_per_cpu_var(v)
580#define pfm_get_cpu_data(a,b) per_cpu(a, b)
581
582static inline void
583pfm_put_task(struct task_struct *task)
584{
585 if (task != current) put_task_struct(task);
586}
587
588static inline void
589pfm_reserve_page(unsigned long a)
590{
591 SetPageReserved(vmalloc_to_page((void *)a));
592}
593static inline void
594pfm_unreserve_page(unsigned long a)
595{
596 ClearPageReserved(vmalloc_to_page((void*)a));
597}
598
599static inline unsigned long
600pfm_protect_ctx_ctxsw(pfm_context_t *x)
601{
602 spin_lock(&(x)->ctx_lock);
603 return 0UL;
604}
605
606static inline void
607pfm_unprotect_ctx_ctxsw(pfm_context_t *x, unsigned long f)
608{
609 spin_unlock(&(x)->ctx_lock);
610}
611
612static inline unsigned int
613pfm_do_munmap(struct mm_struct *mm, unsigned long addr, size_t len, int acct)
614{
615 return do_munmap(mm, addr, len);
616}
617
618static inline unsigned long
619pfm_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, unsigned long exec)
620{
621 return get_unmapped_area(file, addr, len, pgoff, flags);
622}
623
624
625static int
626pfmfs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data,
627 struct vfsmount *mnt)
628{
629 return get_sb_pseudo(fs_type, "pfm:", NULL, PFMFS_MAGIC, mnt);
630}
631
632static struct file_system_type pfm_fs_type = {
633 .name = "pfmfs",
634 .get_sb = pfmfs_get_sb,
635 .kill_sb = kill_anon_super,
636};
637
638DEFINE_PER_CPU(unsigned long, pfm_syst_info);
639DEFINE_PER_CPU(struct task_struct *, pmu_owner);
640DEFINE_PER_CPU(pfm_context_t *, pmu_ctx);
641DEFINE_PER_CPU(unsigned long, pmu_activation_number);
642EXPORT_PER_CPU_SYMBOL_GPL(pfm_syst_info);
643
644
645
646static const struct file_operations pfm_file_ops;
647
648
649
650
651#ifndef CONFIG_SMP
652static void pfm_lazy_save_regs (struct task_struct *ta);
653#endif
654
655void dump_pmu_state(const char *);
656static int pfm_write_ibr_dbr(int mode, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs);
657
658#include "perfmon_itanium.h"
659#include "perfmon_mckinley.h"
660#include "perfmon_montecito.h"
661#include "perfmon_generic.h"
662
663static pmu_config_t *pmu_confs[]={
664 &pmu_conf_mont,
665 &pmu_conf_mck,
666 &pmu_conf_ita,
667 &pmu_conf_gen,
668 NULL
669};
670
671
672static int pfm_end_notify_user(pfm_context_t *ctx);
673
674static inline void
675pfm_clear_psr_pp(void)
676{
677 ia64_rsm(IA64_PSR_PP);
678 ia64_srlz_i();
679}
680
681static inline void
682pfm_set_psr_pp(void)
683{
684 ia64_ssm(IA64_PSR_PP);
685 ia64_srlz_i();
686}
687
688static inline void
689pfm_clear_psr_up(void)
690{
691 ia64_rsm(IA64_PSR_UP);
692 ia64_srlz_i();
693}
694
695static inline void
696pfm_set_psr_up(void)
697{
698 ia64_ssm(IA64_PSR_UP);
699 ia64_srlz_i();
700}
701
702static inline unsigned long
703pfm_get_psr(void)
704{
705 unsigned long tmp;
706 tmp = ia64_getreg(_IA64_REG_PSR);
707 ia64_srlz_i();
708 return tmp;
709}
710
711static inline void
712pfm_set_psr_l(unsigned long val)
713{
714 ia64_setreg(_IA64_REG_PSR_L, val);
715 ia64_srlz_i();
716}
717
718static inline void
719pfm_freeze_pmu(void)
720{
721 ia64_set_pmc(0,1UL);
722 ia64_srlz_d();
723}
724
725static inline void
726pfm_unfreeze_pmu(void)
727{
728 ia64_set_pmc(0,0UL);
729 ia64_srlz_d();
730}
731
732static inline void
733pfm_restore_ibrs(unsigned long *ibrs, unsigned int nibrs)
734{
735 int i;
736
737 for (i=0; i < nibrs; i++) {
738 ia64_set_ibr(i, ibrs[i]);
739 ia64_dv_serialize_instruction();
740 }
741 ia64_srlz_i();
742}
743
744static inline void
745pfm_restore_dbrs(unsigned long *dbrs, unsigned int ndbrs)
746{
747 int i;
748
749 for (i=0; i < ndbrs; i++) {
750 ia64_set_dbr(i, dbrs[i]);
751 ia64_dv_serialize_data();
752 }
753 ia64_srlz_d();
754}
755
756
757
758
759static inline unsigned long
760pfm_read_soft_counter(pfm_context_t *ctx, int i)
761{
762 return ctx->ctx_pmds[i].val + (ia64_get_pmd(i) & pmu_conf->ovfl_val);
763}
764
765
766
767
768static inline void
769pfm_write_soft_counter(pfm_context_t *ctx, int i, unsigned long val)
770{
771 unsigned long ovfl_val = pmu_conf->ovfl_val;
772
773 ctx->ctx_pmds[i].val = val & ~ovfl_val;
774
775
776
777
778 ia64_set_pmd(i, val & ovfl_val);
779}
780
781static pfm_msg_t *
782pfm_get_new_msg(pfm_context_t *ctx)
783{
784 int idx, next;
785
786 next = (ctx->ctx_msgq_tail+1) % PFM_MAX_MSGS;
787
788 DPRINT(("ctx_fd=%p head=%d tail=%d\n", ctx, ctx->ctx_msgq_head, ctx->ctx_msgq_tail));
789 if (next == ctx->ctx_msgq_head) return NULL;
790
791 idx = ctx->ctx_msgq_tail;
792 ctx->ctx_msgq_tail = next;
793
794 DPRINT(("ctx=%p head=%d tail=%d msg=%d\n", ctx, ctx->ctx_msgq_head, ctx->ctx_msgq_tail, idx));
795
796 return ctx->ctx_msgq+idx;
797}
798
799static pfm_msg_t *
800pfm_get_next_msg(pfm_context_t *ctx)
801{
802 pfm_msg_t *msg;
803
804 DPRINT(("ctx=%p head=%d tail=%d\n", ctx, ctx->ctx_msgq_head, ctx->ctx_msgq_tail));
805
806 if (PFM_CTXQ_EMPTY(ctx)) return NULL;
807
808
809
810
811 msg = ctx->ctx_msgq+ctx->ctx_msgq_head;
812
813
814
815
816 ctx->ctx_msgq_head = (ctx->ctx_msgq_head+1) % PFM_MAX_MSGS;
817
818 DPRINT(("ctx=%p head=%d tail=%d type=%d\n", ctx, ctx->ctx_msgq_head, ctx->ctx_msgq_tail, msg->pfm_gen_msg.msg_type));
819
820 return msg;
821}
822
823static void
824pfm_reset_msgq(pfm_context_t *ctx)
825{
826 ctx->ctx_msgq_head = ctx->ctx_msgq_tail = 0;
827 DPRINT(("ctx=%p msgq reset\n", ctx));
828}
829
830static void *
831pfm_rvmalloc(unsigned long size)
832{
833 void *mem;
834 unsigned long addr;
835
836 size = PAGE_ALIGN(size);
837 mem = vmalloc(size);
838 if (mem) {
839
840 memset(mem, 0, size);
841 addr = (unsigned long)mem;
842 while (size > 0) {
843 pfm_reserve_page(addr);
844 addr+=PAGE_SIZE;
845 size-=PAGE_SIZE;
846 }
847 }
848 return mem;
849}
850
851static void
852pfm_rvfree(void *mem, unsigned long size)
853{
854 unsigned long addr;
855
856 if (mem) {
857 DPRINT(("freeing physical buffer @%p size=%lu\n", mem, size));
858 addr = (unsigned long) mem;
859 while ((long) size > 0) {
860 pfm_unreserve_page(addr);
861 addr+=PAGE_SIZE;
862 size-=PAGE_SIZE;
863 }
864 vfree(mem);
865 }
866 return;
867}
868
869static pfm_context_t *
870pfm_context_alloc(int ctx_flags)
871{
872 pfm_context_t *ctx;
873
874
875
876
877
878 ctx = kzalloc(sizeof(pfm_context_t), GFP_KERNEL);
879 if (ctx) {
880 DPRINT(("alloc ctx @%p\n", ctx));
881
882
883
884
885 spin_lock_init(&ctx->ctx_lock);
886
887
888
889
890 ctx->ctx_state = PFM_CTX_UNLOADED;
891
892
893
894
895 ctx->ctx_fl_block = (ctx_flags & PFM_FL_NOTIFY_BLOCK) ? 1 : 0;
896 ctx->ctx_fl_system = (ctx_flags & PFM_FL_SYSTEM_WIDE) ? 1: 0;
897 ctx->ctx_fl_no_msg = (ctx_flags & PFM_FL_OVFL_NO_MSG) ? 1: 0;
898
899
900
901
902
903
904
905
906 init_completion(&ctx->ctx_restart_done);
907
908
909
910
911 ctx->ctx_last_activation = PFM_INVALID_ACTIVATION;
912 SET_LAST_CPU(ctx, -1);
913
914
915
916
917 ctx->ctx_msgq_head = ctx->ctx_msgq_tail = 0;
918 init_waitqueue_head(&ctx->ctx_msgq_wait);
919 init_waitqueue_head(&ctx->ctx_zombieq);
920
921 }
922 return ctx;
923}
924
925static void
926pfm_context_free(pfm_context_t *ctx)
927{
928 if (ctx) {
929 DPRINT(("free ctx @%p\n", ctx));
930 kfree(ctx);
931 }
932}
933
934static void
935pfm_mask_monitoring(struct task_struct *task)
936{
937 pfm_context_t *ctx = PFM_GET_CTX(task);
938 unsigned long mask, val, ovfl_mask;
939 int i;
940
941 DPRINT_ovfl(("masking monitoring for [%d]\n", task_pid_nr(task)));
942
943 ovfl_mask = pmu_conf->ovfl_val;
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963 mask = ctx->ctx_used_pmds[0];
964 for (i = 0; mask; i++, mask>>=1) {
965
966 if ((mask & 0x1) == 0) continue;
967 val = ia64_get_pmd(i);
968
969 if (PMD_IS_COUNTING(i)) {
970
971
972
973 ctx->ctx_pmds[i].val += (val & ovfl_mask);
974 } else {
975 ctx->ctx_pmds[i].val = val;
976 }
977 DPRINT_ovfl(("pmd[%d]=0x%lx hw_pmd=0x%lx\n",
978 i,
979 ctx->ctx_pmds[i].val,
980 val & ovfl_mask));
981 }
982
983
984
985
986
987
988
989
990 mask = ctx->ctx_used_monitors[0] >> PMU_FIRST_COUNTER;
991 for(i= PMU_FIRST_COUNTER; mask; i++, mask>>=1) {
992 if ((mask & 0x1) == 0UL) continue;
993 ia64_set_pmc(i, ctx->th_pmcs[i] & ~0xfUL);
994 ctx->th_pmcs[i] &= ~0xfUL;
995 DPRINT_ovfl(("pmc[%d]=0x%lx\n", i, ctx->th_pmcs[i]));
996 }
997
998
999
1000 ia64_srlz_d();
1001}
1002
1003
1004
1005
1006
1007
1008static void
1009pfm_restore_monitoring(struct task_struct *task)
1010{
1011 pfm_context_t *ctx = PFM_GET_CTX(task);
1012 unsigned long mask, ovfl_mask;
1013 unsigned long psr, val;
1014 int i, is_system;
1015
1016 is_system = ctx->ctx_fl_system;
1017 ovfl_mask = pmu_conf->ovfl_val;
1018
1019 if (task != current) {
1020 printk(KERN_ERR "perfmon.%d: invalid task[%d] current[%d]\n", __LINE__, task_pid_nr(task), task_pid_nr(current));
1021 return;
1022 }
1023 if (ctx->ctx_state != PFM_CTX_MASKED) {
1024 printk(KERN_ERR "perfmon.%d: task[%d] current[%d] invalid state=%d\n", __LINE__,
1025 task_pid_nr(task), task_pid_nr(current), ctx->ctx_state);
1026 return;
1027 }
1028 psr = pfm_get_psr();
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039 if (is_system && (PFM_CPUINFO_GET() & PFM_CPUINFO_DCR_PP)) {
1040
1041 ia64_setreg(_IA64_REG_CR_DCR, ia64_getreg(_IA64_REG_CR_DCR) & ~IA64_DCR_PP);
1042 pfm_clear_psr_pp();
1043 } else {
1044 pfm_clear_psr_up();
1045 }
1046
1047
1048
1049 mask = ctx->ctx_used_pmds[0];
1050 for (i = 0; mask; i++, mask>>=1) {
1051
1052 if ((mask & 0x1) == 0) continue;
1053
1054 if (PMD_IS_COUNTING(i)) {
1055
1056
1057
1058
1059 val = ctx->ctx_pmds[i].val & ovfl_mask;
1060 ctx->ctx_pmds[i].val &= ~ovfl_mask;
1061 } else {
1062 val = ctx->ctx_pmds[i].val;
1063 }
1064 ia64_set_pmd(i, val);
1065
1066 DPRINT(("pmd[%d]=0x%lx hw_pmd=0x%lx\n",
1067 i,
1068 ctx->ctx_pmds[i].val,
1069 val));
1070 }
1071
1072
1073
1074 mask = ctx->ctx_used_monitors[0] >> PMU_FIRST_COUNTER;
1075 for(i= PMU_FIRST_COUNTER; mask; i++, mask>>=1) {
1076 if ((mask & 0x1) == 0UL) continue;
1077 ctx->th_pmcs[i] = ctx->ctx_pmcs[i];
1078 ia64_set_pmc(i, ctx->th_pmcs[i]);
1079 DPRINT(("[%d] pmc[%d]=0x%lx\n",
1080 task_pid_nr(task), i, ctx->th_pmcs[i]));
1081 }
1082 ia64_srlz_d();
1083
1084
1085
1086
1087
1088 if (ctx->ctx_fl_using_dbreg) {
1089 pfm_restore_ibrs(ctx->ctx_ibrs, pmu_conf->num_ibrs);
1090 pfm_restore_dbrs(ctx->ctx_dbrs, pmu_conf->num_dbrs);
1091 }
1092
1093
1094
1095
1096 if (is_system && (PFM_CPUINFO_GET() & PFM_CPUINFO_DCR_PP)) {
1097
1098 ia64_setreg(_IA64_REG_CR_DCR, ia64_getreg(_IA64_REG_CR_DCR) | IA64_DCR_PP);
1099 ia64_srlz_i();
1100 }
1101 pfm_set_psr_l(psr);
1102}
1103
1104static inline void
1105pfm_save_pmds(unsigned long *pmds, unsigned long mask)
1106{
1107 int i;
1108
1109 ia64_srlz_d();
1110
1111 for (i=0; mask; i++, mask>>=1) {
1112 if (mask & 0x1) pmds[i] = ia64_get_pmd(i);
1113 }
1114}
1115
1116
1117
1118
1119static inline void
1120pfm_restore_pmds(unsigned long *pmds, unsigned long mask)
1121{
1122 int i;
1123 unsigned long val, ovfl_val = pmu_conf->ovfl_val;
1124
1125 for (i=0; mask; i++, mask>>=1) {
1126 if ((mask & 0x1) == 0) continue;
1127 val = PMD_IS_COUNTING(i) ? pmds[i] & ovfl_val : pmds[i];
1128 ia64_set_pmd(i, val);
1129 }
1130 ia64_srlz_d();
1131}
1132
1133
1134
1135
1136static inline void
1137pfm_copy_pmds(struct task_struct *task, pfm_context_t *ctx)
1138{
1139 unsigned long ovfl_val = pmu_conf->ovfl_val;
1140 unsigned long mask = ctx->ctx_all_pmds[0];
1141 unsigned long val;
1142 int i;
1143
1144 DPRINT(("mask=0x%lx\n", mask));
1145
1146 for (i=0; mask; i++, mask>>=1) {
1147
1148 val = ctx->ctx_pmds[i].val;
1149
1150
1151
1152
1153
1154
1155
1156 if (PMD_IS_COUNTING(i)) {
1157 ctx->ctx_pmds[i].val = val & ~ovfl_val;
1158 val &= ovfl_val;
1159 }
1160 ctx->th_pmds[i] = val;
1161
1162 DPRINT(("pmd[%d]=0x%lx soft_val=0x%lx\n",
1163 i,
1164 ctx->th_pmds[i],
1165 ctx->ctx_pmds[i].val));
1166 }
1167}
1168
1169
1170
1171
1172static inline void
1173pfm_copy_pmcs(struct task_struct *task, pfm_context_t *ctx)
1174{
1175 unsigned long mask = ctx->ctx_all_pmcs[0];
1176 int i;
1177
1178 DPRINT(("mask=0x%lx\n", mask));
1179
1180 for (i=0; mask; i++, mask>>=1) {
1181
1182 ctx->th_pmcs[i] = ctx->ctx_pmcs[i];
1183 DPRINT(("pmc[%d]=0x%lx\n", i, ctx->th_pmcs[i]));
1184 }
1185}
1186
1187
1188
1189static inline void
1190pfm_restore_pmcs(unsigned long *pmcs, unsigned long mask)
1191{
1192 int i;
1193
1194 for (i=0; mask; i++, mask>>=1) {
1195 if ((mask & 0x1) == 0) continue;
1196 ia64_set_pmc(i, pmcs[i]);
1197 }
1198 ia64_srlz_d();
1199}
1200
1201static inline int
1202pfm_uuid_cmp(pfm_uuid_t a, pfm_uuid_t b)
1203{
1204 return memcmp(a, b, sizeof(pfm_uuid_t));
1205}
1206
1207static inline int
1208pfm_buf_fmt_exit(pfm_buffer_fmt_t *fmt, struct task_struct *task, void *buf, struct pt_regs *regs)
1209{
1210 int ret = 0;
1211 if (fmt->fmt_exit) ret = (*fmt->fmt_exit)(task, buf, regs);
1212 return ret;
1213}
1214
1215static inline int
1216pfm_buf_fmt_getsize(pfm_buffer_fmt_t *fmt, struct task_struct *task, unsigned int flags, int cpu, void *arg, unsigned long *size)
1217{
1218 int ret = 0;
1219 if (fmt->fmt_getsize) ret = (*fmt->fmt_getsize)(task, flags, cpu, arg, size);
1220 return ret;
1221}
1222
1223
1224static inline int
1225pfm_buf_fmt_validate(pfm_buffer_fmt_t *fmt, struct task_struct *task, unsigned int flags,
1226 int cpu, void *arg)
1227{
1228 int ret = 0;
1229 if (fmt->fmt_validate) ret = (*fmt->fmt_validate)(task, flags, cpu, arg);
1230 return ret;
1231}
1232
1233static inline int
1234pfm_buf_fmt_init(pfm_buffer_fmt_t *fmt, struct task_struct *task, void *buf, unsigned int flags,
1235 int cpu, void *arg)
1236{
1237 int ret = 0;
1238 if (fmt->fmt_init) ret = (*fmt->fmt_init)(task, buf, flags, cpu, arg);
1239 return ret;
1240}
1241
1242static inline int
1243pfm_buf_fmt_restart(pfm_buffer_fmt_t *fmt, struct task_struct *task, pfm_ovfl_ctrl_t *ctrl, void *buf, struct pt_regs *regs)
1244{
1245 int ret = 0;
1246 if (fmt->fmt_restart) ret = (*fmt->fmt_restart)(task, ctrl, buf, regs);
1247 return ret;
1248}
1249
1250static inline int
1251pfm_buf_fmt_restart_active(pfm_buffer_fmt_t *fmt, struct task_struct *task, pfm_ovfl_ctrl_t *ctrl, void *buf, struct pt_regs *regs)
1252{
1253 int ret = 0;
1254 if (fmt->fmt_restart_active) ret = (*fmt->fmt_restart_active)(task, ctrl, buf, regs);
1255 return ret;
1256}
1257
1258static pfm_buffer_fmt_t *
1259__pfm_find_buffer_fmt(pfm_uuid_t uuid)
1260{
1261 struct list_head * pos;
1262 pfm_buffer_fmt_t * entry;
1263
1264 list_for_each(pos, &pfm_buffer_fmt_list) {
1265 entry = list_entry(pos, pfm_buffer_fmt_t, fmt_list);
1266 if (pfm_uuid_cmp(uuid, entry->fmt_uuid) == 0)
1267 return entry;
1268 }
1269 return NULL;
1270}
1271
1272
1273
1274
1275static pfm_buffer_fmt_t *
1276pfm_find_buffer_fmt(pfm_uuid_t uuid)
1277{
1278 pfm_buffer_fmt_t * fmt;
1279 spin_lock(&pfm_buffer_fmt_lock);
1280 fmt = __pfm_find_buffer_fmt(uuid);
1281 spin_unlock(&pfm_buffer_fmt_lock);
1282 return fmt;
1283}
1284
1285int
1286pfm_register_buffer_fmt(pfm_buffer_fmt_t *fmt)
1287{
1288 int ret = 0;
1289
1290
1291 if (fmt == NULL || fmt->fmt_name == NULL) return -EINVAL;
1292
1293
1294 if (fmt->fmt_handler == NULL) return -EINVAL;
1295
1296
1297
1298
1299
1300 spin_lock(&pfm_buffer_fmt_lock);
1301
1302 if (__pfm_find_buffer_fmt(fmt->fmt_uuid)) {
1303 printk(KERN_ERR "perfmon: duplicate sampling format: %s\n", fmt->fmt_name);
1304 ret = -EBUSY;
1305 goto out;
1306 }
1307 list_add(&fmt->fmt_list, &pfm_buffer_fmt_list);
1308 printk(KERN_INFO "perfmon: added sampling format %s\n", fmt->fmt_name);
1309
1310out:
1311 spin_unlock(&pfm_buffer_fmt_lock);
1312 return ret;
1313}
1314EXPORT_SYMBOL(pfm_register_buffer_fmt);
1315
1316int
1317pfm_unregister_buffer_fmt(pfm_uuid_t uuid)
1318{
1319 pfm_buffer_fmt_t *fmt;
1320 int ret = 0;
1321
1322 spin_lock(&pfm_buffer_fmt_lock);
1323
1324 fmt = __pfm_find_buffer_fmt(uuid);
1325 if (!fmt) {
1326 printk(KERN_ERR "perfmon: cannot unregister format, not found\n");
1327 ret = -EINVAL;
1328 goto out;
1329 }
1330 list_del_init(&fmt->fmt_list);
1331 printk(KERN_INFO "perfmon: removed sampling format: %s\n", fmt->fmt_name);
1332
1333out:
1334 spin_unlock(&pfm_buffer_fmt_lock);
1335 return ret;
1336
1337}
1338EXPORT_SYMBOL(pfm_unregister_buffer_fmt);
1339
1340extern void update_pal_halt_status(int);
1341
1342static int
1343pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu)
1344{
1345 unsigned long flags;
1346
1347
1348
1349 LOCK_PFS(flags);
1350
1351 DPRINT(("in sys_sessions=%u task_sessions=%u dbregs=%u syswide=%d cpu=%u\n",
1352 pfm_sessions.pfs_sys_sessions,
1353 pfm_sessions.pfs_task_sessions,
1354 pfm_sessions.pfs_sys_use_dbregs,
1355 is_syswide,
1356 cpu));
1357
1358 if (is_syswide) {
1359
1360
1361
1362 if (pfm_sessions.pfs_task_sessions > 0UL) {
1363 DPRINT(("system wide not possible, %u conflicting task_sessions\n",
1364 pfm_sessions.pfs_task_sessions));
1365 goto abort;
1366 }
1367
1368 if (pfm_sessions.pfs_sys_session[cpu]) goto error_conflict;
1369
1370 DPRINT(("reserving system wide session on CPU%u currently on CPU%u\n", cpu, smp_processor_id()));
1371
1372 pfm_sessions.pfs_sys_session[cpu] = task;
1373
1374 pfm_sessions.pfs_sys_sessions++ ;
1375
1376 } else {
1377 if (pfm_sessions.pfs_sys_sessions) goto abort;
1378 pfm_sessions.pfs_task_sessions++;
1379 }
1380
1381 DPRINT(("out sys_sessions=%u task_sessions=%u dbregs=%u syswide=%d cpu=%u\n",
1382 pfm_sessions.pfs_sys_sessions,
1383 pfm_sessions.pfs_task_sessions,
1384 pfm_sessions.pfs_sys_use_dbregs,
1385 is_syswide,
1386 cpu));
1387
1388
1389
1390
1391 update_pal_halt_status(0);
1392
1393 UNLOCK_PFS(flags);
1394
1395 return 0;
1396
1397error_conflict:
1398 DPRINT(("system wide not possible, conflicting session [%d] on CPU%d\n",
1399 task_pid_nr(pfm_sessions.pfs_sys_session[cpu]),
1400 cpu));
1401abort:
1402 UNLOCK_PFS(flags);
1403
1404 return -EBUSY;
1405
1406}
1407
1408static int
1409pfm_unreserve_session(pfm_context_t *ctx, int is_syswide, unsigned int cpu)
1410{
1411 unsigned long flags;
1412
1413
1414
1415 LOCK_PFS(flags);
1416
1417 DPRINT(("in sys_sessions=%u task_sessions=%u dbregs=%u syswide=%d cpu=%u\n",
1418 pfm_sessions.pfs_sys_sessions,
1419 pfm_sessions.pfs_task_sessions,
1420 pfm_sessions.pfs_sys_use_dbregs,
1421 is_syswide,
1422 cpu));
1423
1424
1425 if (is_syswide) {
1426 pfm_sessions.pfs_sys_session[cpu] = NULL;
1427
1428
1429
1430 if (ctx && ctx->ctx_fl_using_dbreg) {
1431 if (pfm_sessions.pfs_sys_use_dbregs == 0) {
1432 printk(KERN_ERR "perfmon: invalid release for ctx %p sys_use_dbregs=0\n", ctx);
1433 } else {
1434 pfm_sessions.pfs_sys_use_dbregs--;
1435 }
1436 }
1437 pfm_sessions.pfs_sys_sessions--;
1438 } else {
1439 pfm_sessions.pfs_task_sessions--;
1440 }
1441 DPRINT(("out sys_sessions=%u task_sessions=%u dbregs=%u syswide=%d cpu=%u\n",
1442 pfm_sessions.pfs_sys_sessions,
1443 pfm_sessions.pfs_task_sessions,
1444 pfm_sessions.pfs_sys_use_dbregs,
1445 is_syswide,
1446 cpu));
1447
1448
1449
1450
1451 if (pfm_sessions.pfs_task_sessions == 0 && pfm_sessions.pfs_sys_sessions == 0)
1452 update_pal_halt_status(1);
1453
1454 UNLOCK_PFS(flags);
1455
1456 return 0;
1457}
1458
1459
1460
1461
1462
1463
1464static int
1465pfm_remove_smpl_mapping(struct task_struct *task, void *vaddr, unsigned long size)
1466{
1467 int r;
1468
1469
1470 if (task->mm == NULL || size == 0UL || vaddr == NULL) {
1471 printk(KERN_ERR "perfmon: pfm_remove_smpl_mapping [%d] invalid context mm=%p\n", task_pid_nr(task), task->mm);
1472 return -EINVAL;
1473 }
1474
1475 DPRINT(("smpl_vaddr=%p size=%lu\n", vaddr, size));
1476
1477
1478
1479
1480 down_write(&task->mm->mmap_sem);
1481
1482 DPRINT(("down_write done smpl_vaddr=%p size=%lu\n", vaddr, size));
1483
1484 r = pfm_do_munmap(task->mm, (unsigned long)vaddr, size, 0);
1485
1486 up_write(&task->mm->mmap_sem);
1487 if (r !=0) {
1488 printk(KERN_ERR "perfmon: [%d] unable to unmap sampling buffer @%p size=%lu\n", task_pid_nr(task), vaddr, size);
1489 }
1490
1491 DPRINT(("do_unmap(%p, %lu)=%d\n", vaddr, size, r));
1492
1493 return 0;
1494}
1495
1496
1497
1498
1499#if 0
1500static int
1501pfm_free_smpl_buffer(pfm_context_t *ctx)
1502{
1503 pfm_buffer_fmt_t *fmt;
1504
1505 if (ctx->ctx_smpl_hdr == NULL) goto invalid_free;
1506
1507
1508
1509
1510 fmt = ctx->ctx_buf_fmt;
1511
1512 DPRINT(("sampling buffer @%p size %lu vaddr=%p\n",
1513 ctx->ctx_smpl_hdr,
1514 ctx->ctx_smpl_size,
1515 ctx->ctx_smpl_vaddr));
1516
1517 pfm_buf_fmt_exit(fmt, current, NULL, NULL);
1518
1519
1520
1521
1522 pfm_rvfree(ctx->ctx_smpl_hdr, ctx->ctx_smpl_size);
1523
1524 ctx->ctx_smpl_hdr = NULL;
1525 ctx->ctx_smpl_size = 0UL;
1526
1527 return 0;
1528
1529invalid_free:
1530 printk(KERN_ERR "perfmon: pfm_free_smpl_buffer [%d] no buffer\n", task_pid_nr(current));
1531 return -EINVAL;
1532}
1533#endif
1534
1535static inline void
1536pfm_exit_smpl_buffer(pfm_buffer_fmt_t *fmt)
1537{
1538 if (fmt == NULL) return;
1539
1540 pfm_buf_fmt_exit(fmt, current, NULL, NULL);
1541
1542}
1543
1544
1545
1546
1547
1548
1549
1550static struct vfsmount *pfmfs_mnt;
1551
1552static int __init
1553init_pfm_fs(void)
1554{
1555 int err = register_filesystem(&pfm_fs_type);
1556 if (!err) {
1557 pfmfs_mnt = kern_mount(&pfm_fs_type);
1558 err = PTR_ERR(pfmfs_mnt);
1559 if (IS_ERR(pfmfs_mnt))
1560 unregister_filesystem(&pfm_fs_type);
1561 else
1562 err = 0;
1563 }
1564 return err;
1565}
1566
1567static ssize_t
1568pfm_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
1569{
1570 pfm_context_t *ctx;
1571 pfm_msg_t *msg;
1572 ssize_t ret;
1573 unsigned long flags;
1574 DECLARE_WAITQUEUE(wait, current);
1575 if (PFM_IS_FILE(filp) == 0) {
1576 printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", task_pid_nr(current));
1577 return -EINVAL;
1578 }
1579
1580 ctx = (pfm_context_t *)filp->private_data;
1581 if (ctx == NULL) {
1582 printk(KERN_ERR "perfmon: pfm_read: NULL ctx [%d]\n", task_pid_nr(current));
1583 return -EINVAL;
1584 }
1585
1586
1587
1588
1589 if (size < sizeof(pfm_msg_t)) {
1590 DPRINT(("message is too small ctx=%p (>=%ld)\n", ctx, sizeof(pfm_msg_t)));
1591 return -EINVAL;
1592 }
1593
1594 PROTECT_CTX(ctx, flags);
1595
1596
1597
1598
1599 add_wait_queue(&ctx->ctx_msgq_wait, &wait);
1600
1601
1602 for(;;) {
1603
1604
1605
1606
1607 set_current_state(TASK_INTERRUPTIBLE);
1608
1609 DPRINT(("head=%d tail=%d\n", ctx->ctx_msgq_head, ctx->ctx_msgq_tail));
1610
1611 ret = 0;
1612 if(PFM_CTXQ_EMPTY(ctx) == 0) break;
1613
1614 UNPROTECT_CTX(ctx, flags);
1615
1616
1617
1618
1619 ret = -EAGAIN;
1620 if(filp->f_flags & O_NONBLOCK) break;
1621
1622
1623
1624
1625 if(signal_pending(current)) {
1626 ret = -EINTR;
1627 break;
1628 }
1629
1630
1631
1632 schedule();
1633
1634 PROTECT_CTX(ctx, flags);
1635 }
1636 DPRINT(("[%d] back to running ret=%ld\n", task_pid_nr(current), ret));
1637 set_current_state(TASK_RUNNING);
1638 remove_wait_queue(&ctx->ctx_msgq_wait, &wait);
1639
1640 if (ret < 0) goto abort;
1641
1642 ret = -EINVAL;
1643 msg = pfm_get_next_msg(ctx);
1644 if (msg == NULL) {
1645 printk(KERN_ERR "perfmon: pfm_read no msg for ctx=%p [%d]\n", ctx, task_pid_nr(current));
1646 goto abort_locked;
1647 }
1648
1649 DPRINT(("fd=%d type=%d\n", msg->pfm_gen_msg.msg_ctx_fd, msg->pfm_gen_msg.msg_type));
1650
1651 ret = -EFAULT;
1652 if(copy_to_user(buf, msg, sizeof(pfm_msg_t)) == 0) ret = sizeof(pfm_msg_t);
1653
1654abort_locked:
1655 UNPROTECT_CTX(ctx, flags);
1656abort:
1657 return ret;
1658}
1659
1660static ssize_t
1661pfm_write(struct file *file, const char __user *ubuf,
1662 size_t size, loff_t *ppos)
1663{
1664 DPRINT(("pfm_write called\n"));
1665 return -EINVAL;
1666}
1667
1668static unsigned int
1669pfm_poll(struct file *filp, poll_table * wait)
1670{
1671 pfm_context_t *ctx;
1672 unsigned long flags;
1673 unsigned int mask = 0;
1674
1675 if (PFM_IS_FILE(filp) == 0) {
1676 printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", task_pid_nr(current));
1677 return 0;
1678 }
1679
1680 ctx = (pfm_context_t *)filp->private_data;
1681 if (ctx == NULL) {
1682 printk(KERN_ERR "perfmon: pfm_poll: NULL ctx [%d]\n", task_pid_nr(current));
1683 return 0;
1684 }
1685
1686
1687 DPRINT(("pfm_poll ctx_fd=%d before poll_wait\n", ctx->ctx_fd));
1688
1689 poll_wait(filp, &ctx->ctx_msgq_wait, wait);
1690
1691 PROTECT_CTX(ctx, flags);
1692
1693 if (PFM_CTXQ_EMPTY(ctx) == 0)
1694 mask = POLLIN | POLLRDNORM;
1695
1696 UNPROTECT_CTX(ctx, flags);
1697
1698 DPRINT(("pfm_poll ctx_fd=%d mask=0x%x\n", ctx->ctx_fd, mask));
1699
1700 return mask;
1701}
1702
1703static int
1704pfm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
1705{
1706 DPRINT(("pfm_ioctl called\n"));
1707 return -EINVAL;
1708}
1709
1710
1711
1712
1713static inline int
1714pfm_do_fasync(int fd, struct file *filp, pfm_context_t *ctx, int on)
1715{
1716 int ret;
1717
1718 ret = fasync_helper (fd, filp, on, &ctx->ctx_async_queue);
1719
1720 DPRINT(("pfm_fasync called by [%d] on ctx_fd=%d on=%d async_queue=%p ret=%d\n",
1721 task_pid_nr(current),
1722 fd,
1723 on,
1724 ctx->ctx_async_queue, ret));
1725
1726 return ret;
1727}
1728
1729static int
1730pfm_fasync(int fd, struct file *filp, int on)
1731{
1732 pfm_context_t *ctx;
1733 int ret;
1734
1735 if (PFM_IS_FILE(filp) == 0) {
1736 printk(KERN_ERR "perfmon: pfm_fasync bad magic [%d]\n", task_pid_nr(current));
1737 return -EBADF;
1738 }
1739
1740 ctx = (pfm_context_t *)filp->private_data;
1741 if (ctx == NULL) {
1742 printk(KERN_ERR "perfmon: pfm_fasync NULL ctx [%d]\n", task_pid_nr(current));
1743 return -EBADF;
1744 }
1745
1746
1747
1748
1749
1750
1751
1752 ret = pfm_do_fasync(fd, filp, ctx, on);
1753
1754
1755 DPRINT(("pfm_fasync called on ctx_fd=%d on=%d async_queue=%p ret=%d\n",
1756 fd,
1757 on,
1758 ctx->ctx_async_queue, ret));
1759
1760 return ret;
1761}
1762
1763#ifdef CONFIG_SMP
1764
1765
1766
1767
1768
1769static void
1770pfm_syswide_force_stop(void *info)
1771{
1772 pfm_context_t *ctx = (pfm_context_t *)info;
1773 struct pt_regs *regs = task_pt_regs(current);
1774 struct task_struct *owner;
1775 unsigned long flags;
1776 int ret;
1777
1778 if (ctx->ctx_cpu != smp_processor_id()) {
1779 printk(KERN_ERR "perfmon: pfm_syswide_force_stop for CPU%d but on CPU%d\n",
1780 ctx->ctx_cpu,
1781 smp_processor_id());
1782 return;
1783 }
1784 owner = GET_PMU_OWNER();
1785 if (owner != ctx->ctx_task) {
1786 printk(KERN_ERR "perfmon: pfm_syswide_force_stop CPU%d unexpected owner [%d] instead of [%d]\n",
1787 smp_processor_id(),
1788 task_pid_nr(owner), task_pid_nr(ctx->ctx_task));
1789 return;
1790 }
1791 if (GET_PMU_CTX() != ctx) {
1792 printk(KERN_ERR "perfmon: pfm_syswide_force_stop CPU%d unexpected ctx %p instead of %p\n",
1793 smp_processor_id(),
1794 GET_PMU_CTX(), ctx);
1795 return;
1796 }
1797
1798 DPRINT(("on CPU%d forcing system wide stop for [%d]\n", smp_processor_id(), task_pid_nr(ctx->ctx_task)));
1799
1800
1801
1802
1803
1804 local_irq_save(flags);
1805
1806 ret = pfm_context_unload(ctx, NULL, 0, regs);
1807 if (ret) {
1808 DPRINT(("context_unload returned %d\n", ret));
1809 }
1810
1811
1812
1813
1814 local_irq_restore(flags);
1815}
1816
1817static void
1818pfm_syswide_cleanup_other_cpu(pfm_context_t *ctx)
1819{
1820 int ret;
1821
1822 DPRINT(("calling CPU%d for cleanup\n", ctx->ctx_cpu));
1823 ret = smp_call_function_single(ctx->ctx_cpu, pfm_syswide_force_stop, ctx, 1);
1824 DPRINT(("called CPU%d for cleanup ret=%d\n", ctx->ctx_cpu, ret));
1825}
1826#endif
1827
1828
1829
1830
1831
1832static int
1833pfm_flush(struct file *filp, fl_owner_t id)
1834{
1835 pfm_context_t *ctx;
1836 struct task_struct *task;
1837 struct pt_regs *regs;
1838 unsigned long flags;
1839 unsigned long smpl_buf_size = 0UL;
1840 void *smpl_buf_vaddr = NULL;
1841 int state, is_system;
1842
1843 if (PFM_IS_FILE(filp) == 0) {
1844 DPRINT(("bad magic for\n"));
1845 return -EBADF;
1846 }
1847
1848 ctx = (pfm_context_t *)filp->private_data;
1849 if (ctx == NULL) {
1850 printk(KERN_ERR "perfmon: pfm_flush: NULL ctx [%d]\n", task_pid_nr(current));
1851 return -EBADF;
1852 }
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867 PROTECT_CTX(ctx, flags);
1868
1869 state = ctx->ctx_state;
1870 is_system = ctx->ctx_fl_system;
1871
1872 task = PFM_CTX_TASK(ctx);
1873 regs = task_pt_regs(task);
1874
1875 DPRINT(("ctx_state=%d is_current=%d\n",
1876 state,
1877 task == current ? 1 : 0));
1878
1879
1880
1881
1882
1883
1884
1885
1886 if (task == current) {
1887#ifdef CONFIG_SMP
1888
1889
1890
1891
1892
1893
1894
1895 if (is_system && ctx->ctx_cpu != smp_processor_id()) {
1896
1897 DPRINT(("should be running on CPU%d\n", ctx->ctx_cpu));
1898
1899
1900
1901 local_irq_restore(flags);
1902
1903 pfm_syswide_cleanup_other_cpu(ctx);
1904
1905
1906
1907
1908 local_irq_save(flags);
1909
1910
1911
1912
1913 } else
1914#endif
1915 {
1916
1917 DPRINT(("forcing unload\n"));
1918
1919
1920
1921
1922 pfm_context_unload(ctx, NULL, 0, regs);
1923
1924 DPRINT(("ctx_state=%d\n", ctx->ctx_state));
1925 }
1926 }
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939 if (ctx->ctx_smpl_vaddr && current->mm) {
1940 smpl_buf_vaddr = ctx->ctx_smpl_vaddr;
1941 smpl_buf_size = ctx->ctx_smpl_size;
1942 }
1943
1944 UNPROTECT_CTX(ctx, flags);
1945
1946
1947
1948
1949
1950
1951
1952 if (smpl_buf_vaddr) pfm_remove_smpl_mapping(current, smpl_buf_vaddr, smpl_buf_size);
1953
1954 return 0;
1955}
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971static int
1972pfm_close(struct inode *inode, struct file *filp)
1973{
1974 pfm_context_t *ctx;
1975 struct task_struct *task;
1976 struct pt_regs *regs;
1977 DECLARE_WAITQUEUE(wait, current);
1978 unsigned long flags;
1979 unsigned long smpl_buf_size = 0UL;
1980 void *smpl_buf_addr = NULL;
1981 int free_possible = 1;
1982 int state, is_system;
1983
1984 DPRINT(("pfm_close called private=%p\n", filp->private_data));
1985
1986 if (PFM_IS_FILE(filp) == 0) {
1987 DPRINT(("bad magic\n"));
1988 return -EBADF;
1989 }
1990
1991 ctx = (pfm_context_t *)filp->private_data;
1992 if (ctx == NULL) {
1993 printk(KERN_ERR "perfmon: pfm_close: NULL ctx [%d]\n", task_pid_nr(current));
1994 return -EBADF;
1995 }
1996
1997 if (filp->f_flags & FASYNC) {
1998 DPRINT(("cleaning up async_queue=%p\n", ctx->ctx_async_queue));
1999 pfm_do_fasync(-1, filp, ctx, 0);
2000 }
2001
2002 PROTECT_CTX(ctx, flags);
2003
2004 state = ctx->ctx_state;
2005 is_system = ctx->ctx_fl_system;
2006
2007 task = PFM_CTX_TASK(ctx);
2008 regs = task_pt_regs(task);
2009
2010 DPRINT(("ctx_state=%d is_current=%d\n",
2011 state,
2012 task == current ? 1 : 0));
2013
2014
2015
2016
2017 if (state == PFM_CTX_UNLOADED) goto doit;
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031 if (state == PFM_CTX_MASKED && CTX_OVFL_NOBLOCK(ctx) == 0) {
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047 ctx->ctx_fl_going_zombie = 1;
2048
2049
2050
2051
2052 complete(&ctx->ctx_restart_done);
2053
2054 DPRINT(("waking up ctx_state=%d\n", state));
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064 set_current_state(TASK_INTERRUPTIBLE);
2065 add_wait_queue(&ctx->ctx_zombieq, &wait);
2066
2067 UNPROTECT_CTX(ctx, flags);
2068
2069
2070
2071
2072
2073
2074 schedule();
2075
2076
2077 PROTECT_CTX(ctx, flags);
2078
2079
2080 remove_wait_queue(&ctx->ctx_zombieq, &wait);
2081 set_current_state(TASK_RUNNING);
2082
2083
2084
2085
2086 DPRINT(("after zombie wakeup ctx_state=%d for\n", state));
2087 }
2088 else if (task != current) {
2089#ifdef CONFIG_SMP
2090
2091
2092
2093 ctx->ctx_state = PFM_CTX_ZOMBIE;
2094
2095 DPRINT(("zombie ctx for [%d]\n", task_pid_nr(task)));
2096
2097
2098
2099
2100 free_possible = 0;
2101#else
2102 pfm_context_unload(ctx, NULL, 0, regs);
2103#endif
2104 }
2105
2106doit:
2107
2108 state = ctx->ctx_state;
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124 if (ctx->ctx_smpl_hdr) {
2125 smpl_buf_addr = ctx->ctx_smpl_hdr;
2126 smpl_buf_size = ctx->ctx_smpl_size;
2127
2128 ctx->ctx_smpl_hdr = NULL;
2129 ctx->ctx_fl_is_sampling = 0;
2130 }
2131
2132 DPRINT(("ctx_state=%d free_possible=%d addr=%p size=%lu\n",
2133 state,
2134 free_possible,
2135 smpl_buf_addr,
2136 smpl_buf_size));
2137
2138 if (smpl_buf_addr) pfm_exit_smpl_buffer(ctx->ctx_buf_fmt);
2139
2140
2141
2142
2143 if (state == PFM_CTX_ZOMBIE) {
2144 pfm_unreserve_session(ctx, ctx->ctx_fl_system , ctx->ctx_cpu);
2145 }
2146
2147
2148
2149
2150
2151 filp->private_data = NULL;
2152
2153
2154
2155
2156
2157
2158
2159
2160 UNPROTECT_CTX(ctx, flags);
2161
2162
2163
2164
2165
2166 if (smpl_buf_addr) pfm_rvfree(smpl_buf_addr, smpl_buf_size);
2167
2168
2169
2170
2171 if (free_possible) pfm_context_free(ctx);
2172
2173 return 0;
2174}
2175
2176static int
2177pfm_no_open(struct inode *irrelevant, struct file *dontcare)
2178{
2179 DPRINT(("pfm_no_open called\n"));
2180 return -ENXIO;
2181}
2182
2183
2184
2185static const struct file_operations pfm_file_ops = {
2186 .llseek = no_llseek,
2187 .read = pfm_read,
2188 .write = pfm_write,
2189 .poll = pfm_poll,
2190 .ioctl = pfm_ioctl,
2191 .open = pfm_no_open,
2192 .fasync = pfm_fasync,
2193 .release = pfm_close,
2194 .flush = pfm_flush
2195};
2196
2197static int
2198pfmfs_delete_dentry(struct dentry *dentry)
2199{
2200 return 1;
2201}
2202
2203static struct dentry_operations pfmfs_dentry_operations = {
2204 .d_delete = pfmfs_delete_dentry,
2205};
2206
2207
2208static struct file *
2209pfm_alloc_file(pfm_context_t *ctx)
2210{
2211 struct file *file;
2212 struct inode *inode;
2213 struct dentry *dentry;
2214 char name[32];
2215 struct qstr this;
2216
2217
2218
2219
2220 inode = new_inode(pfmfs_mnt->mnt_sb);
2221 if (!inode)
2222 return ERR_PTR(-ENOMEM);
2223
2224 DPRINT(("new inode ino=%ld @%p\n", inode->i_ino, inode));
2225
2226 inode->i_mode = S_IFCHR|S_IRUGO;
2227 inode->i_uid = current->fsuid;
2228 inode->i_gid = current->fsgid;
2229
2230 sprintf(name, "[%lu]", inode->i_ino);
2231 this.name = name;
2232 this.len = strlen(name);
2233 this.hash = inode->i_ino;
2234
2235
2236
2237
2238 dentry = d_alloc(pfmfs_mnt->mnt_sb->s_root, &this);
2239 if (!dentry) {
2240 iput(inode);
2241 return ERR_PTR(-ENOMEM);
2242 }
2243
2244 dentry->d_op = &pfmfs_dentry_operations;
2245 d_add(dentry, inode);
2246
2247 file = alloc_file(pfmfs_mnt, dentry, FMODE_READ, &pfm_file_ops);
2248 if (!file) {
2249 dput(dentry);
2250 return ERR_PTR(-ENFILE);
2251 }
2252
2253 file->f_flags = O_RDONLY;
2254 file->private_data = ctx;
2255
2256 return file;
2257}
2258
2259static int
2260pfm_remap_buffer(struct vm_area_struct *vma, unsigned long buf, unsigned long addr, unsigned long size)
2261{
2262 DPRINT(("CPU%d buf=0x%lx addr=0x%lx size=%ld\n", smp_processor_id(), buf, addr, size));
2263
2264 while (size > 0) {
2265 unsigned long pfn = ia64_tpa(buf) >> PAGE_SHIFT;
2266
2267
2268 if (remap_pfn_range(vma, addr, pfn, PAGE_SIZE, PAGE_READONLY))
2269 return -ENOMEM;
2270
2271 addr += PAGE_SIZE;
2272 buf += PAGE_SIZE;
2273 size -= PAGE_SIZE;
2274 }
2275 return 0;
2276}
2277
2278
2279
2280
2281static int
2282pfm_smpl_buffer_alloc(struct task_struct *task, struct file *filp, pfm_context_t *ctx, unsigned long rsize, void **user_vaddr)
2283{
2284 struct mm_struct *mm = task->mm;
2285 struct vm_area_struct *vma = NULL;
2286 unsigned long size;
2287 void *smpl_buf;
2288
2289
2290
2291
2292
2293 size = PAGE_ALIGN(rsize);
2294
2295 DPRINT(("sampling buffer rsize=%lu size=%lu bytes\n", rsize, size));
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305 if (size > task->signal->rlim[RLIMIT_MEMLOCK].rlim_cur)
2306 return -ENOMEM;
2307
2308
2309
2310
2311
2312
2313 smpl_buf = pfm_rvmalloc(size);
2314 if (smpl_buf == NULL) {
2315 DPRINT(("Can't allocate sampling buffer\n"));
2316 return -ENOMEM;
2317 }
2318
2319 DPRINT(("smpl_buf @%p\n", smpl_buf));
2320
2321
2322 vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
2323 if (!vma) {
2324 DPRINT(("Cannot allocate vma\n"));
2325 goto error_kmem;
2326 }
2327
2328
2329
2330
2331 vma->vm_mm = mm;
2332 vma->vm_file = filp;
2333 vma->vm_flags = VM_READ| VM_MAYREAD |VM_RESERVED;
2334 vma->vm_page_prot = PAGE_READONLY;
2335
2336
2337
2338
2339
2340
2341 ctx->ctx_smpl_hdr = smpl_buf;
2342 ctx->ctx_smpl_size = size;
2343
2344
2345
2346
2347
2348
2349
2350 down_write(&task->mm->mmap_sem);
2351
2352
2353 vma->vm_start = pfm_get_unmapped_area(NULL, 0, size, 0, MAP_PRIVATE|MAP_ANONYMOUS, 0);
2354 if (vma->vm_start == 0UL) {
2355 DPRINT(("Cannot find unmapped area for size %ld\n", size));
2356 up_write(&task->mm->mmap_sem);
2357 goto error;
2358 }
2359 vma->vm_end = vma->vm_start + size;
2360 vma->vm_pgoff = vma->vm_start >> PAGE_SHIFT;
2361
2362 DPRINT(("aligned size=%ld, hdr=%p mapped @0x%lx\n", size, ctx->ctx_smpl_hdr, vma->vm_start));
2363
2364
2365 if (pfm_remap_buffer(vma, (unsigned long)smpl_buf, vma->vm_start, size)) {
2366 DPRINT(("Can't remap buffer\n"));
2367 up_write(&task->mm->mmap_sem);
2368 goto error;
2369 }
2370
2371 get_file(filp);
2372
2373
2374
2375
2376
2377 insert_vm_struct(mm, vma);
2378
2379 mm->total_vm += size >> PAGE_SHIFT;
2380 vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file,
2381 vma_pages(vma));
2382 up_write(&task->mm->mmap_sem);
2383
2384
2385
2386
2387 ctx->ctx_smpl_vaddr = (void *)vma->vm_start;
2388 *(unsigned long *)user_vaddr = vma->vm_start;
2389
2390 return 0;
2391
2392error:
2393 kmem_cache_free(vm_area_cachep, vma);
2394error_kmem:
2395 pfm_rvfree(smpl_buf, size);
2396
2397 return -ENOMEM;
2398}
2399
2400
2401
2402
2403static int
2404pfm_bad_permissions(struct task_struct *task)
2405{
2406
2407 DPRINT(("cur: uid=%d gid=%d task: euid=%d suid=%d uid=%d egid=%d sgid=%d\n",
2408 current->uid,
2409 current->gid,
2410 task->euid,
2411 task->suid,
2412 task->uid,
2413 task->egid,
2414 task->sgid));
2415
2416 return ((current->uid != task->euid)
2417 || (current->uid != task->suid)
2418 || (current->uid != task->uid)
2419 || (current->gid != task->egid)
2420 || (current->gid != task->sgid)
2421 || (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE);
2422}
2423
2424static int
2425pfarg_is_sane(struct task_struct *task, pfarg_context_t *pfx)
2426{
2427 int ctx_flags;
2428
2429
2430
2431 ctx_flags = pfx->ctx_flags;
2432
2433 if (ctx_flags & PFM_FL_SYSTEM_WIDE) {
2434
2435
2436
2437
2438 if (ctx_flags & PFM_FL_NOTIFY_BLOCK) {
2439 DPRINT(("cannot use blocking mode when in system wide monitoring\n"));
2440 return -EINVAL;
2441 }
2442 } else {
2443 }
2444
2445
2446 return 0;
2447}
2448
2449static int
2450pfm_setup_buffer_fmt(struct task_struct *task, struct file *filp, pfm_context_t *ctx, unsigned int ctx_flags,
2451 unsigned int cpu, pfarg_context_t *arg)
2452{
2453 pfm_buffer_fmt_t *fmt = NULL;
2454 unsigned long size = 0UL;
2455 void *uaddr = NULL;
2456 void *fmt_arg = NULL;
2457 int ret = 0;
2458#define PFM_CTXARG_BUF_ARG(a) (pfm_buffer_fmt_t *)(a+1)
2459
2460
2461 fmt = pfm_find_buffer_fmt(arg->ctx_smpl_buf_id);
2462 if (fmt == NULL) {
2463 DPRINT(("[%d] cannot find buffer format\n", task_pid_nr(task)));
2464 return -EINVAL;
2465 }
2466
2467
2468
2469
2470 if (fmt->fmt_arg_size) fmt_arg = PFM_CTXARG_BUF_ARG(arg);
2471
2472 ret = pfm_buf_fmt_validate(fmt, task, ctx_flags, cpu, fmt_arg);
2473
2474 DPRINT(("[%d] after validate(0x%x,%d,%p)=%d\n", task_pid_nr(task), ctx_flags, cpu, fmt_arg, ret));
2475
2476 if (ret) goto error;
2477
2478
2479 ctx->ctx_buf_fmt = fmt;
2480 ctx->ctx_fl_is_sampling = 1;
2481
2482
2483
2484
2485 ret = pfm_buf_fmt_getsize(fmt, task, ctx_flags, cpu, fmt_arg, &size);
2486 if (ret) goto error;
2487
2488 if (size) {
2489
2490
2491
2492 ret = pfm_smpl_buffer_alloc(current, filp, ctx, size, &uaddr);
2493 if (ret) goto error;
2494
2495
2496 arg->ctx_smpl_vaddr = uaddr;
2497 }
2498 ret = pfm_buf_fmt_init(fmt, task, ctx->ctx_smpl_hdr, ctx_flags, cpu, fmt_arg);
2499
2500error:
2501 return ret;
2502}
2503
2504static void
2505pfm_reset_pmu_state(pfm_context_t *ctx)
2506{
2507 int i;
2508
2509
2510
2511
2512 for (i=1; PMC_IS_LAST(i) == 0; i++) {
2513 if (PMC_IS_IMPL(i) == 0) continue;
2514 ctx->ctx_pmcs[i] = PMC_DFL_VAL(i);
2515 DPRINT(("pmc[%d]=0x%lx\n", i, ctx->ctx_pmcs[i]));
2516 }
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544 ctx->ctx_all_pmcs[0] = pmu_conf->impl_pmcs[0] & ~0x1;
2545
2546
2547
2548
2549 ctx->ctx_all_pmds[0] = pmu_conf->impl_pmds[0];
2550
2551 DPRINT(("<%d> all_pmcs=0x%lx all_pmds=0x%lx\n", ctx->ctx_fd, ctx->ctx_all_pmcs[0],ctx->ctx_all_pmds[0]));
2552
2553
2554
2555
2556 ctx->ctx_used_ibrs[0] = 0UL;
2557 ctx->ctx_used_dbrs[0] = 0UL;
2558}
2559
2560static int
2561pfm_ctx_getsize(void *arg, size_t *sz)
2562{
2563 pfarg_context_t *req = (pfarg_context_t *)arg;
2564 pfm_buffer_fmt_t *fmt;
2565
2566 *sz = 0;
2567
2568 if (!pfm_uuid_cmp(req->ctx_smpl_buf_id, pfm_null_uuid)) return 0;
2569
2570 fmt = pfm_find_buffer_fmt(req->ctx_smpl_buf_id);
2571 if (fmt == NULL) {
2572 DPRINT(("cannot find buffer format\n"));
2573 return -EINVAL;
2574 }
2575
2576 *sz = fmt->fmt_arg_size;
2577 DPRINT(("arg_size=%lu\n", *sz));
2578
2579 return 0;
2580}
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590static int
2591pfm_task_incompatible(pfm_context_t *ctx, struct task_struct *task)
2592{
2593
2594
2595
2596 if (task->mm == NULL) {
2597 DPRINT(("task [%d] has not memory context (kernel thread)\n", task_pid_nr(task)));
2598 return -EPERM;
2599 }
2600 if (pfm_bad_permissions(task)) {
2601 DPRINT(("no permission to attach to [%d]\n", task_pid_nr(task)));
2602 return -EPERM;
2603 }
2604
2605
2606
2607 if (CTX_OVFL_NOBLOCK(ctx) == 0 && task == current) {
2608 DPRINT(("cannot load a blocking context on self for [%d]\n", task_pid_nr(task)));
2609 return -EINVAL;
2610 }
2611
2612 if (task->exit_state == EXIT_ZOMBIE) {
2613 DPRINT(("cannot attach to zombie task [%d]\n", task_pid_nr(task)));
2614 return -EBUSY;
2615 }
2616
2617
2618
2619
2620 if (task == current) return 0;
2621
2622 if (!task_is_stopped_or_traced(task)) {
2623 DPRINT(("cannot attach to non-stopped task [%d] state=%ld\n", task_pid_nr(task), task->state));
2624 return -EBUSY;
2625 }
2626
2627
2628
2629 wait_task_inactive(task, 0);
2630
2631
2632
2633 return 0;
2634}
2635
2636static int
2637pfm_get_task(pfm_context_t *ctx, pid_t pid, struct task_struct **task)
2638{
2639 struct task_struct *p = current;
2640 int ret;
2641
2642
2643 if (pid < 2) return -EPERM;
2644
2645 if (pid != task_pid_vnr(current)) {
2646
2647 read_lock(&tasklist_lock);
2648
2649 p = find_task_by_vpid(pid);
2650
2651
2652 if (p) get_task_struct(p);
2653
2654 read_unlock(&tasklist_lock);
2655
2656 if (p == NULL) return -ESRCH;
2657 }
2658
2659 ret = pfm_task_incompatible(ctx, p);
2660 if (ret == 0) {
2661 *task = p;
2662 } else if (p != current) {
2663 pfm_put_task(p);
2664 }
2665 return ret;
2666}
2667
2668
2669
2670static int
2671pfm_context_create(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
2672{
2673 pfarg_context_t *req = (pfarg_context_t *)arg;
2674 struct file *filp;
2675 struct path path;
2676 int ctx_flags;
2677 int fd;
2678 int ret;
2679
2680
2681 ret = pfarg_is_sane(current, req);
2682 if (ret < 0)
2683 return ret;
2684
2685 ctx_flags = req->ctx_flags;
2686
2687 ret = -ENOMEM;
2688
2689 fd = get_unused_fd();
2690 if (fd < 0)
2691 return fd;
2692
2693 ctx = pfm_context_alloc(ctx_flags);
2694 if (!ctx)
2695 goto error;
2696
2697 filp = pfm_alloc_file(ctx);
2698 if (IS_ERR(filp)) {
2699 ret = PTR_ERR(filp);
2700 goto error_file;
2701 }
2702
2703 req->ctx_fd = ctx->ctx_fd = fd;
2704
2705
2706
2707
2708 if (pfm_uuid_cmp(req->ctx_smpl_buf_id, pfm_null_uuid)) {
2709 ret = pfm_setup_buffer_fmt(current, filp, ctx, ctx_flags, 0, req);
2710 if (ret)
2711 goto buffer_error;
2712 }
2713
2714 DPRINT(("ctx=%p flags=0x%x system=%d notify_block=%d excl_idle=%d no_msg=%d ctx_fd=%d \n",
2715 ctx,
2716 ctx_flags,
2717 ctx->ctx_fl_system,
2718 ctx->ctx_fl_block,
2719 ctx->ctx_fl_excl_idle,
2720 ctx->ctx_fl_no_msg,
2721 ctx->ctx_fd));
2722
2723
2724
2725
2726 pfm_reset_pmu_state(ctx);
2727
2728 fd_install(fd, filp);
2729
2730 return 0;
2731
2732buffer_error:
2733 path = filp->f_path;
2734 put_filp(filp);
2735 path_put(&path);
2736
2737 if (ctx->ctx_buf_fmt) {
2738 pfm_buf_fmt_exit(ctx->ctx_buf_fmt, current, NULL, regs);
2739 }
2740error_file:
2741 pfm_context_free(ctx);
2742
2743error:
2744 put_unused_fd(fd);
2745 return ret;
2746}
2747
2748static inline unsigned long
2749pfm_new_counter_value (pfm_counter_t *reg, int is_long_reset)
2750{
2751 unsigned long val = is_long_reset ? reg->long_reset : reg->short_reset;
2752 unsigned long new_seed, old_seed = reg->seed, mask = reg->mask;
2753 extern unsigned long carta_random32 (unsigned long seed);
2754
2755 if (reg->flags & PFM_REGFL_RANDOM) {
2756 new_seed = carta_random32(old_seed);
2757 val -= (old_seed & mask);
2758 if ((mask >> 32) != 0)
2759
2760 new_seed |= carta_random32(old_seed >> 32) << 32;
2761 reg->seed = new_seed;
2762 }
2763 reg->lval = val;
2764 return val;
2765}
2766
2767static void
2768pfm_reset_regs_masked(pfm_context_t *ctx, unsigned long *ovfl_regs, int is_long_reset)
2769{
2770 unsigned long mask = ovfl_regs[0];
2771 unsigned long reset_others = 0UL;
2772 unsigned long val;
2773 int i;
2774
2775
2776
2777
2778 mask >>= PMU_FIRST_COUNTER;
2779 for(i = PMU_FIRST_COUNTER; mask; i++, mask >>= 1) {
2780
2781 if ((mask & 0x1UL) == 0UL) continue;
2782
2783 ctx->ctx_pmds[i].val = val = pfm_new_counter_value(ctx->ctx_pmds+ i, is_long_reset);
2784 reset_others |= ctx->ctx_pmds[i].reset_pmds[0];
2785
2786 DPRINT_ovfl((" %s reset ctx_pmds[%d]=%lx\n", is_long_reset ? "long" : "short", i, val));
2787 }
2788
2789
2790
2791
2792 for(i = 0; reset_others; i++, reset_others >>= 1) {
2793
2794 if ((reset_others & 0x1) == 0) continue;
2795
2796 ctx->ctx_pmds[i].val = val = pfm_new_counter_value(ctx->ctx_pmds + i, is_long_reset);
2797
2798 DPRINT_ovfl(("%s reset_others pmd[%d]=%lx\n",
2799 is_long_reset ? "long" : "short", i, val));
2800 }
2801}
2802
2803static void
2804pfm_reset_regs(pfm_context_t *ctx, unsigned long *ovfl_regs, int is_long_reset)
2805{
2806 unsigned long mask = ovfl_regs[0];
2807 unsigned long reset_others = 0UL;
2808 unsigned long val;
2809 int i;
2810
2811 DPRINT_ovfl(("ovfl_regs=0x%lx is_long_reset=%d\n", ovfl_regs[0], is_long_reset));
2812
2813 if (ctx->ctx_state == PFM_CTX_MASKED) {
2814 pfm_reset_regs_masked(ctx, ovfl_regs, is_long_reset);
2815 return;
2816 }
2817
2818
2819
2820
2821 mask >>= PMU_FIRST_COUNTER;
2822 for(i = PMU_FIRST_COUNTER; mask; i++, mask >>= 1) {
2823
2824 if ((mask & 0x1UL) == 0UL) continue;
2825
2826 val = pfm_new_counter_value(ctx->ctx_pmds+ i, is_long_reset);
2827 reset_others |= ctx->ctx_pmds[i].reset_pmds[0];
2828
2829 DPRINT_ovfl((" %s reset ctx_pmds[%d]=%lx\n", is_long_reset ? "long" : "short", i, val));
2830
2831 pfm_write_soft_counter(ctx, i, val);
2832 }
2833
2834
2835
2836
2837 for(i = 0; reset_others; i++, reset_others >>= 1) {
2838
2839 if ((reset_others & 0x1) == 0) continue;
2840
2841 val = pfm_new_counter_value(ctx->ctx_pmds + i, is_long_reset);
2842
2843 if (PMD_IS_COUNTING(i)) {
2844 pfm_write_soft_counter(ctx, i, val);
2845 } else {
2846 ia64_set_pmd(i, val);
2847 }
2848 DPRINT_ovfl(("%s reset_others pmd[%d]=%lx\n",
2849 is_long_reset ? "long" : "short", i, val));
2850 }
2851 ia64_srlz_d();
2852}
2853
2854static int
2855pfm_write_pmcs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
2856{
2857 struct task_struct *task;
2858 pfarg_reg_t *req = (pfarg_reg_t *)arg;
2859 unsigned long value, pmc_pm;
2860 unsigned long smpl_pmds, reset_pmds, impl_pmds;
2861 unsigned int cnum, reg_flags, flags, pmc_type;
2862 int i, can_access_pmu = 0, is_loaded, is_system, expert_mode;
2863 int is_monitor, is_counting, state;
2864 int ret = -EINVAL;
2865 pfm_reg_check_t wr_func;
2866#define PFM_CHECK_PMC_PM(x, y, z) ((x)->ctx_fl_system ^ PMC_PM(y, z))
2867
2868 state = ctx->ctx_state;
2869 is_loaded = state == PFM_CTX_LOADED ? 1 : 0;
2870 is_system = ctx->ctx_fl_system;
2871 task = ctx->ctx_task;
2872 impl_pmds = pmu_conf->impl_pmds[0];
2873
2874 if (state == PFM_CTX_ZOMBIE) return -EINVAL;
2875
2876 if (is_loaded) {
2877
2878
2879
2880
2881
2882 if (is_system && ctx->ctx_cpu != smp_processor_id()) {
2883 DPRINT(("should be running on CPU%d\n", ctx->ctx_cpu));
2884 return -EBUSY;
2885 }
2886 can_access_pmu = GET_PMU_OWNER() == task || is_system ? 1 : 0;
2887 }
2888 expert_mode = pfm_sysctl.expert_mode;
2889
2890 for (i = 0; i < count; i++, req++) {
2891
2892 cnum = req->reg_num;
2893 reg_flags = req->reg_flags;
2894 value = req->reg_value;
2895 smpl_pmds = req->reg_smpl_pmds[0];
2896 reset_pmds = req->reg_reset_pmds[0];
2897 flags = 0;
2898
2899
2900 if (cnum >= PMU_MAX_PMCS) {
2901 DPRINT(("pmc%u is invalid\n", cnum));
2902 goto error;
2903 }
2904
2905 pmc_type = pmu_conf->pmc_desc[cnum].type;
2906 pmc_pm = (value >> pmu_conf->pmc_desc[cnum].pm_pos) & 0x1;
2907 is_counting = (pmc_type & PFM_REG_COUNTING) == PFM_REG_COUNTING ? 1 : 0;
2908 is_monitor = (pmc_type & PFM_REG_MONITOR) == PFM_REG_MONITOR ? 1 : 0;
2909
2910
2911
2912
2913
2914
2915 if ((pmc_type & PFM_REG_IMPL) == 0 || (pmc_type & PFM_REG_CONTROL) == PFM_REG_CONTROL) {
2916 DPRINT(("pmc%u is unimplemented or no-access pmc_type=%x\n", cnum, pmc_type));
2917 goto error;
2918 }
2919 wr_func = pmu_conf->pmc_desc[cnum].write_check;
2920
2921
2922
2923
2924
2925 if (is_monitor && value != PMC_DFL_VAL(cnum) && is_system ^ pmc_pm) {
2926 DPRINT(("pmc%u pmc_pm=%lu is_system=%d\n",
2927 cnum,
2928 pmc_pm,
2929 is_system));
2930 goto error;
2931 }
2932
2933 if (is_counting) {
2934
2935
2936
2937
2938 value |= 1 << PMU_PMC_OI;
2939
2940 if (reg_flags & PFM_REGFL_OVFL_NOTIFY) {
2941 flags |= PFM_REGFL_OVFL_NOTIFY;
2942 }
2943
2944 if (reg_flags & PFM_REGFL_RANDOM) flags |= PFM_REGFL_RANDOM;
2945
2946
2947 if ((smpl_pmds & impl_pmds) != smpl_pmds) {
2948 DPRINT(("invalid smpl_pmds 0x%lx for pmc%u\n", smpl_pmds, cnum));
2949 goto error;
2950 }
2951
2952
2953 if ((reset_pmds & impl_pmds) != reset_pmds) {
2954 DPRINT(("invalid reset_pmds 0x%lx for pmc%u\n", reset_pmds, cnum));
2955 goto error;
2956 }
2957 } else {
2958 if (reg_flags & (PFM_REGFL_OVFL_NOTIFY|PFM_REGFL_RANDOM)) {
2959 DPRINT(("cannot set ovfl_notify or random on pmc%u\n", cnum));
2960 goto error;
2961 }
2962
2963 }
2964
2965
2966
2967
2968 if (likely(expert_mode == 0 && wr_func)) {
2969 ret = (*wr_func)(task, ctx, cnum, &value, regs);
2970 if (ret) goto error;
2971 ret = -EINVAL;
2972 }
2973
2974
2975
2976
2977 PFM_REG_RETFLAG_SET(req->reg_flags, 0);
2978
2979
2980
2981
2982
2983
2984
2985
2986 if (is_counting) {
2987
2988
2989
2990 ctx->ctx_pmds[cnum].flags = flags;
2991
2992 ctx->ctx_pmds[cnum].reset_pmds[0] = reset_pmds;
2993 ctx->ctx_pmds[cnum].smpl_pmds[0] = smpl_pmds;
2994 ctx->ctx_pmds[cnum].eventid = req->reg_smpl_eventid;
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007 CTX_USED_PMD(ctx, reset_pmds);
3008 CTX_USED_PMD(ctx, smpl_pmds);
3009
3010
3011
3012
3013 if (state == PFM_CTX_MASKED) ctx->ctx_ovfl_regs[0] &= ~1UL << cnum;
3014 }
3015
3016
3017
3018
3019
3020 CTX_USED_PMD(ctx, pmu_conf->pmc_desc[cnum].dep_pmd[0]);
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034 if (is_monitor) CTX_USED_MONITOR(ctx, 1UL << cnum);
3035
3036
3037
3038
3039 ctx->ctx_pmcs[cnum] = value;
3040
3041 if (is_loaded) {
3042
3043
3044
3045 if (is_system == 0) ctx->th_pmcs[cnum] = value;
3046
3047
3048
3049
3050 if (can_access_pmu) {
3051 ia64_set_pmc(cnum, value);
3052 }
3053#ifdef CONFIG_SMP
3054 else {
3055
3056
3057
3058
3059
3060
3061
3062 ctx->ctx_reload_pmcs[0] |= 1UL << cnum;
3063 }
3064#endif
3065 }
3066
3067 DPRINT(("pmc[%u]=0x%lx ld=%d apmu=%d flags=0x%x all_pmcs=0x%lx used_pmds=0x%lx eventid=%ld smpl_pmds=0x%lx reset_pmds=0x%lx reloads_pmcs=0x%lx used_monitors=0x%lx ovfl_regs=0x%lx\n",
3068 cnum,
3069 value,
3070 is_loaded,
3071 can_access_pmu,
3072 flags,
3073 ctx->ctx_all_pmcs[0],
3074 ctx->ctx_used_pmds[0],
3075 ctx->ctx_pmds[cnum].eventid,
3076 smpl_pmds,
3077 reset_pmds,
3078 ctx->ctx_reload_pmcs[0],
3079 ctx->ctx_used_monitors[0],
3080 ctx->ctx_ovfl_regs[0]));
3081 }
3082
3083
3084
3085
3086 if (can_access_pmu) ia64_srlz_d();
3087
3088 return 0;
3089error:
3090 PFM_REG_RETFLAG_SET(req->reg_flags, PFM_REG_RETFL_EINVAL);
3091 return ret;
3092}
3093
3094static int
3095pfm_write_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
3096{
3097 struct task_struct *task;
3098 pfarg_reg_t *req = (pfarg_reg_t *)arg;
3099 unsigned long value, hw_value, ovfl_mask;
3100 unsigned int cnum;
3101 int i, can_access_pmu = 0, state;
3102 int is_counting, is_loaded, is_system, expert_mode;
3103 int ret = -EINVAL;
3104 pfm_reg_check_t wr_func;
3105
3106
3107 state = ctx->ctx_state;
3108 is_loaded = state == PFM_CTX_LOADED ? 1 : 0;
3109 is_system = ctx->ctx_fl_system;
3110 ovfl_mask = pmu_conf->ovfl_val;
3111 task = ctx->ctx_task;
3112
3113 if (unlikely(state == PFM_CTX_ZOMBIE)) return -EINVAL;
3114
3115
3116
3117
3118
3119 if (likely(is_loaded)) {
3120
3121
3122
3123
3124
3125 if (unlikely(is_system && ctx->ctx_cpu != smp_processor_id())) {
3126 DPRINT(("should be running on CPU%d\n", ctx->ctx_cpu));
3127 return -EBUSY;
3128 }
3129 can_access_pmu = GET_PMU_OWNER() == task || is_system ? 1 : 0;
3130 }
3131 expert_mode = pfm_sysctl.expert_mode;
3132
3133 for (i = 0; i < count; i++, req++) {
3134
3135 cnum = req->reg_num;
3136 value = req->reg_value;
3137
3138 if (!PMD_IS_IMPL(cnum)) {
3139 DPRINT(("pmd[%u] is unimplemented or invalid\n", cnum));
3140 goto abort_mission;
3141 }
3142 is_counting = PMD_IS_COUNTING(cnum);
3143 wr_func = pmu_conf->pmd_desc[cnum].write_check;
3144
3145
3146
3147
3148 if (unlikely(expert_mode == 0 && wr_func)) {
3149 unsigned long v = value;
3150
3151 ret = (*wr_func)(task, ctx, cnum, &v, regs);
3152 if (ret) goto abort_mission;
3153
3154 value = v;
3155 ret = -EINVAL;
3156 }
3157
3158
3159
3160
3161 PFM_REG_RETFLAG_SET(req->reg_flags, 0);
3162
3163
3164
3165
3166 hw_value = value;
3167
3168
3169
3170
3171 if (is_counting) {
3172
3173
3174
3175 ctx->ctx_pmds[cnum].lval = value;
3176
3177
3178
3179
3180 if (is_loaded) {
3181 hw_value = value & ovfl_mask;
3182 value = value & ~ovfl_mask;
3183 }
3184 }
3185
3186
3187
3188 ctx->ctx_pmds[cnum].long_reset = req->reg_long_reset;
3189 ctx->ctx_pmds[cnum].short_reset = req->reg_short_reset;
3190
3191
3192
3193
3194 ctx->ctx_pmds[cnum].seed = req->reg_random_seed;
3195 ctx->ctx_pmds[cnum].mask = req->reg_random_mask;
3196
3197
3198
3199
3200 ctx->ctx_pmds[cnum].val = value;
3201
3202
3203
3204
3205
3206
3207
3208 CTX_USED_PMD(ctx, PMD_PMD_DEP(cnum));
3209
3210
3211
3212
3213 CTX_USED_PMD(ctx, RDEP(cnum));
3214
3215
3216
3217
3218
3219 if (is_counting && state == PFM_CTX_MASKED) {
3220 ctx->ctx_ovfl_regs[0] &= ~1UL << cnum;
3221 }
3222
3223 if (is_loaded) {
3224
3225
3226
3227 if (is_system == 0) ctx->th_pmds[cnum] = hw_value;
3228
3229
3230
3231
3232 if (can_access_pmu) {
3233 ia64_set_pmd(cnum, hw_value);
3234 } else {
3235#ifdef CONFIG_SMP
3236
3237
3238
3239
3240
3241 ctx->ctx_reload_pmds[0] |= 1UL << cnum;
3242#endif
3243 }
3244 }
3245
3246 DPRINT(("pmd[%u]=0x%lx ld=%d apmu=%d, hw_value=0x%lx ctx_pmd=0x%lx short_reset=0x%lx "
3247 "long_reset=0x%lx notify=%c seed=0x%lx mask=0x%lx used_pmds=0x%lx reset_pmds=0x%lx reload_pmds=0x%lx all_pmds=0x%lx ovfl_regs=0x%lx\n",
3248 cnum,
3249 value,
3250 is_loaded,
3251 can_access_pmu,
3252 hw_value,
3253 ctx->ctx_pmds[cnum].val,
3254 ctx->ctx_pmds[cnum].short_reset,
3255 ctx->ctx_pmds[cnum].long_reset,
3256 PMC_OVFL_NOTIFY(ctx, cnum) ? 'Y':'N',
3257 ctx->ctx_pmds[cnum].seed,
3258 ctx->ctx_pmds[cnum].mask,
3259 ctx->ctx_used_pmds[0],
3260 ctx->ctx_pmds[cnum].reset_pmds[0],
3261 ctx->ctx_reload_pmds[0],
3262 ctx->ctx_all_pmds[0],
3263 ctx->ctx_ovfl_regs[0]));
3264 }
3265
3266
3267
3268
3269 if (can_access_pmu) ia64_srlz_d();
3270
3271 return 0;
3272
3273abort_mission:
3274
3275
3276
3277 PFM_REG_RETFLAG_SET(req->reg_flags, PFM_REG_RETFL_EINVAL);
3278 return ret;
3279}
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290static int
3291pfm_read_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
3292{
3293 struct task_struct *task;
3294 unsigned long val = 0UL, lval, ovfl_mask, sval;
3295 pfarg_reg_t *req = (pfarg_reg_t *)arg;
3296 unsigned int cnum, reg_flags = 0;
3297 int i, can_access_pmu = 0, state;
3298 int is_loaded, is_system, is_counting, expert_mode;
3299 int ret = -EINVAL;
3300 pfm_reg_check_t rd_func;
3301
3302
3303
3304
3305
3306
3307 state = ctx->ctx_state;
3308 is_loaded = state == PFM_CTX_LOADED ? 1 : 0;
3309 is_system = ctx->ctx_fl_system;
3310 ovfl_mask = pmu_conf->ovfl_val;
3311 task = ctx->ctx_task;
3312
3313 if (state == PFM_CTX_ZOMBIE) return -EINVAL;
3314
3315 if (likely(is_loaded)) {
3316
3317
3318
3319
3320
3321 if (unlikely(is_system && ctx->ctx_cpu != smp_processor_id())) {
3322 DPRINT(("should be running on CPU%d\n", ctx->ctx_cpu));
3323 return -EBUSY;
3324 }
3325
3326
3327
3328 can_access_pmu = GET_PMU_OWNER() == task || is_system ? 1 : 0;
3329
3330 if (can_access_pmu) ia64_srlz_d();
3331 }
3332 expert_mode = pfm_sysctl.expert_mode;
3333
3334 DPRINT(("ld=%d apmu=%d ctx_state=%d\n",
3335 is_loaded,
3336 can_access_pmu,
3337 state));
3338
3339
3340
3341
3342
3343
3344 for (i = 0; i < count; i++, req++) {
3345
3346 cnum = req->reg_num;
3347 reg_flags = req->reg_flags;
3348
3349 if (unlikely(!PMD_IS_IMPL(cnum))) goto error;
3350
3351
3352
3353
3354
3355
3356
3357
3358 if (unlikely(!CTX_IS_USED_PMD(ctx, cnum))) goto error;
3359
3360 sval = ctx->ctx_pmds[cnum].val;
3361 lval = ctx->ctx_pmds[cnum].lval;
3362 is_counting = PMD_IS_COUNTING(cnum);
3363
3364
3365
3366
3367
3368
3369 if (can_access_pmu){
3370 val = ia64_get_pmd(cnum);
3371 } else {
3372
3373
3374
3375
3376
3377 val = is_loaded ? ctx->th_pmds[cnum] : 0UL;
3378 }
3379 rd_func = pmu_conf->pmd_desc[cnum].read_check;
3380
3381 if (is_counting) {
3382
3383
3384
3385 val &= ovfl_mask;
3386 val += sval;
3387 }
3388
3389
3390
3391
3392 if (unlikely(expert_mode == 0 && rd_func)) {
3393 unsigned long v = val;
3394 ret = (*rd_func)(ctx->ctx_task, ctx, cnum, &v, regs);
3395 if (ret) goto error;
3396 val = v;
3397 ret = -EINVAL;
3398 }
3399
3400 PFM_REG_RETFLAG_SET(reg_flags, 0);
3401
3402 DPRINT(("pmd[%u]=0x%lx\n", cnum, val));
3403
3404
3405
3406
3407
3408
3409 req->reg_value = val;
3410 req->reg_flags = reg_flags;
3411 req->reg_last_reset_val = lval;
3412 }
3413
3414 return 0;
3415
3416error:
3417 PFM_REG_RETFLAG_SET(req->reg_flags, PFM_REG_RETFL_EINVAL);
3418 return ret;
3419}
3420
3421int
3422pfm_mod_write_pmcs(struct task_struct *task, void *req, unsigned int nreq, struct pt_regs *regs)
3423{
3424 pfm_context_t *ctx;
3425
3426 if (req == NULL) return -EINVAL;
3427
3428 ctx = GET_PMU_CTX();
3429
3430 if (ctx == NULL) return -EINVAL;
3431
3432
3433
3434
3435
3436 if (task != current && ctx->ctx_fl_system == 0) return -EBUSY;
3437
3438 return pfm_write_pmcs(ctx, req, nreq, regs);
3439}
3440EXPORT_SYMBOL(pfm_mod_write_pmcs);
3441
3442int
3443pfm_mod_read_pmds(struct task_struct *task, void *req, unsigned int nreq, struct pt_regs *regs)
3444{
3445 pfm_context_t *ctx;
3446
3447 if (req == NULL) return -EINVAL;
3448
3449 ctx = GET_PMU_CTX();
3450
3451 if (ctx == NULL) return -EINVAL;
3452
3453
3454
3455
3456
3457 if (task != current && ctx->ctx_fl_system == 0) return -EBUSY;
3458
3459 return pfm_read_pmds(ctx, req, nreq, regs);
3460}
3461EXPORT_SYMBOL(pfm_mod_read_pmds);
3462
3463
3464
3465
3466
3467int
3468pfm_use_debug_registers(struct task_struct *task)
3469{
3470 pfm_context_t *ctx = task->thread.pfm_context;
3471 unsigned long flags;
3472 int ret = 0;
3473
3474 if (pmu_conf->use_rr_dbregs == 0) return 0;
3475
3476 DPRINT(("called for [%d]\n", task_pid_nr(task)));
3477
3478
3479
3480
3481 if (task->thread.flags & IA64_THREAD_DBG_VALID) return 0;
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491 if (ctx && ctx->ctx_fl_using_dbreg == 1) return -1;
3492
3493 LOCK_PFS(flags);
3494
3495
3496
3497
3498
3499 if (pfm_sessions.pfs_sys_use_dbregs> 0)
3500 ret = -1;
3501 else
3502 pfm_sessions.pfs_ptrace_use_dbregs++;
3503
3504 DPRINT(("ptrace_use_dbregs=%u sys_use_dbregs=%u by [%d] ret = %d\n",
3505 pfm_sessions.pfs_ptrace_use_dbregs,
3506 pfm_sessions.pfs_sys_use_dbregs,
3507 task_pid_nr(task), ret));
3508
3509 UNLOCK_PFS(flags);
3510
3511 return ret;
3512}
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522int
3523pfm_release_debug_registers(struct task_struct *task)
3524{
3525 unsigned long flags;
3526 int ret;
3527
3528 if (pmu_conf->use_rr_dbregs == 0) return 0;
3529
3530 LOCK_PFS(flags);
3531 if (pfm_sessions.pfs_ptrace_use_dbregs == 0) {
3532 printk(KERN_ERR "perfmon: invalid release for [%d] ptrace_use_dbregs=0\n", task_pid_nr(task));
3533 ret = -1;
3534 } else {
3535 pfm_sessions.pfs_ptrace_use_dbregs--;
3536 ret = 0;
3537 }
3538 UNLOCK_PFS(flags);
3539
3540 return ret;
3541}
3542
3543static int
3544pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
3545{
3546 struct task_struct *task;
3547 pfm_buffer_fmt_t *fmt;
3548 pfm_ovfl_ctrl_t rst_ctrl;
3549 int state, is_system;
3550 int ret = 0;
3551
3552 state = ctx->ctx_state;
3553 fmt = ctx->ctx_buf_fmt;
3554 is_system = ctx->ctx_fl_system;
3555 task = PFM_CTX_TASK(ctx);
3556
3557 switch(state) {
3558 case PFM_CTX_MASKED:
3559 break;
3560 case PFM_CTX_LOADED:
3561 if (CTX_HAS_SMPL(ctx) && fmt->fmt_restart_active) break;
3562
3563 case PFM_CTX_UNLOADED:
3564 case PFM_CTX_ZOMBIE:
3565 DPRINT(("invalid state=%d\n", state));
3566 return -EBUSY;
3567 default:
3568 DPRINT(("state=%d, cannot operate (no active_restart handler)\n", state));
3569 return -EINVAL;
3570 }
3571
3572
3573
3574
3575
3576
3577 if (is_system && ctx->ctx_cpu != smp_processor_id()) {
3578 DPRINT(("should be running on CPU%d\n", ctx->ctx_cpu));
3579 return -EBUSY;
3580 }
3581
3582
3583 if (unlikely(task == NULL)) {
3584 printk(KERN_ERR "perfmon: [%d] pfm_restart no task\n", task_pid_nr(current));
3585 return -EINVAL;
3586 }
3587
3588 if (task == current || is_system) {
3589
3590 fmt = ctx->ctx_buf_fmt;
3591
3592 DPRINT(("restarting self %d ovfl=0x%lx\n",
3593 task_pid_nr(task),
3594 ctx->ctx_ovfl_regs[0]));
3595
3596 if (CTX_HAS_SMPL(ctx)) {
3597
3598 prefetch(ctx->ctx_smpl_hdr);
3599
3600 rst_ctrl.bits.mask_monitoring = 0;
3601 rst_ctrl.bits.reset_ovfl_pmds = 0;
3602
3603 if (state == PFM_CTX_LOADED)
3604 ret = pfm_buf_fmt_restart_active(fmt, task, &rst_ctrl, ctx->ctx_smpl_hdr, regs);
3605 else
3606 ret = pfm_buf_fmt_restart(fmt, task, &rst_ctrl, ctx->ctx_smpl_hdr, regs);
3607 } else {
3608 rst_ctrl.bits.mask_monitoring = 0;
3609 rst_ctrl.bits.reset_ovfl_pmds = 1;
3610 }
3611
3612 if (ret == 0) {
3613 if (rst_ctrl.bits.reset_ovfl_pmds)
3614 pfm_reset_regs(ctx, ctx->ctx_ovfl_regs, PFM_PMD_LONG_RESET);
3615
3616 if (rst_ctrl.bits.mask_monitoring == 0) {
3617 DPRINT(("resuming monitoring for [%d]\n", task_pid_nr(task)));
3618
3619 if (state == PFM_CTX_MASKED) pfm_restore_monitoring(task);
3620 } else {
3621 DPRINT(("keeping monitoring stopped for [%d]\n", task_pid_nr(task)));
3622
3623
3624 }
3625 }
3626
3627
3628
3629 ctx->ctx_ovfl_regs[0] = 0UL;
3630
3631
3632
3633
3634 ctx->ctx_state = PFM_CTX_LOADED;
3635
3636
3637
3638
3639 ctx->ctx_fl_can_restart = 0;
3640
3641 return 0;
3642 }
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652 if (state == PFM_CTX_MASKED) {
3653 if (ctx->ctx_fl_can_restart == 0) return -EINVAL;
3654
3655
3656
3657
3658 ctx->ctx_fl_can_restart = 0;
3659 }
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677 if (CTX_OVFL_NOBLOCK(ctx) == 0 && state == PFM_CTX_MASKED) {
3678 DPRINT(("unblocking [%d] \n", task_pid_nr(task)));
3679 complete(&ctx->ctx_restart_done);
3680 } else {
3681 DPRINT(("[%d] armed exit trap\n", task_pid_nr(task)));
3682
3683 ctx->ctx_fl_trap_reason = PFM_TRAP_REASON_RESET;
3684
3685 PFM_SET_WORK_PENDING(task, 1);
3686
3687 tsk_set_notify_resume(task);
3688
3689
3690
3691
3692 }
3693 return 0;
3694}
3695
3696static int
3697pfm_debug(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
3698{
3699 unsigned int m = *(unsigned int *)arg;
3700
3701 pfm_sysctl.debug = m == 0 ? 0 : 1;
3702
3703 printk(KERN_INFO "perfmon debugging %s (timing reset)\n", pfm_sysctl.debug ? "on" : "off");
3704
3705 if (m == 0) {
3706 memset(pfm_stats, 0, sizeof(pfm_stats));
3707 for(m=0; m < NR_CPUS; m++) pfm_stats[m].pfm_ovfl_intr_cycles_min = ~0UL;
3708 }
3709 return 0;
3710}
3711
3712
3713
3714
3715static int
3716pfm_write_ibr_dbr(int mode, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
3717{
3718 struct thread_struct *thread = NULL;
3719 struct task_struct *task;
3720 pfarg_dbreg_t *req = (pfarg_dbreg_t *)arg;
3721 unsigned long flags;
3722 dbreg_t dbreg;
3723 unsigned int rnum;
3724 int first_time;
3725 int ret = 0, state;
3726 int i, can_access_pmu = 0;
3727 int is_system, is_loaded;
3728
3729 if (pmu_conf->use_rr_dbregs == 0) return -EINVAL;
3730
3731 state = ctx->ctx_state;
3732 is_loaded = state == PFM_CTX_LOADED ? 1 : 0;
3733 is_system = ctx->ctx_fl_system;
3734 task = ctx->ctx_task;
3735
3736 if (state == PFM_CTX_ZOMBIE) return -EINVAL;
3737
3738
3739
3740
3741
3742 if (is_loaded) {
3743 thread = &task->thread;
3744
3745
3746
3747
3748
3749 if (unlikely(is_system && ctx->ctx_cpu != smp_processor_id())) {
3750 DPRINT(("should be running on CPU%d\n", ctx->ctx_cpu));
3751 return -EBUSY;
3752 }
3753 can_access_pmu = GET_PMU_OWNER() == task || is_system ? 1 : 0;
3754 }
3755
3756
3757
3758
3759
3760
3761
3762
3763 first_time = ctx->ctx_fl_using_dbreg == 0;
3764
3765
3766
3767
3768 if (is_loaded && (thread->flags & IA64_THREAD_DBG_VALID) != 0) {
3769 DPRINT(("debug registers already in use for [%d]\n", task_pid_nr(task)));
3770 return -EBUSY;
3771 }
3772
3773
3774
3775
3776
3777
3778
3779
3780 if (is_loaded) {
3781 LOCK_PFS(flags);
3782
3783 if (first_time && is_system) {
3784 if (pfm_sessions.pfs_ptrace_use_dbregs)
3785 ret = -EBUSY;
3786 else
3787 pfm_sessions.pfs_sys_use_dbregs++;
3788 }
3789 UNLOCK_PFS(flags);
3790 }
3791
3792 if (ret != 0) return ret;
3793
3794
3795
3796
3797
3798 ctx->ctx_fl_using_dbreg = 1;
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809 if (first_time && can_access_pmu) {
3810 DPRINT(("[%d] clearing ibrs, dbrs\n", task_pid_nr(task)));
3811 for (i=0; i < pmu_conf->num_ibrs; i++) {
3812 ia64_set_ibr(i, 0UL);
3813 ia64_dv_serialize_instruction();
3814 }
3815 ia64_srlz_i();
3816 for (i=0; i < pmu_conf->num_dbrs; i++) {
3817 ia64_set_dbr(i, 0UL);
3818 ia64_dv_serialize_data();
3819 }
3820 ia64_srlz_d();
3821 }
3822
3823
3824
3825
3826 for (i = 0; i < count; i++, req++) {
3827
3828 rnum = req->dbreg_num;
3829 dbreg.val = req->dbreg_value;
3830
3831 ret = -EINVAL;
3832
3833 if ((mode == PFM_CODE_RR && rnum >= PFM_NUM_IBRS) || ((mode == PFM_DATA_RR) && rnum >= PFM_NUM_DBRS)) {
3834 DPRINT(("invalid register %u val=0x%lx mode=%d i=%d count=%d\n",
3835 rnum, dbreg.val, mode, i, count));
3836
3837 goto abort_mission;
3838 }
3839
3840
3841
3842
3843 if (rnum & 0x1) {
3844 if (mode == PFM_CODE_RR)
3845 dbreg.ibr.ibr_x = 0;
3846 else
3847 dbreg.dbr.dbr_r = dbreg.dbr.dbr_w = 0;
3848 }
3849
3850 PFM_REG_RETFLAG_SET(req->dbreg_flags, 0);
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862 if (mode == PFM_CODE_RR) {
3863 CTX_USED_IBR(ctx, rnum);
3864
3865 if (can_access_pmu) {
3866 ia64_set_ibr(rnum, dbreg.val);
3867 ia64_dv_serialize_instruction();
3868 }
3869
3870 ctx->ctx_ibrs[rnum] = dbreg.val;
3871
3872 DPRINT(("write ibr%u=0x%lx used_ibrs=0x%x ld=%d apmu=%d\n",
3873 rnum, dbreg.val, ctx->ctx_used_ibrs[0], is_loaded, can_access_pmu));
3874 } else {
3875 CTX_USED_DBR(ctx, rnum);
3876
3877 if (can_access_pmu) {
3878 ia64_set_dbr(rnum, dbreg.val);
3879 ia64_dv_serialize_data();
3880 }
3881 ctx->ctx_dbrs[rnum] = dbreg.val;
3882
3883 DPRINT(("write dbr%u=0x%lx used_dbrs=0x%x ld=%d apmu=%d\n",
3884 rnum, dbreg.val, ctx->ctx_used_dbrs[0], is_loaded, can_access_pmu));
3885 }
3886 }
3887
3888 return 0;
3889
3890abort_mission:
3891
3892
3893
3894 if (first_time) {
3895 LOCK_PFS(flags);
3896 if (ctx->ctx_fl_system) {
3897 pfm_sessions.pfs_sys_use_dbregs--;
3898 }
3899 UNLOCK_PFS(flags);
3900 ctx->ctx_fl_using_dbreg = 0;
3901 }
3902
3903
3904
3905 PFM_REG_RETFLAG_SET(req->dbreg_flags, PFM_REG_RETFL_EINVAL);
3906
3907 return ret;
3908}
3909
3910static int
3911pfm_write_ibrs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
3912{
3913 return pfm_write_ibr_dbr(PFM_CODE_RR, ctx, arg, count, regs);
3914}
3915
3916static int
3917pfm_write_dbrs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
3918{
3919 return pfm_write_ibr_dbr(PFM_DATA_RR, ctx, arg, count, regs);
3920}
3921
3922int
3923pfm_mod_write_ibrs(struct task_struct *task, void *req, unsigned int nreq, struct pt_regs *regs)
3924{
3925 pfm_context_t *ctx;
3926
3927 if (req == NULL) return -EINVAL;
3928
3929 ctx = GET_PMU_CTX();
3930
3931 if (ctx == NULL) return -EINVAL;
3932
3933
3934
3935
3936
3937 if (task != current && ctx->ctx_fl_system == 0) return -EBUSY;
3938
3939 return pfm_write_ibrs(ctx, req, nreq, regs);
3940}
3941EXPORT_SYMBOL(pfm_mod_write_ibrs);
3942
3943int
3944pfm_mod_write_dbrs(struct task_struct *task, void *req, unsigned int nreq, struct pt_regs *regs)
3945{
3946 pfm_context_t *ctx;
3947
3948 if (req == NULL) return -EINVAL;
3949
3950 ctx = GET_PMU_CTX();
3951
3952 if (ctx == NULL) return -EINVAL;
3953
3954
3955
3956
3957
3958 if (task != current && ctx->ctx_fl_system == 0) return -EBUSY;
3959
3960 return pfm_write_dbrs(ctx, req, nreq, regs);
3961}
3962EXPORT_SYMBOL(pfm_mod_write_dbrs);
3963
3964
3965static int
3966pfm_get_features(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
3967{
3968 pfarg_features_t *req = (pfarg_features_t *)arg;
3969
3970 req->ft_version = PFM_VERSION;
3971 return 0;
3972}
3973
3974static int
3975pfm_stop(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
3976{
3977 struct pt_regs *tregs;
3978 struct task_struct *task = PFM_CTX_TASK(ctx);
3979 int state, is_system;
3980
3981 state = ctx->ctx_state;
3982 is_system = ctx->ctx_fl_system;
3983
3984
3985
3986
3987 if (state == PFM_CTX_UNLOADED) return -EINVAL;
3988
3989
3990
3991
3992
3993
3994 if (is_system && ctx->ctx_cpu != smp_processor_id()) {
3995 DPRINT(("should be running on CPU%d\n", ctx->ctx_cpu));
3996 return -EBUSY;
3997 }
3998 DPRINT(("task [%d] ctx_state=%d is_system=%d\n",
3999 task_pid_nr(PFM_CTX_TASK(ctx)),
4000 state,
4001 is_system));
4002
4003
4004
4005
4006
4007 if (is_system) {
4008
4009
4010
4011
4012
4013 ia64_setreg(_IA64_REG_CR_DCR, ia64_getreg(_IA64_REG_CR_DCR) & ~IA64_DCR_PP);
4014 ia64_srlz_i();
4015
4016
4017
4018
4019 PFM_CPUINFO_CLEAR(PFM_CPUINFO_DCR_PP);
4020
4021
4022
4023
4024 pfm_clear_psr_pp();
4025
4026
4027
4028
4029 ia64_psr(regs)->pp = 0;
4030
4031 return 0;
4032 }
4033
4034
4035
4036
4037 if (task == current) {
4038
4039 pfm_clear_psr_up();
4040
4041
4042
4043
4044 ia64_psr(regs)->up = 0;
4045 } else {
4046 tregs = task_pt_regs(task);
4047
4048
4049
4050
4051 ia64_psr(tregs)->up = 0;
4052
4053
4054
4055
4056 ctx->ctx_saved_psr_up = 0;
4057 DPRINT(("task=[%d]\n", task_pid_nr(task)));
4058 }
4059 return 0;
4060}
4061
4062
4063static int
4064pfm_start(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
4065{
4066 struct pt_regs *tregs;
4067 int state, is_system;
4068
4069 state = ctx->ctx_state;
4070 is_system = ctx->ctx_fl_system;
4071
4072 if (state != PFM_CTX_LOADED) return -EINVAL;
4073
4074
4075
4076
4077
4078
4079 if (is_system && ctx->ctx_cpu != smp_processor_id()) {
4080 DPRINT(("should be running on CPU%d\n", ctx->ctx_cpu));
4081 return -EBUSY;
4082 }
4083
4084
4085
4086
4087
4088
4089 if (is_system) {
4090
4091
4092
4093
4094 ia64_psr(regs)->pp = 1;
4095
4096
4097
4098
4099 PFM_CPUINFO_SET(PFM_CPUINFO_DCR_PP);
4100
4101
4102
4103
4104 pfm_set_psr_pp();
4105
4106
4107 ia64_setreg(_IA64_REG_CR_DCR, ia64_getreg(_IA64_REG_CR_DCR) | IA64_DCR_PP);
4108 ia64_srlz_i();
4109
4110 return 0;
4111 }
4112
4113
4114
4115
4116
4117 if (ctx->ctx_task == current) {
4118
4119
4120 pfm_set_psr_up();
4121
4122
4123
4124
4125 ia64_psr(regs)->up = 1;
4126
4127 } else {
4128 tregs = task_pt_regs(ctx->ctx_task);
4129
4130
4131
4132
4133
4134 ctx->ctx_saved_psr_up = IA64_PSR_UP;
4135
4136
4137
4138
4139 ia64_psr(tregs)->up = 1;
4140 }
4141 return 0;
4142}
4143
4144static int
4145pfm_get_pmc_reset(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
4146{
4147 pfarg_reg_t *req = (pfarg_reg_t *)arg;
4148 unsigned int cnum;
4149 int i;
4150 int ret = -EINVAL;
4151
4152 for (i = 0; i < count; i++, req++) {
4153
4154 cnum = req->reg_num;
4155
4156 if (!PMC_IS_IMPL(cnum)) goto abort_mission;
4157
4158 req->reg_value = PMC_DFL_VAL(cnum);
4159
4160 PFM_REG_RETFLAG_SET(req->reg_flags, 0);
4161
4162 DPRINT(("pmc_reset_val pmc[%u]=0x%lx\n", cnum, req->reg_value));
4163 }
4164 return 0;
4165
4166abort_mission:
4167 PFM_REG_RETFLAG_SET(req->reg_flags, PFM_REG_RETFL_EINVAL);
4168 return ret;
4169}
4170
4171static int
4172pfm_check_task_exist(pfm_context_t *ctx)
4173{
4174 struct task_struct *g, *t;
4175 int ret = -ESRCH;
4176
4177 read_lock(&tasklist_lock);
4178
4179 do_each_thread (g, t) {
4180 if (t->thread.pfm_context == ctx) {
4181 ret = 0;
4182 goto out;
4183 }
4184 } while_each_thread (g, t);
4185out:
4186 read_unlock(&tasklist_lock);
4187
4188 DPRINT(("pfm_check_task_exist: ret=%d ctx=%p\n", ret, ctx));
4189
4190 return ret;
4191}
4192
4193static int
4194pfm_context_load(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
4195{
4196 struct task_struct *task;
4197 struct thread_struct *thread;
4198 struct pfm_context_t *old;
4199 unsigned long flags;
4200#ifndef CONFIG_SMP
4201 struct task_struct *owner_task = NULL;
4202#endif
4203 pfarg_load_t *req = (pfarg_load_t *)arg;
4204 unsigned long *pmcs_source, *pmds_source;
4205 int the_cpu;
4206 int ret = 0;
4207 int state, is_system, set_dbregs = 0;
4208
4209 state = ctx->ctx_state;
4210 is_system = ctx->ctx_fl_system;
4211
4212
4213
4214 if (state != PFM_CTX_UNLOADED) {
4215 DPRINT(("cannot load to [%d], invalid ctx_state=%d\n",
4216 req->load_pid,
4217 ctx->ctx_state));
4218 return -EBUSY;
4219 }
4220
4221 DPRINT(("load_pid [%d] using_dbreg=%d\n", req->load_pid, ctx->ctx_fl_using_dbreg));
4222
4223 if (CTX_OVFL_NOBLOCK(ctx) == 0 && req->load_pid == current->pid) {
4224 DPRINT(("cannot use blocking mode on self\n"));
4225 return -EINVAL;
4226 }
4227
4228 ret = pfm_get_task(ctx, req->load_pid, &task);
4229 if (ret) {
4230 DPRINT(("load_pid [%d] get_task=%d\n", req->load_pid, ret));
4231 return ret;
4232 }
4233
4234 ret = -EINVAL;
4235
4236
4237
4238
4239 if (is_system && task != current) {
4240 DPRINT(("system wide is self monitoring only load_pid=%d\n",
4241 req->load_pid));
4242 goto error;
4243 }
4244
4245 thread = &task->thread;
4246
4247 ret = 0;
4248
4249
4250
4251
4252 if (ctx->ctx_fl_using_dbreg) {
4253 if (thread->flags & IA64_THREAD_DBG_VALID) {
4254 ret = -EBUSY;
4255 DPRINT(("load_pid [%d] task is debugged, cannot load range restrictions\n", req->load_pid));
4256 goto error;
4257 }
4258 LOCK_PFS(flags);
4259
4260 if (is_system) {
4261 if (pfm_sessions.pfs_ptrace_use_dbregs) {
4262 DPRINT(("cannot load [%d] dbregs in use\n",
4263 task_pid_nr(task)));
4264 ret = -EBUSY;
4265 } else {
4266 pfm_sessions.pfs_sys_use_dbregs++;
4267 DPRINT(("load [%d] increased sys_use_dbreg=%u\n", task_pid_nr(task), pfm_sessions.pfs_sys_use_dbregs));
4268 set_dbregs = 1;
4269 }
4270 }
4271
4272 UNLOCK_PFS(flags);
4273
4274 if (ret) goto error;
4275 }
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292 the_cpu = ctx->ctx_cpu = smp_processor_id();
4293
4294 ret = -EBUSY;
4295
4296
4297
4298 ret = pfm_reserve_session(current, is_system, the_cpu);
4299 if (ret) goto error;
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310 DPRINT(("before cmpxchg() old_ctx=%p new_ctx=%p\n",
4311 thread->pfm_context, ctx));
4312
4313 ret = -EBUSY;
4314 old = ia64_cmpxchg(acq, &thread->pfm_context, NULL, ctx, sizeof(pfm_context_t *));
4315 if (old != NULL) {
4316 DPRINT(("load_pid [%d] already has a context\n", req->load_pid));
4317 goto error_unres;
4318 }
4319
4320 pfm_reset_msgq(ctx);
4321
4322 ctx->ctx_state = PFM_CTX_LOADED;
4323
4324
4325
4326
4327 ctx->ctx_task = task;
4328
4329 if (is_system) {
4330
4331
4332
4333 PFM_CPUINFO_SET(PFM_CPUINFO_SYST_WIDE);
4334 PFM_CPUINFO_CLEAR(PFM_CPUINFO_DCR_PP);
4335
4336 if (ctx->ctx_fl_excl_idle) PFM_CPUINFO_SET(PFM_CPUINFO_EXCL_IDLE);
4337 } else {
4338 thread->flags |= IA64_THREAD_PM_VALID;
4339 }
4340
4341
4342
4343
4344 pfm_copy_pmds(task, ctx);
4345 pfm_copy_pmcs(task, ctx);
4346
4347 pmcs_source = ctx->th_pmcs;
4348 pmds_source = ctx->th_pmds;
4349
4350
4351
4352
4353 if (task == current) {
4354
4355 if (is_system == 0) {
4356
4357
4358 ia64_psr(regs)->sp = 0;
4359 DPRINT(("clearing psr.sp for [%d]\n", task_pid_nr(task)));
4360
4361 SET_LAST_CPU(ctx, smp_processor_id());
4362 INC_ACTIVATION();
4363 SET_ACTIVATION(ctx);
4364#ifndef CONFIG_SMP
4365
4366
4367
4368 owner_task = GET_PMU_OWNER();
4369 if (owner_task) pfm_lazy_save_regs(owner_task);
4370#endif
4371 }
4372
4373
4374
4375
4376 pfm_restore_pmds(pmds_source, ctx->ctx_all_pmds[0]);
4377 pfm_restore_pmcs(pmcs_source, ctx->ctx_all_pmcs[0]);
4378
4379 ctx->ctx_reload_pmcs[0] = 0UL;
4380 ctx->ctx_reload_pmds[0] = 0UL;
4381
4382
4383
4384
4385 if (ctx->ctx_fl_using_dbreg) {
4386 pfm_restore_ibrs(ctx->ctx_ibrs, pmu_conf->num_ibrs);
4387 pfm_restore_dbrs(ctx->ctx_dbrs, pmu_conf->num_dbrs);
4388 }
4389
4390
4391
4392 SET_PMU_OWNER(task, ctx);
4393
4394 DPRINT(("context loaded on PMU for [%d]\n", task_pid_nr(task)));
4395 } else {
4396
4397
4398
4399 regs = task_pt_regs(task);
4400
4401
4402 ctx->ctx_last_activation = PFM_INVALID_ACTIVATION;
4403 SET_LAST_CPU(ctx, -1);
4404
4405
4406 ctx->ctx_saved_psr_up = 0UL;
4407 ia64_psr(regs)->up = ia64_psr(regs)->pp = 0;
4408 }
4409
4410 ret = 0;
4411
4412error_unres:
4413 if (ret) pfm_unreserve_session(ctx, ctx->ctx_fl_system, the_cpu);
4414error:
4415
4416
4417
4418 if (ret && set_dbregs) {
4419 LOCK_PFS(flags);
4420 pfm_sessions.pfs_sys_use_dbregs--;
4421 UNLOCK_PFS(flags);
4422 }
4423
4424
4425
4426 if (is_system == 0 && task != current) {
4427 pfm_put_task(task);
4428
4429 if (ret == 0) {
4430 ret = pfm_check_task_exist(ctx);
4431 if (ret) {
4432 ctx->ctx_state = PFM_CTX_UNLOADED;
4433 ctx->ctx_task = NULL;
4434 }
4435 }
4436 }
4437 return ret;
4438}
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448static void pfm_flush_pmds(struct task_struct *, pfm_context_t *ctx);
4449
4450static int
4451pfm_context_unload(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
4452{
4453 struct task_struct *task = PFM_CTX_TASK(ctx);
4454 struct pt_regs *tregs;
4455 int prev_state, is_system;
4456 int ret;
4457
4458 DPRINT(("ctx_state=%d task [%d]\n", ctx->ctx_state, task ? task_pid_nr(task) : -1));
4459
4460 prev_state = ctx->ctx_state;
4461 is_system = ctx->ctx_fl_system;
4462
4463
4464
4465
4466 if (prev_state == PFM_CTX_UNLOADED) {
4467 DPRINT(("ctx_state=%d, nothing to do\n", prev_state));
4468 return 0;
4469 }
4470
4471
4472
4473
4474 ret = pfm_stop(ctx, NULL, 0, regs);
4475 if (ret) return ret;
4476
4477 ctx->ctx_state = PFM_CTX_UNLOADED;
4478
4479
4480
4481
4482
4483
4484 if (is_system) {
4485
4486
4487
4488
4489
4490
4491 PFM_CPUINFO_CLEAR(PFM_CPUINFO_SYST_WIDE);
4492 PFM_CPUINFO_CLEAR(PFM_CPUINFO_EXCL_IDLE);
4493
4494
4495
4496
4497
4498 pfm_flush_pmds(current, ctx);
4499
4500
4501
4502
4503
4504 if (prev_state != PFM_CTX_ZOMBIE)
4505 pfm_unreserve_session(ctx, 1 , ctx->ctx_cpu);
4506
4507
4508
4509
4510 task->thread.pfm_context = NULL;
4511
4512
4513
4514 ctx->ctx_task = NULL;
4515
4516
4517
4518
4519 return 0;
4520 }
4521
4522
4523
4524
4525 tregs = task == current ? regs : task_pt_regs(task);
4526
4527 if (task == current) {
4528
4529
4530
4531 ia64_psr(regs)->sp = 1;
4532
4533 DPRINT(("setting psr.sp for [%d]\n", task_pid_nr(task)));
4534 }
4535
4536
4537
4538
4539 pfm_flush_pmds(task, ctx);
4540
4541
4542
4543
4544
4545
4546
4547 if (prev_state != PFM_CTX_ZOMBIE)
4548 pfm_unreserve_session(ctx, 0 , ctx->ctx_cpu);
4549
4550
4551
4552
4553 ctx->ctx_last_activation = PFM_INVALID_ACTIVATION;
4554 SET_LAST_CPU(ctx, -1);
4555
4556
4557
4558
4559 task->thread.flags &= ~IA64_THREAD_PM_VALID;
4560
4561
4562
4563
4564 task->thread.pfm_context = NULL;
4565 ctx->ctx_task = NULL;
4566
4567 PFM_SET_WORK_PENDING(task, 0);
4568
4569 ctx->ctx_fl_trap_reason = PFM_TRAP_REASON_NONE;
4570 ctx->ctx_fl_can_restart = 0;
4571 ctx->ctx_fl_going_zombie = 0;
4572
4573 DPRINT(("disconnected [%d] from context\n", task_pid_nr(task)));
4574
4575 return 0;
4576}
4577
4578
4579
4580
4581
4582
4583void
4584pfm_exit_thread(struct task_struct *task)
4585{
4586 pfm_context_t *ctx;
4587 unsigned long flags;
4588 struct pt_regs *regs = task_pt_regs(task);
4589 int ret, state;
4590 int free_ok = 0;
4591
4592 ctx = PFM_GET_CTX(task);
4593
4594 PROTECT_CTX(ctx, flags);
4595
4596 DPRINT(("state=%d task [%d]\n", ctx->ctx_state, task_pid_nr(task)));
4597
4598 state = ctx->ctx_state;
4599 switch(state) {
4600 case PFM_CTX_UNLOADED:
4601
4602
4603
4604
4605 printk(KERN_ERR "perfmon: pfm_exit_thread [%d] ctx unloaded\n", task_pid_nr(task));
4606 break;
4607 case PFM_CTX_LOADED:
4608 case PFM_CTX_MASKED:
4609 ret = pfm_context_unload(ctx, NULL, 0, regs);
4610 if (ret) {
4611 printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task_pid_nr(task), state, ret);
4612 }
4613 DPRINT(("ctx unloaded for current state was %d\n", state));
4614
4615 pfm_end_notify_user(ctx);
4616 break;
4617 case PFM_CTX_ZOMBIE:
4618 ret = pfm_context_unload(ctx, NULL, 0, regs);
4619 if (ret) {
4620 printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task_pid_nr(task), state, ret);
4621 }
4622 free_ok = 1;
4623 break;
4624 default:
4625 printk(KERN_ERR "perfmon: pfm_exit_thread [%d] unexpected state=%d\n", task_pid_nr(task), state);
4626 break;
4627 }
4628 UNPROTECT_CTX(ctx, flags);
4629
4630 { u64 psr = pfm_get_psr();
4631 BUG_ON(psr & (IA64_PSR_UP|IA64_PSR_PP));
4632 BUG_ON(GET_PMU_OWNER());
4633 BUG_ON(ia64_psr(regs)->up);
4634 BUG_ON(ia64_psr(regs)->pp);
4635 }
4636
4637
4638
4639
4640
4641 if (free_ok) pfm_context_free(ctx);
4642}
4643
4644
4645
4646
4647#define PFM_CMD(name, flags, arg_count, arg_type, getsz) { name, #name, flags, arg_count, sizeof(arg_type), getsz }
4648#define PFM_CMD_S(name, flags) { name, #name, flags, 0, 0, NULL }
4649#define PFM_CMD_PCLRWS (PFM_CMD_FD|PFM_CMD_ARG_RW|PFM_CMD_STOP)
4650#define PFM_CMD_PCLRW (PFM_CMD_FD|PFM_CMD_ARG_RW)
4651#define PFM_CMD_NONE { NULL, "no-cmd", 0, 0, 0, NULL}
4652
4653static pfm_cmd_desc_t pfm_cmd_tab[]={
4654PFM_CMD_NONE,
4655PFM_CMD(pfm_write_pmcs, PFM_CMD_PCLRWS, PFM_CMD_ARG_MANY, pfarg_reg_t, NULL),
4656PFM_CMD(pfm_write_pmds, PFM_CMD_PCLRWS, PFM_CMD_ARG_MANY, pfarg_reg_t, NULL),
4657PFM_CMD(pfm_read_pmds, PFM_CMD_PCLRWS, PFM_CMD_ARG_MANY, pfarg_reg_t, NULL),
4658PFM_CMD_S(pfm_stop, PFM_CMD_PCLRWS),
4659PFM_CMD_S(pfm_start, PFM_CMD_PCLRWS),
4660PFM_CMD_NONE,
4661PFM_CMD_NONE,
4662PFM_CMD(pfm_context_create, PFM_CMD_ARG_RW, 1, pfarg_context_t, pfm_ctx_getsize),
4663PFM_CMD_NONE,
4664PFM_CMD_S(pfm_restart, PFM_CMD_PCLRW),
4665PFM_CMD_NONE,
4666PFM_CMD(pfm_get_features, PFM_CMD_ARG_RW, 1, pfarg_features_t, NULL),
4667PFM_CMD(pfm_debug, 0, 1, unsigned int, NULL),
4668PFM_CMD_NONE,
4669PFM_CMD(pfm_get_pmc_reset, PFM_CMD_ARG_RW, PFM_CMD_ARG_MANY, pfarg_reg_t, NULL),
4670PFM_CMD(pfm_context_load, PFM_CMD_PCLRWS, 1, pfarg_load_t, NULL),
4671PFM_CMD_S(pfm_context_unload, PFM_CMD_PCLRWS),
4672PFM_CMD_NONE,
4673PFM_CMD_NONE,
4674PFM_CMD_NONE,
4675PFM_CMD_NONE,
4676PFM_CMD_NONE,
4677PFM_CMD_NONE,
4678PFM_CMD_NONE,
4679PFM_CMD_NONE,
4680PFM_CMD_NONE,
4681PFM_CMD_NONE,
4682PFM_CMD_NONE,
4683PFM_CMD_NONE,
4684PFM_CMD_NONE,
4685PFM_CMD_NONE,
4686PFM_CMD(pfm_write_ibrs, PFM_CMD_PCLRWS, PFM_CMD_ARG_MANY, pfarg_dbreg_t, NULL),
4687PFM_CMD(pfm_write_dbrs, PFM_CMD_PCLRWS, PFM_CMD_ARG_MANY, pfarg_dbreg_t, NULL)
4688};
4689#define PFM_CMD_COUNT (sizeof(pfm_cmd_tab)/sizeof(pfm_cmd_desc_t))
4690
4691static int
4692pfm_check_task_state(pfm_context_t *ctx, int cmd, unsigned long flags)
4693{
4694 struct task_struct *task;
4695 int state, old_state;
4696
4697recheck:
4698 state = ctx->ctx_state;
4699 task = ctx->ctx_task;
4700
4701 if (task == NULL) {
4702 DPRINT(("context %d no task, state=%d\n", ctx->ctx_fd, state));
4703 return 0;
4704 }
4705
4706 DPRINT(("context %d state=%d [%d] task_state=%ld must_stop=%d\n",
4707 ctx->ctx_fd,
4708 state,
4709 task_pid_nr(task),
4710 task->state, PFM_CMD_STOPPED(cmd)));
4711
4712
4713
4714
4715
4716
4717
4718
4719 if (task == current || ctx->ctx_fl_system) return 0;
4720
4721
4722
4723
4724 switch(state) {
4725 case PFM_CTX_UNLOADED:
4726
4727
4728
4729 return 0;
4730 case PFM_CTX_ZOMBIE:
4731
4732
4733
4734 DPRINT(("cmd %d state zombie cannot operate on context\n", cmd));
4735 return -EINVAL;
4736 case PFM_CTX_MASKED:
4737
4738
4739
4740
4741 if (cmd != PFM_UNLOAD_CONTEXT) return 0;
4742 }
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754 if (PFM_CMD_STOPPED(cmd)) {
4755 if (!task_is_stopped_or_traced(task)) {
4756 DPRINT(("[%d] task not in stopped state\n", task_pid_nr(task)));
4757 return -EBUSY;
4758 }
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773 old_state = state;
4774
4775 UNPROTECT_CTX(ctx, flags);
4776
4777 wait_task_inactive(task, 0);
4778
4779 PROTECT_CTX(ctx, flags);
4780
4781
4782
4783
4784 if (ctx->ctx_state != old_state) {
4785 DPRINT(("old_state=%d new_state=%d\n", old_state, ctx->ctx_state));
4786 goto recheck;
4787 }
4788 }
4789 return 0;
4790}
4791
4792
4793
4794
4795asmlinkage long
4796sys_perfmonctl (int fd, int cmd, void __user *arg, int count)
4797{
4798 struct file *file = NULL;
4799 pfm_context_t *ctx = NULL;
4800 unsigned long flags = 0UL;
4801 void *args_k = NULL;
4802 long ret;
4803 size_t base_sz, sz, xtra_sz = 0;
4804 int narg, completed_args = 0, call_made = 0, cmd_flags;
4805 int (*func)(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs);
4806 int (*getsize)(void *arg, size_t *sz);
4807#define PFM_MAX_ARGSIZE 4096
4808
4809
4810
4811
4812 if (unlikely(pmu_conf == NULL)) return -ENOSYS;
4813
4814 if (unlikely(cmd < 0 || cmd >= PFM_CMD_COUNT)) {
4815 DPRINT(("invalid cmd=%d\n", cmd));
4816 return -EINVAL;
4817 }
4818
4819 func = pfm_cmd_tab[cmd].cmd_func;
4820 narg = pfm_cmd_tab[cmd].cmd_narg;
4821 base_sz = pfm_cmd_tab[cmd].cmd_argsize;
4822 getsize = pfm_cmd_tab[cmd].cmd_getsize;
4823 cmd_flags = pfm_cmd_tab[cmd].cmd_flags;
4824
4825 if (unlikely(func == NULL)) {
4826 DPRINT(("invalid cmd=%d\n", cmd));
4827 return -EINVAL;
4828 }
4829
4830 DPRINT(("cmd=%s idx=%d narg=0x%x argsz=%lu count=%d\n",
4831 PFM_CMD_NAME(cmd),
4832 cmd,
4833 narg,
4834 base_sz,
4835 count));
4836
4837
4838
4839
4840 if (unlikely((narg == PFM_CMD_ARG_MANY && count <= 0) || (narg > 0 && narg != count)))
4841 return -EINVAL;
4842
4843restart_args:
4844 sz = xtra_sz + base_sz*count;
4845
4846
4847
4848 if (unlikely(sz > PFM_MAX_ARGSIZE)) {
4849 printk(KERN_ERR "perfmon: [%d] argument too big %lu\n", task_pid_nr(current), sz);
4850 return -E2BIG;
4851 }
4852
4853
4854
4855
4856 if (likely(count && args_k == NULL)) {
4857 args_k = kmalloc(PFM_MAX_ARGSIZE, GFP_KERNEL);
4858 if (args_k == NULL) return -ENOMEM;
4859 }
4860
4861 ret = -EFAULT;
4862
4863
4864
4865
4866
4867
4868 if (sz && copy_from_user(args_k, arg, sz)) {
4869 DPRINT(("cannot copy_from_user %lu bytes @%p\n", sz, arg));
4870 goto error_args;
4871 }
4872
4873
4874
4875
4876 if (completed_args == 0 && getsize) {
4877
4878
4879
4880 ret = (*getsize)(args_k, &xtra_sz);
4881 if (ret) goto error_args;
4882
4883 completed_args = 1;
4884
4885 DPRINT(("restart_args sz=%lu xtra_sz=%lu\n", sz, xtra_sz));
4886
4887
4888 if (likely(xtra_sz)) goto restart_args;
4889 }
4890
4891 if (unlikely((cmd_flags & PFM_CMD_FD) == 0)) goto skip_fd;
4892
4893 ret = -EBADF;
4894
4895 file = fget(fd);
4896 if (unlikely(file == NULL)) {
4897 DPRINT(("invalid fd %d\n", fd));
4898 goto error_args;
4899 }
4900 if (unlikely(PFM_IS_FILE(file) == 0)) {
4901 DPRINT(("fd %d not related to perfmon\n", fd));
4902 goto error_args;
4903 }
4904
4905 ctx = (pfm_context_t *)file->private_data;
4906 if (unlikely(ctx == NULL)) {
4907 DPRINT(("no context for fd %d\n", fd));
4908 goto error_args;
4909 }
4910 prefetch(&ctx->ctx_state);
4911
4912 PROTECT_CTX(ctx, flags);
4913
4914
4915
4916
4917 ret = pfm_check_task_state(ctx, cmd, flags);
4918 if (unlikely(ret)) goto abort_locked;
4919
4920skip_fd:
4921 ret = (*func)(ctx, args_k, count, task_pt_regs(current));
4922
4923 call_made = 1;
4924
4925abort_locked:
4926 if (likely(ctx)) {
4927 DPRINT(("context unlocked\n"));
4928 UNPROTECT_CTX(ctx, flags);
4929 }
4930
4931
4932 if (call_made && PFM_CMD_RW_ARG(cmd) && copy_to_user(arg, args_k, base_sz*count)) ret = -EFAULT;
4933
4934error_args:
4935 if (file)
4936 fput(file);
4937
4938 kfree(args_k);
4939
4940 DPRINT(("cmd=%s ret=%ld\n", PFM_CMD_NAME(cmd), ret));
4941
4942 return ret;
4943}
4944
4945static void
4946pfm_resume_after_ovfl(pfm_context_t *ctx, unsigned long ovfl_regs, struct pt_regs *regs)
4947{
4948 pfm_buffer_fmt_t *fmt = ctx->ctx_buf_fmt;
4949 pfm_ovfl_ctrl_t rst_ctrl;
4950 int state;
4951 int ret = 0;
4952
4953 state = ctx->ctx_state;
4954
4955
4956
4957
4958 if (CTX_HAS_SMPL(ctx)) {
4959
4960 rst_ctrl.bits.mask_monitoring = 0;
4961 rst_ctrl.bits.reset_ovfl_pmds = 0;
4962
4963 if (state == PFM_CTX_LOADED)
4964 ret = pfm_buf_fmt_restart_active(fmt, current, &rst_ctrl, ctx->ctx_smpl_hdr, regs);
4965 else
4966 ret = pfm_buf_fmt_restart(fmt, current, &rst_ctrl, ctx->ctx_smpl_hdr, regs);
4967 } else {
4968 rst_ctrl.bits.mask_monitoring = 0;
4969 rst_ctrl.bits.reset_ovfl_pmds = 1;
4970 }
4971
4972 if (ret == 0) {
4973 if (rst_ctrl.bits.reset_ovfl_pmds) {
4974 pfm_reset_regs(ctx, &ovfl_regs, PFM_PMD_LONG_RESET);
4975 }
4976 if (rst_ctrl.bits.mask_monitoring == 0) {
4977 DPRINT(("resuming monitoring\n"));
4978 if (ctx->ctx_state == PFM_CTX_MASKED) pfm_restore_monitoring(current);
4979 } else {
4980 DPRINT(("stopping monitoring\n"));
4981
4982 }
4983 ctx->ctx_state = PFM_CTX_LOADED;
4984 }
4985}
4986
4987
4988
4989
4990
4991static void
4992pfm_context_force_terminate(pfm_context_t *ctx, struct pt_regs *regs)
4993{
4994 int ret;
4995
4996 DPRINT(("entering for [%d]\n", task_pid_nr(current)));
4997
4998 ret = pfm_context_unload(ctx, NULL, 0, regs);
4999 if (ret) {
5000 printk(KERN_ERR "pfm_context_force_terminate: [%d] unloaded failed with %d\n", task_pid_nr(current), ret);
5001 }
5002
5003
5004
5005
5006 wake_up_interruptible(&ctx->ctx_zombieq);
5007
5008
5009
5010
5011
5012
5013}
5014
5015static int pfm_ovfl_notify_user(pfm_context_t *ctx, unsigned long ovfl_pmds);
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026void
5027pfm_handle_work(void)
5028{
5029 pfm_context_t *ctx;
5030 struct pt_regs *regs;
5031 unsigned long flags, dummy_flags;
5032 unsigned long ovfl_regs;
5033 unsigned int reason;
5034 int ret;
5035
5036 ctx = PFM_GET_CTX(current);
5037 if (ctx == NULL) {
5038 printk(KERN_ERR "perfmon: [%d] has no PFM context\n",
5039 task_pid_nr(current));
5040 return;
5041 }
5042
5043 PROTECT_CTX(ctx, flags);
5044
5045 PFM_SET_WORK_PENDING(current, 0);
5046
5047 tsk_clear_notify_resume(current);
5048
5049 regs = task_pt_regs(current);
5050
5051
5052
5053
5054 reason = ctx->ctx_fl_trap_reason;
5055 ctx->ctx_fl_trap_reason = PFM_TRAP_REASON_NONE;
5056 ovfl_regs = ctx->ctx_ovfl_regs[0];
5057
5058 DPRINT(("reason=%d state=%d\n", reason, ctx->ctx_state));
5059
5060
5061
5062
5063 if (ctx->ctx_fl_going_zombie || ctx->ctx_state == PFM_CTX_ZOMBIE)
5064 goto do_zombie;
5065
5066
5067 if (reason == PFM_TRAP_REASON_RESET)
5068 goto skip_blocking;
5069
5070
5071
5072
5073
5074 UNPROTECT_CTX(ctx, flags);
5075
5076
5077
5078
5079 local_irq_enable();
5080
5081 DPRINT(("before block sleeping\n"));
5082
5083
5084
5085
5086
5087 ret = wait_for_completion_interruptible(&ctx->ctx_restart_done);
5088
5089 DPRINT(("after block sleeping ret=%d\n", ret));
5090
5091
5092
5093
5094
5095
5096
5097 PROTECT_CTX(ctx, dummy_flags);
5098
5099
5100
5101
5102
5103
5104
5105 ovfl_regs = ctx->ctx_ovfl_regs[0];
5106
5107 if (ctx->ctx_fl_going_zombie) {
5108do_zombie:
5109 DPRINT(("context is zombie, bailing out\n"));
5110 pfm_context_force_terminate(ctx, regs);
5111 goto nothing_to_do;
5112 }
5113
5114
5115
5116 if (ret < 0)
5117 goto nothing_to_do;
5118
5119skip_blocking:
5120 pfm_resume_after_ovfl(ctx, ovfl_regs, regs);
5121 ctx->ctx_ovfl_regs[0] = 0UL;
5122
5123nothing_to_do:
5124
5125
5126
5127 UNPROTECT_CTX(ctx, flags);
5128}
5129
5130static int
5131pfm_notify_user(pfm_context_t *ctx, pfm_msg_t *msg)
5132{
5133 if (ctx->ctx_state == PFM_CTX_ZOMBIE) {
5134 DPRINT(("ignoring overflow notification, owner is zombie\n"));
5135 return 0;
5136 }
5137
5138 DPRINT(("waking up somebody\n"));
5139
5140 if (msg) wake_up_interruptible(&ctx->ctx_msgq_wait);
5141
5142
5143
5144
5145
5146 kill_fasync (&ctx->ctx_async_queue, SIGIO, POLL_IN);
5147
5148 return 0;
5149}
5150
5151static int
5152pfm_ovfl_notify_user(pfm_context_t *ctx, unsigned long ovfl_pmds)
5153{
5154 pfm_msg_t *msg = NULL;
5155
5156 if (ctx->ctx_fl_no_msg == 0) {
5157 msg = pfm_get_new_msg(ctx);
5158 if (msg == NULL) {
5159 printk(KERN_ERR "perfmon: pfm_ovfl_notify_user no more notification msgs\n");
5160 return -1;
5161 }
5162
5163 msg->pfm_ovfl_msg.msg_type = PFM_MSG_OVFL;
5164 msg->pfm_ovfl_msg.msg_ctx_fd = ctx->ctx_fd;
5165 msg->pfm_ovfl_msg.msg_active_set = 0;
5166 msg->pfm_ovfl_msg.msg_ovfl_pmds[0] = ovfl_pmds;
5167 msg->pfm_ovfl_msg.msg_ovfl_pmds[1] = 0UL;
5168 msg->pfm_ovfl_msg.msg_ovfl_pmds[2] = 0UL;
5169 msg->pfm_ovfl_msg.msg_ovfl_pmds[3] = 0UL;
5170 msg->pfm_ovfl_msg.msg_tstamp = 0UL;
5171 }
5172
5173 DPRINT(("ovfl msg: msg=%p no_msg=%d fd=%d ovfl_pmds=0x%lx\n",
5174 msg,
5175 ctx->ctx_fl_no_msg,
5176 ctx->ctx_fd,
5177 ovfl_pmds));
5178
5179 return pfm_notify_user(ctx, msg);
5180}
5181
5182static int
5183pfm_end_notify_user(pfm_context_t *ctx)
5184{
5185 pfm_msg_t *msg;
5186
5187 msg = pfm_get_new_msg(ctx);
5188 if (msg == NULL) {
5189 printk(KERN_ERR "perfmon: pfm_end_notify_user no more notification msgs\n");
5190 return -1;
5191 }
5192
5193 memset(msg, 0, sizeof(*msg));
5194
5195 msg->pfm_end_msg.msg_type = PFM_MSG_END;
5196 msg->pfm_end_msg.msg_ctx_fd = ctx->ctx_fd;
5197 msg->pfm_ovfl_msg.msg_tstamp = 0UL;
5198
5199 DPRINT(("end msg: msg=%p no_msg=%d ctx_fd=%d\n",
5200 msg,
5201 ctx->ctx_fl_no_msg,
5202 ctx->ctx_fd));
5203
5204 return pfm_notify_user(ctx, msg);
5205}
5206
5207
5208
5209
5210
5211static void
5212pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, struct pt_regs *regs)
5213{
5214 pfm_ovfl_arg_t *ovfl_arg;
5215 unsigned long mask;
5216 unsigned long old_val, ovfl_val, new_val;
5217 unsigned long ovfl_notify = 0UL, ovfl_pmds = 0UL, smpl_pmds = 0UL, reset_pmds;
5218 unsigned long tstamp;
5219 pfm_ovfl_ctrl_t ovfl_ctrl;
5220 unsigned int i, has_smpl;
5221 int must_notify = 0;
5222
5223 if (unlikely(ctx->ctx_state == PFM_CTX_ZOMBIE)) goto stop_monitoring;
5224
5225
5226
5227
5228 if (unlikely((pmc0 & 0x1) == 0)) goto sanity_check;
5229
5230 tstamp = ia64_get_itc();
5231 mask = pmc0 >> PMU_FIRST_COUNTER;
5232 ovfl_val = pmu_conf->ovfl_val;
5233 has_smpl = CTX_HAS_SMPL(ctx);
5234
5235 DPRINT_ovfl(("pmc0=0x%lx pid=%d iip=0x%lx, %s "
5236 "used_pmds=0x%lx\n",
5237 pmc0,
5238 task ? task_pid_nr(task): -1,
5239 (regs ? regs->cr_iip : 0),
5240 CTX_OVFL_NOBLOCK(ctx) ? "nonblocking" : "blocking",
5241 ctx->ctx_used_pmds[0]));
5242
5243
5244
5245
5246
5247
5248 for (i = PMU_FIRST_COUNTER; mask ; i++, mask >>= 1) {
5249
5250
5251 if ((mask & 0x1) == 0) continue;
5252
5253
5254
5255
5256
5257
5258
5259 old_val = new_val = ctx->ctx_pmds[i].val;
5260 new_val += 1 + ovfl_val;
5261 ctx->ctx_pmds[i].val = new_val;
5262
5263
5264
5265
5266 if (likely(old_val > new_val)) {
5267 ovfl_pmds |= 1UL << i;
5268 if (PMC_OVFL_NOTIFY(ctx, i)) ovfl_notify |= 1UL << i;
5269 }
5270
5271 DPRINT_ovfl(("ctx_pmd[%d].val=0x%lx old_val=0x%lx pmd=0x%lx ovfl_pmds=0x%lx ovfl_notify=0x%lx\n",
5272 i,
5273 new_val,
5274 old_val,
5275 ia64_get_pmd(i) & ovfl_val,
5276 ovfl_pmds,
5277 ovfl_notify));
5278 }
5279
5280
5281
5282
5283 if (ovfl_pmds == 0UL) return;
5284
5285
5286
5287
5288 ovfl_ctrl.val = 0;
5289 reset_pmds = 0UL;
5290
5291
5292
5293
5294
5295 if (has_smpl) {
5296 unsigned long start_cycles, end_cycles;
5297 unsigned long pmd_mask;
5298 int j, k, ret = 0;
5299 int this_cpu = smp_processor_id();
5300
5301 pmd_mask = ovfl_pmds >> PMU_FIRST_COUNTER;
5302 ovfl_arg = &ctx->ctx_ovfl_arg;
5303
5304 prefetch(ctx->ctx_smpl_hdr);
5305
5306 for(i=PMU_FIRST_COUNTER; pmd_mask && ret == 0; i++, pmd_mask >>=1) {
5307
5308 mask = 1UL << i;
5309
5310 if ((pmd_mask & 0x1) == 0) continue;
5311
5312 ovfl_arg->ovfl_pmd = (unsigned char )i;
5313 ovfl_arg->ovfl_notify = ovfl_notify & mask ? 1 : 0;
5314 ovfl_arg->active_set = 0;
5315 ovfl_arg->ovfl_ctrl.val = 0;
5316 ovfl_arg->smpl_pmds[0] = smpl_pmds = ctx->ctx_pmds[i].smpl_pmds[0];
5317
5318 ovfl_arg->pmd_value = ctx->ctx_pmds[i].val;
5319 ovfl_arg->pmd_last_reset = ctx->ctx_pmds[i].lval;
5320 ovfl_arg->pmd_eventid = ctx->ctx_pmds[i].eventid;
5321
5322
5323
5324
5325
5326 if (smpl_pmds) {
5327 for(j=0, k=0; smpl_pmds; j++, smpl_pmds >>=1) {
5328 if ((smpl_pmds & 0x1) == 0) continue;
5329 ovfl_arg->smpl_pmds_values[k++] = PMD_IS_COUNTING(j) ? pfm_read_soft_counter(ctx, j) : ia64_get_pmd(j);
5330 DPRINT_ovfl(("smpl_pmd[%d]=pmd%u=0x%lx\n", k-1, j, ovfl_arg->smpl_pmds_values[k-1]));
5331 }
5332 }
5333
5334 pfm_stats[this_cpu].pfm_smpl_handler_calls++;
5335
5336 start_cycles = ia64_get_itc();
5337
5338
5339
5340
5341 ret = (*ctx->ctx_buf_fmt->fmt_handler)(task, ctx->ctx_smpl_hdr, ovfl_arg, regs, tstamp);
5342
5343 end_cycles = ia64_get_itc();
5344
5345
5346
5347
5348
5349 ovfl_ctrl.bits.notify_user |= ovfl_arg->ovfl_ctrl.bits.notify_user;
5350 ovfl_ctrl.bits.block_task |= ovfl_arg->ovfl_ctrl.bits.block_task;
5351 ovfl_ctrl.bits.mask_monitoring |= ovfl_arg->ovfl_ctrl.bits.mask_monitoring;
5352
5353
5354
5355 if (ovfl_arg->ovfl_ctrl.bits.reset_ovfl_pmds) reset_pmds |= mask;
5356
5357 pfm_stats[this_cpu].pfm_smpl_handler_cycles += end_cycles - start_cycles;
5358 }
5359
5360
5361
5362 if (ret && pmd_mask) {
5363 DPRINT(("handler aborts leftover ovfl_pmds=0x%lx\n",
5364 pmd_mask<<PMU_FIRST_COUNTER));
5365 }
5366
5367
5368
5369 ovfl_pmds &= ~reset_pmds;
5370 } else {
5371
5372
5373
5374
5375 ovfl_ctrl.bits.notify_user = ovfl_notify ? 1 : 0;
5376 ovfl_ctrl.bits.block_task = ovfl_notify ? 1 : 0;
5377 ovfl_ctrl.bits.mask_monitoring = ovfl_notify ? 1 : 0;
5378 ovfl_ctrl.bits.reset_ovfl_pmds = ovfl_notify ? 0 : 1;
5379
5380
5381
5382 if (ovfl_notify == 0) reset_pmds = ovfl_pmds;
5383 }
5384
5385 DPRINT_ovfl(("ovfl_pmds=0x%lx reset_pmds=0x%lx\n", ovfl_pmds, reset_pmds));
5386
5387
5388
5389
5390 if (reset_pmds) {
5391 unsigned long bm = reset_pmds;
5392 pfm_reset_regs(ctx, &bm, PFM_PMD_SHORT_RESET);
5393 }
5394
5395 if (ovfl_notify && ovfl_ctrl.bits.notify_user) {
5396
5397
5398
5399 ctx->ctx_ovfl_regs[0] = ovfl_pmds;
5400
5401
5402
5403
5404 if (CTX_OVFL_NOBLOCK(ctx) == 0 && ovfl_ctrl.bits.block_task) {
5405
5406 ctx->ctx_fl_trap_reason = PFM_TRAP_REASON_BLOCK;
5407
5408
5409
5410
5411 PFM_SET_WORK_PENDING(task, 1);
5412
5413
5414
5415
5416
5417 tsk_set_notify_resume(task);
5418 }
5419
5420
5421
5422
5423 must_notify = 1;
5424 }
5425
5426 DPRINT_ovfl(("owner [%d] pending=%ld reason=%u ovfl_pmds=0x%lx ovfl_notify=0x%lx masked=%d\n",
5427 GET_PMU_OWNER() ? task_pid_nr(GET_PMU_OWNER()) : -1,
5428 PFM_GET_WORK_PENDING(task),
5429 ctx->ctx_fl_trap_reason,
5430 ovfl_pmds,
5431 ovfl_notify,
5432 ovfl_ctrl.bits.mask_monitoring ? 1 : 0));
5433
5434
5435
5436 if (ovfl_ctrl.bits.mask_monitoring) {
5437 pfm_mask_monitoring(task);
5438 ctx->ctx_state = PFM_CTX_MASKED;
5439 ctx->ctx_fl_can_restart = 1;
5440 }
5441
5442
5443
5444
5445 if (must_notify) pfm_ovfl_notify_user(ctx, ovfl_notify);
5446
5447 return;
5448
5449sanity_check:
5450 printk(KERN_ERR "perfmon: CPU%d overflow handler [%d] pmc0=0x%lx\n",
5451 smp_processor_id(),
5452 task ? task_pid_nr(task) : -1,
5453 pmc0);
5454 return;
5455
5456stop_monitoring:
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485 DPRINT(("ctx is zombie for [%d], converted to spurious\n", task ? task_pid_nr(task): -1));
5486 pfm_clear_psr_up();
5487 ia64_psr(regs)->up = 0;
5488 ia64_psr(regs)->sp = 1;
5489 return;
5490}
5491
5492static int
5493pfm_do_interrupt_handler(void *arg, struct pt_regs *regs)
5494{
5495 struct task_struct *task;
5496 pfm_context_t *ctx;
5497 unsigned long flags;
5498 u64 pmc0;
5499 int this_cpu = smp_processor_id();
5500 int retval = 0;