Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arch: x86: Remove CONFIG_OPROFILE support

The "oprofile" user-space tools don't use the kernel OPROFILE support
any more, and haven't in a long time. User-space has been converted to
the perf interfaces.

Remove the old oprofile's architecture specific support.

Suggested-by: Christoph Hellwig <hch@infradead.org>
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Acked-by: Robert Richter <rric@kernel.org>
Acked-by: William Cohen <wcohen@redhat.com>
Acked-by: Al Viro <viro@zeniv.linux.org.uk>
Acked-by: Thomas Gleixner <tglx@linutronix.de>

+1 -2602
-1
arch/x86/Kconfig
··· 206 206 select HAVE_MOVE_PMD 207 207 select HAVE_MOVE_PUD 208 208 select HAVE_NMI 209 - select HAVE_OPROFILE 210 209 select HAVE_OPTPROBES 211 210 select HAVE_PCSPKR_PLATFORM 212 211 select HAVE_PERF_EVENTS
-3
arch/x86/Makefile
··· 229 229 drivers-$(CONFIG_MATH_EMULATION) += arch/x86/math-emu/ 230 230 drivers-$(CONFIG_PCI) += arch/x86/pci/ 231 231 232 - # must be linked after kernel/ 233 - drivers-$(CONFIG_OPROFILE) += arch/x86/oprofile/ 234 - 235 232 # suspend and hibernation support 236 233 drivers-$(CONFIG_PM) += arch/x86/power/ 237 234
-1
arch/x86/include/asm/nmi.h
··· 9 9 10 10 #ifdef CONFIG_X86_LOCAL_APIC 11 11 12 - extern int avail_to_resrv_perfctr_nmi_bit(unsigned int); 13 12 extern int reserve_perfctr_nmi(unsigned int); 14 13 extern void release_perfctr_nmi(unsigned int); 15 14 extern int reserve_evntsel_nmi(unsigned int);
+1 -10
arch/x86/kernel/cpu/perfctr-watchdog.c
··· 3 3 * local apic based NMI watchdog for various CPUs. 4 4 * 5 5 * This file also handles reservation of performance counters for coordination 6 - * with other users (like oprofile). 6 + * with other users. 7 7 * 8 8 * Note that these events normally don't tick when the CPU idles. This means 9 9 * the frequency varies with CPU load. ··· 104 104 return 0; 105 105 106 106 } 107 - 108 - /* checks for a bit availability (hack for oprofile) */ 109 - int avail_to_resrv_perfctr_nmi_bit(unsigned int counter) 110 - { 111 - BUG_ON(counter > NMI_MAX_COUNTER_BITS); 112 - 113 - return !test_bit(counter, perfctr_nmi_owner); 114 - } 115 - EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi_bit); 116 107 117 108 int reserve_perfctr_nmi(unsigned int msr) 118 109 {
-12
arch/x86/oprofile/Makefile
··· 1 - # SPDX-License-Identifier: GPL-2.0 2 - obj-$(CONFIG_OPROFILE) += oprofile.o 3 - 4 - DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ 5 - oprof.o cpu_buffer.o buffer_sync.o \ 6 - event_buffer.o oprofile_files.o \ 7 - oprofilefs.o oprofile_stats.o \ 8 - timer_int.o nmi_timer_int.o ) 9 - 10 - oprofile-y := $(DRIVER_OBJS) init.o backtrace.o 11 - oprofile-$(CONFIG_X86_LOCAL_APIC) += nmi_int.o op_model_amd.o \ 12 - op_model_ppro.o op_model_p4.o
-127
arch/x86/oprofile/backtrace.c
··· 1 - /** 2 - * @file backtrace.c 3 - * 4 - * @remark Copyright 2002 OProfile authors 5 - * @remark Read the file COPYING 6 - * 7 - * @author John Levon 8 - * @author David Smith 9 - */ 10 - 11 - #include <linux/oprofile.h> 12 - #include <linux/sched.h> 13 - #include <linux/mm.h> 14 - #include <linux/compat.h> 15 - #include <linux/uaccess.h> 16 - 17 - #include <asm/ptrace.h> 18 - #include <asm/stacktrace.h> 19 - #include <asm/unwind.h> 20 - 21 - #ifdef CONFIG_COMPAT 22 - static struct stack_frame_ia32 * 23 - dump_user_backtrace_32(struct stack_frame_ia32 *head) 24 - { 25 - /* Also check accessibility of one struct frame_head beyond: */ 26 - struct stack_frame_ia32 bufhead[2]; 27 - struct stack_frame_ia32 *fp; 28 - unsigned long bytes; 29 - 30 - bytes = copy_from_user_nmi(bufhead, head, sizeof(bufhead)); 31 - if (bytes != 0) 32 - return NULL; 33 - 34 - fp = (struct stack_frame_ia32 *) compat_ptr(bufhead[0].next_frame); 35 - 36 - oprofile_add_trace(bufhead[0].return_address); 37 - 38 - /* frame pointers should strictly progress back up the stack 39 - * (towards higher addresses) */ 40 - if (head >= fp) 41 - return NULL; 42 - 43 - return fp; 44 - } 45 - 46 - static inline int 47 - x86_backtrace_32(struct pt_regs * const regs, unsigned int depth) 48 - { 49 - struct stack_frame_ia32 *head; 50 - 51 - /* User process is IA32 */ 52 - if (!current || user_64bit_mode(regs)) 53 - return 0; 54 - 55 - head = (struct stack_frame_ia32 *) regs->bp; 56 - while (depth-- && head) 57 - head = dump_user_backtrace_32(head); 58 - 59 - return 1; 60 - } 61 - 62 - #else 63 - static inline int 64 - x86_backtrace_32(struct pt_regs * const regs, unsigned int depth) 65 - { 66 - return 0; 67 - } 68 - #endif /* CONFIG_COMPAT */ 69 - 70 - static struct stack_frame *dump_user_backtrace(struct stack_frame *head) 71 - { 72 - /* Also check accessibility of one struct frame_head beyond: */ 73 - struct stack_frame bufhead[2]; 74 - unsigned long bytes; 75 - 76 - bytes = copy_from_user_nmi(bufhead, head, sizeof(bufhead)); 77 - if (bytes != 0) 78 - return NULL; 79 - 80 - oprofile_add_trace(bufhead[0].return_address); 81 - 82 - /* frame pointers should strictly progress back up the stack 83 - * (towards higher addresses) */ 84 - if (head >= bufhead[0].next_frame) 85 - return NULL; 86 - 87 - return bufhead[0].next_frame; 88 - } 89 - 90 - void 91 - x86_backtrace(struct pt_regs * const regs, unsigned int depth) 92 - { 93 - struct stack_frame *head = (struct stack_frame *)frame_pointer(regs); 94 - 95 - if (!user_mode(regs)) { 96 - struct unwind_state state; 97 - unsigned long addr; 98 - 99 - if (!depth) 100 - return; 101 - 102 - oprofile_add_trace(regs->ip); 103 - 104 - if (!--depth) 105 - return; 106 - 107 - for (unwind_start(&state, current, regs, NULL); 108 - !unwind_done(&state); unwind_next_frame(&state)) { 109 - addr = unwind_get_return_address(&state); 110 - if (!addr) 111 - break; 112 - 113 - oprofile_add_trace(addr); 114 - 115 - if (!--depth) 116 - break; 117 - } 118 - 119 - return; 120 - } 121 - 122 - if (x86_backtrace_32(regs, depth)) 123 - return; 124 - 125 - while (depth-- && head) 126 - head = dump_user_backtrace(head); 127 - }
-38
arch/x86/oprofile/init.c
··· 1 - /** 2 - * @file init.c 3 - * 4 - * @remark Copyright 2002 OProfile authors 5 - * @remark Read the file COPYING 6 - * 7 - * @author John Levon <levon@movementarian.org> 8 - */ 9 - 10 - #include <linux/oprofile.h> 11 - #include <linux/init.h> 12 - #include <linux/errno.h> 13 - 14 - /* 15 - * We support CPUs that have performance counters like the Pentium Pro 16 - * with the NMI mode driver. 17 - */ 18 - 19 - #ifdef CONFIG_X86_LOCAL_APIC 20 - extern int op_nmi_init(struct oprofile_operations *ops); 21 - extern void op_nmi_exit(void); 22 - #else 23 - static int op_nmi_init(struct oprofile_operations *ops) { return -ENODEV; } 24 - static void op_nmi_exit(void) { } 25 - #endif 26 - 27 - extern void x86_backtrace(struct pt_regs * const regs, unsigned int depth); 28 - 29 - int __init oprofile_arch_init(struct oprofile_operations *ops) 30 - { 31 - ops->backtrace = x86_backtrace; 32 - return op_nmi_init(ops); 33 - } 34 - 35 - void oprofile_arch_exit(void) 36 - { 37 - op_nmi_exit(); 38 - }
-780
arch/x86/oprofile/nmi_int.c
··· 1 - /** 2 - * @file nmi_int.c 3 - * 4 - * @remark Copyright 2002-2009 OProfile authors 5 - * @remark Read the file COPYING 6 - * 7 - * @author John Levon <levon@movementarian.org> 8 - * @author Robert Richter <robert.richter@amd.com> 9 - * @author Barry Kasindorf <barry.kasindorf@amd.com> 10 - * @author Jason Yeh <jason.yeh@amd.com> 11 - * @author Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> 12 - */ 13 - 14 - #include <linux/init.h> 15 - #include <linux/notifier.h> 16 - #include <linux/smp.h> 17 - #include <linux/oprofile.h> 18 - #include <linux/syscore_ops.h> 19 - #include <linux/slab.h> 20 - #include <linux/moduleparam.h> 21 - #include <linux/kdebug.h> 22 - #include <linux/cpu.h> 23 - #include <asm/nmi.h> 24 - #include <asm/msr.h> 25 - #include <asm/apic.h> 26 - 27 - #include "op_counter.h" 28 - #include "op_x86_model.h" 29 - 30 - static struct op_x86_model_spec *model; 31 - static DEFINE_PER_CPU(struct op_msrs, cpu_msrs); 32 - static DEFINE_PER_CPU(unsigned long, saved_lvtpc); 33 - 34 - /* must be protected with get_online_cpus()/put_online_cpus(): */ 35 - static int nmi_enabled; 36 - static int ctr_running; 37 - 38 - struct op_counter_config counter_config[OP_MAX_COUNTER]; 39 - 40 - /* common functions */ 41 - 42 - u64 op_x86_get_ctrl(struct op_x86_model_spec const *model, 43 - struct op_counter_config *counter_config) 44 - { 45 - u64 val = 0; 46 - u16 event = (u16)counter_config->event; 47 - 48 - val |= ARCH_PERFMON_EVENTSEL_INT; 49 - val |= counter_config->user ? ARCH_PERFMON_EVENTSEL_USR : 0; 50 - val |= counter_config->kernel ? ARCH_PERFMON_EVENTSEL_OS : 0; 51 - val |= (counter_config->unit_mask & 0xFF) << 8; 52 - counter_config->extra &= (ARCH_PERFMON_EVENTSEL_INV | 53 - ARCH_PERFMON_EVENTSEL_EDGE | 54 - ARCH_PERFMON_EVENTSEL_CMASK); 55 - val |= counter_config->extra; 56 - event &= model->event_mask ? model->event_mask : 0xFF; 57 - val |= event & 0xFF; 58 - val |= (u64)(event & 0x0F00) << 24; 59 - 60 - return val; 61 - } 62 - 63 - 64 - static int profile_exceptions_notify(unsigned int val, struct pt_regs *regs) 65 - { 66 - if (ctr_running) 67 - model->check_ctrs(regs, this_cpu_ptr(&cpu_msrs)); 68 - else if (!nmi_enabled) 69 - return NMI_DONE; 70 - else 71 - model->stop(this_cpu_ptr(&cpu_msrs)); 72 - return NMI_HANDLED; 73 - } 74 - 75 - static void nmi_cpu_save_registers(struct op_msrs *msrs) 76 - { 77 - struct op_msr *counters = msrs->counters; 78 - struct op_msr *controls = msrs->controls; 79 - unsigned int i; 80 - 81 - for (i = 0; i < model->num_counters; ++i) { 82 - if (counters[i].addr) 83 - rdmsrl(counters[i].addr, counters[i].saved); 84 - } 85 - 86 - for (i = 0; i < model->num_controls; ++i) { 87 - if (controls[i].addr) 88 - rdmsrl(controls[i].addr, controls[i].saved); 89 - } 90 - } 91 - 92 - static void nmi_cpu_start(void *dummy) 93 - { 94 - struct op_msrs const *msrs = this_cpu_ptr(&cpu_msrs); 95 - if (!msrs->controls) 96 - WARN_ON_ONCE(1); 97 - else 98 - model->start(msrs); 99 - } 100 - 101 - static int nmi_start(void) 102 - { 103 - get_online_cpus(); 104 - ctr_running = 1; 105 - /* make ctr_running visible to the nmi handler: */ 106 - smp_mb(); 107 - on_each_cpu(nmi_cpu_start, NULL, 1); 108 - put_online_cpus(); 109 - return 0; 110 - } 111 - 112 - static void nmi_cpu_stop(void *dummy) 113 - { 114 - struct op_msrs const *msrs = this_cpu_ptr(&cpu_msrs); 115 - if (!msrs->controls) 116 - WARN_ON_ONCE(1); 117 - else 118 - model->stop(msrs); 119 - } 120 - 121 - static void nmi_stop(void) 122 - { 123 - get_online_cpus(); 124 - on_each_cpu(nmi_cpu_stop, NULL, 1); 125 - ctr_running = 0; 126 - put_online_cpus(); 127 - } 128 - 129 - #ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX 130 - 131 - static DEFINE_PER_CPU(int, switch_index); 132 - 133 - static inline int has_mux(void) 134 - { 135 - return !!model->switch_ctrl; 136 - } 137 - 138 - inline int op_x86_phys_to_virt(int phys) 139 - { 140 - return __this_cpu_read(switch_index) + phys; 141 - } 142 - 143 - inline int op_x86_virt_to_phys(int virt) 144 - { 145 - return virt % model->num_counters; 146 - } 147 - 148 - static void nmi_shutdown_mux(void) 149 - { 150 - int i; 151 - 152 - if (!has_mux()) 153 - return; 154 - 155 - for_each_possible_cpu(i) { 156 - kfree(per_cpu(cpu_msrs, i).multiplex); 157 - per_cpu(cpu_msrs, i).multiplex = NULL; 158 - per_cpu(switch_index, i) = 0; 159 - } 160 - } 161 - 162 - static int nmi_setup_mux(void) 163 - { 164 - size_t multiplex_size = 165 - sizeof(struct op_msr) * model->num_virt_counters; 166 - int i; 167 - 168 - if (!has_mux()) 169 - return 1; 170 - 171 - for_each_possible_cpu(i) { 172 - per_cpu(cpu_msrs, i).multiplex = 173 - kzalloc(multiplex_size, GFP_KERNEL); 174 - if (!per_cpu(cpu_msrs, i).multiplex) 175 - return 0; 176 - } 177 - 178 - return 1; 179 - } 180 - 181 - static void nmi_cpu_setup_mux(int cpu, struct op_msrs const * const msrs) 182 - { 183 - int i; 184 - struct op_msr *multiplex = msrs->multiplex; 185 - 186 - if (!has_mux()) 187 - return; 188 - 189 - for (i = 0; i < model->num_virt_counters; ++i) { 190 - if (counter_config[i].enabled) { 191 - multiplex[i].saved = -(u64)counter_config[i].count; 192 - } else { 193 - multiplex[i].saved = 0; 194 - } 195 - } 196 - 197 - per_cpu(switch_index, cpu) = 0; 198 - } 199 - 200 - static void nmi_cpu_save_mpx_registers(struct op_msrs *msrs) 201 - { 202 - struct op_msr *counters = msrs->counters; 203 - struct op_msr *multiplex = msrs->multiplex; 204 - int i; 205 - 206 - for (i = 0; i < model->num_counters; ++i) { 207 - int virt = op_x86_phys_to_virt(i); 208 - if (counters[i].addr) 209 - rdmsrl(counters[i].addr, multiplex[virt].saved); 210 - } 211 - } 212 - 213 - static void nmi_cpu_restore_mpx_registers(struct op_msrs *msrs) 214 - { 215 - struct op_msr *counters = msrs->counters; 216 - struct op_msr *multiplex = msrs->multiplex; 217 - int i; 218 - 219 - for (i = 0; i < model->num_counters; ++i) { 220 - int virt = op_x86_phys_to_virt(i); 221 - if (counters[i].addr) 222 - wrmsrl(counters[i].addr, multiplex[virt].saved); 223 - } 224 - } 225 - 226 - static void nmi_cpu_switch(void *dummy) 227 - { 228 - int cpu = smp_processor_id(); 229 - int si = per_cpu(switch_index, cpu); 230 - struct op_msrs *msrs = &per_cpu(cpu_msrs, cpu); 231 - 232 - nmi_cpu_stop(NULL); 233 - nmi_cpu_save_mpx_registers(msrs); 234 - 235 - /* move to next set */ 236 - si += model->num_counters; 237 - if ((si >= model->num_virt_counters) || (counter_config[si].count == 0)) 238 - per_cpu(switch_index, cpu) = 0; 239 - else 240 - per_cpu(switch_index, cpu) = si; 241 - 242 - model->switch_ctrl(model, msrs); 243 - nmi_cpu_restore_mpx_registers(msrs); 244 - 245 - nmi_cpu_start(NULL); 246 - } 247 - 248 - 249 - /* 250 - * Quick check to see if multiplexing is necessary. 251 - * The check should be sufficient since counters are used 252 - * in ordre. 253 - */ 254 - static int nmi_multiplex_on(void) 255 - { 256 - return counter_config[model->num_counters].count ? 0 : -EINVAL; 257 - } 258 - 259 - static int nmi_switch_event(void) 260 - { 261 - if (!has_mux()) 262 - return -ENOSYS; /* not implemented */ 263 - if (nmi_multiplex_on() < 0) 264 - return -EINVAL; /* not necessary */ 265 - 266 - get_online_cpus(); 267 - if (ctr_running) 268 - on_each_cpu(nmi_cpu_switch, NULL, 1); 269 - put_online_cpus(); 270 - 271 - return 0; 272 - } 273 - 274 - static inline void mux_init(struct oprofile_operations *ops) 275 - { 276 - if (has_mux()) 277 - ops->switch_events = nmi_switch_event; 278 - } 279 - 280 - static void mux_clone(int cpu) 281 - { 282 - if (!has_mux()) 283 - return; 284 - 285 - memcpy(per_cpu(cpu_msrs, cpu).multiplex, 286 - per_cpu(cpu_msrs, 0).multiplex, 287 - sizeof(struct op_msr) * model->num_virt_counters); 288 - } 289 - 290 - #else 291 - 292 - inline int op_x86_phys_to_virt(int phys) { return phys; } 293 - inline int op_x86_virt_to_phys(int virt) { return virt; } 294 - static inline void nmi_shutdown_mux(void) { } 295 - static inline int nmi_setup_mux(void) { return 1; } 296 - static inline void 297 - nmi_cpu_setup_mux(int cpu, struct op_msrs const * const msrs) { } 298 - static inline void mux_init(struct oprofile_operations *ops) { } 299 - static void mux_clone(int cpu) { } 300 - 301 - #endif 302 - 303 - static void free_msrs(void) 304 - { 305 - int i; 306 - for_each_possible_cpu(i) { 307 - kfree(per_cpu(cpu_msrs, i).counters); 308 - per_cpu(cpu_msrs, i).counters = NULL; 309 - kfree(per_cpu(cpu_msrs, i).controls); 310 - per_cpu(cpu_msrs, i).controls = NULL; 311 - } 312 - nmi_shutdown_mux(); 313 - } 314 - 315 - static int allocate_msrs(void) 316 - { 317 - size_t controls_size = sizeof(struct op_msr) * model->num_controls; 318 - size_t counters_size = sizeof(struct op_msr) * model->num_counters; 319 - 320 - int i; 321 - for_each_possible_cpu(i) { 322 - per_cpu(cpu_msrs, i).counters = kzalloc(counters_size, 323 - GFP_KERNEL); 324 - if (!per_cpu(cpu_msrs, i).counters) 325 - goto fail; 326 - per_cpu(cpu_msrs, i).controls = kzalloc(controls_size, 327 - GFP_KERNEL); 328 - if (!per_cpu(cpu_msrs, i).controls) 329 - goto fail; 330 - } 331 - 332 - if (!nmi_setup_mux()) 333 - goto fail; 334 - 335 - return 1; 336 - 337 - fail: 338 - free_msrs(); 339 - return 0; 340 - } 341 - 342 - static void nmi_cpu_setup(void) 343 - { 344 - int cpu = smp_processor_id(); 345 - struct op_msrs *msrs = &per_cpu(cpu_msrs, cpu); 346 - 347 - nmi_cpu_save_registers(msrs); 348 - raw_spin_lock(&oprofilefs_lock); 349 - model->setup_ctrs(model, msrs); 350 - nmi_cpu_setup_mux(cpu, msrs); 351 - raw_spin_unlock(&oprofilefs_lock); 352 - per_cpu(saved_lvtpc, cpu) = apic_read(APIC_LVTPC); 353 - apic_write(APIC_LVTPC, APIC_DM_NMI); 354 - } 355 - 356 - static void nmi_cpu_restore_registers(struct op_msrs *msrs) 357 - { 358 - struct op_msr *counters = msrs->counters; 359 - struct op_msr *controls = msrs->controls; 360 - unsigned int i; 361 - 362 - for (i = 0; i < model->num_controls; ++i) { 363 - if (controls[i].addr) 364 - wrmsrl(controls[i].addr, controls[i].saved); 365 - } 366 - 367 - for (i = 0; i < model->num_counters; ++i) { 368 - if (counters[i].addr) 369 - wrmsrl(counters[i].addr, counters[i].saved); 370 - } 371 - } 372 - 373 - static void nmi_cpu_shutdown(void) 374 - { 375 - unsigned int v; 376 - int cpu = smp_processor_id(); 377 - struct op_msrs *msrs = &per_cpu(cpu_msrs, cpu); 378 - 379 - /* restoring APIC_LVTPC can trigger an apic error because the delivery 380 - * mode and vector nr combination can be illegal. That's by design: on 381 - * power on apic lvt contain a zero vector nr which are legal only for 382 - * NMI delivery mode. So inhibit apic err before restoring lvtpc 383 - */ 384 - v = apic_read(APIC_LVTERR); 385 - apic_write(APIC_LVTERR, v | APIC_LVT_MASKED); 386 - apic_write(APIC_LVTPC, per_cpu(saved_lvtpc, cpu)); 387 - apic_write(APIC_LVTERR, v); 388 - nmi_cpu_restore_registers(msrs); 389 - } 390 - 391 - static int nmi_cpu_online(unsigned int cpu) 392 - { 393 - local_irq_disable(); 394 - if (nmi_enabled) 395 - nmi_cpu_setup(); 396 - if (ctr_running) 397 - nmi_cpu_start(NULL); 398 - local_irq_enable(); 399 - return 0; 400 - } 401 - 402 - static int nmi_cpu_down_prep(unsigned int cpu) 403 - { 404 - local_irq_disable(); 405 - if (ctr_running) 406 - nmi_cpu_stop(NULL); 407 - if (nmi_enabled) 408 - nmi_cpu_shutdown(); 409 - local_irq_enable(); 410 - return 0; 411 - } 412 - 413 - static int nmi_create_files(struct dentry *root) 414 - { 415 - unsigned int i; 416 - 417 - for (i = 0; i < model->num_virt_counters; ++i) { 418 - struct dentry *dir; 419 - char buf[4]; 420 - 421 - /* quick little hack to _not_ expose a counter if it is not 422 - * available for use. This should protect userspace app. 423 - * NOTE: assumes 1:1 mapping here (that counters are organized 424 - * sequentially in their struct assignment). 425 - */ 426 - if (!avail_to_resrv_perfctr_nmi_bit(op_x86_virt_to_phys(i))) 427 - continue; 428 - 429 - snprintf(buf, sizeof(buf), "%d", i); 430 - dir = oprofilefs_mkdir(root, buf); 431 - oprofilefs_create_ulong(dir, "enabled", &counter_config[i].enabled); 432 - oprofilefs_create_ulong(dir, "event", &counter_config[i].event); 433 - oprofilefs_create_ulong(dir, "count", &counter_config[i].count); 434 - oprofilefs_create_ulong(dir, "unit_mask", &counter_config[i].unit_mask); 435 - oprofilefs_create_ulong(dir, "kernel", &counter_config[i].kernel); 436 - oprofilefs_create_ulong(dir, "user", &counter_config[i].user); 437 - oprofilefs_create_ulong(dir, "extra", &counter_config[i].extra); 438 - } 439 - 440 - return 0; 441 - } 442 - 443 - static enum cpuhp_state cpuhp_nmi_online; 444 - 445 - static int nmi_setup(void) 446 - { 447 - int err = 0; 448 - int cpu; 449 - 450 - if (!allocate_msrs()) 451 - return -ENOMEM; 452 - 453 - /* We need to serialize save and setup for HT because the subset 454 - * of msrs are distinct for save and setup operations 455 - */ 456 - 457 - /* Assume saved/restored counters are the same on all CPUs */ 458 - err = model->fill_in_addresses(&per_cpu(cpu_msrs, 0)); 459 - if (err) 460 - goto fail; 461 - 462 - for_each_possible_cpu(cpu) { 463 - if (!IS_ENABLED(CONFIG_SMP) || !cpu) 464 - continue; 465 - 466 - memcpy(per_cpu(cpu_msrs, cpu).counters, 467 - per_cpu(cpu_msrs, 0).counters, 468 - sizeof(struct op_msr) * model->num_counters); 469 - 470 - memcpy(per_cpu(cpu_msrs, cpu).controls, 471 - per_cpu(cpu_msrs, 0).controls, 472 - sizeof(struct op_msr) * model->num_controls); 473 - 474 - mux_clone(cpu); 475 - } 476 - 477 - nmi_enabled = 0; 478 - ctr_running = 0; 479 - /* make variables visible to the nmi handler: */ 480 - smp_mb(); 481 - err = register_nmi_handler(NMI_LOCAL, profile_exceptions_notify, 482 - 0, "oprofile"); 483 - if (err) 484 - goto fail; 485 - 486 - nmi_enabled = 1; 487 - /* make nmi_enabled visible to the nmi handler: */ 488 - smp_mb(); 489 - err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "x86/oprofile:online", 490 - nmi_cpu_online, nmi_cpu_down_prep); 491 - if (err < 0) 492 - goto fail_nmi; 493 - cpuhp_nmi_online = err; 494 - return 0; 495 - fail_nmi: 496 - unregister_nmi_handler(NMI_LOCAL, "oprofile"); 497 - fail: 498 - free_msrs(); 499 - return err; 500 - } 501 - 502 - static void nmi_shutdown(void) 503 - { 504 - struct op_msrs *msrs; 505 - 506 - cpuhp_remove_state(cpuhp_nmi_online); 507 - nmi_enabled = 0; 508 - ctr_running = 0; 509 - 510 - /* make variables visible to the nmi handler: */ 511 - smp_mb(); 512 - unregister_nmi_handler(NMI_LOCAL, "oprofile"); 513 - msrs = &get_cpu_var(cpu_msrs); 514 - model->shutdown(msrs); 515 - free_msrs(); 516 - put_cpu_var(cpu_msrs); 517 - } 518 - 519 - #ifdef CONFIG_PM 520 - 521 - static int nmi_suspend(void) 522 - { 523 - /* Only one CPU left, just stop that one */ 524 - if (nmi_enabled == 1) 525 - nmi_cpu_stop(NULL); 526 - return 0; 527 - } 528 - 529 - static void nmi_resume(void) 530 - { 531 - if (nmi_enabled == 1) 532 - nmi_cpu_start(NULL); 533 - } 534 - 535 - static struct syscore_ops oprofile_syscore_ops = { 536 - .resume = nmi_resume, 537 - .suspend = nmi_suspend, 538 - }; 539 - 540 - static void __init init_suspend_resume(void) 541 - { 542 - register_syscore_ops(&oprofile_syscore_ops); 543 - } 544 - 545 - static void exit_suspend_resume(void) 546 - { 547 - unregister_syscore_ops(&oprofile_syscore_ops); 548 - } 549 - 550 - #else 551 - 552 - static inline void init_suspend_resume(void) { } 553 - static inline void exit_suspend_resume(void) { } 554 - 555 - #endif /* CONFIG_PM */ 556 - 557 - static int __init p4_init(char **cpu_type) 558 - { 559 - __u8 cpu_model = boot_cpu_data.x86_model; 560 - 561 - if (cpu_model > 6 || cpu_model == 5) 562 - return 0; 563 - 564 - #ifndef CONFIG_SMP 565 - *cpu_type = "i386/p4"; 566 - model = &op_p4_spec; 567 - return 1; 568 - #else 569 - switch (smp_num_siblings) { 570 - case 1: 571 - *cpu_type = "i386/p4"; 572 - model = &op_p4_spec; 573 - return 1; 574 - 575 - case 2: 576 - *cpu_type = "i386/p4-ht"; 577 - model = &op_p4_ht2_spec; 578 - return 1; 579 - } 580 - #endif 581 - 582 - printk(KERN_INFO "oprofile: P4 HyperThreading detected with > 2 threads\n"); 583 - printk(KERN_INFO "oprofile: Reverting to timer mode.\n"); 584 - return 0; 585 - } 586 - 587 - enum __force_cpu_type { 588 - reserved = 0, /* do not force */ 589 - timer, 590 - arch_perfmon, 591 - }; 592 - 593 - static int force_cpu_type; 594 - 595 - static int set_cpu_type(const char *str, const struct kernel_param *kp) 596 - { 597 - if (!strcmp(str, "timer")) { 598 - force_cpu_type = timer; 599 - printk(KERN_INFO "oprofile: forcing NMI timer mode\n"); 600 - } else if (!strcmp(str, "arch_perfmon")) { 601 - force_cpu_type = arch_perfmon; 602 - printk(KERN_INFO "oprofile: forcing architectural perfmon\n"); 603 - } else { 604 - force_cpu_type = 0; 605 - } 606 - 607 - return 0; 608 - } 609 - module_param_call(cpu_type, set_cpu_type, NULL, NULL, 0); 610 - 611 - static int __init ppro_init(char **cpu_type) 612 - { 613 - __u8 cpu_model = boot_cpu_data.x86_model; 614 - struct op_x86_model_spec *spec = &op_ppro_spec; /* default */ 615 - 616 - if (force_cpu_type == arch_perfmon && boot_cpu_has(X86_FEATURE_ARCH_PERFMON)) 617 - return 0; 618 - 619 - /* 620 - * Documentation on identifying Intel processors by CPU family 621 - * and model can be found in the Intel Software Developer's 622 - * Manuals (SDM): 623 - * 624 - * http://www.intel.com/products/processor/manuals/ 625 - * 626 - * As of May 2010 the documentation for this was in the: 627 - * "Intel 64 and IA-32 Architectures Software Developer's 628 - * Manual Volume 3B: System Programming Guide", "Table B-1 629 - * CPUID Signature Values of DisplayFamily_DisplayModel". 630 - */ 631 - switch (cpu_model) { 632 - case 0 ... 2: 633 - *cpu_type = "i386/ppro"; 634 - break; 635 - case 3 ... 5: 636 - *cpu_type = "i386/pii"; 637 - break; 638 - case 6 ... 8: 639 - case 10 ... 11: 640 - *cpu_type = "i386/piii"; 641 - break; 642 - case 9: 643 - case 13: 644 - *cpu_type = "i386/p6_mobile"; 645 - break; 646 - case 14: 647 - *cpu_type = "i386/core"; 648 - break; 649 - case 0x0f: 650 - case 0x16: 651 - case 0x17: 652 - case 0x1d: 653 - *cpu_type = "i386/core_2"; 654 - break; 655 - case 0x1a: 656 - case 0x1e: 657 - case 0x2e: 658 - spec = &op_arch_perfmon_spec; 659 - *cpu_type = "i386/core_i7"; 660 - break; 661 - case 0x1c: 662 - *cpu_type = "i386/atom"; 663 - break; 664 - default: 665 - /* Unknown */ 666 - return 0; 667 - } 668 - 669 - model = spec; 670 - return 1; 671 - } 672 - 673 - int __init op_nmi_init(struct oprofile_operations *ops) 674 - { 675 - __u8 vendor = boot_cpu_data.x86_vendor; 676 - __u8 family = boot_cpu_data.x86; 677 - char *cpu_type = NULL; 678 - int ret = 0; 679 - 680 - if (!boot_cpu_has(X86_FEATURE_APIC)) 681 - return -ENODEV; 682 - 683 - if (force_cpu_type == timer) 684 - return -ENODEV; 685 - 686 - switch (vendor) { 687 - case X86_VENDOR_AMD: 688 - /* Needs to be at least an Athlon (or hammer in 32bit mode) */ 689 - 690 - switch (family) { 691 - case 6: 692 - cpu_type = "i386/athlon"; 693 - break; 694 - case 0xf: 695 - /* 696 - * Actually it could be i386/hammer too, but 697 - * give user space an consistent name. 698 - */ 699 - cpu_type = "x86-64/hammer"; 700 - break; 701 - case 0x10: 702 - cpu_type = "x86-64/family10"; 703 - break; 704 - case 0x11: 705 - cpu_type = "x86-64/family11h"; 706 - break; 707 - case 0x12: 708 - cpu_type = "x86-64/family12h"; 709 - break; 710 - case 0x14: 711 - cpu_type = "x86-64/family14h"; 712 - break; 713 - case 0x15: 714 - cpu_type = "x86-64/family15h"; 715 - break; 716 - default: 717 - return -ENODEV; 718 - } 719 - model = &op_amd_spec; 720 - break; 721 - 722 - case X86_VENDOR_INTEL: 723 - switch (family) { 724 - /* Pentium IV */ 725 - case 0xf: 726 - p4_init(&cpu_type); 727 - break; 728 - 729 - /* A P6-class processor */ 730 - case 6: 731 - ppro_init(&cpu_type); 732 - break; 733 - 734 - default: 735 - break; 736 - } 737 - 738 - if (cpu_type) 739 - break; 740 - 741 - if (!boot_cpu_has(X86_FEATURE_ARCH_PERFMON)) 742 - return -ENODEV; 743 - 744 - /* use arch perfmon as fallback */ 745 - cpu_type = "i386/arch_perfmon"; 746 - model = &op_arch_perfmon_spec; 747 - break; 748 - 749 - default: 750 - return -ENODEV; 751 - } 752 - 753 - /* default values, can be overwritten by model */ 754 - ops->create_files = nmi_create_files; 755 - ops->setup = nmi_setup; 756 - ops->shutdown = nmi_shutdown; 757 - ops->start = nmi_start; 758 - ops->stop = nmi_stop; 759 - ops->cpu_type = cpu_type; 760 - 761 - if (model->init) 762 - ret = model->init(ops); 763 - if (ret) 764 - return ret; 765 - 766 - if (!model->num_virt_counters) 767 - model->num_virt_counters = model->num_counters; 768 - 769 - mux_init(ops); 770 - 771 - init_suspend_resume(); 772 - 773 - printk(KERN_INFO "oprofile: using NMI interrupt.\n"); 774 - return 0; 775 - } 776 - 777 - void op_nmi_exit(void) 778 - { 779 - exit_suspend_resume(); 780 - }
-30
arch/x86/oprofile/op_counter.h
··· 1 - /** 2 - * @file op_counter.h 3 - * 4 - * @remark Copyright 2002 OProfile authors 5 - * @remark Read the file COPYING 6 - * 7 - * @author John Levon 8 - */ 9 - 10 - #ifndef OP_COUNTER_H 11 - #define OP_COUNTER_H 12 - 13 - #define OP_MAX_COUNTER 32 14 - 15 - /* Per-perfctr configuration as set via 16 - * oprofilefs. 17 - */ 18 - struct op_counter_config { 19 - unsigned long count; 20 - unsigned long enabled; 21 - unsigned long event; 22 - unsigned long kernel; 23 - unsigned long user; 24 - unsigned long unit_mask; 25 - unsigned long extra; 26 - }; 27 - 28 - extern struct op_counter_config counter_config[]; 29 - 30 - #endif /* OP_COUNTER_H */
-542
arch/x86/oprofile/op_model_amd.c
··· 1 - /* 2 - * @file op_model_amd.c 3 - * athlon / K7 / K8 / Family 10h model-specific MSR operations 4 - * 5 - * @remark Copyright 2002-2009 OProfile authors 6 - * @remark Read the file COPYING 7 - * 8 - * @author John Levon 9 - * @author Philippe Elie 10 - * @author Graydon Hoare 11 - * @author Robert Richter <robert.richter@amd.com> 12 - * @author Barry Kasindorf <barry.kasindorf@amd.com> 13 - * @author Jason Yeh <jason.yeh@amd.com> 14 - * @author Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> 15 - */ 16 - 17 - #include <linux/oprofile.h> 18 - #include <linux/device.h> 19 - #include <linux/pci.h> 20 - #include <linux/percpu.h> 21 - 22 - #include <asm/ptrace.h> 23 - #include <asm/msr.h> 24 - #include <asm/nmi.h> 25 - #include <asm/apic.h> 26 - #include <asm/processor.h> 27 - 28 - #include "op_x86_model.h" 29 - #include "op_counter.h" 30 - 31 - #ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX 32 - #define NUM_VIRT_COUNTERS 32 33 - #else 34 - #define NUM_VIRT_COUNTERS 0 35 - #endif 36 - 37 - #define OP_EVENT_MASK 0x0FFF 38 - #define OP_CTR_OVERFLOW (1ULL<<31) 39 - 40 - #define MSR_AMD_EVENTSEL_RESERVED ((0xFFFFFCF0ULL<<32)|(1ULL<<21)) 41 - 42 - static int num_counters; 43 - static unsigned long reset_value[OP_MAX_COUNTER]; 44 - 45 - #define IBS_FETCH_SIZE 6 46 - #define IBS_OP_SIZE 12 47 - 48 - static u32 ibs_caps; 49 - 50 - struct ibs_config { 51 - unsigned long op_enabled; 52 - unsigned long fetch_enabled; 53 - unsigned long max_cnt_fetch; 54 - unsigned long max_cnt_op; 55 - unsigned long rand_en; 56 - unsigned long dispatched_ops; 57 - unsigned long branch_target; 58 - }; 59 - 60 - struct ibs_state { 61 - u64 ibs_op_ctl; 62 - int branch_target; 63 - unsigned long sample_size; 64 - }; 65 - 66 - static struct ibs_config ibs_config; 67 - static struct ibs_state ibs_state; 68 - 69 - /* 70 - * IBS randomization macros 71 - */ 72 - #define IBS_RANDOM_BITS 12 73 - #define IBS_RANDOM_MASK ((1ULL << IBS_RANDOM_BITS) - 1) 74 - #define IBS_RANDOM_MAXCNT_OFFSET (1ULL << (IBS_RANDOM_BITS - 5)) 75 - 76 - /* 77 - * 16-bit Linear Feedback Shift Register (LFSR) 78 - * 79 - * 16 14 13 11 80 - * Feedback polynomial = X + X + X + X + 1 81 - */ 82 - static unsigned int lfsr_random(void) 83 - { 84 - static unsigned int lfsr_value = 0xF00D; 85 - unsigned int bit; 86 - 87 - /* Compute next bit to shift in */ 88 - bit = ((lfsr_value >> 0) ^ 89 - (lfsr_value >> 2) ^ 90 - (lfsr_value >> 3) ^ 91 - (lfsr_value >> 5)) & 0x0001; 92 - 93 - /* Advance to next register value */ 94 - lfsr_value = (lfsr_value >> 1) | (bit << 15); 95 - 96 - return lfsr_value; 97 - } 98 - 99 - /* 100 - * IBS software randomization 101 - * 102 - * The IBS periodic op counter is randomized in software. The lower 12 103 - * bits of the 20 bit counter are randomized. IbsOpCurCnt is 104 - * initialized with a 12 bit random value. 105 - */ 106 - static inline u64 op_amd_randomize_ibs_op(u64 val) 107 - { 108 - unsigned int random = lfsr_random(); 109 - 110 - if (!(ibs_caps & IBS_CAPS_RDWROPCNT)) 111 - /* 112 - * Work around if the hw can not write to IbsOpCurCnt 113 - * 114 - * Randomize the lower 8 bits of the 16 bit 115 - * IbsOpMaxCnt [15:0] value in the range of -128 to 116 - * +127 by adding/subtracting an offset to the 117 - * maximum count (IbsOpMaxCnt). 118 - * 119 - * To avoid over or underflows and protect upper bits 120 - * starting at bit 16, the initial value for 121 - * IbsOpMaxCnt must fit in the range from 0x0081 to 122 - * 0xff80. 123 - */ 124 - val += (s8)(random >> 4); 125 - else 126 - val |= (u64)(random & IBS_RANDOM_MASK) << 32; 127 - 128 - return val; 129 - } 130 - 131 - static inline void 132 - op_amd_handle_ibs(struct pt_regs * const regs, 133 - struct op_msrs const * const msrs) 134 - { 135 - u64 val, ctl; 136 - struct op_entry entry; 137 - 138 - if (!ibs_caps) 139 - return; 140 - 141 - if (ibs_config.fetch_enabled) { 142 - rdmsrl(MSR_AMD64_IBSFETCHCTL, ctl); 143 - if (ctl & IBS_FETCH_VAL) { 144 - rdmsrl(MSR_AMD64_IBSFETCHLINAD, val); 145 - oprofile_write_reserve(&entry, regs, val, 146 - IBS_FETCH_CODE, IBS_FETCH_SIZE); 147 - oprofile_add_data64(&entry, val); 148 - oprofile_add_data64(&entry, ctl); 149 - rdmsrl(MSR_AMD64_IBSFETCHPHYSAD, val); 150 - oprofile_add_data64(&entry, val); 151 - oprofile_write_commit(&entry); 152 - 153 - /* reenable the IRQ */ 154 - ctl &= ~(IBS_FETCH_VAL | IBS_FETCH_CNT); 155 - ctl |= IBS_FETCH_ENABLE; 156 - wrmsrl(MSR_AMD64_IBSFETCHCTL, ctl); 157 - } 158 - } 159 - 160 - if (ibs_config.op_enabled) { 161 - rdmsrl(MSR_AMD64_IBSOPCTL, ctl); 162 - if (ctl & IBS_OP_VAL) { 163 - rdmsrl(MSR_AMD64_IBSOPRIP, val); 164 - oprofile_write_reserve(&entry, regs, val, IBS_OP_CODE, 165 - ibs_state.sample_size); 166 - oprofile_add_data64(&entry, val); 167 - rdmsrl(MSR_AMD64_IBSOPDATA, val); 168 - oprofile_add_data64(&entry, val); 169 - rdmsrl(MSR_AMD64_IBSOPDATA2, val); 170 - oprofile_add_data64(&entry, val); 171 - rdmsrl(MSR_AMD64_IBSOPDATA3, val); 172 - oprofile_add_data64(&entry, val); 173 - rdmsrl(MSR_AMD64_IBSDCLINAD, val); 174 - oprofile_add_data64(&entry, val); 175 - rdmsrl(MSR_AMD64_IBSDCPHYSAD, val); 176 - oprofile_add_data64(&entry, val); 177 - if (ibs_state.branch_target) { 178 - rdmsrl(MSR_AMD64_IBSBRTARGET, val); 179 - oprofile_add_data(&entry, (unsigned long)val); 180 - } 181 - oprofile_write_commit(&entry); 182 - 183 - /* reenable the IRQ */ 184 - ctl = op_amd_randomize_ibs_op(ibs_state.ibs_op_ctl); 185 - wrmsrl(MSR_AMD64_IBSOPCTL, ctl); 186 - } 187 - } 188 - } 189 - 190 - static inline void op_amd_start_ibs(void) 191 - { 192 - u64 val; 193 - 194 - if (!ibs_caps) 195 - return; 196 - 197 - memset(&ibs_state, 0, sizeof(ibs_state)); 198 - 199 - /* 200 - * Note: Since the max count settings may out of range we 201 - * write back the actual used values so that userland can read 202 - * it. 203 - */ 204 - 205 - if (ibs_config.fetch_enabled) { 206 - val = ibs_config.max_cnt_fetch >> 4; 207 - val = min(val, IBS_FETCH_MAX_CNT); 208 - ibs_config.max_cnt_fetch = val << 4; 209 - val |= ibs_config.rand_en ? IBS_FETCH_RAND_EN : 0; 210 - val |= IBS_FETCH_ENABLE; 211 - wrmsrl(MSR_AMD64_IBSFETCHCTL, val); 212 - } 213 - 214 - if (ibs_config.op_enabled) { 215 - val = ibs_config.max_cnt_op >> 4; 216 - if (!(ibs_caps & IBS_CAPS_RDWROPCNT)) { 217 - /* 218 - * IbsOpCurCnt not supported. See 219 - * op_amd_randomize_ibs_op() for details. 220 - */ 221 - val = clamp(val, 0x0081ULL, 0xFF80ULL); 222 - ibs_config.max_cnt_op = val << 4; 223 - } else { 224 - /* 225 - * The start value is randomized with a 226 - * positive offset, we need to compensate it 227 - * with the half of the randomized range. Also 228 - * avoid underflows. 229 - */ 230 - val += IBS_RANDOM_MAXCNT_OFFSET; 231 - if (ibs_caps & IBS_CAPS_OPCNTEXT) 232 - val = min(val, IBS_OP_MAX_CNT_EXT); 233 - else 234 - val = min(val, IBS_OP_MAX_CNT); 235 - ibs_config.max_cnt_op = 236 - (val - IBS_RANDOM_MAXCNT_OFFSET) << 4; 237 - } 238 - val = ((val & ~IBS_OP_MAX_CNT) << 4) | (val & IBS_OP_MAX_CNT); 239 - val |= ibs_config.dispatched_ops ? IBS_OP_CNT_CTL : 0; 240 - val |= IBS_OP_ENABLE; 241 - ibs_state.ibs_op_ctl = val; 242 - ibs_state.sample_size = IBS_OP_SIZE; 243 - if (ibs_config.branch_target) { 244 - ibs_state.branch_target = 1; 245 - ibs_state.sample_size++; 246 - } 247 - val = op_amd_randomize_ibs_op(ibs_state.ibs_op_ctl); 248 - wrmsrl(MSR_AMD64_IBSOPCTL, val); 249 - } 250 - } 251 - 252 - static void op_amd_stop_ibs(void) 253 - { 254 - if (!ibs_caps) 255 - return; 256 - 257 - if (ibs_config.fetch_enabled) 258 - /* clear max count and enable */ 259 - wrmsrl(MSR_AMD64_IBSFETCHCTL, 0); 260 - 261 - if (ibs_config.op_enabled) 262 - /* clear max count and enable */ 263 - wrmsrl(MSR_AMD64_IBSOPCTL, 0); 264 - } 265 - 266 - #ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX 267 - 268 - static void op_mux_switch_ctrl(struct op_x86_model_spec const *model, 269 - struct op_msrs const * const msrs) 270 - { 271 - u64 val; 272 - int i; 273 - 274 - /* enable active counters */ 275 - for (i = 0; i < num_counters; ++i) { 276 - int virt = op_x86_phys_to_virt(i); 277 - if (!reset_value[virt]) 278 - continue; 279 - rdmsrl(msrs->controls[i].addr, val); 280 - val &= model->reserved; 281 - val |= op_x86_get_ctrl(model, &counter_config[virt]); 282 - wrmsrl(msrs->controls[i].addr, val); 283 - } 284 - } 285 - 286 - #endif 287 - 288 - /* functions for op_amd_spec */ 289 - 290 - static void op_amd_shutdown(struct op_msrs const * const msrs) 291 - { 292 - int i; 293 - 294 - for (i = 0; i < num_counters; ++i) { 295 - if (!msrs->counters[i].addr) 296 - continue; 297 - release_perfctr_nmi(MSR_K7_PERFCTR0 + i); 298 - release_evntsel_nmi(MSR_K7_EVNTSEL0 + i); 299 - } 300 - } 301 - 302 - static int op_amd_fill_in_addresses(struct op_msrs * const msrs) 303 - { 304 - int i; 305 - 306 - for (i = 0; i < num_counters; i++) { 307 - if (!reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i)) 308 - goto fail; 309 - if (!reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i)) { 310 - release_perfctr_nmi(MSR_K7_PERFCTR0 + i); 311 - goto fail; 312 - } 313 - /* both registers must be reserved */ 314 - if (num_counters == AMD64_NUM_COUNTERS_CORE) { 315 - msrs->counters[i].addr = MSR_F15H_PERF_CTR + (i << 1); 316 - msrs->controls[i].addr = MSR_F15H_PERF_CTL + (i << 1); 317 - } else { 318 - msrs->controls[i].addr = MSR_K7_EVNTSEL0 + i; 319 - msrs->counters[i].addr = MSR_K7_PERFCTR0 + i; 320 - } 321 - continue; 322 - fail: 323 - if (!counter_config[i].enabled) 324 - continue; 325 - op_x86_warn_reserved(i); 326 - op_amd_shutdown(msrs); 327 - return -EBUSY; 328 - } 329 - 330 - return 0; 331 - } 332 - 333 - static void op_amd_setup_ctrs(struct op_x86_model_spec const *model, 334 - struct op_msrs const * const msrs) 335 - { 336 - u64 val; 337 - int i; 338 - 339 - /* setup reset_value */ 340 - for (i = 0; i < OP_MAX_COUNTER; ++i) { 341 - if (counter_config[i].enabled 342 - && msrs->counters[op_x86_virt_to_phys(i)].addr) 343 - reset_value[i] = counter_config[i].count; 344 - else 345 - reset_value[i] = 0; 346 - } 347 - 348 - /* clear all counters */ 349 - for (i = 0; i < num_counters; ++i) { 350 - if (!msrs->controls[i].addr) 351 - continue; 352 - rdmsrl(msrs->controls[i].addr, val); 353 - if (val & ARCH_PERFMON_EVENTSEL_ENABLE) 354 - op_x86_warn_in_use(i); 355 - val &= model->reserved; 356 - wrmsrl(msrs->controls[i].addr, val); 357 - /* 358 - * avoid a false detection of ctr overflows in NMI 359 - * handler 360 - */ 361 - wrmsrl(msrs->counters[i].addr, -1LL); 362 - } 363 - 364 - /* enable active counters */ 365 - for (i = 0; i < num_counters; ++i) { 366 - int virt = op_x86_phys_to_virt(i); 367 - if (!reset_value[virt]) 368 - continue; 369 - 370 - /* setup counter registers */ 371 - wrmsrl(msrs->counters[i].addr, -(u64)reset_value[virt]); 372 - 373 - /* setup control registers */ 374 - rdmsrl(msrs->controls[i].addr, val); 375 - val &= model->reserved; 376 - val |= op_x86_get_ctrl(model, &counter_config[virt]); 377 - wrmsrl(msrs->controls[i].addr, val); 378 - } 379 - } 380 - 381 - static int op_amd_check_ctrs(struct pt_regs * const regs, 382 - struct op_msrs const * const msrs) 383 - { 384 - u64 val; 385 - int i; 386 - 387 - for (i = 0; i < num_counters; ++i) { 388 - int virt = op_x86_phys_to_virt(i); 389 - if (!reset_value[virt]) 390 - continue; 391 - rdmsrl(msrs->counters[i].addr, val); 392 - /* bit is clear if overflowed: */ 393 - if (val & OP_CTR_OVERFLOW) 394 - continue; 395 - oprofile_add_sample(regs, virt); 396 - wrmsrl(msrs->counters[i].addr, -(u64)reset_value[virt]); 397 - } 398 - 399 - op_amd_handle_ibs(regs, msrs); 400 - 401 - /* See op_model_ppro.c */ 402 - return 1; 403 - } 404 - 405 - static void op_amd_start(struct op_msrs const * const msrs) 406 - { 407 - u64 val; 408 - int i; 409 - 410 - for (i = 0; i < num_counters; ++i) { 411 - if (!reset_value[op_x86_phys_to_virt(i)]) 412 - continue; 413 - rdmsrl(msrs->controls[i].addr, val); 414 - val |= ARCH_PERFMON_EVENTSEL_ENABLE; 415 - wrmsrl(msrs->controls[i].addr, val); 416 - } 417 - 418 - op_amd_start_ibs(); 419 - } 420 - 421 - static void op_amd_stop(struct op_msrs const * const msrs) 422 - { 423 - u64 val; 424 - int i; 425 - 426 - /* 427 - * Subtle: stop on all counters to avoid race with setting our 428 - * pm callback 429 - */ 430 - for (i = 0; i < num_counters; ++i) { 431 - if (!reset_value[op_x86_phys_to_virt(i)]) 432 - continue; 433 - rdmsrl(msrs->controls[i].addr, val); 434 - val &= ~ARCH_PERFMON_EVENTSEL_ENABLE; 435 - wrmsrl(msrs->controls[i].addr, val); 436 - } 437 - 438 - op_amd_stop_ibs(); 439 - } 440 - 441 - /* 442 - * check and reserve APIC extended interrupt LVT offset for IBS if 443 - * available 444 - */ 445 - 446 - static void init_ibs(void) 447 - { 448 - ibs_caps = get_ibs_caps(); 449 - 450 - if (!ibs_caps) 451 - return; 452 - 453 - printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", ibs_caps); 454 - } 455 - 456 - static int (*create_arch_files)(struct dentry *root); 457 - 458 - static int setup_ibs_files(struct dentry *root) 459 - { 460 - struct dentry *dir; 461 - int ret = 0; 462 - 463 - /* architecture specific files */ 464 - if (create_arch_files) 465 - ret = create_arch_files(root); 466 - 467 - if (ret) 468 - return ret; 469 - 470 - if (!ibs_caps) 471 - return ret; 472 - 473 - /* model specific files */ 474 - 475 - /* setup some reasonable defaults */ 476 - memset(&ibs_config, 0, sizeof(ibs_config)); 477 - ibs_config.max_cnt_fetch = 250000; 478 - ibs_config.max_cnt_op = 250000; 479 - 480 - if (ibs_caps & IBS_CAPS_FETCHSAM) { 481 - dir = oprofilefs_mkdir(root, "ibs_fetch"); 482 - oprofilefs_create_ulong(dir, "enable", 483 - &ibs_config.fetch_enabled); 484 - oprofilefs_create_ulong(dir, "max_count", 485 - &ibs_config.max_cnt_fetch); 486 - oprofilefs_create_ulong(dir, "rand_enable", 487 - &ibs_config.rand_en); 488 - } 489 - 490 - if (ibs_caps & IBS_CAPS_OPSAM) { 491 - dir = oprofilefs_mkdir(root, "ibs_op"); 492 - oprofilefs_create_ulong(dir, "enable", 493 - &ibs_config.op_enabled); 494 - oprofilefs_create_ulong(dir, "max_count", 495 - &ibs_config.max_cnt_op); 496 - if (ibs_caps & IBS_CAPS_OPCNT) 497 - oprofilefs_create_ulong(dir, "dispatched_ops", 498 - &ibs_config.dispatched_ops); 499 - if (ibs_caps & IBS_CAPS_BRNTRGT) 500 - oprofilefs_create_ulong(dir, "branch_target", 501 - &ibs_config.branch_target); 502 - } 503 - 504 - return 0; 505 - } 506 - 507 - struct op_x86_model_spec op_amd_spec; 508 - 509 - static int op_amd_init(struct oprofile_operations *ops) 510 - { 511 - init_ibs(); 512 - create_arch_files = ops->create_files; 513 - ops->create_files = setup_ibs_files; 514 - 515 - if (boot_cpu_data.x86 == 0x15) { 516 - num_counters = AMD64_NUM_COUNTERS_CORE; 517 - } else { 518 - num_counters = AMD64_NUM_COUNTERS; 519 - } 520 - 521 - op_amd_spec.num_counters = num_counters; 522 - op_amd_spec.num_controls = num_counters; 523 - op_amd_spec.num_virt_counters = max(num_counters, NUM_VIRT_COUNTERS); 524 - 525 - return 0; 526 - } 527 - 528 - struct op_x86_model_spec op_amd_spec = { 529 - /* num_counters/num_controls filled in at runtime */ 530 - .reserved = MSR_AMD_EVENTSEL_RESERVED, 531 - .event_mask = OP_EVENT_MASK, 532 - .init = op_amd_init, 533 - .fill_in_addresses = &op_amd_fill_in_addresses, 534 - .setup_ctrs = &op_amd_setup_ctrs, 535 - .check_ctrs = &op_amd_check_ctrs, 536 - .start = &op_amd_start, 537 - .stop = &op_amd_stop, 538 - .shutdown = &op_amd_shutdown, 539 - #ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX 540 - .switch_ctrl = &op_mux_switch_ctrl, 541 - #endif 542 - };
-723
arch/x86/oprofile/op_model_p4.c
··· 1 - /** 2 - * @file op_model_p4.c 3 - * P4 model-specific MSR operations 4 - * 5 - * @remark Copyright 2002 OProfile authors 6 - * @remark Read the file COPYING 7 - * 8 - * @author Graydon Hoare 9 - */ 10 - 11 - #include <linux/oprofile.h> 12 - #include <linux/smp.h> 13 - #include <linux/ptrace.h> 14 - #include <asm/nmi.h> 15 - #include <asm/msr.h> 16 - #include <asm/fixmap.h> 17 - #include <asm/apic.h> 18 - 19 - 20 - #include "op_x86_model.h" 21 - #include "op_counter.h" 22 - 23 - #define NUM_EVENTS 39 24 - 25 - #define NUM_COUNTERS_NON_HT 8 26 - #define NUM_ESCRS_NON_HT 45 27 - #define NUM_CCCRS_NON_HT 18 28 - #define NUM_CONTROLS_NON_HT (NUM_ESCRS_NON_HT + NUM_CCCRS_NON_HT) 29 - 30 - #define NUM_COUNTERS_HT2 4 31 - #define NUM_ESCRS_HT2 23 32 - #define NUM_CCCRS_HT2 9 33 - #define NUM_CONTROLS_HT2 (NUM_ESCRS_HT2 + NUM_CCCRS_HT2) 34 - 35 - #define OP_CTR_OVERFLOW (1ULL<<31) 36 - 37 - static unsigned int num_counters = NUM_COUNTERS_NON_HT; 38 - static unsigned int num_controls = NUM_CONTROLS_NON_HT; 39 - 40 - /* this has to be checked dynamically since the 41 - hyper-threadedness of a chip is discovered at 42 - kernel boot-time. */ 43 - static inline void setup_num_counters(void) 44 - { 45 - #ifdef CONFIG_SMP 46 - if (smp_num_siblings == 2) { 47 - num_counters = NUM_COUNTERS_HT2; 48 - num_controls = NUM_CONTROLS_HT2; 49 - } 50 - #endif 51 - } 52 - 53 - static inline int addr_increment(void) 54 - { 55 - #ifdef CONFIG_SMP 56 - return smp_num_siblings == 2 ? 2 : 1; 57 - #else 58 - return 1; 59 - #endif 60 - } 61 - 62 - 63 - /* tables to simulate simplified hardware view of p4 registers */ 64 - struct p4_counter_binding { 65 - int virt_counter; 66 - int counter_address; 67 - int cccr_address; 68 - }; 69 - 70 - struct p4_event_binding { 71 - int escr_select; /* value to put in CCCR */ 72 - int event_select; /* value to put in ESCR */ 73 - struct { 74 - int virt_counter; /* for this counter... */ 75 - int escr_address; /* use this ESCR */ 76 - } bindings[2]; 77 - }; 78 - 79 - /* nb: these CTR_* defines are a duplicate of defines in 80 - event/i386.p4*events. */ 81 - 82 - 83 - #define CTR_BPU_0 (1 << 0) 84 - #define CTR_MS_0 (1 << 1) 85 - #define CTR_FLAME_0 (1 << 2) 86 - #define CTR_IQ_4 (1 << 3) 87 - #define CTR_BPU_2 (1 << 4) 88 - #define CTR_MS_2 (1 << 5) 89 - #define CTR_FLAME_2 (1 << 6) 90 - #define CTR_IQ_5 (1 << 7) 91 - 92 - static struct p4_counter_binding p4_counters[NUM_COUNTERS_NON_HT] = { 93 - { CTR_BPU_0, MSR_P4_BPU_PERFCTR0, MSR_P4_BPU_CCCR0 }, 94 - { CTR_MS_0, MSR_P4_MS_PERFCTR0, MSR_P4_MS_CCCR0 }, 95 - { CTR_FLAME_0, MSR_P4_FLAME_PERFCTR0, MSR_P4_FLAME_CCCR0 }, 96 - { CTR_IQ_4, MSR_P4_IQ_PERFCTR4, MSR_P4_IQ_CCCR4 }, 97 - { CTR_BPU_2, MSR_P4_BPU_PERFCTR2, MSR_P4_BPU_CCCR2 }, 98 - { CTR_MS_2, MSR_P4_MS_PERFCTR2, MSR_P4_MS_CCCR2 }, 99 - { CTR_FLAME_2, MSR_P4_FLAME_PERFCTR2, MSR_P4_FLAME_CCCR2 }, 100 - { CTR_IQ_5, MSR_P4_IQ_PERFCTR5, MSR_P4_IQ_CCCR5 } 101 - }; 102 - 103 - #define NUM_UNUSED_CCCRS (NUM_CCCRS_NON_HT - NUM_COUNTERS_NON_HT) 104 - 105 - /* p4 event codes in libop/op_event.h are indices into this table. */ 106 - 107 - static struct p4_event_binding p4_events[NUM_EVENTS] = { 108 - 109 - { /* BRANCH_RETIRED */ 110 - 0x05, 0x06, 111 - { {CTR_IQ_4, MSR_P4_CRU_ESCR2}, 112 - {CTR_IQ_5, MSR_P4_CRU_ESCR3} } 113 - }, 114 - 115 - { /* MISPRED_BRANCH_RETIRED */ 116 - 0x04, 0x03, 117 - { { CTR_IQ_4, MSR_P4_CRU_ESCR0}, 118 - { CTR_IQ_5, MSR_P4_CRU_ESCR1} } 119 - }, 120 - 121 - { /* TC_DELIVER_MODE */ 122 - 0x01, 0x01, 123 - { { CTR_MS_0, MSR_P4_TC_ESCR0}, 124 - { CTR_MS_2, MSR_P4_TC_ESCR1} } 125 - }, 126 - 127 - { /* BPU_FETCH_REQUEST */ 128 - 0x00, 0x03, 129 - { { CTR_BPU_0, MSR_P4_BPU_ESCR0}, 130 - { CTR_BPU_2, MSR_P4_BPU_ESCR1} } 131 - }, 132 - 133 - { /* ITLB_REFERENCE */ 134 - 0x03, 0x18, 135 - { { CTR_BPU_0, MSR_P4_ITLB_ESCR0}, 136 - { CTR_BPU_2, MSR_P4_ITLB_ESCR1} } 137 - }, 138 - 139 - { /* MEMORY_CANCEL */ 140 - 0x05, 0x02, 141 - { { CTR_FLAME_0, MSR_P4_DAC_ESCR0}, 142 - { CTR_FLAME_2, MSR_P4_DAC_ESCR1} } 143 - }, 144 - 145 - { /* MEMORY_COMPLETE */ 146 - 0x02, 0x08, 147 - { { CTR_FLAME_0, MSR_P4_SAAT_ESCR0}, 148 - { CTR_FLAME_2, MSR_P4_SAAT_ESCR1} } 149 - }, 150 - 151 - { /* LOAD_PORT_REPLAY */ 152 - 0x02, 0x04, 153 - { { CTR_FLAME_0, MSR_P4_SAAT_ESCR0}, 154 - { CTR_FLAME_2, MSR_P4_SAAT_ESCR1} } 155 - }, 156 - 157 - { /* STORE_PORT_REPLAY */ 158 - 0x02, 0x05, 159 - { { CTR_FLAME_0, MSR_P4_SAAT_ESCR0}, 160 - { CTR_FLAME_2, MSR_P4_SAAT_ESCR1} } 161 - }, 162 - 163 - { /* MOB_LOAD_REPLAY */ 164 - 0x02, 0x03, 165 - { { CTR_BPU_0, MSR_P4_MOB_ESCR0}, 166 - { CTR_BPU_2, MSR_P4_MOB_ESCR1} } 167 - }, 168 - 169 - { /* PAGE_WALK_TYPE */ 170 - 0x04, 0x01, 171 - { { CTR_BPU_0, MSR_P4_PMH_ESCR0}, 172 - { CTR_BPU_2, MSR_P4_PMH_ESCR1} } 173 - }, 174 - 175 - { /* BSQ_CACHE_REFERENCE */ 176 - 0x07, 0x0c, 177 - { { CTR_BPU_0, MSR_P4_BSU_ESCR0}, 178 - { CTR_BPU_2, MSR_P4_BSU_ESCR1} } 179 - }, 180 - 181 - { /* IOQ_ALLOCATION */ 182 - 0x06, 0x03, 183 - { { CTR_BPU_0, MSR_P4_FSB_ESCR0}, 184 - { 0, 0 } } 185 - }, 186 - 187 - { /* IOQ_ACTIVE_ENTRIES */ 188 - 0x06, 0x1a, 189 - { { CTR_BPU_2, MSR_P4_FSB_ESCR1}, 190 - { 0, 0 } } 191 - }, 192 - 193 - { /* FSB_DATA_ACTIVITY */ 194 - 0x06, 0x17, 195 - { { CTR_BPU_0, MSR_P4_FSB_ESCR0}, 196 - { CTR_BPU_2, MSR_P4_FSB_ESCR1} } 197 - }, 198 - 199 - { /* BSQ_ALLOCATION */ 200 - 0x07, 0x05, 201 - { { CTR_BPU_0, MSR_P4_BSU_ESCR0}, 202 - { 0, 0 } } 203 - }, 204 - 205 - { /* BSQ_ACTIVE_ENTRIES */ 206 - 0x07, 0x06, 207 - { { CTR_BPU_2, MSR_P4_BSU_ESCR1 /* guess */}, 208 - { 0, 0 } } 209 - }, 210 - 211 - { /* X87_ASSIST */ 212 - 0x05, 0x03, 213 - { { CTR_IQ_4, MSR_P4_CRU_ESCR2}, 214 - { CTR_IQ_5, MSR_P4_CRU_ESCR3} } 215 - }, 216 - 217 - { /* SSE_INPUT_ASSIST */ 218 - 0x01, 0x34, 219 - { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, 220 - { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } 221 - }, 222 - 223 - { /* PACKED_SP_UOP */ 224 - 0x01, 0x08, 225 - { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, 226 - { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } 227 - }, 228 - 229 - { /* PACKED_DP_UOP */ 230 - 0x01, 0x0c, 231 - { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, 232 - { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } 233 - }, 234 - 235 - { /* SCALAR_SP_UOP */ 236 - 0x01, 0x0a, 237 - { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, 238 - { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } 239 - }, 240 - 241 - { /* SCALAR_DP_UOP */ 242 - 0x01, 0x0e, 243 - { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, 244 - { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } 245 - }, 246 - 247 - { /* 64BIT_MMX_UOP */ 248 - 0x01, 0x02, 249 - { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, 250 - { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } 251 - }, 252 - 253 - { /* 128BIT_MMX_UOP */ 254 - 0x01, 0x1a, 255 - { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, 256 - { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } 257 - }, 258 - 259 - { /* X87_FP_UOP */ 260 - 0x01, 0x04, 261 - { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, 262 - { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } 263 - }, 264 - 265 - { /* X87_SIMD_MOVES_UOP */ 266 - 0x01, 0x2e, 267 - { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, 268 - { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } 269 - }, 270 - 271 - { /* MACHINE_CLEAR */ 272 - 0x05, 0x02, 273 - { { CTR_IQ_4, MSR_P4_CRU_ESCR2}, 274 - { CTR_IQ_5, MSR_P4_CRU_ESCR3} } 275 - }, 276 - 277 - { /* GLOBAL_POWER_EVENTS */ 278 - 0x06, 0x13 /* older manual says 0x05, newer 0x13 */, 279 - { { CTR_BPU_0, MSR_P4_FSB_ESCR0}, 280 - { CTR_BPU_2, MSR_P4_FSB_ESCR1} } 281 - }, 282 - 283 - { /* TC_MS_XFER */ 284 - 0x00, 0x05, 285 - { { CTR_MS_0, MSR_P4_MS_ESCR0}, 286 - { CTR_MS_2, MSR_P4_MS_ESCR1} } 287 - }, 288 - 289 - { /* UOP_QUEUE_WRITES */ 290 - 0x00, 0x09, 291 - { { CTR_MS_0, MSR_P4_MS_ESCR0}, 292 - { CTR_MS_2, MSR_P4_MS_ESCR1} } 293 - }, 294 - 295 - { /* FRONT_END_EVENT */ 296 - 0x05, 0x08, 297 - { { CTR_IQ_4, MSR_P4_CRU_ESCR2}, 298 - { CTR_IQ_5, MSR_P4_CRU_ESCR3} } 299 - }, 300 - 301 - { /* EXECUTION_EVENT */ 302 - 0x05, 0x0c, 303 - { { CTR_IQ_4, MSR_P4_CRU_ESCR2}, 304 - { CTR_IQ_5, MSR_P4_CRU_ESCR3} } 305 - }, 306 - 307 - { /* REPLAY_EVENT */ 308 - 0x05, 0x09, 309 - { { CTR_IQ_4, MSR_P4_CRU_ESCR2}, 310 - { CTR_IQ_5, MSR_P4_CRU_ESCR3} } 311 - }, 312 - 313 - { /* INSTR_RETIRED */ 314 - 0x04, 0x02, 315 - { { CTR_IQ_4, MSR_P4_CRU_ESCR0}, 316 - { CTR_IQ_5, MSR_P4_CRU_ESCR1} } 317 - }, 318 - 319 - { /* UOPS_RETIRED */ 320 - 0x04, 0x01, 321 - { { CTR_IQ_4, MSR_P4_CRU_ESCR0}, 322 - { CTR_IQ_5, MSR_P4_CRU_ESCR1} } 323 - }, 324 - 325 - { /* UOP_TYPE */ 326 - 0x02, 0x02, 327 - { { CTR_IQ_4, MSR_P4_RAT_ESCR0}, 328 - { CTR_IQ_5, MSR_P4_RAT_ESCR1} } 329 - }, 330 - 331 - { /* RETIRED_MISPRED_BRANCH_TYPE */ 332 - 0x02, 0x05, 333 - { { CTR_MS_0, MSR_P4_TBPU_ESCR0}, 334 - { CTR_MS_2, MSR_P4_TBPU_ESCR1} } 335 - }, 336 - 337 - { /* RETIRED_BRANCH_TYPE */ 338 - 0x02, 0x04, 339 - { { CTR_MS_0, MSR_P4_TBPU_ESCR0}, 340 - { CTR_MS_2, MSR_P4_TBPU_ESCR1} } 341 - } 342 - }; 343 - 344 - 345 - #define MISC_PMC_ENABLED_P(x) ((x) & 1 << 7) 346 - 347 - #define ESCR_RESERVED_BITS 0x80000003 348 - #define ESCR_CLEAR(escr) ((escr) &= ESCR_RESERVED_BITS) 349 - #define ESCR_SET_USR_0(escr, usr) ((escr) |= (((usr) & 1) << 2)) 350 - #define ESCR_SET_OS_0(escr, os) ((escr) |= (((os) & 1) << 3)) 351 - #define ESCR_SET_USR_1(escr, usr) ((escr) |= (((usr) & 1))) 352 - #define ESCR_SET_OS_1(escr, os) ((escr) |= (((os) & 1) << 1)) 353 - #define ESCR_SET_EVENT_SELECT(escr, sel) ((escr) |= (((sel) & 0x3f) << 25)) 354 - #define ESCR_SET_EVENT_MASK(escr, mask) ((escr) |= (((mask) & 0xffff) << 9)) 355 - 356 - #define CCCR_RESERVED_BITS 0x38030FFF 357 - #define CCCR_CLEAR(cccr) ((cccr) &= CCCR_RESERVED_BITS) 358 - #define CCCR_SET_REQUIRED_BITS(cccr) ((cccr) |= 0x00030000) 359 - #define CCCR_SET_ESCR_SELECT(cccr, sel) ((cccr) |= (((sel) & 0x07) << 13)) 360 - #define CCCR_SET_PMI_OVF_0(cccr) ((cccr) |= (1<<26)) 361 - #define CCCR_SET_PMI_OVF_1(cccr) ((cccr) |= (1<<27)) 362 - #define CCCR_SET_ENABLE(cccr) ((cccr) |= (1<<12)) 363 - #define CCCR_SET_DISABLE(cccr) ((cccr) &= ~(1<<12)) 364 - #define CCCR_OVF_P(cccr) ((cccr) & (1U<<31)) 365 - #define CCCR_CLEAR_OVF(cccr) ((cccr) &= (~(1U<<31))) 366 - 367 - 368 - /* this assigns a "stagger" to the current CPU, which is used throughout 369 - the code in this module as an extra array offset, to select the "even" 370 - or "odd" part of all the divided resources. */ 371 - static unsigned int get_stagger(void) 372 - { 373 - #ifdef CONFIG_SMP 374 - int cpu = smp_processor_id(); 375 - return cpu != cpumask_first(this_cpu_cpumask_var_ptr(cpu_sibling_map)); 376 - #endif 377 - return 0; 378 - } 379 - 380 - 381 - /* finally, mediate access to a real hardware counter 382 - by passing a "virtual" counter numer to this macro, 383 - along with your stagger setting. */ 384 - #define VIRT_CTR(stagger, i) ((i) + ((num_counters) * (stagger))) 385 - 386 - static unsigned long reset_value[NUM_COUNTERS_NON_HT]; 387 - 388 - static void p4_shutdown(struct op_msrs const * const msrs) 389 - { 390 - int i; 391 - 392 - for (i = 0; i < num_counters; ++i) { 393 - if (msrs->counters[i].addr) 394 - release_perfctr_nmi(msrs->counters[i].addr); 395 - } 396 - /* 397 - * some of the control registers are specially reserved in 398 - * conjunction with the counter registers (hence the starting offset). 399 - * This saves a few bits. 400 - */ 401 - for (i = num_counters; i < num_controls; ++i) { 402 - if (msrs->controls[i].addr) 403 - release_evntsel_nmi(msrs->controls[i].addr); 404 - } 405 - } 406 - 407 - static int p4_fill_in_addresses(struct op_msrs * const msrs) 408 - { 409 - unsigned int i; 410 - unsigned int addr, cccraddr, stag; 411 - 412 - setup_num_counters(); 413 - stag = get_stagger(); 414 - 415 - /* the counter & cccr registers we pay attention to */ 416 - for (i = 0; i < num_counters; ++i) { 417 - addr = p4_counters[VIRT_CTR(stag, i)].counter_address; 418 - cccraddr = p4_counters[VIRT_CTR(stag, i)].cccr_address; 419 - if (reserve_perfctr_nmi(addr)) { 420 - msrs->counters[i].addr = addr; 421 - msrs->controls[i].addr = cccraddr; 422 - } 423 - } 424 - 425 - /* 43 ESCR registers in three or four discontiguous group */ 426 - for (addr = MSR_P4_BSU_ESCR0 + stag; 427 - addr < MSR_P4_IQ_ESCR0; ++i, addr += addr_increment()) { 428 - if (reserve_evntsel_nmi(addr)) 429 - msrs->controls[i].addr = addr; 430 - } 431 - 432 - /* no IQ_ESCR0/1 on some models, we save a seconde time BSU_ESCR0/1 433 - * to avoid special case in nmi_{save|restore}_registers() */ 434 - if (boot_cpu_data.x86_model >= 0x3) { 435 - for (addr = MSR_P4_BSU_ESCR0 + stag; 436 - addr <= MSR_P4_BSU_ESCR1; ++i, addr += addr_increment()) { 437 - if (reserve_evntsel_nmi(addr)) 438 - msrs->controls[i].addr = addr; 439 - } 440 - } else { 441 - for (addr = MSR_P4_IQ_ESCR0 + stag; 442 - addr <= MSR_P4_IQ_ESCR1; ++i, addr += addr_increment()) { 443 - if (reserve_evntsel_nmi(addr)) 444 - msrs->controls[i].addr = addr; 445 - } 446 - } 447 - 448 - for (addr = MSR_P4_RAT_ESCR0 + stag; 449 - addr <= MSR_P4_SSU_ESCR0; ++i, addr += addr_increment()) { 450 - if (reserve_evntsel_nmi(addr)) 451 - msrs->controls[i].addr = addr; 452 - } 453 - 454 - for (addr = MSR_P4_MS_ESCR0 + stag; 455 - addr <= MSR_P4_TC_ESCR1; ++i, addr += addr_increment()) { 456 - if (reserve_evntsel_nmi(addr)) 457 - msrs->controls[i].addr = addr; 458 - } 459 - 460 - for (addr = MSR_P4_IX_ESCR0 + stag; 461 - addr <= MSR_P4_CRU_ESCR3; ++i, addr += addr_increment()) { 462 - if (reserve_evntsel_nmi(addr)) 463 - msrs->controls[i].addr = addr; 464 - } 465 - 466 - /* there are 2 remaining non-contiguously located ESCRs */ 467 - 468 - if (num_counters == NUM_COUNTERS_NON_HT) { 469 - /* standard non-HT CPUs handle both remaining ESCRs*/ 470 - if (reserve_evntsel_nmi(MSR_P4_CRU_ESCR5)) 471 - msrs->controls[i++].addr = MSR_P4_CRU_ESCR5; 472 - if (reserve_evntsel_nmi(MSR_P4_CRU_ESCR4)) 473 - msrs->controls[i++].addr = MSR_P4_CRU_ESCR4; 474 - 475 - } else if (stag == 0) { 476 - /* HT CPUs give the first remainder to the even thread, as 477 - the 32nd control register */ 478 - if (reserve_evntsel_nmi(MSR_P4_CRU_ESCR4)) 479 - msrs->controls[i++].addr = MSR_P4_CRU_ESCR4; 480 - 481 - } else { 482 - /* and two copies of the second to the odd thread, 483 - for the 22st and 23nd control registers */ 484 - if (reserve_evntsel_nmi(MSR_P4_CRU_ESCR5)) { 485 - msrs->controls[i++].addr = MSR_P4_CRU_ESCR5; 486 - msrs->controls[i++].addr = MSR_P4_CRU_ESCR5; 487 - } 488 - } 489 - 490 - for (i = 0; i < num_counters; ++i) { 491 - if (!counter_config[i].enabled) 492 - continue; 493 - if (msrs->controls[i].addr) 494 - continue; 495 - op_x86_warn_reserved(i); 496 - p4_shutdown(msrs); 497 - return -EBUSY; 498 - } 499 - 500 - return 0; 501 - } 502 - 503 - 504 - static void pmc_setup_one_p4_counter(unsigned int ctr) 505 - { 506 - int i; 507 - int const maxbind = 2; 508 - unsigned int cccr = 0; 509 - unsigned int escr = 0; 510 - unsigned int high = 0; 511 - unsigned int counter_bit; 512 - struct p4_event_binding *ev = NULL; 513 - unsigned int stag; 514 - 515 - stag = get_stagger(); 516 - 517 - /* convert from counter *number* to counter *bit* */ 518 - counter_bit = 1 << VIRT_CTR(stag, ctr); 519 - 520 - /* find our event binding structure. */ 521 - if (counter_config[ctr].event <= 0 || counter_config[ctr].event > NUM_EVENTS) { 522 - printk(KERN_ERR 523 - "oprofile: P4 event code 0x%lx out of range\n", 524 - counter_config[ctr].event); 525 - return; 526 - } 527 - 528 - ev = &(p4_events[counter_config[ctr].event - 1]); 529 - 530 - for (i = 0; i < maxbind; i++) { 531 - if (ev->bindings[i].virt_counter & counter_bit) { 532 - 533 - /* modify ESCR */ 534 - rdmsr(ev->bindings[i].escr_address, escr, high); 535 - ESCR_CLEAR(escr); 536 - if (stag == 0) { 537 - ESCR_SET_USR_0(escr, counter_config[ctr].user); 538 - ESCR_SET_OS_0(escr, counter_config[ctr].kernel); 539 - } else { 540 - ESCR_SET_USR_1(escr, counter_config[ctr].user); 541 - ESCR_SET_OS_1(escr, counter_config[ctr].kernel); 542 - } 543 - ESCR_SET_EVENT_SELECT(escr, ev->event_select); 544 - ESCR_SET_EVENT_MASK(escr, counter_config[ctr].unit_mask); 545 - wrmsr(ev->bindings[i].escr_address, escr, high); 546 - 547 - /* modify CCCR */ 548 - rdmsr(p4_counters[VIRT_CTR(stag, ctr)].cccr_address, 549 - cccr, high); 550 - CCCR_CLEAR(cccr); 551 - CCCR_SET_REQUIRED_BITS(cccr); 552 - CCCR_SET_ESCR_SELECT(cccr, ev->escr_select); 553 - if (stag == 0) 554 - CCCR_SET_PMI_OVF_0(cccr); 555 - else 556 - CCCR_SET_PMI_OVF_1(cccr); 557 - wrmsr(p4_counters[VIRT_CTR(stag, ctr)].cccr_address, 558 - cccr, high); 559 - return; 560 - } 561 - } 562 - 563 - printk(KERN_ERR 564 - "oprofile: P4 event code 0x%lx no binding, stag %d ctr %d\n", 565 - counter_config[ctr].event, stag, ctr); 566 - } 567 - 568 - 569 - static void p4_setup_ctrs(struct op_x86_model_spec const *model, 570 - struct op_msrs const * const msrs) 571 - { 572 - unsigned int i; 573 - unsigned int low, high; 574 - unsigned int stag; 575 - 576 - stag = get_stagger(); 577 - 578 - rdmsr(MSR_IA32_MISC_ENABLE, low, high); 579 - if (!MISC_PMC_ENABLED_P(low)) { 580 - printk(KERN_ERR "oprofile: P4 PMC not available\n"); 581 - return; 582 - } 583 - 584 - /* clear the cccrs we will use */ 585 - for (i = 0; i < num_counters; i++) { 586 - if (unlikely(!msrs->controls[i].addr)) 587 - continue; 588 - rdmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high); 589 - CCCR_CLEAR(low); 590 - CCCR_SET_REQUIRED_BITS(low); 591 - wrmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high); 592 - } 593 - 594 - /* clear all escrs (including those outside our concern) */ 595 - for (i = num_counters; i < num_controls; i++) { 596 - if (unlikely(!msrs->controls[i].addr)) 597 - continue; 598 - wrmsr(msrs->controls[i].addr, 0, 0); 599 - } 600 - 601 - /* setup all counters */ 602 - for (i = 0; i < num_counters; ++i) { 603 - if (counter_config[i].enabled && msrs->controls[i].addr) { 604 - reset_value[i] = counter_config[i].count; 605 - pmc_setup_one_p4_counter(i); 606 - wrmsrl(p4_counters[VIRT_CTR(stag, i)].counter_address, 607 - -(u64)counter_config[i].count); 608 - } else { 609 - reset_value[i] = 0; 610 - } 611 - } 612 - } 613 - 614 - 615 - static int p4_check_ctrs(struct pt_regs * const regs, 616 - struct op_msrs const * const msrs) 617 - { 618 - unsigned long ctr, low, high, stag, real; 619 - int i; 620 - 621 - stag = get_stagger(); 622 - 623 - for (i = 0; i < num_counters; ++i) { 624 - 625 - if (!reset_value[i]) 626 - continue; 627 - 628 - /* 629 - * there is some eccentricity in the hardware which 630 - * requires that we perform 2 extra corrections: 631 - * 632 - * - check both the CCCR:OVF flag for overflow and the 633 - * counter high bit for un-flagged overflows. 634 - * 635 - * - write the counter back twice to ensure it gets 636 - * updated properly. 637 - * 638 - * the former seems to be related to extra NMIs happening 639 - * during the current NMI; the latter is reported as errata 640 - * N15 in intel doc 249199-029, pentium 4 specification 641 - * update, though their suggested work-around does not 642 - * appear to solve the problem. 643 - */ 644 - 645 - real = VIRT_CTR(stag, i); 646 - 647 - rdmsr(p4_counters[real].cccr_address, low, high); 648 - rdmsr(p4_counters[real].counter_address, ctr, high); 649 - if (CCCR_OVF_P(low) || !(ctr & OP_CTR_OVERFLOW)) { 650 - oprofile_add_sample(regs, i); 651 - wrmsrl(p4_counters[real].counter_address, 652 - -(u64)reset_value[i]); 653 - CCCR_CLEAR_OVF(low); 654 - wrmsr(p4_counters[real].cccr_address, low, high); 655 - wrmsrl(p4_counters[real].counter_address, 656 - -(u64)reset_value[i]); 657 - } 658 - } 659 - 660 - /* P4 quirk: you have to re-unmask the apic vector */ 661 - apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED); 662 - 663 - /* See op_model_ppro.c */ 664 - return 1; 665 - } 666 - 667 - 668 - static void p4_start(struct op_msrs const * const msrs) 669 - { 670 - unsigned int low, high, stag; 671 - int i; 672 - 673 - stag = get_stagger(); 674 - 675 - for (i = 0; i < num_counters; ++i) { 676 - if (!reset_value[i]) 677 - continue; 678 - rdmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high); 679 - CCCR_SET_ENABLE(low); 680 - wrmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high); 681 - } 682 - } 683 - 684 - 685 - static void p4_stop(struct op_msrs const * const msrs) 686 - { 687 - unsigned int low, high, stag; 688 - int i; 689 - 690 - stag = get_stagger(); 691 - 692 - for (i = 0; i < num_counters; ++i) { 693 - if (!reset_value[i]) 694 - continue; 695 - rdmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high); 696 - CCCR_SET_DISABLE(low); 697 - wrmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high); 698 - } 699 - } 700 - 701 - #ifdef CONFIG_SMP 702 - struct op_x86_model_spec op_p4_ht2_spec = { 703 - .num_counters = NUM_COUNTERS_HT2, 704 - .num_controls = NUM_CONTROLS_HT2, 705 - .fill_in_addresses = &p4_fill_in_addresses, 706 - .setup_ctrs = &p4_setup_ctrs, 707 - .check_ctrs = &p4_check_ctrs, 708 - .start = &p4_start, 709 - .stop = &p4_stop, 710 - .shutdown = &p4_shutdown 711 - }; 712 - #endif 713 - 714 - struct op_x86_model_spec op_p4_spec = { 715 - .num_counters = NUM_COUNTERS_NON_HT, 716 - .num_controls = NUM_CONTROLS_NON_HT, 717 - .fill_in_addresses = &p4_fill_in_addresses, 718 - .setup_ctrs = &p4_setup_ctrs, 719 - .check_ctrs = &p4_check_ctrs, 720 - .start = &p4_start, 721 - .stop = &p4_stop, 722 - .shutdown = &p4_shutdown 723 - };
-245
arch/x86/oprofile/op_model_ppro.c
··· 1 - /* 2 - * @file op_model_ppro.h 3 - * Family 6 perfmon and architectural perfmon MSR operations 4 - * 5 - * @remark Copyright 2002 OProfile authors 6 - * @remark Copyright 2008 Intel Corporation 7 - * @remark Read the file COPYING 8 - * 9 - * @author John Levon 10 - * @author Philippe Elie 11 - * @author Graydon Hoare 12 - * @author Andi Kleen 13 - * @author Robert Richter <robert.richter@amd.com> 14 - */ 15 - 16 - #include <linux/oprofile.h> 17 - #include <linux/slab.h> 18 - #include <asm/ptrace.h> 19 - #include <asm/msr.h> 20 - #include <asm/apic.h> 21 - #include <asm/nmi.h> 22 - 23 - #include "op_x86_model.h" 24 - #include "op_counter.h" 25 - 26 - static int num_counters = 2; 27 - static int counter_width = 32; 28 - 29 - #define MSR_PPRO_EVENTSEL_RESERVED ((0xFFFFFFFFULL<<32)|(1ULL<<21)) 30 - 31 - static u64 reset_value[OP_MAX_COUNTER]; 32 - 33 - static void ppro_shutdown(struct op_msrs const * const msrs) 34 - { 35 - int i; 36 - 37 - for (i = 0; i < num_counters; ++i) { 38 - if (!msrs->counters[i].addr) 39 - continue; 40 - release_perfctr_nmi(MSR_P6_PERFCTR0 + i); 41 - release_evntsel_nmi(MSR_P6_EVNTSEL0 + i); 42 - } 43 - } 44 - 45 - static int ppro_fill_in_addresses(struct op_msrs * const msrs) 46 - { 47 - int i; 48 - 49 - for (i = 0; i < num_counters; i++) { 50 - if (!reserve_perfctr_nmi(MSR_P6_PERFCTR0 + i)) 51 - goto fail; 52 - if (!reserve_evntsel_nmi(MSR_P6_EVNTSEL0 + i)) { 53 - release_perfctr_nmi(MSR_P6_PERFCTR0 + i); 54 - goto fail; 55 - } 56 - /* both registers must be reserved */ 57 - msrs->counters[i].addr = MSR_P6_PERFCTR0 + i; 58 - msrs->controls[i].addr = MSR_P6_EVNTSEL0 + i; 59 - continue; 60 - fail: 61 - if (!counter_config[i].enabled) 62 - continue; 63 - op_x86_warn_reserved(i); 64 - ppro_shutdown(msrs); 65 - return -EBUSY; 66 - } 67 - 68 - return 0; 69 - } 70 - 71 - 72 - static void ppro_setup_ctrs(struct op_x86_model_spec const *model, 73 - struct op_msrs const * const msrs) 74 - { 75 - u64 val; 76 - int i; 77 - 78 - if (boot_cpu_has(X86_FEATURE_ARCH_PERFMON)) { 79 - union cpuid10_eax eax; 80 - eax.full = cpuid_eax(0xa); 81 - 82 - /* 83 - * For Core2 (family 6, model 15), don't reset the 84 - * counter width: 85 - */ 86 - if (!(eax.split.version_id == 0 && 87 - __this_cpu_read(cpu_info.x86) == 6 && 88 - __this_cpu_read(cpu_info.x86_model) == 15)) { 89 - 90 - if (counter_width < eax.split.bit_width) 91 - counter_width = eax.split.bit_width; 92 - } 93 - } 94 - 95 - /* clear all counters */ 96 - for (i = 0; i < num_counters; ++i) { 97 - if (!msrs->controls[i].addr) 98 - continue; 99 - rdmsrl(msrs->controls[i].addr, val); 100 - if (val & ARCH_PERFMON_EVENTSEL_ENABLE) 101 - op_x86_warn_in_use(i); 102 - val &= model->reserved; 103 - wrmsrl(msrs->controls[i].addr, val); 104 - /* 105 - * avoid a false detection of ctr overflows in NMI * 106 - * handler 107 - */ 108 - wrmsrl(msrs->counters[i].addr, -1LL); 109 - } 110 - 111 - /* enable active counters */ 112 - for (i = 0; i < num_counters; ++i) { 113 - if (counter_config[i].enabled && msrs->counters[i].addr) { 114 - reset_value[i] = counter_config[i].count; 115 - wrmsrl(msrs->counters[i].addr, -reset_value[i]); 116 - rdmsrl(msrs->controls[i].addr, val); 117 - val &= model->reserved; 118 - val |= op_x86_get_ctrl(model, &counter_config[i]); 119 - wrmsrl(msrs->controls[i].addr, val); 120 - } else { 121 - reset_value[i] = 0; 122 - } 123 - } 124 - } 125 - 126 - 127 - static int ppro_check_ctrs(struct pt_regs * const regs, 128 - struct op_msrs const * const msrs) 129 - { 130 - u64 val; 131 - int i; 132 - 133 - for (i = 0; i < num_counters; ++i) { 134 - if (!reset_value[i]) 135 - continue; 136 - rdmsrl(msrs->counters[i].addr, val); 137 - if (val & (1ULL << (counter_width - 1))) 138 - continue; 139 - oprofile_add_sample(regs, i); 140 - wrmsrl(msrs->counters[i].addr, -reset_value[i]); 141 - } 142 - 143 - /* Only P6 based Pentium M need to re-unmask the apic vector but it 144 - * doesn't hurt other P6 variant */ 145 - apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED); 146 - 147 - /* We can't work out if we really handled an interrupt. We 148 - * might have caught a *second* counter just after overflowing 149 - * the interrupt for this counter then arrives 150 - * and we don't find a counter that's overflowed, so we 151 - * would return 0 and get dazed + confused. Instead we always 152 - * assume we found an overflow. This sucks. 153 - */ 154 - return 1; 155 - } 156 - 157 - 158 - static void ppro_start(struct op_msrs const * const msrs) 159 - { 160 - u64 val; 161 - int i; 162 - 163 - for (i = 0; i < num_counters; ++i) { 164 - if (reset_value[i]) { 165 - rdmsrl(msrs->controls[i].addr, val); 166 - val |= ARCH_PERFMON_EVENTSEL_ENABLE; 167 - wrmsrl(msrs->controls[i].addr, val); 168 - } 169 - } 170 - } 171 - 172 - 173 - static void ppro_stop(struct op_msrs const * const msrs) 174 - { 175 - u64 val; 176 - int i; 177 - 178 - for (i = 0; i < num_counters; ++i) { 179 - if (!reset_value[i]) 180 - continue; 181 - rdmsrl(msrs->controls[i].addr, val); 182 - val &= ~ARCH_PERFMON_EVENTSEL_ENABLE; 183 - wrmsrl(msrs->controls[i].addr, val); 184 - } 185 - } 186 - 187 - struct op_x86_model_spec op_ppro_spec = { 188 - .num_counters = 2, 189 - .num_controls = 2, 190 - .reserved = MSR_PPRO_EVENTSEL_RESERVED, 191 - .fill_in_addresses = &ppro_fill_in_addresses, 192 - .setup_ctrs = &ppro_setup_ctrs, 193 - .check_ctrs = &ppro_check_ctrs, 194 - .start = &ppro_start, 195 - .stop = &ppro_stop, 196 - .shutdown = &ppro_shutdown 197 - }; 198 - 199 - /* 200 - * Architectural performance monitoring. 201 - * 202 - * Newer Intel CPUs (Core1+) have support for architectural 203 - * events described in CPUID 0xA. See the IA32 SDM Vol3b.18 for details. 204 - * The advantage of this is that it can be done without knowing about 205 - * the specific CPU. 206 - */ 207 - 208 - static void arch_perfmon_setup_counters(void) 209 - { 210 - union cpuid10_eax eax; 211 - 212 - eax.full = cpuid_eax(0xa); 213 - 214 - /* Workaround for BIOS bugs in 6/15. Taken from perfmon2 */ 215 - if (eax.split.version_id == 0 && boot_cpu_data.x86 == 6 && 216 - boot_cpu_data.x86_model == 15) { 217 - eax.split.version_id = 2; 218 - eax.split.num_counters = 2; 219 - eax.split.bit_width = 40; 220 - } 221 - 222 - num_counters = min((int)eax.split.num_counters, OP_MAX_COUNTER); 223 - 224 - op_arch_perfmon_spec.num_counters = num_counters; 225 - op_arch_perfmon_spec.num_controls = num_counters; 226 - } 227 - 228 - static int arch_perfmon_init(struct oprofile_operations *ignore) 229 - { 230 - arch_perfmon_setup_counters(); 231 - return 0; 232 - } 233 - 234 - struct op_x86_model_spec op_arch_perfmon_spec = { 235 - .reserved = MSR_PPRO_EVENTSEL_RESERVED, 236 - .init = &arch_perfmon_init, 237 - /* num_counters/num_controls filled in at runtime */ 238 - .fill_in_addresses = &ppro_fill_in_addresses, 239 - /* user space does the cpuid check for available events */ 240 - .setup_ctrs = &ppro_setup_ctrs, 241 - .check_ctrs = &ppro_check_ctrs, 242 - .start = &ppro_start, 243 - .stop = &ppro_stop, 244 - .shutdown = &ppro_shutdown 245 - };
-90
arch/x86/oprofile/op_x86_model.h
··· 1 - /** 2 - * @file op_x86_model.h 3 - * interface to x86 model-specific MSR operations 4 - * 5 - * @remark Copyright 2002 OProfile authors 6 - * @remark Read the file COPYING 7 - * 8 - * @author Graydon Hoare 9 - * @author Robert Richter <robert.richter@amd.com> 10 - */ 11 - 12 - #ifndef OP_X86_MODEL_H 13 - #define OP_X86_MODEL_H 14 - 15 - #include <asm/types.h> 16 - #include <asm/perf_event.h> 17 - 18 - struct op_msr { 19 - unsigned long addr; 20 - u64 saved; 21 - }; 22 - 23 - struct op_msrs { 24 - struct op_msr *counters; 25 - struct op_msr *controls; 26 - struct op_msr *multiplex; 27 - }; 28 - 29 - struct pt_regs; 30 - 31 - struct oprofile_operations; 32 - 33 - /* The model vtable abstracts the differences between 34 - * various x86 CPU models' perfctr support. 35 - */ 36 - struct op_x86_model_spec { 37 - unsigned int num_counters; 38 - unsigned int num_controls; 39 - unsigned int num_virt_counters; 40 - u64 reserved; 41 - u16 event_mask; 42 - int (*init)(struct oprofile_operations *ops); 43 - int (*fill_in_addresses)(struct op_msrs * const msrs); 44 - void (*setup_ctrs)(struct op_x86_model_spec const *model, 45 - struct op_msrs const * const msrs); 46 - int (*check_ctrs)(struct pt_regs * const regs, 47 - struct op_msrs const * const msrs); 48 - void (*start)(struct op_msrs const * const msrs); 49 - void (*stop)(struct op_msrs const * const msrs); 50 - void (*shutdown)(struct op_msrs const * const msrs); 51 - #ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX 52 - void (*switch_ctrl)(struct op_x86_model_spec const *model, 53 - struct op_msrs const * const msrs); 54 - #endif 55 - }; 56 - 57 - struct op_counter_config; 58 - 59 - static inline void op_x86_warn_in_use(int counter) 60 - { 61 - /* 62 - * The warning indicates an already running counter. If 63 - * oprofile doesn't collect data, then try using a different 64 - * performance counter on your platform to monitor the desired 65 - * event. Delete counter #%d from the desired event by editing 66 - * the /usr/share/oprofile/%s/<cpu>/events file. If the event 67 - * cannot be monitored by any other counter, contact your 68 - * hardware or BIOS vendor. 69 - */ 70 - pr_warn("oprofile: counter #%d on cpu #%d may already be used\n", 71 - counter, smp_processor_id()); 72 - } 73 - 74 - static inline void op_x86_warn_reserved(int counter) 75 - { 76 - pr_warn("oprofile: counter #%d is already reserved\n", counter); 77 - } 78 - 79 - extern u64 op_x86_get_ctrl(struct op_x86_model_spec const *model, 80 - struct op_counter_config *counter_config); 81 - extern int op_x86_phys_to_virt(int phys); 82 - extern int op_x86_virt_to_phys(int virt); 83 - 84 - extern struct op_x86_model_spec op_ppro_spec; 85 - extern struct op_x86_model_spec op_p4_spec; 86 - extern struct op_x86_model_spec op_p4_ht2_spec; 87 - extern struct op_x86_model_spec op_amd_spec; 88 - extern struct op_x86_model_spec op_arch_perfmon_spec; 89 - 90 - #endif /* OP_X86_MODEL_H */