]> bbs.cooldavid.org Git - net-next-2.6.git/blob - arch/x86/kernel/cpu/perf_event_p4.c
x86, perf: Use apic_write unconditionally
[net-next-2.6.git] / arch / x86 / kernel / cpu / perf_event_p4.c
1 /*
2  * Netburst Perfomance Events (P4, old Xeon)
3  *
4  *  Copyright (C) 2010 Parallels, Inc., Cyrill Gorcunov <gorcunov@openvz.org>
5  *  Copyright (C) 2010 Intel Corporation, Lin Ming <ming.m.lin@intel.com>
6  *
7  *  For licencing details see kernel-base/COPYING
8  */
9
10 #ifdef CONFIG_CPU_SUP_INTEL
11
12 #include <asm/perf_event_p4.h>
13
14 /*
15  * array indices: 0,1 - HT threads, used with HT enabled cpu
16  */
17 struct p4_event_template {
18         u32 opcode;                     /* ESCR event + CCCR selector */
19         u64 config;                     /* packed predefined bits */
20         int dep;                        /* upstream dependency event index */
21         unsigned int emask;             /* ESCR EventMask */
22         unsigned int escr_msr[2];       /* ESCR MSR for this event */
23         unsigned int cntr[2];           /* counter index (offset) */
24 };
25
26 struct p4_pmu_res {
27         /* maps hw_conf::idx into template for ESCR sake */
28         struct p4_event_template *tpl[ARCH_P4_MAX_CCCR];
29 };
30
31 static DEFINE_PER_CPU(struct p4_pmu_res, p4_pmu_config);
32
33 /*
34  * WARN: CCCR1 doesn't have a working enable bit so try to not
35  * use it if possible
36  *
37  * Also as only we start to support raw events we will need to
38  * append _all_ P4_EVENT_PACK'ed events here
39  */
40 struct p4_event_template p4_templates[] = {
41         [0] = {
42                 .opcode = P4_UOP_TYPE,
43                 .config = 0,
44                 .dep    = -1,
45                 .emask  =
46                         P4_EVENT_ATTR(P4_UOP_TYPE, TAGLOADS)    |
47                         P4_EVENT_ATTR(P4_UOP_TYPE, TAGSTORES),
48                 .escr_msr       = { MSR_P4_RAT_ESCR0, MSR_P4_RAT_ESCR1 },
49                 .cntr           = { 16, 17 },
50         },
51         [1] = {
52                 .opcode = P4_GLOBAL_POWER_EVENTS,
53                 .config = 0,
54                 .dep    = -1,
55                 .emask  =
56                         P4_EVENT_ATTR(P4_GLOBAL_POWER_EVENTS, RUNNING),
57                 .escr_msr       = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
58                 .cntr           = { 0, 2 },
59         },
60         [2] = {
61                 .opcode = P4_INSTR_RETIRED,
62                 .config = 0,
63                 .dep    = -1, /* needs front-end tagging */
64                 .emask  =
65                         P4_EVENT_ATTR(P4_INSTR_RETIRED, NBOGUSNTAG)     |
66                         P4_EVENT_ATTR(P4_INSTR_RETIRED, BOGUSNTAG),
67                 .escr_msr       = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
68                 .cntr           = { 12, 14 },
69         },
70         [3] = {
71                 .opcode = P4_BSQ_CACHE_REFERENCE,
72                 .config = 0,
73                 .dep    = -1,
74                 .emask  =
75                         P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_2ndL_HITS)     |
76                         P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_2ndL_HITE)     |
77                         P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_2ndL_HITM)     |
78                         P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_3rdL_HITS)     |
79                         P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_3rdL_HITE)     |
80                         P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_3rdL_HITM),
81                 .escr_msr       = { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR1 },
82                 .cntr           = { 0, 2 },
83         },
84         [4] = {
85                 .opcode = P4_BSQ_CACHE_REFERENCE,
86                 .config = 0,
87                 .dep    = -1,
88                 .emask  =
89                         P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_2ndL_MISS)     |
90                         P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_3rdL_MISS)     |
91                         P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, WR_2ndL_MISS),
92                 .escr_msr       = { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR1 },
93                 .cntr           = { 0, 3 },
94         },
95         [5] = {
96                 .opcode = P4_RETIRED_BRANCH_TYPE,
97                 .config = 0,
98                 .dep    = -1,
99                 .emask  =
100                         P4_EVENT_ATTR(P4_RETIRED_BRANCH_TYPE, CONDITIONAL)      |
101                         P4_EVENT_ATTR(P4_RETIRED_BRANCH_TYPE, CALL)             |
102                         P4_EVENT_ATTR(P4_RETIRED_BRANCH_TYPE, RETURN)           |
103                         P4_EVENT_ATTR(P4_RETIRED_BRANCH_TYPE, INDIRECT),
104                 .escr_msr       = { MSR_P4_TBPU_ESCR0, MSR_P4_TBPU_ESCR1 },
105                 .cntr           = { 4, 6 },
106         },
107         [6] = {
108                 .opcode = P4_MISPRED_BRANCH_RETIRED,
109                 .config = 0,
110                 .dep    = -1,
111                 .emask  =
112                         P4_EVENT_ATTR(P4_MISPRED_BRANCH_RETIRED, NBOGUS),
113                 .escr_msr       = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
114                 .cntr           = { 12, 14 },
115         },
116         [7] = {
117                 .opcode = P4_FSB_DATA_ACTIVITY,
118                 .config = p4_config_pack_cccr(P4_CCCR_EDGE | P4_CCCR_COMPARE),
119                 .dep    = -1,
120                 .emask  =
121                         P4_EVENT_ATTR(P4_FSB_DATA_ACTIVITY, DRDY_DRV)   |
122                         P4_EVENT_ATTR(P4_FSB_DATA_ACTIVITY, DRDY_OWN),
123                 .escr_msr       = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
124                 .cntr           = { 0, 2 },
125         },
126 };
127
128 static struct p4_event_template *p4_event_map[PERF_COUNT_HW_MAX] = {
129         /* non-halted CPU clocks */
130         [PERF_COUNT_HW_CPU_CYCLES]              = &p4_templates[1],
131
132         /* retired instructions: dep on tagging the FSB */
133         [PERF_COUNT_HW_INSTRUCTIONS]            = &p4_templates[2],
134
135         /* cache hits */
136         [PERF_COUNT_HW_CACHE_REFERENCES]        = &p4_templates[3],
137
138         /* cache misses */
139         [PERF_COUNT_HW_CACHE_MISSES]            = &p4_templates[4],
140
141         /* branch instructions retired */
142         [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]     = &p4_templates[5],
143
144         /* mispredicted branches retired */
145         [PERF_COUNT_HW_BRANCH_MISSES]           = &p4_templates[6],
146
147         /* bus ready clocks (cpu is driving #DRDY_DRV\#DRDY_OWN):  */
148         [PERF_COUNT_HW_BUS_CYCLES]              = &p4_templates[7],
149 };
150
151 static u64 p4_pmu_event_map(int hw_event)
152 {
153         struct p4_event_template *tpl;
154         u64 config;
155
156         if (hw_event > ARRAY_SIZE(p4_event_map)) {
157                 printk_once(KERN_ERR "PMU: Incorrect event index\n");
158                 return 0;
159         }
160         tpl = p4_event_map[hw_event];
161
162         /*
163          * fill config up according to
164          * a predefined event template
165          */
166         config  = tpl->config;
167         config |= p4_config_pack_escr(P4_EVENT_UNPACK_EVENT(tpl->opcode) << P4_EVNTSEL_EVENT_SHIFT);
168         config |= p4_config_pack_escr(tpl->emask << P4_EVNTSEL_EVENTMASK_SHIFT);
169         config |= p4_config_pack_cccr(P4_EVENT_UNPACK_SELECTOR(tpl->opcode) << P4_CCCR_ESCR_SELECT_SHIFT);
170
171         /* on HT machine we need a special bit */
172         if (p4_ht_active() && p4_ht_thread(raw_smp_processor_id()))
173                 config = p4_set_ht_bit(config);
174
175         return config;
176 }
177
178 /*
179  * Note that we still have 5 events (from global events SDM list)
180  * intersected in opcode+emask bits so we will need another
181  * scheme there do distinguish templates.
182  */
183 static inline int p4_pmu_emask_match(unsigned int dst, unsigned int src)
184 {
185         return dst & src;
186 }
187
188 static struct p4_event_template *p4_pmu_template_lookup(u64 config)
189 {
190         u32 opcode = p4_config_unpack_opcode(config);
191         unsigned int emask = p4_config_unpack_emask(config);
192         unsigned int i;
193
194         for (i = 0; i < ARRAY_SIZE(p4_templates); i++) {
195                 if (opcode == p4_templates[i].opcode &&
196                         p4_pmu_emask_match(emask, p4_templates[i].emask))
197                         return &p4_templates[i];
198         }
199
200         return NULL;
201 }
202
203 /*
204  * We don't control raw events so it's up to the caller
205  * to pass sane values (and we don't count the thread number
206  * on HT machine but allow HT-compatible specifics to be
207  * passed on)
208  */
209 static u64 p4_pmu_raw_event(u64 hw_event)
210 {
211         return hw_event &
212                 (p4_config_pack_escr(P4_EVNTSEL_MASK_HT) |
213                  p4_config_pack_cccr(P4_CCCR_MASK_HT));
214 }
215
216 static int p4_hw_config(struct perf_event_attr *attr, struct hw_perf_event *hwc)
217 {
218         int cpu = raw_smp_processor_id();
219
220         /*
221          * the reason we use cpu that early is that: if we get scheduled
222          * first time on the same cpu -- we will not need swap thread
223          * specific flags in config (and will save some cpu cycles)
224          */
225
226         /* CCCR by default */
227         hwc->config = p4_config_pack_cccr(p4_default_cccr_conf(cpu));
228
229         /* Count user and OS events unless not requested to */
230         hwc->config |= p4_config_pack_escr(p4_default_escr_conf(cpu, attr->exclude_kernel,
231                                                                 attr->exclude_user));
232         return 0;
233 }
234
235 static inline void p4_pmu_clear_cccr_ovf(struct hw_perf_event *hwc)
236 {
237         unsigned long dummy;
238
239         rdmsrl(hwc->config_base + hwc->idx, dummy);
240         if (dummy & P4_CCCR_OVF) {
241                 (void)checking_wrmsrl(hwc->config_base + hwc->idx,
242                         ((u64)dummy) & ~P4_CCCR_OVF);
243         }
244 }
245
246 static inline void p4_pmu_disable_event(struct perf_event *event)
247 {
248         struct hw_perf_event *hwc = &event->hw;
249
250         /*
251          * If event gets disabled while counter is in overflowed
252          * state we need to clear P4_CCCR_OVF, otherwise interrupt get
253          * asserted again and again
254          */
255         (void)checking_wrmsrl(hwc->config_base + hwc->idx,
256                 (u64)(p4_config_unpack_cccr(hwc->config)) &
257                         ~P4_CCCR_ENABLE & ~P4_CCCR_OVF);
258 }
259
260 static void p4_pmu_disable_all(void)
261 {
262         struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
263         int idx;
264
265         for (idx = 0; idx < x86_pmu.num_events; idx++) {
266                 struct perf_event *event = cpuc->events[idx];
267                 if (!test_bit(idx, cpuc->active_mask))
268                         continue;
269                 p4_pmu_disable_event(event);
270         }
271 }
272
273 static void p4_pmu_enable_event(struct perf_event *event)
274 {
275         struct hw_perf_event *hwc = &event->hw;
276         int thread = p4_ht_config_thread(hwc->config);
277         u64 escr_conf = p4_config_unpack_escr(p4_clear_ht_bit(hwc->config));
278         u64 escr_base;
279         struct p4_event_template *tpl;
280         struct p4_pmu_res *c;
281
282         /*
283          * some preparation work from per-cpu private fields
284          * since we need to find out which ESCR to use
285          */
286         c = &__get_cpu_var(p4_pmu_config);
287         tpl = c->tpl[hwc->idx];
288         if (!tpl) {
289                 pr_crit("%s: Wrong index: %d\n", __func__, hwc->idx);
290                 return;
291         }
292         escr_base = (u64)tpl->escr_msr[thread];
293
294         /*
295          * - we dont support cascaded counters yet
296          * - and counter 1 is broken (erratum)
297          */
298         WARN_ON_ONCE(p4_is_event_cascaded(hwc->config));
299         WARN_ON_ONCE(hwc->idx == 1);
300
301         (void)checking_wrmsrl(escr_base, escr_conf);
302         (void)checking_wrmsrl(hwc->config_base + hwc->idx,
303                 (u64)(p4_config_unpack_cccr(hwc->config)) | P4_CCCR_ENABLE);
304 }
305
306 static void p4_pmu_enable_all(void)
307 {
308         struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
309         int idx;
310
311         for (idx = 0; idx < x86_pmu.num_events; idx++) {
312                 struct perf_event *event = cpuc->events[idx];
313                 if (!test_bit(idx, cpuc->active_mask))
314                         continue;
315                 p4_pmu_enable_event(event);
316         }
317 }
318
319 static int p4_pmu_handle_irq(struct pt_regs *regs)
320 {
321         struct perf_sample_data data;
322         struct cpu_hw_events *cpuc;
323         struct perf_event *event;
324         struct hw_perf_event *hwc;
325         int idx, handled = 0;
326         u64 val;
327
328         data.addr = 0;
329         data.raw = NULL;
330
331         cpuc = &__get_cpu_var(cpu_hw_events);
332
333         for (idx = 0; idx < x86_pmu.num_events; idx++) {
334
335                 if (!test_bit(idx, cpuc->active_mask))
336                         continue;
337
338                 event = cpuc->events[idx];
339                 hwc = &event->hw;
340
341                 WARN_ON_ONCE(hwc->idx != idx);
342
343                 /*
344                  * FIXME: Redundant call, actually not needed
345                  * but just to check if we're screwed
346                  */
347                 p4_pmu_clear_cccr_ovf(hwc);
348
349                 val = x86_perf_event_update(event);
350                 if (val & (1ULL << (x86_pmu.event_bits - 1)))
351                         continue;
352
353                 /*
354                  * event overflow
355                  */
356                 handled         = 1;
357                 data.period     = event->hw.last_period;
358
359                 if (!x86_perf_event_set_period(event))
360                         continue;
361                 if (perf_event_overflow(event, 1, &data, regs))
362                         p4_pmu_disable_event(event);
363         }
364
365         if (handled) {
366                 /* p4 quirk: unmask it again */
367                 apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED);
368                 inc_irq_stat(apic_perf_irqs);
369         }
370
371         return handled;
372 }
373
374 /*
375  * swap thread specific fields according to a thread
376  * we are going to run on
377  */
378 static void p4_pmu_swap_config_ts(struct hw_perf_event *hwc, int cpu)
379 {
380         u32 escr, cccr;
381
382         /*
383          * we either lucky and continue on same cpu or no HT support
384          */
385         if (!p4_should_swap_ts(hwc->config, cpu))
386                 return;
387
388         /*
389          * the event is migrated from an another logical
390          * cpu, so we need to swap thread specific flags
391          */
392
393         escr = p4_config_unpack_escr(hwc->config);
394         cccr = p4_config_unpack_cccr(hwc->config);
395
396         if (p4_ht_thread(cpu)) {
397                 cccr &= ~P4_CCCR_OVF_PMI_T0;
398                 cccr |= P4_CCCR_OVF_PMI_T1;
399                 if (escr & P4_EVNTSEL_T0_OS) {
400                         escr &= ~P4_EVNTSEL_T0_OS;
401                         escr |= P4_EVNTSEL_T1_OS;
402                 }
403                 if (escr & P4_EVNTSEL_T0_USR) {
404                         escr &= ~P4_EVNTSEL_T0_USR;
405                         escr |= P4_EVNTSEL_T1_USR;
406                 }
407                 hwc->config  = p4_config_pack_escr(escr);
408                 hwc->config |= p4_config_pack_cccr(cccr);
409                 hwc->config |= P4_CONFIG_HT;
410         } else {
411                 cccr &= ~P4_CCCR_OVF_PMI_T1;
412                 cccr |= P4_CCCR_OVF_PMI_T0;
413                 if (escr & P4_EVNTSEL_T1_OS) {
414                         escr &= ~P4_EVNTSEL_T1_OS;
415                         escr |= P4_EVNTSEL_T0_OS;
416                 }
417                 if (escr & P4_EVNTSEL_T1_USR) {
418                         escr &= ~P4_EVNTSEL_T1_USR;
419                         escr |= P4_EVNTSEL_T0_USR;
420                 }
421                 hwc->config  = p4_config_pack_escr(escr);
422                 hwc->config |= p4_config_pack_cccr(cccr);
423                 hwc->config &= ~P4_CONFIG_HT;
424         }
425 }
426
427 /* ESCRs are not sequential in memory so we need a map */
428 static unsigned int p4_escr_map[ARCH_P4_TOTAL_ESCR] = {
429         MSR_P4_ALF_ESCR0,       /*  0 */
430         MSR_P4_ALF_ESCR1,       /*  1 */
431         MSR_P4_BPU_ESCR0,       /*  2 */
432         MSR_P4_BPU_ESCR1,       /*  3 */
433         MSR_P4_BSU_ESCR0,       /*  4 */
434         MSR_P4_BSU_ESCR1,       /*  5 */
435         MSR_P4_CRU_ESCR0,       /*  6 */
436         MSR_P4_CRU_ESCR1,       /*  7 */
437         MSR_P4_CRU_ESCR2,       /*  8 */
438         MSR_P4_CRU_ESCR3,       /*  9 */
439         MSR_P4_CRU_ESCR4,       /* 10 */
440         MSR_P4_CRU_ESCR5,       /* 11 */
441         MSR_P4_DAC_ESCR0,       /* 12 */
442         MSR_P4_DAC_ESCR1,       /* 13 */
443         MSR_P4_FIRM_ESCR0,      /* 14 */
444         MSR_P4_FIRM_ESCR1,      /* 15 */
445         MSR_P4_FLAME_ESCR0,     /* 16 */
446         MSR_P4_FLAME_ESCR1,     /* 17 */
447         MSR_P4_FSB_ESCR0,       /* 18 */
448         MSR_P4_FSB_ESCR1,       /* 19 */
449         MSR_P4_IQ_ESCR0,        /* 20 */
450         MSR_P4_IQ_ESCR1,        /* 21 */
451         MSR_P4_IS_ESCR0,        /* 22 */
452         MSR_P4_IS_ESCR1,        /* 23 */
453         MSR_P4_ITLB_ESCR0,      /* 24 */
454         MSR_P4_ITLB_ESCR1,      /* 25 */
455         MSR_P4_IX_ESCR0,        /* 26 */
456         MSR_P4_IX_ESCR1,        /* 27 */
457         MSR_P4_MOB_ESCR0,       /* 28 */
458         MSR_P4_MOB_ESCR1,       /* 29 */
459         MSR_P4_MS_ESCR0,        /* 30 */
460         MSR_P4_MS_ESCR1,        /* 31 */
461         MSR_P4_PMH_ESCR0,       /* 32 */
462         MSR_P4_PMH_ESCR1,       /* 33 */
463         MSR_P4_RAT_ESCR0,       /* 34 */
464         MSR_P4_RAT_ESCR1,       /* 35 */
465         MSR_P4_SAAT_ESCR0,      /* 36 */
466         MSR_P4_SAAT_ESCR1,      /* 37 */
467         MSR_P4_SSU_ESCR0,       /* 38 */
468         MSR_P4_SSU_ESCR1,       /* 39 */
469         MSR_P4_TBPU_ESCR0,      /* 40 */
470         MSR_P4_TBPU_ESCR1,      /* 41 */
471         MSR_P4_TC_ESCR0,        /* 42 */
472         MSR_P4_TC_ESCR1,        /* 43 */
473         MSR_P4_U2L_ESCR0,       /* 44 */
474         MSR_P4_U2L_ESCR1,       /* 45 */
475 };
476
477 static int p4_get_escr_idx(unsigned int addr)
478 {
479         unsigned int i;
480
481         for (i = 0; i < ARRAY_SIZE(p4_escr_map); i++) {
482                 if (addr == p4_escr_map[i])
483                         return i;
484         }
485
486         return -1;
487 }
488
489 static int p4_pmu_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
490 {
491         unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
492         unsigned long escr_mask[BITS_TO_LONGS(ARCH_P4_TOTAL_ESCR)];
493
494         struct hw_perf_event *hwc;
495         struct p4_event_template *tpl;
496         struct p4_pmu_res *c;
497         int cpu = raw_smp_processor_id();
498         int escr_idx, thread, i, num;
499
500         bitmap_zero(used_mask, X86_PMC_IDX_MAX);
501         bitmap_zero(escr_mask, ARCH_P4_TOTAL_ESCR);
502
503         c = &__get_cpu_var(p4_pmu_config);
504         /*
505          * Firstly find out which resource events are going
506          * to use, if ESCR+CCCR tuple is already borrowed
507          * then get out of here
508          */
509         for (i = 0, num = n; i < n; i++, num--) {
510                 hwc = &cpuc->event_list[i]->hw;
511                 tpl = p4_pmu_template_lookup(hwc->config);
512                 if (!tpl)
513                         goto done;
514                 thread = p4_ht_thread(cpu);
515                 escr_idx = p4_get_escr_idx(tpl->escr_msr[thread]);
516                 if (escr_idx == -1)
517                         goto done;
518
519                 /* already allocated and remains on the same cpu */
520                 if (hwc->idx != -1 && !p4_should_swap_ts(hwc->config, cpu)) {
521                         if (assign)
522                                 assign[i] = hwc->idx;
523                         /* upstream dependent event */
524                         if (unlikely(tpl->dep != -1))
525                                 printk_once(KERN_WARNING "PMU: Dep events are "
526                                         "not implemented yet\n");
527                         goto reserve;
528                 }
529
530                 /* it may be already borrowed */
531                 if (test_bit(tpl->cntr[thread], used_mask) ||
532                         test_bit(escr_idx, escr_mask))
533                         goto done;
534
535                 /*
536                  * ESCR+CCCR+COUNTERs are available to use lets swap
537                  * thread specific bits, push assigned bits
538                  * back and save template into per-cpu
539                  * area (which will allow us to find out the ESCR
540                  * to be used at moment of "enable event via real MSR")
541                  */
542                 p4_pmu_swap_config_ts(hwc, cpu);
543                 if (assign) {
544                         assign[i] = tpl->cntr[thread];
545                         c->tpl[assign[i]] = tpl;
546                 }
547 reserve:
548                 set_bit(tpl->cntr[thread], used_mask);
549                 set_bit(escr_idx, escr_mask);
550         }
551
552 done:
553         return num ? -ENOSPC : 0;
554 }
555
556 static __initconst struct x86_pmu p4_pmu = {
557         .name                   = "Netburst P4/Xeon",
558         .handle_irq             = p4_pmu_handle_irq,
559         .disable_all            = p4_pmu_disable_all,
560         .enable_all             = p4_pmu_enable_all,
561         .enable                 = p4_pmu_enable_event,
562         .disable                = p4_pmu_disable_event,
563         .eventsel               = MSR_P4_BPU_CCCR0,
564         .perfctr                = MSR_P4_BPU_PERFCTR0,
565         .event_map              = p4_pmu_event_map,
566         .raw_event              = p4_pmu_raw_event,
567         .max_events             = ARRAY_SIZE(p4_event_map),
568         .get_event_constraints  = x86_get_event_constraints,
569         /*
570          * IF HT disabled we may need to use all
571          * ARCH_P4_MAX_CCCR counters simulaneously
572          * though leave it restricted at moment assuming
573          * HT is on
574          */
575         .num_events             = ARCH_P4_MAX_CCCR,
576         .apic                   = 1,
577         .event_bits             = 40,
578         .event_mask             = (1ULL << 40) - 1,
579         .max_period             = (1ULL << 39) - 1,
580         .hw_config              = p4_hw_config,
581         .schedule_events        = p4_pmu_schedule_events,
582 };
583
584 static __init int p4_pmu_init(void)
585 {
586         unsigned int low, high;
587
588         /* If we get stripped -- indexig fails */
589         BUILD_BUG_ON(ARCH_P4_MAX_CCCR > X86_PMC_MAX_GENERIC);
590
591         rdmsr(MSR_IA32_MISC_ENABLE, low, high);
592         if (!(low & (1 << 7))) {
593                 pr_cont("unsupported Netburst CPU model %d ",
594                         boot_cpu_data.x86_model);
595                 return -ENODEV;
596         }
597
598         pr_cont("Netburst events, ");
599
600         x86_pmu = p4_pmu;
601
602         return 0;
603 }
604
605 #endif /* CONFIG_CPU_SUP_INTEL */