1 diff --git a/Documentation/ABI/testing/sysfs-perfmon b/Documentation/ABI/testing/sysfs-perfmon
5 +++ b/Documentation/ABI/testing/sysfs-perfmon
7 +What: /sys/kernel/perfmon
10 +Contact: eranian@gmail.com
12 +Description: provide the configuration interface for the perfmon2 subsystems.
13 + The tree contains information about the detected hardware, current
14 + state of the subsystem as well as some configuration parameters.
16 + The tree consists of the following entries:
18 + /sys/kernel/perfmon/debug (read-write):
20 + Enable perfmon2 debugging output via klogd. Debug messages produced during
21 + PMU interrupt handling are not controlled by this entry. The traces a rate-limited
22 + to avoid flooding of the console. It is possible to change the throttling
23 + via /proc/sys/kernel/printk_ratelimit. The value is interpreted as a bitmask.
24 + Each bit enables a particular type of debug messages. Refer to the file
25 + include/linux/perfmon_kern.h for more information
27 + /sys/kernel/perfmon/pmc_max_fast_arg (read-only):
29 + Number of perfmon2 syscall arguments copied directly onto the
30 + stack (copy_from_user) for pfm_write_pmcs(). Copying to the stack avoids
31 + having to allocate a buffer. The unit is the number of pfarg_pmc_t
34 + /sys/kernel/perfmon/pmd_max_fast_arg (read-only):
36 + Number of perfmon2 syscall arguments copied directly onto the
37 + stack (copy_from_user) for pfm_write_pmds()/pfm_read_pmds(). Copying
38 + to the stack avoids having to allocate a buffer. The unit is the number
39 + of pfarg_pmd_t structures.
42 + /sys/kernel/perfmon/reset_stats (write-only):
44 + Reset the statistics collected by perfmon2. Stats are available
45 + per-cpu via debugfs.
47 + /sys/kernel/perfmon/smpl_buffer_mem_cur (read-only):
49 + Reports the amount of memory currently dedicated to sampling
50 + buffers by the kernel. The unit is byte.
52 + /sys/kernel/perfmon/smpl_buffer_mem_max (read-write):
54 + Maximum amount of kernel memory usable for sampling buffers. -1 means
55 + everything that is available. Unit is byte.
57 + /sys/kernel/perfmon/smpl_buffer_mem_cur (read-only):
59 + Current utilization of kernel memory in bytes.
61 + /sys/kernel/perfmon/sys_group (read-write):
63 + Users group allowed to create a system-wide perfmon2 context (session).
64 + -1 means any group. This control will be kept until we find a package
65 + able to control capabilities via PAM.
67 + /sys/kernel/perfmon/task_group (read-write):
69 + Users group allowed to create a per-thread context (session).
70 + -1 means any group. This control will be kept until we find a
71 + package able to control capabilities via PAM.
73 + /sys/kernel/perfmon/sys_sessions_count (read-only):
75 + Number of system-wide contexts currently attached to CPUs.
77 + /sys/kernel/perfmon/task_sessions_count (read-only):
79 + Number of per-thread contexts currently attached to threads.
81 + /sys/kernel/perfmon/version (read-only):
83 + Perfmon2 interface revision number.
85 + /sys/kernel/perfmon/arg_mem_max(read-write):
87 + Maximum size of vector arguments expressed in bytes. Can be modified
89 + /sys/kernel/perfmon/mode(read-write):
91 + Bitmask to enable/disable certain perfmon2 features.
93 + - bit 0: if set, then reserved bitfield are ignored on PMC writes
94 diff --git a/Documentation/ABI/testing/sysfs-perfmon-fmt b/Documentation/ABI/testing/sysfs-perfmon-fmt
96 index 0000000..1b45270
98 +++ b/Documentation/ABI/testing/sysfs-perfmon-fmt
100 +What: /sys/kernel/perfmon/formats
102 +KernelVersion: 2.6.24
103 +Contact: eranian@gmail.com
105 +Description: provide description of available perfmon2 custom sampling buffer formats
106 + which are implemented as independent kernel modules. Each formats gets
107 + a subdir which a few entries.
109 + The name of the subdir is the name of the sampling format. The same name
110 + must be passed to pfm_create_context() to use the format.
112 + Each subdir XX contains the following entries:
114 + /sys/kernel/perfmon/formats/XX/version (read-only):
116 + Version number of the format in clear text and null terminated.
118 diff --git a/Documentation/ABI/testing/sysfs-perfmon-pmu b/Documentation/ABI/testing/sysfs-perfmon-pmu
120 index 0000000..a1afc7e
122 +++ b/Documentation/ABI/testing/sysfs-perfmon-pmu
124 +What: /sys/kernel/perfmon/pmu
126 +KernelVersion: 2.6.24
127 +Contact: eranian@gmail.com
129 +Description: provide information about the currently loaded PMU description module.
130 + The module contains the mapping of the actual performance counter registers
131 + onto the logical PMU exposed by perfmon. There is at most one PMU description
132 + module loaded at any time.
134 + The sysfs PMU tree provides a description of the mapping for each register.
135 + There is one subdir per config and data registers along an entry for the
136 + name of the PMU model.
138 + The model entry is as follows:
140 + /sys/kernel/perfmon/pmu_desc/model (read-only):
142 + Name of the PMU model is clear text and zero terminated.
144 + Then for each logical PMU register, XX, gets a subtree with the following entries:
146 + /sys/kernel/perfmon/pmu_desc/pm*XX/addr (read-only):
148 + The physical address or index of the actual underlying hardware register.
149 + On Itanium, it corresponds to the index. But on X86 processor, this is
150 + the actual MSR address.
152 + /sys/kernel/perfmon/pmu_desc/pm*XX/dfl_val (read-only):
154 + The default value of the register in hexadecimal.
156 + /sys/kernel/perfmon/pmu_desc/pm*XX/name (read-only):
158 + The name of the hardware register.
160 + /sys/kernel/perfmon/pmu_desc/pm*XX/rsvd_msk (read-only):
162 + The bitmask of reserved bits, i.e., bits which cannot be changed by
163 + applications. When a bit is set, it means the corresponding bit in the
164 + actual register is reserved.
166 + /sys/kernel/perfmon/pmu_desc/pm*XX/width (read-only):
168 + the width in bits of the registers. This field is only relevant for counter
170 diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
171 index 1150444..2652b6c 100644
172 --- a/Documentation/kernel-parameters.txt
173 +++ b/Documentation/kernel-parameters.txt
174 @@ -1643,6 +1643,9 @@ and is between 256 and 4096 characters. It is defined in the file
176 See arch/parisc/kernel/pdc_chassis.c
178 + perfmon_debug [PERFMON] Enables Perfmon debug messages. Needed
179 + to see traces of the early startup startup phase.
182 See Documentation/paride.txt.
184 diff --git a/Documentation/perfmon2-debugfs.txt b/Documentation/perfmon2-debugfs.txt
186 index 0000000..b30cae8
188 +++ b/Documentation/perfmon2-debugfs.txt
190 + The perfmon2 debug and statistics interface
191 + ------------------------------------------
193 + <eranian@gmail.com>
195 +The perfmon2 interfaces exports a set of statistics which are used to tune and
196 +debug the implementation. The data is composed of a set of very simple metrics
197 +mostly aggregated counts and durations. They instruments key points in the
198 +perfmon2 code, such as context switch and interrupt handling.
200 +The data is accessible via the debug filesystem (debugfs). Thus you need to
201 +have the filesystem support enabled in your kernel. Furthermore since, 2.6.25,
202 +the perfmon2 statistics interface is an optional component. It needs to be
203 +explicitely enabled in the kernel config file (CONFIG_PERFMON_DEBUG_FS).
205 +To access the data, the debugs filesystem must be mounted. Supposing the mount
206 +point is /debugfs, you would need to do:
207 + $ mount -t debugs none /debugfs
209 +The data is located under the perfmon subdirectory and is organized per CPU.
210 +For each CPU, the same set of metrics is available, one metric per file in
213 +The metrics are as follows:
215 + ctxswin_count (read-only):
217 + Number of PMU context switch in.
219 + ctxswin_ns (read-only):
221 + Number of nanoseconds spent in the PMU context switch in
222 + routine. Dividing this number by the value of ctxswin_count,
223 + yields average cost of the PMU context switch in.
225 + ctxswout_count (read-only):
227 + Number of PMU context switch out.
229 + ctxswout_ns (read-only):
231 + Number of nanoseconds spent in the PMU context switch in
232 + routine. Dividing this number by the value of ctxswout_count,
233 + yields average cost of the PMU context switch out.
235 + fmt_handler_calls (read-only):
237 + Number of calls to the sampling format routine that handles
238 + PMU interrupts, i.e., typically the routine that records a
241 + fmt_handler_ns (read-only):
243 + Number of nanoseconds spent in the routine that handle PMU
244 + interrupt in the sampling format. Dividing this number by
245 + the number of calls provided by fmt_handler_calls, yields
246 + average time spent in this routine.
248 + ovfl_intr_all_count (read-only):
250 + Number of PMU interrupts received by the kernel.
253 + ovfl_intr_nmi_count (read-only):
255 + Number of Non Maskeable Interrupts (NMI) received by the kernel
256 + for perfmon. This is relevant only on X86 hardware.
258 + ovfl_intr_ns (read-only):
260 + Number of nanoseconds spent in the perfmon2 PMU interrupt
261 + handler routine. Dividing this number of ovfl_intr_all_count
262 + yields the average time to handle one PMU interrupt.
264 + ovfl_intr_regular_count (read-only):
266 + Number of PMU interrupts which are actually processed by
267 + the perfmon interrupt handler. There may be spurious or replay
270 + ovfl_intr_replay_count (read-only):
272 + Number of PMU interrupts which were replayed on context switch
273 + in or on event set switching. Interrupts get replayed when they
274 + were in flight at the time monitoring had to be stopped.
276 + perfmon/ovfl_intr_spurious_count (read-only):
278 + Number of PMU interrupts which were dropped because there was
279 + no active context (session).
281 + ovfl_notify_count (read-only):
283 + Number of user level notifications sent. Notifications are
284 + appended as messages to the context queue. Notifications may
285 + be sent on PMU interrupts.
287 + pfm_restart_count (read-only):
289 + Number of times pfm_restart() is called.
291 + reset_pmds_count (read-only):
293 + Number of times pfm_reset_pmds() is called.
295 + set_switch_count (read-only):
297 + Number of event set switches.
299 + set_switch_ns (read-only):
301 + Number of nanoseconds spent in the set switching routine.
302 + Dividing this number by set_switch_count yields the average
303 + cost of switching sets.
305 + handle_timeout_count (read-only):
307 + Number of times the pfm_handle_timeout() routine is called.
308 + It is used for timeout-based set switching.
310 + handle_work_count (read-only):
312 + Number of times pfm_handle_work() is called. The routine
313 + handles asynchronous perfmon2 work for per-thread contexts
316 diff --git a/Documentation/perfmon2.txt b/Documentation/perfmon2.txt
318 index 0000000..4a8fada
320 +++ b/Documentation/perfmon2.txt
322 + The perfmon2 hardware monitoring interface
323 + ------------------------------------------
325 + <eranian@gmail.com>
329 + The perfmon2 interface provides access to the hardware performance counters of
330 + major processors. Nowadays, all processors implement some flavors of performance
331 + counters which capture micro-architectural level information such as the number
332 + of elapsed cycles, number of cache misses, and so on.
334 + The interface is implemented as a set of new system calls and a set of config files
337 + It is possible to monitoring a single thread or a CPU. In either mode, applications
338 + can count or collect samples. System-wide monitoring is supported by running a
339 + monitoring session on each CPU. The interface support event-based sampling where the
340 + sampling period is expressed as the number of occurrences of event, instead of just a
341 + timeout. This approach provides a much better granularity and flexibility.
343 + For performance reason, it is possible to use a kernel-level sampling buffer to minimize
344 + the overhead incurred by sampling. The format of the buffer, i.e., what is recorded, how
345 + it is recorded, and how it is exported to user-land is controlled by a kernel module called
346 + a custom sampling format. The current implementation comes with a default format but
347 + it is possible to create additional formats. There is an in-kernel registration
348 + interface for formats. Each format is identified by a simple string which a tool
349 + can pass when a monitoring session is created.
351 + The interface also provides support for event set and multiplexing to work around
352 + hardware limitations in the number of available counters or in how events can be
353 + combined. Each set defines as many counters as the hardware can support. The kernel
354 + then multiplexes the sets. The interface supports time-base switching but also
355 + overflow based switching, i.e., after n overflows of designated counters.
357 + Applications never manipulates the actual performance counter registers. Instead they see
358 + a logical Performance Monitoring Unit (PMU) composed of a set of config register (PMC)
359 + and a set of data registers (PMD). Note that PMD are not necessarily counters, they
360 + can be buffers. The logical PMU is then mapped onto the actual PMU using a mapping
361 + table which is implemented as a kernel module. The mapping is chosen once for each
362 + new processor. It is visible in /sys/kernel/perfmon/pmu_desc. The kernel module
363 + is automatically loaded on first use.
365 + A monitoring session, or context, is uniquely identified by a file descriptor
366 + obtained when the context is created. File sharing semantics apply to access
367 + the context inside a process. A context is never inherited across fork. The file
368 + descriptor can be used to received counter overflow notifications or when the
369 + sampling buffer is full. It is possible to use poll/select on the descriptor
370 + to wait for notifications from multiplex contexts. Similarly, the descriptor
371 + supports asynchronous notification via SIGIO.
373 + Counters are always exported as being 64-bit wide regardless of what the underlying
374 + hardware implements.
376 +II/ Kernel compilation
378 + To enable perfmon2, you need to enable CONFIG_PERFMON
380 +III/ OProfile interactions
382 + The set of features offered by perfmon2 is rich enough to support migrating
383 + Oprofile on top of it. That means that PMU programming and low-level interrupt
384 + handling could be done by perfmon2. The Oprofile sampling buffer management code
385 + in the kernel as well as how samples are exported to users could remain through
386 + the use of a custom sampling buffer format. This is how Oprofile work on Itanium.
388 + The current interactions with Oprofile are:
389 + - on X86: Both subsystems can be compiled into the same kernel. There is enforced
390 + mutual exclusion between the two subsystems. When there is an Oprofile
391 + session, no perfmon2 session can exist and vice-versa. Perfmon2 session
392 + encapsulates both per-thread and system-wide sessions here.
394 + - On IA-64: Oprofile works on top of perfmon2. Oprofile being a system-wide monitoring
395 + tool, the regular per-thread vs. system-wide session restrictions apply.
397 + - on PPC: no integration yet. You need to enable/disble one of the two subsystems
398 + - on MIPS: no integration yet. You need to enable/disble one of the two subsystems
402 + We have released a simple monitoring tool to demonstrate the feature of the
403 + interface. The tool is called pfmon and it comes with a simple helper library
404 + called libpfm. The library comes with a set of examples to show how to use the
405 + kernel perfmon2 interface. Visit http://perfmon2.sf.net for details.
407 + There maybe other tools available for perfmon2.
411 + The best way to learn how to program perfmon2, is to take a look at the source
412 + code for the examples in libpfm. The source code is available from:
413 + http://perfmon2.sf.net
415 +VI/ System calls overview
417 + The interface is implemented by the following system calls:
419 + * int pfm_create_context(pfarg_ctx_t *ctx, char *fmt, void *arg, size_t arg_size)
421 + This function create a perfmon2 context. The type of context is per-thread by
422 + default unless PFM_FL_SYSTEM_WIDE is passed in ctx. The sampling format name
423 + is passed in fmt. Arguments to the format are passed in arg which is of size
424 + arg_size. Upon successful return, the file descriptor identifying the context
427 + * int pfm_write_pmds(int fd, pfarg_pmd_t *pmds, int n)
429 + This function is used to program the PMD registers. It is possible to pass
432 + * int pfm_write_pmcs(int fd, pfarg_pmc_t *pmds, int n)
434 + This function is used to program the PMC registers. It is possible to pass
437 + * int pfm_read_pmds(int fd, pfarg_pmd_t *pmds, int n)
439 + This function is used to read the PMD registers. It is possible to pass
442 + * int pfm_load_context(int fd, pfarg_load_t *load)
444 + This function is used to attach the context to a thread or CPU.
445 + Thread means kernel-visible thread (NPTL). The thread identification
446 + as obtained by gettid must be passed to load->load_target.
448 + To operate on another thread (not self), it is mandatory that the thread
449 + be stopped via ptrace().
451 + To attach to a CPU, the CPU number must be specified in load->load_target
452 + AND the call must be issued on that CPU. To monitor a CPU, a thread MUST
453 + be pinned on that CPU.
455 + Until the context is attached, the actual counters are not accessed.
457 + * int pfm_unload_context(int fd)
459 + The context is detached for the thread or CPU is was attached to.
460 + As a consequence monitoring is stopped.
462 + When monitoring another thread, the thread MUST be stopped via ptrace()
463 + for this function to succeed.
465 + * int pfm_start(int fd, pfarg_start_t *st)
467 + Start monitoring. The context must be attached for this function to succeed.
468 + Optionally, it is possible to specify the event set on which to start using the
469 + st argument, otherwise just pass NULL.
471 + When monitoring another thread, the thread MUST be stopped via ptrace()
472 + for this function to succeed.
474 + * int pfm_stop(int fd)
476 + Stop monitoring. The context must be attached for this function to succeed.
478 + When monitoring another thread, the thread MUST be stopped via ptrace()
479 + for this function to succeed.
482 + * int pfm_create_evtsets(int fd, pfarg_setdesc_t *sets, int n)
484 + This function is used to create or change event sets. By default set 0 exists.
485 + It is possible to create/change multiple sets in one call.
487 + The context must be detached for this call to succeed.
489 + Sets are identified by a 16-bit integer. They are sorted based on this
490 + set and switching occurs in a round-robin fashion.
492 + * int pfm_delete_evtsets(int fd, pfarg_setdesc_t *sets, int n)
494 + Delete event sets. The context must be detached for this call to succeed.
497 + * int pfm_getinfo_evtsets(int fd, pfarg_setinfo_t *sets, int n)
499 + Retrieve information about event sets. In particular it is possible
500 + to get the number of activation of a set. It is possible to retrieve
501 + information about multiple sets in one call.
504 + * int pfm_restart(int fd)
506 + Indicate to the kernel that the application is done processing an overflow
507 + notification. A consequence of this call could be that monitoring resumes.
509 + * int read(fd, pfm_msg_t *msg, sizeof(pfm_msg_t))
511 + the regular read() system call can be used with the context file descriptor to
512 + receive overflow notification messages. Non-blocking read() is supported.
514 + Each message carry information about the overflow such as which counter overflowed
515 + and where the program was (interrupted instruction pointer).
517 + * int close(int fd)
519 + To destroy a context, the regular close() system call is used.
522 +VII/ /sys interface overview
524 + Refer to Documentation/ABI/testing/sysfs-perfmon-* for a detailed description
525 + of the sysfs interface of perfmon2.
527 +VIII/ debugfs interface overview
529 + Refer to Documentation/perfmon2-debugfs.txt for a detailed description of the
530 + debug and statistics interface of perfmon2.
534 + Visit http://perfmon2.sf.net
535 diff --git a/MAINTAINERS b/MAINTAINERS
536 index 8dae455..fb38c2a 100644
539 @@ -3239,6 +3239,14 @@ M: balbir@linux.vnet.ibm.com
540 L: linux-kernel@vger.kernel.org
545 +M: eranian@gmail.com
546 +L: perfmon2-devel@lists.sf.net
547 +W: http://perfmon2.sf.net
548 +T: git kernel.org:/pub/scm/linux/kernel/git/eranian/linux-2.6
554 diff --git a/Makefile b/Makefile
555 index 16e3fbb..7bb1320 100644
558 @@ -620,6 +620,7 @@ export mod_strip_cmd
560 ifeq ($(KBUILD_EXTMOD),)
561 core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
562 +core-$(CONFIG_PERFMON) += perfmon/
564 vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
565 $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
566 diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
567 index 48e496f..1d79b01 100644
568 --- a/arch/ia64/Kconfig
569 +++ b/arch/ia64/Kconfig
570 @@ -470,14 +470,6 @@ config COMPAT_FOR_U64_ALIGNMENT
571 config IA64_MCA_RECOVERY
572 tristate "MCA recovery from errors other than TLB."
575 - bool "Performance monitor support"
577 - Selects whether support for the IA-64 performance monitor hardware
578 - is included in the kernel. This makes some kernel data-structures a
579 - little bigger and slows down execution a bit, but it is generally
580 - a good idea to turn this on. If you're unsure, say Y.
583 tristate "/proc/pal support"
585 @@ -549,6 +541,8 @@ source "drivers/firmware/Kconfig"
587 source "fs/Kconfig.binfmt"
589 +source "arch/ia64/perfmon/Kconfig"
593 menu "Power management and ACPI"
594 diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile
595 index 905d25b..9aa622d 100644
596 --- a/arch/ia64/Makefile
597 +++ b/arch/ia64/Makefile
598 @@ -57,6 +57,7 @@ core-$(CONFIG_IA64_GENERIC) += arch/ia64/dig/
599 core-$(CONFIG_IA64_HP_ZX1) += arch/ia64/dig/
600 core-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/dig/
601 core-$(CONFIG_IA64_SGI_SN2) += arch/ia64/sn/
602 +core-$(CONFIG_PERFMON) += arch/ia64/perfmon/
603 core-$(CONFIG_IA64_SGI_UV) += arch/ia64/uv/
604 core-$(CONFIG_KVM) += arch/ia64/kvm/
606 diff --git a/arch/ia64/configs/generic_defconfig b/arch/ia64/configs/generic_defconfig
607 index 9f48397..ff9572a 100644
608 --- a/arch/ia64/configs/generic_defconfig
609 +++ b/arch/ia64/configs/generic_defconfig
610 @@ -209,7 +209,6 @@ CONFIG_IA32_SUPPORT=y
612 CONFIG_COMPAT_FOR_U64_ALIGNMENT=y
613 CONFIG_IA64_MCA_RECOVERY=y
615 CONFIG_IA64_PALINFO=y
616 # CONFIG_IA64_MC_ERR_INJECT is not set
618 @@ -234,6 +233,16 @@ CONFIG_BINFMT_ELF=y
622 +# Hardware Performance Monitoring support
625 +CONFIG_IA64_PERFMON_COMPAT=y
626 +CONFIG_IA64_PERFMON_GENERIC=m
627 +CONFIG_IA64_PERFMON_ITANIUM=y
628 +CONFIG_IA64_PERFMON_MCKINLEY=y
629 +CONFIG_IA64_PERFMON_MONTECITO=y
632 # Power management and ACPI
635 diff --git a/arch/ia64/include/asm/Kbuild b/arch/ia64/include/asm/Kbuild
636 index ccbe8ae..cf64b3b 100644
637 --- a/arch/ia64/include/asm/Kbuild
638 +++ b/arch/ia64/include/asm/Kbuild
639 @@ -5,10 +5,12 @@ header-y += fpu.h
641 header-y += ia64regs.h
642 header-y += intel_intrin.h
643 -header-y += perfmon_default_smpl.h
644 header-y += ptrace_offsets.h
646 header-y += ucontext.h
647 +header-y += perfmon.h
648 +header-y += perfmon_compat.h
649 +header-y += perfmon_default_smpl.h
651 unifdef-y += gcc_intrin.h
652 unifdef-y += intrinsics.h
653 diff --git a/arch/ia64/include/asm/hw_irq.h b/arch/ia64/include/asm/hw_irq.h
654 index 5c99cbc..4a45cb0 100644
655 --- a/arch/ia64/include/asm/hw_irq.h
656 +++ b/arch/ia64/include/asm/hw_irq.h
657 @@ -67,9 +67,9 @@ extern int ia64_last_device_vector;
658 #define IA64_NUM_DEVICE_VECTORS (IA64_LAST_DEVICE_VECTOR - IA64_FIRST_DEVICE_VECTOR + 1)
660 #define IA64_MCA_RENDEZ_VECTOR 0xe8 /* MCA rendez interrupt */
661 -#define IA64_PERFMON_VECTOR 0xee /* performance monitor interrupt vector */
662 #define IA64_TIMER_VECTOR 0xef /* use highest-prio group 15 interrupt for timer */
663 #define IA64_MCA_WAKEUP_VECTOR 0xf0 /* MCA wakeup (must be >MCA_RENDEZ_VECTOR) */
664 +#define IA64_PERFMON_VECTOR 0xf1 /* performance monitor interrupt vector */
665 #define IA64_IPI_LOCAL_TLB_FLUSH 0xfc /* SMP flush local TLB */
666 #define IA64_IPI_RESCHEDULE 0xfd /* SMP reschedule */
667 #define IA64_IPI_VECTOR 0xfe /* inter-processor interrupt vector */
668 diff --git a/arch/ia64/include/asm/perfmon.h b/arch/ia64/include/asm/perfmon.h
669 index 7f3333d..150c4b4 100644
670 --- a/arch/ia64/include/asm/perfmon.h
671 +++ b/arch/ia64/include/asm/perfmon.h
674 - * Copyright (C) 2001-2003 Hewlett-Packard Co
675 - * Stephane Eranian <eranian@hpl.hp.com>
678 -#ifndef _ASM_IA64_PERFMON_H
679 -#define _ASM_IA64_PERFMON_H
682 - * perfmon comamnds supported on all CPU models
684 -#define PFM_WRITE_PMCS 0x01
685 -#define PFM_WRITE_PMDS 0x02
686 -#define PFM_READ_PMDS 0x03
687 -#define PFM_STOP 0x04
688 -#define PFM_START 0x05
689 -#define PFM_ENABLE 0x06 /* obsolete */
690 -#define PFM_DISABLE 0x07 /* obsolete */
691 -#define PFM_CREATE_CONTEXT 0x08
692 -#define PFM_DESTROY_CONTEXT 0x09 /* obsolete use close() */
693 -#define PFM_RESTART 0x0a
694 -#define PFM_PROTECT_CONTEXT 0x0b /* obsolete */
695 -#define PFM_GET_FEATURES 0x0c
696 -#define PFM_DEBUG 0x0d
697 -#define PFM_UNPROTECT_CONTEXT 0x0e /* obsolete */
698 -#define PFM_GET_PMC_RESET_VAL 0x0f
699 -#define PFM_LOAD_CONTEXT 0x10
700 -#define PFM_UNLOAD_CONTEXT 0x11
703 - * PMU model specific commands (may not be supported on all PMU models)
705 -#define PFM_WRITE_IBRS 0x20
706 -#define PFM_WRITE_DBRS 0x21
711 -#define PFM_FL_NOTIFY_BLOCK 0x01 /* block task on user level notifications */
712 -#define PFM_FL_SYSTEM_WIDE 0x02 /* create a system wide context */
713 -#define PFM_FL_OVFL_NO_MSG 0x80 /* do not post overflow/end messages for notification */
718 -#define PFM_SETFL_EXCL_IDLE 0x01 /* exclude idle task (syswide only) XXX: DO NOT USE YET */
723 -#define PFM_REGFL_OVFL_NOTIFY 0x1 /* send notification on overflow */
724 -#define PFM_REGFL_RANDOM 0x2 /* randomize sampling interval */
727 - * PMD/PMC/IBR/DBR return flags (ignored on input)
728 + * Copyright (c) 2001-2007 Hewlett-Packard Development Company, L.P.
729 + * Contributed by Stephane Eranian <eranian@hpl.hp.com>
731 - * Those flags are used on output and must be checked in case EAGAIN is returned
732 - * by any of the calls using a pfarg_reg_t or pfarg_dbreg_t structure.
734 -#define PFM_REG_RETFL_NOTAVAIL (1UL<<31) /* set if register is implemented but not available */
735 -#define PFM_REG_RETFL_EINVAL (1UL<<30) /* set if register entry is invalid */
736 -#define PFM_REG_RETFL_MASK (PFM_REG_RETFL_NOTAVAIL|PFM_REG_RETFL_EINVAL)
738 -#define PFM_REG_HAS_ERROR(flag) (((flag) & PFM_REG_RETFL_MASK) != 0)
740 -typedef unsigned char pfm_uuid_t[16]; /* custom sampling buffer identifier type */
743 - * Request structure used to define a context
746 - pfm_uuid_t ctx_smpl_buf_id; /* which buffer format to use (if needed) */
747 - unsigned long ctx_flags; /* noblock/block */
748 - unsigned short ctx_nextra_sets; /* number of extra event sets (you always get 1) */
749 - unsigned short ctx_reserved1; /* for future use */
750 - int ctx_fd; /* return arg: unique identification for context */
751 - void *ctx_smpl_vaddr; /* return arg: virtual address of sampling buffer, is used */
752 - unsigned long ctx_reserved2[11];/* for future use */
756 - * Request structure used to write/read a PMC or PMD
759 - unsigned int reg_num; /* which register */
760 - unsigned short reg_set; /* event set for this register */
761 - unsigned short reg_reserved1; /* for future use */
763 - unsigned long reg_value; /* initial pmc/pmd value */
764 - unsigned long reg_flags; /* input: pmc/pmd flags, return: reg error */
766 - unsigned long reg_long_reset; /* reset after buffer overflow notification */
767 - unsigned long reg_short_reset; /* reset after counter overflow */
769 - unsigned long reg_reset_pmds[4]; /* which other counters to reset on overflow */
770 - unsigned long reg_random_seed; /* seed value when randomization is used */
771 - unsigned long reg_random_mask; /* bitmask used to limit random value */
772 - unsigned long reg_last_reset_val;/* return: PMD last reset value */
774 - unsigned long reg_smpl_pmds[4]; /* which pmds are accessed when PMC overflows */
775 - unsigned long reg_smpl_eventid; /* opaque sampling event identifier */
777 - unsigned long reg_reserved2[3]; /* for future use */
781 - unsigned int dbreg_num; /* which debug register */
782 - unsigned short dbreg_set; /* event set for this register */
783 - unsigned short dbreg_reserved1; /* for future use */
784 - unsigned long dbreg_value; /* value for debug register */
785 - unsigned long dbreg_flags; /* return: dbreg error */
786 - unsigned long dbreg_reserved2[1]; /* for future use */
790 - unsigned int ft_version; /* perfmon: major [16-31], minor [0-15] */
791 - unsigned int ft_reserved; /* reserved for future use */
792 - unsigned long reserved[4]; /* for future use */
796 - pid_t load_pid; /* process to load the context into */
797 - unsigned short load_set; /* first event set to load */
798 - unsigned short load_reserved1; /* for future use */
799 - unsigned long load_reserved2[3]; /* for future use */
803 - int msg_type; /* generic message header */
804 - int msg_ctx_fd; /* generic message header */
805 - unsigned long msg_ovfl_pmds[4]; /* which PMDs overflowed */
806 - unsigned short msg_active_set; /* active set at the time of overflow */
807 - unsigned short msg_reserved1; /* for future use */
808 - unsigned int msg_reserved2; /* for future use */
809 - unsigned long msg_tstamp; /* for perf tuning/debug */
813 - int msg_type; /* generic message header */
814 - int msg_ctx_fd; /* generic message header */
815 - unsigned long msg_tstamp; /* for perf tuning */
819 - int msg_type; /* type of the message */
820 - int msg_ctx_fd; /* unique identifier for the context */
821 - unsigned long msg_tstamp; /* for perf tuning */
824 -#define PFM_MSG_OVFL 1 /* an overflow happened */
825 -#define PFM_MSG_END 2 /* task to which context was attached ended */
828 - pfm_ovfl_msg_t pfm_ovfl_msg;
829 - pfm_end_msg_t pfm_end_msg;
830 - pfm_gen_msg_t pfm_gen_msg;
834 - * Define the version numbers for both perfmon as a whole and the sampling buffer format.
835 + * This file contains Itanium Processor Family specific definitions
836 + * for the perfmon interface.
838 + * This program is free software; you can redistribute it and/or
839 + * modify it under the terms of version 2 of the GNU General Public
840 + * License as published by the Free Software Foundation.
842 + * This program is distributed in the hope that it will be useful,
843 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
844 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
845 + * General Public License for more details.
847 + * You should have received a copy of the GNU General Public License
848 + * along with this program; if not, write to the Free Software
849 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
852 -#define PFM_VERSION_MAJ 2U
853 -#define PFM_VERSION_MIN 0U
854 -#define PFM_VERSION (((PFM_VERSION_MAJ&0xffff)<<16)|(PFM_VERSION_MIN & 0xffff))
855 -#define PFM_VERSION_MAJOR(x) (((x)>>16) & 0xffff)
856 -#define PFM_VERSION_MINOR(x) ((x) & 0xffff)
858 +#ifndef _ASM_IA64_PERFMON_H_
859 +#define _ASM_IA64_PERFMON_H_
862 - * miscellaneous architected definitions
863 + * arch-specific user visible interface definitions
865 -#define PMU_FIRST_COUNTER 4 /* first counting monitor (PMC/PMD) */
866 -#define PMU_MAX_PMCS 256 /* maximum architected number of PMC registers */
867 -#define PMU_MAX_PMDS 256 /* maximum architected number of PMD registers */
871 -extern long perfmonctl(int fd, int cmd, void *arg, int narg);
874 - void (*handler)(int irq, void *arg, struct pt_regs *regs);
875 -} pfm_intr_handler_desc_t;
877 -extern void pfm_save_regs (struct task_struct *);
878 -extern void pfm_load_regs (struct task_struct *);
880 -extern void pfm_exit_thread(struct task_struct *);
881 -extern int pfm_use_debug_registers(struct task_struct *);
882 -extern int pfm_release_debug_registers(struct task_struct *);
883 -extern void pfm_syst_wide_update_task(struct task_struct *, unsigned long info, int is_ctxswin);
884 -extern void pfm_inherit(struct task_struct *task, struct pt_regs *regs);
885 -extern void pfm_init_percpu(void);
886 -extern void pfm_handle_work(void);
887 -extern int pfm_install_alt_pmu_interrupt(pfm_intr_handler_desc_t *h);
888 -extern int pfm_remove_alt_pmu_interrupt(pfm_intr_handler_desc_t *h);
889 +#define PFM_ARCH_MAX_PMCS (256+64)
890 +#define PFM_ARCH_MAX_PMDS (256+64)
895 - * Reset PMD register flags
897 -#define PFM_PMD_SHORT_RESET 0
898 -#define PFM_PMD_LONG_RESET 1
903 - unsigned int notify_user:1; /* notify user program of overflow */
904 - unsigned int reset_ovfl_pmds:1; /* reset overflowed PMDs */
905 - unsigned int block_task:1; /* block monitored task on kernel exit */
906 - unsigned int mask_monitoring:1; /* mask monitors via PMCx.plm */
907 - unsigned int reserved:28; /* for future use */
912 - unsigned char ovfl_pmd; /* index of overflowed PMD */
913 - unsigned char ovfl_notify; /* =1 if monitor requested overflow notification */
914 - unsigned short active_set; /* event set active at the time of the overflow */
915 - pfm_ovfl_ctrl_t ovfl_ctrl; /* return: perfmon controls to set by handler */
917 - unsigned long pmd_last_reset; /* last reset value of of the PMD */
918 - unsigned long smpl_pmds[4]; /* bitmask of other PMD of interest on overflow */
919 - unsigned long smpl_pmds_values[PMU_MAX_PMDS]; /* values for the other PMDs of interest */
920 - unsigned long pmd_value; /* current 64-bit value of the PMD */
921 - unsigned long pmd_eventid; /* eventid associated with PMD */
927 - pfm_uuid_t fmt_uuid;
928 - size_t fmt_arg_size;
929 - unsigned long fmt_flags;
931 - int (*fmt_validate)(struct task_struct *task, unsigned int flags, int cpu, void *arg);
932 - int (*fmt_getsize)(struct task_struct *task, unsigned int flags, int cpu, void *arg, unsigned long *size);
933 - int (*fmt_init)(struct task_struct *task, void *buf, unsigned int flags, int cpu, void *arg);
934 - int (*fmt_handler)(struct task_struct *task, void *buf, pfm_ovfl_arg_t *arg, struct pt_regs *regs, unsigned long stamp);
935 - int (*fmt_restart)(struct task_struct *task, pfm_ovfl_ctrl_t *ctrl, void *buf, struct pt_regs *regs);
936 - int (*fmt_restart_active)(struct task_struct *task, pfm_ovfl_ctrl_t *ctrl, void *buf, struct pt_regs *regs);
937 - int (*fmt_exit)(struct task_struct *task, void *buf, struct pt_regs *regs);
939 - struct list_head fmt_list;
942 -extern int pfm_register_buffer_fmt(pfm_buffer_fmt_t *fmt);
943 -extern int pfm_unregister_buffer_fmt(pfm_uuid_t uuid);
944 +#define PFM_ARCH_PMD_STK_ARG 8
945 +#define PFM_ARCH_PMC_STK_ARG 8
948 - * perfmon interface exported to modules
949 + * Itanium specific context flags
951 + * bits[00-15]: generic flags (see asm/perfmon.h)
952 + * bits[16-31]: arch-specific flags
954 -extern int pfm_mod_read_pmds(struct task_struct *, void *req, unsigned int nreq, struct pt_regs *regs);
955 -extern int pfm_mod_write_pmcs(struct task_struct *, void *req, unsigned int nreq, struct pt_regs *regs);
956 -extern int pfm_mod_write_ibrs(struct task_struct *task, void *req, unsigned int nreq, struct pt_regs *regs);
957 -extern int pfm_mod_write_dbrs(struct task_struct *task, void *req, unsigned int nreq, struct pt_regs *regs);
958 +#define PFM_ITA_FL_INSECURE 0x10000 /* clear psr.sp on non system, non self */
961 - * describe the content of the local_cpu_date->pfm_syst_info field
962 + * Itanium specific public event set flags (set_flags)
964 + * event set flags layout:
965 + * bits[00-15] : generic flags
966 + * bits[16-31] : arch-specific flags
968 -#define PFM_CPUINFO_SYST_WIDE 0x1 /* if set a system wide session exists */
969 -#define PFM_CPUINFO_DCR_PP 0x2 /* if set the system wide session has started */
970 -#define PFM_CPUINFO_EXCL_IDLE 0x4 /* the system wide session excludes the idle task */
971 +#define PFM_ITA_SETFL_EXCL_INTR 0x10000 /* exclude interrupt execution */
972 +#define PFM_ITA_SETFL_INTR_ONLY 0x20000 /* include only interrupt execution */
973 +#define PFM_ITA_SETFL_IDLE_EXCL 0x40000 /* stop monitoring in idle loop */
976 - * sysctl control structure. visible to sampling formats
977 + * compatibility for version v2.0 of the interface
980 - int debug; /* turn on/off debugging via syslog */
981 - int debug_ovfl; /* turn on/off debug printk in overflow handler */
982 - int fastctxsw; /* turn on/off fast (unsecure) ctxsw */
983 - int expert_mode; /* turn on/off value checking */
985 -extern pfm_sysctl_t pfm_sysctl;
988 -#endif /* __KERNEL__ */
989 +#include <asm/perfmon_compat.h>
991 -#endif /* _ASM_IA64_PERFMON_H */
992 +#endif /* _ASM_IA64_PERFMON_H_ */
993 diff --git a/arch/ia64/include/asm/perfmon_compat.h b/arch/ia64/include/asm/perfmon_compat.h
995 index 0000000..5c14514
997 +++ b/arch/ia64/include/asm/perfmon_compat.h
1000 + * Copyright (c) 2001-2006 Hewlett-Packard Development Company, L.P.
1001 + * Contributed by Stephane Eranian <eranian@hpl.hp.com>
1003 + * This header file contains perfmon interface definition
1004 + * that are now obsolete and should be dropped in favor
1005 + * of their equivalent functions as explained below.
1007 + * This program is free software; you can redistribute it and/or
1008 + * modify it under the terms of version 2 of the GNU General Public
1009 + * License as published by the Free Software Foundation.
1011 + * This program is distributed in the hope that it will be useful,
1012 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1013 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1014 + * General Public License for more details.
1016 + * You should have received a copy of the GNU General Public License
1017 + * along with this program; if not, write to the Free Software
1018 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1022 +#ifndef _ASM_IA64_PERFMON_COMPAT_H_
1023 +#define _ASM_IA64_PERFMON_COMPAT_H_
1026 + * custom sampling buffer identifier type
1028 +typedef __u8 pfm_uuid_t[16];
1031 + * obsolete perfmon commands. Supported only on IA-64 for
1032 + * backward compatiblity reasons with perfmon v2.0.
1034 +#define PFM_WRITE_PMCS 0x01 /* use pfm_write_pmcs */
1035 +#define PFM_WRITE_PMDS 0x02 /* use pfm_write_pmds */
1036 +#define PFM_READ_PMDS 0x03 /* use pfm_read_pmds */
1037 +#define PFM_STOP 0x04 /* use pfm_stop */
1038 +#define PFM_START 0x05 /* use pfm_start */
1039 +#define PFM_ENABLE 0x06 /* obsolete */
1040 +#define PFM_DISABLE 0x07 /* obsolete */
1041 +#define PFM_CREATE_CONTEXT 0x08 /* use pfm_create_context */
1042 +#define PFM_DESTROY_CONTEXT 0x09 /* use close() */
1043 +#define PFM_RESTART 0x0a /* use pfm_restart */
1044 +#define PFM_PROTECT_CONTEXT 0x0b /* obsolete */
1045 +#define PFM_GET_FEATURES 0x0c /* use /proc/sys/perfmon */
1046 +#define PFM_DEBUG 0x0d /* /proc/sys/kernel/perfmon/debug */
1047 +#define PFM_UNPROTECT_CONTEXT 0x0e /* obsolete */
1048 +#define PFM_GET_PMC_RESET_VAL 0x0f /* use /proc/perfmon_map */
1049 +#define PFM_LOAD_CONTEXT 0x10 /* use pfm_load_context */
1050 +#define PFM_UNLOAD_CONTEXT 0x11 /* use pfm_unload_context */
1053 + * PMU model specific commands (may not be supported on all PMU models)
1055 +#define PFM_WRITE_IBRS 0x20 /* obsolete: use PFM_WRITE_PMCS[256-263]*/
1056 +#define PFM_WRITE_DBRS 0x21 /* obsolete: use PFM_WRITE_PMCS[264-271]*/
1059 + * argument to PFM_CREATE_CONTEXT
1061 +struct pfarg_context {
1062 + pfm_uuid_t ctx_smpl_buf_id; /* buffer format to use */
1063 + unsigned long ctx_flags; /* noblock/block */
1064 + unsigned int ctx_reserved1; /* for future use */
1065 + int ctx_fd; /* return: fildesc */
1066 + void *ctx_smpl_vaddr; /* return: vaddr of buffer */
1067 + unsigned long ctx_reserved3[11];/* for future use */
1071 + * argument structure for PFM_WRITE_PMCS/PFM_WRITE_PMDS/PFM_WRITE_PMDS
1074 + unsigned int reg_num; /* which register */
1075 + unsigned short reg_set; /* event set for this register */
1076 + unsigned short reg_reserved1; /* for future use */
1078 + unsigned long reg_value; /* initial pmc/pmd value */
1079 + unsigned long reg_flags; /* input: flags, ret: error */
1081 + unsigned long reg_long_reset; /* reset value after notification */
1082 + unsigned long reg_short_reset; /* reset after counter overflow */
1084 + unsigned long reg_reset_pmds[4]; /* registers to reset on overflow */
1085 + unsigned long reg_random_seed; /* seed for randomization */
1086 + unsigned long reg_random_mask; /* random range limit */
1087 + unsigned long reg_last_reset_val;/* return: PMD last reset value */
1089 + unsigned long reg_smpl_pmds[4]; /* pmds to be saved on overflow */
1090 + unsigned long reg_smpl_eventid; /* opaque sampling event id */
1091 + unsigned long reg_ovfl_switch_cnt;/* #overflows to switch */
1093 + unsigned long reg_reserved2[2]; /* for future use */
1097 + * argument to PFM_WRITE_IBRS/PFM_WRITE_DBRS
1099 +struct pfarg_dbreg {
1100 + unsigned int dbreg_num; /* which debug register */
1101 + unsigned short dbreg_set; /* event set */
1102 + unsigned short dbreg_reserved1; /* for future use */
1103 + unsigned long dbreg_value; /* value for debug register */
1104 + unsigned long dbreg_flags; /* return: dbreg error */
1105 + unsigned long dbreg_reserved2[1]; /* for future use */
1109 + * argument to PFM_GET_FEATURES
1111 +struct pfarg_features {
1112 + unsigned int ft_version; /* major [16-31], minor [0-15] */
1113 + unsigned int ft_reserved; /* reserved for future use */
1114 + unsigned long reserved[4]; /* for future use */
1118 + int msg_type; /* generic message header */
1119 + int msg_ctx_fd; /* generic message header */
1120 + unsigned long msg_ovfl_pmds[4]; /* which PMDs overflowed */
1121 + unsigned short msg_active_set; /* active set on overflow */
1122 + unsigned short msg_reserved1; /* for future use */
1123 + unsigned int msg_reserved2; /* for future use */
1124 + unsigned long msg_tstamp; /* for perf tuning/debug */
1128 + int msg_type; /* generic message header */
1129 + int msg_ctx_fd; /* generic message header */
1130 + unsigned long msg_tstamp; /* for perf tuning */
1134 + int msg_type; /* type of the message */
1135 + int msg_ctx_fd; /* context file descriptor */
1136 + unsigned long msg_tstamp; /* for perf tuning */
1141 + pfm_ovfl_msg_t pfm_ovfl_msg;
1142 + pfm_end_msg_t pfm_end_msg;
1143 + pfm_gen_msg_t pfm_gen_msg;
1147 + * PMD/PMC return flags in case of error (ignored on input)
1149 + * reg_flags layout:
1150 + * bit 00-15 : generic flags
1151 + * bits[16-23] : arch-specific flags (see asm/perfmon.h)
1152 + * bit 24-31 : error codes
1154 + * Those flags are used on output and must be checked in case EINVAL is
1155 + * returned by a command accepting a vector of values and each has a flag
1156 + * field, such as pfarg_reg or pfarg_reg
1158 +#define PFM_REG_RETFL_NOTAVAIL (1<<31) /* not implemented or unaccessible */
1159 +#define PFM_REG_RETFL_EINVAL (1<<30) /* entry is invalid */
1160 +#define PFM_REG_RETFL_MASK (PFM_REG_RETFL_NOTAVAIL|\
1161 + PFM_REG_RETFL_EINVAL)
1163 +#define PFM_REG_HAS_ERROR(flag) (((flag) & PFM_REG_RETFL_MASK) != 0)
1165 +#endif /* _ASM_IA64_PERFMON_COMPAT_H_ */
1166 diff --git a/arch/ia64/include/asm/perfmon_default_smpl.h b/arch/ia64/include/asm/perfmon_default_smpl.h
1167 index 48822c0..8234f32 100644
1168 --- a/arch/ia64/include/asm/perfmon_default_smpl.h
1169 +++ b/arch/ia64/include/asm/perfmon_default_smpl.h
1172 - * Copyright (C) 2002-2003 Hewlett-Packard Co
1173 - * Stephane Eranian <eranian@hpl.hp.com>
1174 + * Copyright (c) 2002-2006 Hewlett-Packard Development Company, L.P.
1175 + * Contributed by Stephane Eranian <eranian@hpl.hp.com>
1177 - * This file implements the default sampling buffer format
1178 - * for Linux/ia64 perfmon subsystem.
1179 + * This file implements the old default sampling buffer format
1180 + * for the perfmon2 subsystem. For IA-64 only.
1182 + * It requires the use of the perfmon_compat.h header. It is recommended
1183 + * that applications be ported to the new format instead.
1185 + * This program is free software; you can redistribute it and/or
1186 + * modify it under the terms of version 2 of the GNU General Public
1187 + * License as published by the Free Software Foundation.
1189 + * This program is distributed in the hope that it will be useful,
1190 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1191 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1192 + * General Public License for more details.
1194 + * You should have received a copy of the GNU General Public License
1195 + * along with this program; if not, write to the Free Software
1196 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1199 -#ifndef __PERFMON_DEFAULT_SMPL_H__
1200 -#define __PERFMON_DEFAULT_SMPL_H__ 1
1201 +#ifndef __ASM_IA64_PERFMON_DEFAULT_SMPL_H__
1202 +#define __ASM_IA64_PERFMON_DEFAULT_SMPL_H__ 1
1205 +#error "this file must be used for compatibility reasons only on IA-64"
1208 #define PFM_DEFAULT_SMPL_UUID { \
1209 - 0x4d, 0x72, 0xbe, 0xc0, 0x06, 0x64, 0x41, 0x43, 0x82, 0xb4, 0xd3, 0xfd, 0x27, 0x24, 0x3c, 0x97}
1210 + 0x4d, 0x72, 0xbe, 0xc0, 0x06, 0x64, 0x41, 0x43, 0x82,\
1211 + 0xb4, 0xd3, 0xfd, 0x27, 0x24, 0x3c, 0x97}
1214 * format specific parameters (passed at context creation)
1217 +struct pfm_default_smpl_arg {
1218 unsigned long buf_size; /* size of the buffer in bytes */
1219 unsigned int flags; /* buffer specific flags */
1220 unsigned int res1; /* for future use */
1221 unsigned long reserved[2]; /* for future use */
1222 -} pfm_default_smpl_arg_t;
1226 * combined context+format specific structure. Can be passed
1227 - * to PFM_CONTEXT_CREATE
1228 + * to PFM_CONTEXT_CREATE (not PFM_CONTEXT_CREATE2)
1231 - pfarg_context_t ctx_arg;
1232 - pfm_default_smpl_arg_t buf_arg;
1233 -} pfm_default_smpl_ctx_arg_t;
1234 +struct pfm_default_smpl_ctx_arg {
1235 + struct pfarg_context ctx_arg;
1236 + struct pfm_default_smpl_arg buf_arg;
1240 * This header is at the beginning of the sampling buffer returned to the user.
1241 * It is directly followed by the first record.
1244 - unsigned long hdr_count; /* how many valid entries */
1245 - unsigned long hdr_cur_offs; /* current offset from top of buffer */
1246 - unsigned long hdr_reserved2; /* reserved for future use */
1247 +struct pfm_default_smpl_hdr {
1248 + u64 hdr_count; /* how many valid entries */
1249 + u64 hdr_cur_offs; /* current offset from top of buffer */
1250 + u64 dr_reserved2; /* reserved for future use */
1252 - unsigned long hdr_overflows; /* how many times the buffer overflowed */
1253 - unsigned long hdr_buf_size; /* how many bytes in the buffer */
1254 + u64 hdr_overflows; /* how many times the buffer overflowed */
1255 + u64 hdr_buf_size; /* how many bytes in the buffer */
1257 - unsigned int hdr_version; /* contains perfmon version (smpl format diffs) */
1258 - unsigned int hdr_reserved1; /* for future use */
1259 - unsigned long hdr_reserved[10]; /* for future use */
1260 -} pfm_default_smpl_hdr_t;
1261 + u32 hdr_version; /* smpl format version*/
1262 + u32 hdr_reserved1; /* for future use */
1263 + u64 hdr_reserved[10]; /* for future use */
1267 * Entry header in the sampling buffer. The header is directly followed
1268 - * with the values of the PMD registers of interest saved in increasing
1269 - * index order: PMD4, PMD5, and so on. How many PMDs are present depends
1270 + * with the values of the PMD registers of interest saved in increasing
1271 + * index order: PMD4, PMD5, and so on. How many PMDs are present depends
1272 * on how the session was programmed.
1274 * In the case where multiple counters overflow at the same time, multiple
1275 * entries are written consecutively.
1277 - * last_reset_value member indicates the initial value of the overflowed PMD.
1278 + * last_reset_value member indicates the initial value of the overflowed PMD.
1281 - int pid; /* thread id (for NPTL, this is gettid()) */
1282 - unsigned char reserved1[3]; /* reserved for future use */
1283 - unsigned char ovfl_pmd; /* index of overflowed PMD */
1285 - unsigned long last_reset_val; /* initial value of overflowed PMD */
1286 - unsigned long ip; /* where did the overflow interrupt happened */
1287 - unsigned long tstamp; /* ar.itc when entering perfmon intr. handler */
1289 - unsigned short cpu; /* cpu on which the overfow occured */
1290 - unsigned short set; /* event set active when overflow ocurred */
1291 - int tgid; /* thread group id (for NPTL, this is getpid()) */
1292 -} pfm_default_smpl_entry_t;
1293 +struct pfm_default_smpl_entry {
1294 + pid_t pid; /* thread id (for NPTL, this is gettid()) */
1295 + uint8_t reserved1[3]; /* for future use */
1296 + uint8_t ovfl_pmd; /* overflow pmd for this sample */
1297 + u64 last_reset_val; /* initial value of overflowed PMD */
1298 + unsigned long ip; /* where did the overflow interrupt happened */
1299 + u64 tstamp; /* overflow timetamp */
1300 + u16 cpu; /* cpu on which the overfow occured */
1301 + u16 set; /* event set active when overflow ocurred */
1302 + pid_t tgid; /* thread group id (for NPTL, this is getpid()) */
1305 -#define PFM_DEFAULT_MAX_PMDS 64 /* how many pmds supported by data structures (sizeof(unsigned long) */
1306 -#define PFM_DEFAULT_MAX_ENTRY_SIZE (sizeof(pfm_default_smpl_entry_t)+(sizeof(unsigned long)*PFM_DEFAULT_MAX_PMDS))
1307 -#define PFM_DEFAULT_SMPL_MIN_BUF_SIZE (sizeof(pfm_default_smpl_hdr_t)+PFM_DEFAULT_MAX_ENTRY_SIZE)
1308 +#define PFM_DEFAULT_MAX_PMDS 64 /* #pmds supported */
1309 +#define PFM_DEFAULT_MAX_ENTRY_SIZE (sizeof(struct pfm_default_smpl_entry)+\
1310 + (sizeof(u64)*PFM_DEFAULT_MAX_PMDS))
1311 +#define PFM_DEFAULT_SMPL_MIN_BUF_SIZE (sizeof(struct pfm_default_smpl_hdr)+\
1312 + PFM_DEFAULT_MAX_ENTRY_SIZE)
1314 #define PFM_DEFAULT_SMPL_VERSION_MAJ 2U
1315 -#define PFM_DEFAULT_SMPL_VERSION_MIN 0U
1316 -#define PFM_DEFAULT_SMPL_VERSION (((PFM_DEFAULT_SMPL_VERSION_MAJ&0xffff)<<16)|(PFM_DEFAULT_SMPL_VERSION_MIN & 0xffff))
1317 +#define PFM_DEFAULT_SMPL_VERSION_MIN 1U
1318 +#define PFM_DEFAULT_SMPL_VERSION (((PFM_DEFAULT_SMPL_VERSION_MAJ&0xffff)<<16)|\
1319 + (PFM_DEFAULT_SMPL_VERSION_MIN & 0xffff))
1321 -#endif /* __PERFMON_DEFAULT_SMPL_H__ */
1322 +#endif /* __ASM_IA64_PERFMON_DEFAULT_SMPL_H__ */
1323 diff --git a/arch/ia64/include/asm/perfmon_kern.h b/arch/ia64/include/asm/perfmon_kern.h
1324 new file mode 100644
1325 index 0000000..fb40459
1327 +++ b/arch/ia64/include/asm/perfmon_kern.h
1330 + * Copyright (c) 2001-2007 Hewlett-Packard Development Company, L.P.
1331 + * Contributed by Stephane Eranian <eranian@hpl.hp.com>
1333 + * This file contains Itanium Processor Family specific definitions
1334 + * for the perfmon interface.
1336 + * This program is free software; you can redistribute it and/or
1337 + * modify it under the terms of version 2 of the GNU General Public
1338 + * License as published by the Free Software Foundation.
1340 + * This program is distributed in the hope that it will be useful,
1341 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1342 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1343 + * General Public License for more details.
1345 + * You should have received a copy of the GNU General Public License
1346 + * along with this program; if not, write to the Free Software
1347 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1350 +#ifndef _ASM_IA64_PERFMON_KERN_H_
1351 +#define _ASM_IA64_PERFMON_KERN_H_
1355 +#ifdef CONFIG_PERFMON
1356 +#include <asm/unistd.h>
1357 +#include <asm/hw_irq.h>
1360 + * describe the content of the pfm_syst_info field
1362 + * bits[00-15] : generic flags
1363 + * bits[16-31] : arch-specific flags
1365 +#define PFM_ITA_CPUINFO_IDLE_EXCL 0x10000 /* stop monitoring in idle loop */
1368 + * For some CPUs, the upper bits of a counter must be set in order for the
1369 + * overflow interrupt to happen. On overflow, the counter has wrapped around,
1370 + * and the upper bits are cleared. This function may be used to set them back.
1372 +static inline void pfm_arch_ovfl_reset_pmd(struct pfm_context *ctx,
1373 + unsigned int cnum)
1377 + * called from __pfm_interrupt_handler(). ctx is not NULL.
1378 + * ctx is locked. PMU interrupt is masked.
1380 + * must stop all monitoring to ensure handler has consistent view.
1381 + * must collect overflowed PMDs bitmask into povfls_pmds and
1382 + * npend_ovfls. If no interrupt detected then npend_ovfls
1383 + * must be set to zero.
1385 +static inline void pfm_arch_intr_freeze_pmu(struct pfm_context *ctx,
1386 + struct pfm_event_set *set)
1391 + * do not overwrite existing value, must
1392 + * process those first (coming from context switch replay)
1394 + if (set->npend_ovfls)
1399 + tmp = ia64_get_pmc(0) & ~0xf;
1401 + set->povfl_pmds[0] = tmp;
1403 + set->npend_ovfls = ia64_popcnt(tmp);
1406 +static inline int pfm_arch_init_pmu_config(void)
1411 +static inline void pfm_arch_resend_irq(struct pfm_context *ctx)
1413 + ia64_resend_irq(IA64_PERFMON_VECTOR);
1416 +static inline void pfm_arch_clear_pmd_ovfl_cond(struct pfm_context *ctx,
1417 + struct pfm_event_set *set)
1420 +static inline void pfm_arch_serialize(void)
1425 +static inline void pfm_arch_intr_unfreeze_pmu(struct pfm_context *ctx)
1427 + PFM_DBG_ovfl("state=%d", ctx->state);
1428 + ia64_set_pmc(0, 0);
1429 + /* no serialization */
1432 +static inline void pfm_arch_write_pmc(struct pfm_context *ctx,
1433 + unsigned int cnum, u64 value)
1436 + ia64_set_pmc(pfm_pmu_conf->pmc_desc[cnum].hw_addr, value);
1437 + } else if (cnum < 264) {
1438 + ia64_set_ibr(cnum-256, value);
1439 + ia64_dv_serialize_instruction();
1441 + ia64_set_dbr(cnum-264, value);
1442 + ia64_dv_serialize_instruction();
1447 + * On IA-64, for per-thread context which have the ITA_FL_INSECURE
1448 + * flag, it is possible to start/stop monitoring directly from user evel
1449 + * without calling pfm_start()/pfm_stop. This allows very lightweight
1450 + * control yet the kernel sometimes needs to know if monitoring is actually
1453 + * Tracking of this information is normally done by pfm_start/pfm_stop
1454 + * in flags.started. Here we need to compensate by checking actual
1457 +static inline int pfm_arch_is_active(struct pfm_context *ctx)
1459 + return ctx->flags.started
1460 + || ia64_getreg(_IA64_REG_PSR) & (IA64_PSR_UP|IA64_PSR_PP);
1463 +static inline void pfm_arch_write_pmd(struct pfm_context *ctx,
1464 + unsigned int cnum, u64 value)
1467 + * for a counting PMD, overflow bit must be cleared
1469 + if (pfm_pmu_conf->pmd_desc[cnum].type & PFM_REG_C64)
1470 + value &= pfm_pmu_conf->ovfl_mask;
1473 + * for counters, write to upper bits are ignored, no need to mask
1475 + ia64_set_pmd(pfm_pmu_conf->pmd_desc[cnum].hw_addr, value);
1478 +static inline u64 pfm_arch_read_pmd(struct pfm_context *ctx, unsigned int cnum)
1480 + return ia64_get_pmd(pfm_pmu_conf->pmd_desc[cnum].hw_addr);
1483 +static inline u64 pfm_arch_read_pmc(struct pfm_context *ctx, unsigned int cnum)
1485 + return ia64_get_pmc(pfm_pmu_conf->pmc_desc[cnum].hw_addr);
1488 +static inline void pfm_arch_ctxswout_sys(struct task_struct *task,
1489 + struct pfm_context *ctx)
1491 + struct pt_regs *regs;
1493 + regs = task_pt_regs(task);
1494 + ia64_psr(regs)->pp = 0;
1497 +static inline void pfm_arch_ctxswin_sys(struct task_struct *task,
1498 + struct pfm_context *ctx)
1500 + struct pt_regs *regs;
1502 + if (!(ctx->active_set->flags & PFM_ITA_SETFL_INTR_ONLY)) {
1503 + regs = task_pt_regs(task);
1504 + ia64_psr(regs)->pp = 1;
1509 + * On IA-64, the PMDs are NOT saved by pfm_arch_freeze_pmu()
1510 + * when entering the PMU interrupt handler, thus, we need
1511 + * to save them in pfm_switch_sets_from_intr()
1513 +static inline void pfm_arch_save_pmds_from_intr(struct pfm_context *ctx,
1514 + struct pfm_event_set *set)
1516 + pfm_save_pmds(ctx, set);
1519 +int pfm_arch_context_create(struct pfm_context *ctx, u32 ctx_flags);
1521 +static inline void pfm_arch_context_free(struct pfm_context *ctx)
1524 +int pfm_arch_ctxswout_thread(struct task_struct *task, struct pfm_context *ctx);
1525 +void pfm_arch_ctxswin_thread(struct task_struct *task,
1526 + struct pfm_context *ctx);
1528 +void pfm_arch_unload_context(struct pfm_context *ctx);
1529 +int pfm_arch_load_context(struct pfm_context *ctx);
1530 +int pfm_arch_setfl_sane(struct pfm_context *ctx, u32 flags);
1532 +void pfm_arch_mask_monitoring(struct pfm_context *ctx,
1533 + struct pfm_event_set *set);
1534 +void pfm_arch_unmask_monitoring(struct pfm_context *ctx,
1535 + struct pfm_event_set *set);
1537 +void pfm_arch_restore_pmds(struct pfm_context *ctx, struct pfm_event_set *set);
1538 +void pfm_arch_restore_pmcs(struct pfm_context *ctx, struct pfm_event_set *set);
1540 +void pfm_arch_stop(struct task_struct *task, struct pfm_context *ctx);
1541 +void pfm_arch_start(struct task_struct *task, struct pfm_context *ctx);
1543 +int pfm_arch_init(void);
1544 +void pfm_arch_init_percpu(void);
1545 +char *pfm_arch_get_pmu_module_name(void);
1547 +int __pfm_use_dbregs(struct task_struct *task);
1548 +int __pfm_release_dbregs(struct task_struct *task);
1549 +int pfm_ia64_mark_dbregs_used(struct pfm_context *ctx,
1550 + struct pfm_event_set *set);
1552 +void pfm_arch_show_session(struct seq_file *m);
1554 +static inline int pfm_arch_pmu_acquire(u64 *unavail_pmcs, u64 *unavail_pmds)
1559 +static inline void pfm_arch_pmu_release(void)
1562 +/* not necessary on IA-64 */
1563 +static inline void pfm_cacheflush(void *addr, unsigned int len)
1567 + * miscellaneous architected definitions
1569 +#define PFM_ITA_FCNTR 4 /* first counting monitor (PMC/PMD) */
1572 + * private event set flags (set_priv_flags)
1574 +#define PFM_ITA_SETFL_USE_DBR 0x1000000 /* set uses debug registers */
1578 + * Itanium-specific data structures
1580 +struct pfm_ia64_context_flags {
1581 + unsigned int use_dbr:1; /* use range restrictions (debug registers) */
1582 + unsigned int insecure:1; /* insecure monitoring for non-self session */
1583 + unsigned int reserved:30;/* for future use */
1586 +struct pfm_arch_context {
1587 + struct pfm_ia64_context_flags flags; /* arch specific ctx flags */
1588 + u64 ctx_saved_psr_up;/* storage for psr_up */
1589 +#ifdef CONFIG_IA64_PERFMON_COMPAT
1590 + void *ctx_smpl_vaddr; /* vaddr of user mapping */
1594 +#ifdef CONFIG_IA64_PERFMON_COMPAT
1595 +ssize_t pfm_arch_compat_read(struct pfm_context *ctx,
1599 +int pfm_ia64_compat_init(void);
1600 +int pfm_smpl_buf_alloc_compat(struct pfm_context *ctx,
1601 + size_t rsize, struct file *filp);
1603 +static inline ssize_t pfm_arch_compat_read(struct pfm_context *ctx,
1611 +static inline int pfm_smpl_buf_alloc_compat(struct pfm_context *ctx,
1612 + size_t rsize, struct file *filp)
1618 +static inline void pfm_arch_arm_handle_work(struct task_struct *task)
1621 + * On IA-64, we ran out of bits in the bottom 7 bits of the
1622 + * threadinfo bitmask.Thus we used a 2-stage approach by piggybacking
1623 + * on NOTIFY_RESUME and then in do_notify_resume() we demultiplex and
1624 + * call pfm_handle_work() if needed
1626 + set_tsk_thread_flag(task, TIF_NOTIFY_RESUME);
1629 +static inline void pfm_arch_disarm_handle_work(struct task_struct *task)
1632 + * we cannot just clear TIF_NOTIFY_RESUME because other TIF flags are
1633 + * piggybackedonto it: TIF_PERFMON_WORK, TIF_RESTORE_RSE
1635 + * The tsk_clear_notify_resume() checks if any of those are set before
1636 + * clearing the * bit
1638 + tsk_clear_notify_resume(task);
1641 +static inline int pfm_arch_pmu_config_init(struct pfm_pmu_config *cfg)
1646 +extern struct pfm_ia64_pmu_info *pfm_ia64_pmu_info;
1648 +#define PFM_ARCH_CTX_SIZE (sizeof(struct pfm_arch_context))
1651 + * IA-64 does not need extra alignment requirements for the sampling buffer
1653 +#define PFM_ARCH_SMPL_ALIGN_SIZE 0
1656 +static inline void pfm_release_dbregs(struct task_struct *task)
1658 + if (task->thread.flags & IA64_THREAD_DBG_VALID)
1659 + __pfm_release_dbregs(task);
1662 +#define pfm_use_dbregs(_t) __pfm_use_dbregs(_t)
1664 +static inline int pfm_arch_get_base_syscall(void)
1666 + return __NR_pfm_create_context;
1669 +struct pfm_arch_pmu_info {
1670 + unsigned long mask_pmcs[PFM_PMC_BV]; /* modify on when masking */
1673 +DECLARE_PER_CPU(u32, pfm_syst_info);
1674 +#else /* !CONFIG_PERFMON */
1676 + * perfmon ia64-specific hooks
1678 +#define pfm_release_dbregs(_t) do { } while (0)
1679 +#define pfm_use_dbregs(_t) (0)
1681 +#endif /* CONFIG_PERFMON */
1683 +#endif /* __KERNEL__ */
1684 +#endif /* _ASM_IA64_PERFMON_KERN_H_ */
1685 diff --git a/arch/ia64/include/asm/processor.h b/arch/ia64/include/asm/processor.h
1686 index f88fa05..9d6af9c 100644
1687 --- a/arch/ia64/include/asm/processor.h
1688 +++ b/arch/ia64/include/asm/processor.h
1691 #define IA64_THREAD_FPH_VALID (__IA64_UL(1) << 0) /* floating-point high state valid? */
1692 #define IA64_THREAD_DBG_VALID (__IA64_UL(1) << 1) /* debug registers valid? */
1693 -#define IA64_THREAD_PM_VALID (__IA64_UL(1) << 2) /* performance registers valid? */
1694 #define IA64_THREAD_UAC_NOPRINT (__IA64_UL(1) << 3) /* don't log unaligned accesses */
1695 #define IA64_THREAD_UAC_SIGBUS (__IA64_UL(1) << 4) /* generate SIGBUS on unaligned acc. */
1696 #define IA64_THREAD_MIGRATION (__IA64_UL(1) << 5) /* require migration
1697 @@ -321,14 +320,6 @@ struct thread_struct {
1699 # define INIT_THREAD_IA32
1700 #endif /* CONFIG_IA32_SUPPORT */
1701 -#ifdef CONFIG_PERFMON
1702 - void *pfm_context; /* pointer to detailed PMU context */
1703 - unsigned long pfm_needs_checking; /* when >0, pending perfmon work on kernel exit */
1704 -# define INIT_THREAD_PM .pfm_context = NULL, \
1705 - .pfm_needs_checking = 0UL,
1707 -# define INIT_THREAD_PM
1709 __u64 dbr[IA64_NUM_DBG_REGS];
1710 __u64 ibr[IA64_NUM_DBG_REGS];
1711 struct ia64_fpreg fph[96]; /* saved/loaded on demand */
1712 @@ -343,7 +334,6 @@ struct thread_struct {
1713 .task_size = DEFAULT_TASK_SIZE, \
1714 .last_fph_cpu = -1, \
1719 .fph = {{{{0}}}, } \
1720 diff --git a/arch/ia64/include/asm/system.h b/arch/ia64/include/asm/system.h
1721 index 927a381..ab5aeea 100644
1722 --- a/arch/ia64/include/asm/system.h
1723 +++ b/arch/ia64/include/asm/system.h
1724 @@ -217,6 +217,7 @@ struct task_struct;
1725 extern void ia64_save_extra (struct task_struct *task);
1726 extern void ia64_load_extra (struct task_struct *task);
1729 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
1730 extern void ia64_account_on_switch (struct task_struct *prev, struct task_struct *next);
1731 # define IA64_ACCOUNT_ON_SWITCH(p,n) ia64_account_on_switch(p,n)
1732 @@ -224,16 +225,9 @@ extern void ia64_account_on_switch (struct task_struct *prev, struct task_struct
1733 # define IA64_ACCOUNT_ON_SWITCH(p,n)
1736 -#ifdef CONFIG_PERFMON
1737 - DECLARE_PER_CPU(unsigned long, pfm_syst_info);
1738 -# define PERFMON_IS_SYSWIDE() (__get_cpu_var(pfm_syst_info) & 0x1)
1740 -# define PERFMON_IS_SYSWIDE() (0)
1743 -#define IA64_HAS_EXTRA_STATE(t) \
1744 - ((t)->thread.flags & (IA64_THREAD_DBG_VALID|IA64_THREAD_PM_VALID) \
1745 - || IS_IA32_PROCESS(task_pt_regs(t)) || PERFMON_IS_SYSWIDE())
1746 +#define IA64_HAS_EXTRA_STATE(t) \
1747 + (((t)->thread.flags & IA64_THREAD_DBG_VALID) \
1748 + || IS_IA32_PROCESS(task_pt_regs(t)))
1750 #define __switch_to(prev,next,last) do { \
1751 IA64_ACCOUNT_ON_SWITCH(prev, next); \
1752 @@ -241,6 +235,10 @@ extern void ia64_account_on_switch (struct task_struct *prev, struct task_struct
1753 ia64_save_extra(prev); \
1754 if (IA64_HAS_EXTRA_STATE(next)) \
1755 ia64_load_extra(next); \
1756 + if (test_tsk_thread_flag(prev, TIF_PERFMON_CTXSW)) \
1757 + pfm_ctxsw_out(prev, next); \
1758 + if (test_tsk_thread_flag(next, TIF_PERFMON_CTXSW)) \
1759 + pfm_ctxsw_in(prev, next); \
1760 ia64_psr(task_pt_regs(next))->dfh = !ia64_is_local_fpu_owner(next); \
1761 (last) = ia64_switch_to((next)); \
1763 diff --git a/arch/ia64/include/asm/thread_info.h b/arch/ia64/include/asm/thread_info.h
1764 index 7c60fcd..3355332 100644
1765 --- a/arch/ia64/include/asm/thread_info.h
1766 +++ b/arch/ia64/include/asm/thread_info.h
1767 @@ -110,6 +110,8 @@ extern void tsk_clear_notify_resume(struct task_struct *tsk);
1768 #define TIF_DB_DISABLED 19 /* debug trap disabled for fsyscall */
1769 #define TIF_FREEZE 20 /* is freezing for suspend */
1770 #define TIF_RESTORE_RSE 21 /* user RBS is newer than kernel RBS */
1771 +#define TIF_PERFMON_CTXSW 22 /* perfmon needs ctxsw calls */
1772 +#define TIF_PERFMON_WORK 23 /* work for pfm_handle_work() */
1774 #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
1775 #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
1776 @@ -123,6 +125,8 @@ extern void tsk_clear_notify_resume(struct task_struct *tsk);
1777 #define _TIF_DB_DISABLED (1 << TIF_DB_DISABLED)
1778 #define _TIF_FREEZE (1 << TIF_FREEZE)
1779 #define _TIF_RESTORE_RSE (1 << TIF_RESTORE_RSE)
1780 +#define _TIF_PERFMON_CTXSW (1 << TIF_PERFMON_CTXSW)
1781 +#define _TIF_PERFMON_WORK (1 << TIF_PERFMON_WORK)
1783 /* "work to do on user-return" bits */
1784 #define TIF_ALLWORK_MASK (_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SYSCALL_AUDIT|\
1785 diff --git a/arch/ia64/include/asm/unistd.h b/arch/ia64/include/asm/unistd.h
1786 index d535833..29a43bc 100644
1787 --- a/arch/ia64/include/asm/unistd.h
1788 +++ b/arch/ia64/include/asm/unistd.h
1789 @@ -308,11 +308,23 @@
1790 #define __NR_dup3 1316
1791 #define __NR_pipe2 1317
1792 #define __NR_inotify_init1 1318
1793 +#define __NR_pfm_create_context 1319
1794 +#define __NR_pfm_write_pmcs (__NR_pfm_create_context+1)
1795 +#define __NR_pfm_write_pmds (__NR_pfm_create_context+2)
1796 +#define __NR_pfm_read_pmds (__NR_pfm_create_context+3)
1797 +#define __NR_pfm_load_context (__NR_pfm_create_context+4)
1798 +#define __NR_pfm_start (__NR_pfm_create_context+5)
1799 +#define __NR_pfm_stop (__NR_pfm_create_context+6)
1800 +#define __NR_pfm_restart (__NR_pfm_create_context+7)
1801 +#define __NR_pfm_create_evtsets (__NR_pfm_create_context+8)
1802 +#define __NR_pfm_getinfo_evtsets (__NR_pfm_create_context+9)
1803 +#define __NR_pfm_delete_evtsets (__NR_pfm_create_context+10)
1804 +#define __NR_pfm_unload_context (__NR_pfm_create_context+11)
1809 -#define NR_syscalls 295 /* length of syscall table */
1810 +#define NR_syscalls 307 /* length of syscall table */
1813 * The following defines stop scripts/checksyscalls.sh from complaining about
1814 diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
1815 index 87fea11..b5ac54c 100644
1816 --- a/arch/ia64/kernel/Makefile
1817 +++ b/arch/ia64/kernel/Makefile
1819 extra-y := head.o init_task.o vmlinux.lds
1821 obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o \
1822 - irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o \
1823 + irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o ptrace.o sal.o \
1824 salinfo.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \
1825 unwind.o mca.o mca_asm.o topology.o
1827 @@ -23,7 +23,6 @@ obj-$(CONFIG_IOSAPIC) += iosapic.o
1828 obj-$(CONFIG_MODULES) += module.o
1829 obj-$(CONFIG_SMP) += smp.o smpboot.o
1830 obj-$(CONFIG_NUMA) += numa.o
1831 -obj-$(CONFIG_PERFMON) += perfmon_default_smpl.o
1832 obj-$(CONFIG_IA64_CYCLONE) += cyclone.o
1833 obj-$(CONFIG_CPU_FREQ) += cpufreq/
1834 obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o
1835 diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
1836 index 0dd6c14..f1c3e41 100644
1837 --- a/arch/ia64/kernel/entry.S
1838 +++ b/arch/ia64/kernel/entry.S
1839 @@ -1697,6 +1697,18 @@ sys_call_table:
1842 data8 sys_inotify_init1
1843 + data8 sys_pfm_create_context
1844 + data8 sys_pfm_write_pmcs // 1320
1845 + data8 sys_pfm_write_pmds
1846 + data8 sys_pfm_read_pmds
1847 + data8 sys_pfm_load_context
1848 + data8 sys_pfm_start
1849 + data8 sys_pfm_stop // 1325
1850 + data8 sys_pfm_restart
1851 + data8 sys_pfm_create_evtsets
1852 + data8 sys_pfm_getinfo_evtsets
1853 + data8 sys_pfm_delete_evtsets
1854 + data8 sys_pfm_unload_context // 1330
1856 .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls
1857 #endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
1858 diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
1859 index 28d3d48..ede8024 100644
1860 --- a/arch/ia64/kernel/irq_ia64.c
1861 +++ b/arch/ia64/kernel/irq_ia64.c
1863 #include <asm/system.h>
1864 #include <asm/tlbflush.h>
1866 -#ifdef CONFIG_PERFMON
1867 -# include <asm/perfmon.h>
1872 #define IRQ_VECTOR_UNASSIGNED (0)
1873 @@ -660,9 +656,6 @@ init_IRQ (void)
1877 -#ifdef CONFIG_PERFMON
1878 - pfm_init_percpu();
1880 platform_irq_init();
1883 diff --git a/arch/ia64/kernel/perfmon_default_smpl.c b/arch/ia64/kernel/perfmon_default_smpl.c
1884 deleted file mode 100644
1885 index 5f637bb..0000000
1886 --- a/arch/ia64/kernel/perfmon_default_smpl.c
1890 - * Copyright (C) 2002-2003 Hewlett-Packard Co
1891 - * Stephane Eranian <eranian@hpl.hp.com>
1893 - * This file implements the default sampling buffer format
1894 - * for the Linux/ia64 perfmon-2 subsystem.
1896 -#include <linux/kernel.h>
1897 -#include <linux/types.h>
1898 -#include <linux/module.h>
1899 -#include <linux/init.h>
1900 -#include <asm/delay.h>
1901 -#include <linux/smp.h>
1903 -#include <asm/perfmon.h>
1904 -#include <asm/perfmon_default_smpl.h>
1906 -MODULE_AUTHOR("Stephane Eranian <eranian@hpl.hp.com>");
1907 -MODULE_DESCRIPTION("perfmon default sampling format");
1908 -MODULE_LICENSE("GPL");
1910 -#define DEFAULT_DEBUG 1
1912 -#ifdef DEFAULT_DEBUG
1913 -#define DPRINT(a) \
1915 - if (unlikely(pfm_sysctl.debug >0)) { printk("%s.%d: CPU%d ", __func__, __LINE__, smp_processor_id()); printk a; } \
1918 -#define DPRINT_ovfl(a) \
1920 - if (unlikely(pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0)) { printk("%s.%d: CPU%d ", __func__, __LINE__, smp_processor_id()); printk a; } \
1925 -#define DPRINT_ovfl(a)
1929 -default_validate(struct task_struct *task, unsigned int flags, int cpu, void *data)
1931 - pfm_default_smpl_arg_t *arg = (pfm_default_smpl_arg_t*)data;
1934 - if (data == NULL) {
1935 - DPRINT(("[%d] no argument passed\n", task_pid_nr(task)));
1939 - DPRINT(("[%d] validate flags=0x%x CPU%d\n", task_pid_nr(task), flags, cpu));
1942 - * must hold at least the buffer header + one minimally sized entry
1944 - if (arg->buf_size < PFM_DEFAULT_SMPL_MIN_BUF_SIZE) return -EINVAL;
1946 - DPRINT(("buf_size=%lu\n", arg->buf_size));
1952 -default_get_size(struct task_struct *task, unsigned int flags, int cpu, void *data, unsigned long *size)
1954 - pfm_default_smpl_arg_t *arg = (pfm_default_smpl_arg_t *)data;
1957 - * size has been validated in default_validate
1959 - *size = arg->buf_size;
1965 -default_init(struct task_struct *task, void *buf, unsigned int flags, int cpu, void *data)
1967 - pfm_default_smpl_hdr_t *hdr;
1968 - pfm_default_smpl_arg_t *arg = (pfm_default_smpl_arg_t *)data;
1970 - hdr = (pfm_default_smpl_hdr_t *)buf;
1972 - hdr->hdr_version = PFM_DEFAULT_SMPL_VERSION;
1973 - hdr->hdr_buf_size = arg->buf_size;
1974 - hdr->hdr_cur_offs = sizeof(*hdr);
1975 - hdr->hdr_overflows = 0UL;
1976 - hdr->hdr_count = 0UL;
1978 - DPRINT(("[%d] buffer=%p buf_size=%lu hdr_size=%lu hdr_version=%u cur_offs=%lu\n",
1979 - task_pid_nr(task),
1981 - hdr->hdr_buf_size,
1984 - hdr->hdr_cur_offs));
1990 -default_handler(struct task_struct *task, void *buf, pfm_ovfl_arg_t *arg, struct pt_regs *regs, unsigned long stamp)
1992 - pfm_default_smpl_hdr_t *hdr;
1993 - pfm_default_smpl_entry_t *ent;
1995 - unsigned long *e, entry_size;
1996 - unsigned int npmds, i;
1997 - unsigned char ovfl_pmd;
1998 - unsigned char ovfl_notify;
2000 - if (unlikely(buf == NULL || arg == NULL|| regs == NULL || task == NULL)) {
2001 - DPRINT(("[%d] invalid arguments buf=%p arg=%p\n", task->pid, buf, arg));
2005 - hdr = (pfm_default_smpl_hdr_t *)buf;
2006 - cur = buf+hdr->hdr_cur_offs;
2007 - last = buf+hdr->hdr_buf_size;
2008 - ovfl_pmd = arg->ovfl_pmd;
2009 - ovfl_notify = arg->ovfl_notify;
2012 - * precheck for sanity
2014 - if ((last - cur) < PFM_DEFAULT_MAX_ENTRY_SIZE) goto full;
2016 - npmds = hweight64(arg->smpl_pmds[0]);
2018 - ent = (pfm_default_smpl_entry_t *)cur;
2020 - prefetch(arg->smpl_pmds_values);
2022 - entry_size = sizeof(*ent) + (npmds << 3);
2024 - /* position for first pmd */
2025 - e = (unsigned long *)(ent+1);
2029 - DPRINT_ovfl(("[%d] count=%lu cur=%p last=%p free_bytes=%lu ovfl_pmd=%d ovfl_notify=%d npmds=%u\n",
2035 - ovfl_notify, npmds));
2038 - * current = task running at the time of the overflow.
2041 - * - this is ususally the task being monitored.
2042 - * Under certain conditions, it might be a different task
2045 - * - this is not necessarily the task controlling the session
2047 - ent->pid = current->pid;
2048 - ent->ovfl_pmd = ovfl_pmd;
2049 - ent->last_reset_val = arg->pmd_last_reset; //pmd[0].reg_last_reset_val;
2052 - * where did the fault happen (includes slot number)
2054 - ent->ip = regs->cr_iip | ((regs->cr_ipsr >> 41) & 0x3);
2056 - ent->tstamp = stamp;
2057 - ent->cpu = smp_processor_id();
2058 - ent->set = arg->active_set;
2059 - ent->tgid = current->tgid;
2062 - * selectively store PMDs in increasing index number
2065 - unsigned long *val = arg->smpl_pmds_values;
2066 - for(i=0; i < npmds; i++) {
2072 - * update position for next entry
2074 - hdr->hdr_cur_offs += entry_size;
2075 - cur += entry_size;
2078 - * post check to avoid losing the last sample
2080 - if ((last - cur) < PFM_DEFAULT_MAX_ENTRY_SIZE) goto full;
2083 - * keep same ovfl_pmds, ovfl_notify
2085 - arg->ovfl_ctrl.bits.notify_user = 0;
2086 - arg->ovfl_ctrl.bits.block_task = 0;
2087 - arg->ovfl_ctrl.bits.mask_monitoring = 0;
2088 - arg->ovfl_ctrl.bits.reset_ovfl_pmds = 1; /* reset before returning from interrupt handler */
2092 - DPRINT_ovfl(("sampling buffer full free=%lu, count=%lu, ovfl_notify=%d\n", last-cur, hdr->hdr_count, ovfl_notify));
2095 - * increment number of buffer overflow.
2096 - * important to detect duplicate set of samples.
2098 - hdr->hdr_overflows++;
2101 - * if no notification requested, then we saturate the buffer
2103 - if (ovfl_notify == 0) {
2104 - arg->ovfl_ctrl.bits.notify_user = 0;
2105 - arg->ovfl_ctrl.bits.block_task = 0;
2106 - arg->ovfl_ctrl.bits.mask_monitoring = 1;
2107 - arg->ovfl_ctrl.bits.reset_ovfl_pmds = 0;
2109 - arg->ovfl_ctrl.bits.notify_user = 1;
2110 - arg->ovfl_ctrl.bits.block_task = 1; /* ignored for non-blocking context */
2111 - arg->ovfl_ctrl.bits.mask_monitoring = 1;
2112 - arg->ovfl_ctrl.bits.reset_ovfl_pmds = 0; /* no reset now */
2114 - return -1; /* we are full, sorry */
2118 -default_restart(struct task_struct *task, pfm_ovfl_ctrl_t *ctrl, void *buf, struct pt_regs *regs)
2120 - pfm_default_smpl_hdr_t *hdr;
2122 - hdr = (pfm_default_smpl_hdr_t *)buf;
2124 - hdr->hdr_count = 0UL;
2125 - hdr->hdr_cur_offs = sizeof(*hdr);
2127 - ctrl->bits.mask_monitoring = 0;
2128 - ctrl->bits.reset_ovfl_pmds = 1; /* uses long-reset values */
2134 -default_exit(struct task_struct *task, void *buf, struct pt_regs *regs)
2136 - DPRINT(("[%d] exit(%p)\n", task_pid_nr(task), buf));
2140 -static pfm_buffer_fmt_t default_fmt={
2141 - .fmt_name = "default_format",
2142 - .fmt_uuid = PFM_DEFAULT_SMPL_UUID,
2143 - .fmt_arg_size = sizeof(pfm_default_smpl_arg_t),
2144 - .fmt_validate = default_validate,
2145 - .fmt_getsize = default_get_size,
2146 - .fmt_init = default_init,
2147 - .fmt_handler = default_handler,
2148 - .fmt_restart = default_restart,
2149 - .fmt_restart_active = default_restart,
2150 - .fmt_exit = default_exit,
2154 -pfm_default_smpl_init_module(void)
2158 - ret = pfm_register_buffer_fmt(&default_fmt);
2160 - printk("perfmon_default_smpl: %s v%u.%u registered\n",
2161 - default_fmt.fmt_name,
2162 - PFM_DEFAULT_SMPL_VERSION_MAJ,
2163 - PFM_DEFAULT_SMPL_VERSION_MIN);
2165 - printk("perfmon_default_smpl: %s cannot register ret=%d\n",
2166 - default_fmt.fmt_name,
2174 -pfm_default_smpl_cleanup_module(void)
2177 - ret = pfm_unregister_buffer_fmt(default_fmt.fmt_uuid);
2179 - printk("perfmon_default_smpl: unregister %s=%d\n", default_fmt.fmt_name, ret);
2182 -module_init(pfm_default_smpl_init_module);
2183 -module_exit(pfm_default_smpl_cleanup_module);
2185 diff --git a/arch/ia64/kernel/perfmon_generic.h b/arch/ia64/kernel/perfmon_generic.h
2186 deleted file mode 100644
2187 index 6748947..0000000
2188 --- a/arch/ia64/kernel/perfmon_generic.h
2192 - * This file contains the generic PMU register description tables
2193 - * and pmc checker used by perfmon.c.
2195 - * Copyright (C) 2002-2003 Hewlett Packard Co
2196 - * Stephane Eranian <eranian@hpl.hp.com>
2199 -static pfm_reg_desc_t pfm_gen_pmc_desc[PMU_MAX_PMCS]={
2200 -/* pmc0 */ { PFM_REG_CONTROL , 0, 0x1UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2201 -/* pmc1 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2202 -/* pmc2 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2203 -/* pmc3 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2204 -/* pmc4 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(4),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2205 -/* pmc5 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(5),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2206 -/* pmc6 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(6),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2207 -/* pmc7 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(7),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2208 - { PFM_REG_END , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
2211 -static pfm_reg_desc_t pfm_gen_pmd_desc[PMU_MAX_PMDS]={
2212 -/* pmd0 */ { PFM_REG_NOTIMPL , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}},
2213 -/* pmd1 */ { PFM_REG_NOTIMPL , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}},
2214 -/* pmd2 */ { PFM_REG_NOTIMPL , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}},
2215 -/* pmd3 */ { PFM_REG_NOTIMPL , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}},
2216 -/* pmd4 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(4),0UL, 0UL, 0UL}},
2217 -/* pmd5 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(5),0UL, 0UL, 0UL}},
2218 -/* pmd6 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(6),0UL, 0UL, 0UL}},
2219 -/* pmd7 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(7),0UL, 0UL, 0UL}},
2220 - { PFM_REG_END , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
2224 - * impl_pmcs, impl_pmds are computed at runtime to minimize errors!
2226 -static pmu_config_t pmu_conf_gen={
2227 - .pmu_name = "Generic",
2228 - .pmu_family = 0xff, /* any */
2229 - .ovfl_val = (1UL << 32) - 1,
2230 - .num_ibrs = 0, /* does not use */
2231 - .num_dbrs = 0, /* does not use */
2232 - .pmd_desc = pfm_gen_pmd_desc,
2233 - .pmc_desc = pfm_gen_pmc_desc
2236 diff --git a/arch/ia64/kernel/perfmon_itanium.h b/arch/ia64/kernel/perfmon_itanium.h
2237 deleted file mode 100644
2238 index d1d508a..0000000
2239 --- a/arch/ia64/kernel/perfmon_itanium.h
2243 - * This file contains the Itanium PMU register description tables
2244 - * and pmc checker used by perfmon.c.
2246 - * Copyright (C) 2002-2003 Hewlett Packard Co
2247 - * Stephane Eranian <eranian@hpl.hp.com>
2249 -static int pfm_ita_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
2251 -static pfm_reg_desc_t pfm_ita_pmc_desc[PMU_MAX_PMCS]={
2252 -/* pmc0 */ { PFM_REG_CONTROL , 0, 0x1UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2253 -/* pmc1 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2254 -/* pmc2 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2255 -/* pmc3 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2256 -/* pmc4 */ { PFM_REG_COUNTING, 6, 0x0UL, -1UL, NULL, NULL, {RDEP(4),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2257 -/* pmc5 */ { PFM_REG_COUNTING, 6, 0x0UL, -1UL, NULL, NULL, {RDEP(5),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2258 -/* pmc6 */ { PFM_REG_COUNTING, 6, 0x0UL, -1UL, NULL, NULL, {RDEP(6),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2259 -/* pmc7 */ { PFM_REG_COUNTING, 6, 0x0UL, -1UL, NULL, NULL, {RDEP(7),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2260 -/* pmc8 */ { PFM_REG_CONFIG , 0, 0xf00000003ffffff8UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2261 -/* pmc9 */ { PFM_REG_CONFIG , 0, 0xf00000003ffffff8UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2262 -/* pmc10 */ { PFM_REG_MONITOR , 6, 0x0UL, -1UL, NULL, NULL, {RDEP(0)|RDEP(1),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2263 -/* pmc11 */ { PFM_REG_MONITOR , 6, 0x0000000010000000UL, -1UL, NULL, pfm_ita_pmc_check, {RDEP(2)|RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2264 -/* pmc12 */ { PFM_REG_MONITOR , 6, 0x0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2265 -/* pmc13 */ { PFM_REG_CONFIG , 0, 0x0003ffff00000001UL, -1UL, NULL, pfm_ita_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2266 - { PFM_REG_END , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
2269 -static pfm_reg_desc_t pfm_ita_pmd_desc[PMU_MAX_PMDS]={
2270 -/* pmd0 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(1),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
2271 -/* pmd1 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(0),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
2272 -/* pmd2 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
2273 -/* pmd3 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(2)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
2274 -/* pmd4 */ { PFM_REG_COUNTING, 0, 0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(4),0UL, 0UL, 0UL}},
2275 -/* pmd5 */ { PFM_REG_COUNTING, 0, 0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(5),0UL, 0UL, 0UL}},
2276 -/* pmd6 */ { PFM_REG_COUNTING, 0, 0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(6),0UL, 0UL, 0UL}},
2277 -/* pmd7 */ { PFM_REG_COUNTING, 0, 0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(7),0UL, 0UL, 0UL}},
2278 -/* pmd8 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
2279 -/* pmd9 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
2280 -/* pmd10 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
2281 -/* pmd11 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
2282 -/* pmd12 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
2283 -/* pmd13 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
2284 -/* pmd14 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
2285 -/* pmd15 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
2286 -/* pmd16 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
2287 -/* pmd17 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(2)|RDEP(3),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
2288 - { PFM_REG_END , 0, 0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
2292 -pfm_ita_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs)
2297 - /* sanitfy check */
2298 - if (ctx == NULL) return -EINVAL;
2300 - is_loaded = ctx->ctx_state == PFM_CTX_LOADED || ctx->ctx_state == PFM_CTX_MASKED;
2303 - * we must clear the (instruction) debug registers if pmc13.ta bit is cleared
2304 - * before they are written (fl_using_dbreg==0) to avoid picking up stale information.
2306 - if (cnum == 13 && is_loaded && ((*val & 0x1) == 0UL) && ctx->ctx_fl_using_dbreg == 0) {
2308 - DPRINT(("pmc[%d]=0x%lx has active pmc13.ta cleared, clearing ibr\n", cnum, *val));
2310 - /* don't mix debug with perfmon */
2311 - if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
2314 - * a count of 0 will mark the debug registers as in use and also
2315 - * ensure that they are properly cleared.
2317 - ret = pfm_write_ibr_dbr(1, ctx, NULL, 0, regs);
2318 - if (ret) return ret;
2322 - * we must clear the (data) debug registers if pmc11.pt bit is cleared
2323 - * before they are written (fl_using_dbreg==0) to avoid picking up stale information.
2325 - if (cnum == 11 && is_loaded && ((*val >> 28)& 0x1) == 0 && ctx->ctx_fl_using_dbreg == 0) {
2327 - DPRINT(("pmc[%d]=0x%lx has active pmc11.pt cleared, clearing dbr\n", cnum, *val));
2329 - /* don't mix debug with perfmon */
2330 - if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
2333 - * a count of 0 will mark the debug registers as in use and also
2334 - * ensure that they are properly cleared.
2336 - ret = pfm_write_ibr_dbr(0, ctx, NULL, 0, regs);
2337 - if (ret) return ret;
2343 - * impl_pmcs, impl_pmds are computed at runtime to minimize errors!
2345 -static pmu_config_t pmu_conf_ita={
2346 - .pmu_name = "Itanium",
2347 - .pmu_family = 0x7,
2348 - .ovfl_val = (1UL << 32) - 1,
2349 - .pmd_desc = pfm_ita_pmd_desc,
2350 - .pmc_desc = pfm_ita_pmc_desc,
2353 - .use_rr_dbregs = 1, /* debug register are use for range retrictions */
2357 diff --git a/arch/ia64/kernel/perfmon_mckinley.h b/arch/ia64/kernel/perfmon_mckinley.h
2358 deleted file mode 100644
2359 index c4bec7a..0000000
2360 --- a/arch/ia64/kernel/perfmon_mckinley.h
2364 - * This file contains the McKinley PMU register description tables
2365 - * and pmc checker used by perfmon.c.
2367 - * Copyright (C) 2002-2003 Hewlett Packard Co
2368 - * Stephane Eranian <eranian@hpl.hp.com>
2370 -static int pfm_mck_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
2372 -static pfm_reg_desc_t pfm_mck_pmc_desc[PMU_MAX_PMCS]={
2373 -/* pmc0 */ { PFM_REG_CONTROL , 0, 0x1UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2374 -/* pmc1 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2375 -/* pmc2 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2376 -/* pmc3 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2377 -/* pmc4 */ { PFM_REG_COUNTING, 6, 0x0000000000800000UL, 0xfffff7fUL, NULL, pfm_mck_pmc_check, {RDEP(4),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2378 -/* pmc5 */ { PFM_REG_COUNTING, 6, 0x0UL, 0xfffff7fUL, NULL, pfm_mck_pmc_check, {RDEP(5),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2379 -/* pmc6 */ { PFM_REG_COUNTING, 6, 0x0UL, 0xfffff7fUL, NULL, pfm_mck_pmc_check, {RDEP(6),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2380 -/* pmc7 */ { PFM_REG_COUNTING, 6, 0x0UL, 0xfffff7fUL, NULL, pfm_mck_pmc_check, {RDEP(7),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2381 -/* pmc8 */ { PFM_REG_CONFIG , 0, 0xffffffff3fffffffUL, 0xffffffff3ffffffbUL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2382 -/* pmc9 */ { PFM_REG_CONFIG , 0, 0xffffffff3ffffffcUL, 0xffffffff3ffffffbUL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2383 -/* pmc10 */ { PFM_REG_MONITOR , 4, 0x0UL, 0xffffUL, NULL, pfm_mck_pmc_check, {RDEP(0)|RDEP(1),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2384 -/* pmc11 */ { PFM_REG_MONITOR , 6, 0x0UL, 0x30f01cf, NULL, pfm_mck_pmc_check, {RDEP(2)|RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2385 -/* pmc12 */ { PFM_REG_MONITOR , 6, 0x0UL, 0xffffUL, NULL, pfm_mck_pmc_check, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2386 -/* pmc13 */ { PFM_REG_CONFIG , 0, 0x00002078fefefefeUL, 0x1e00018181818UL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2387 -/* pmc14 */ { PFM_REG_CONFIG , 0, 0x0db60db60db60db6UL, 0x2492UL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2388 -/* pmc15 */ { PFM_REG_CONFIG , 0, 0x00000000fffffff0UL, 0xfUL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
2389 - { PFM_REG_END , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
2392 -static pfm_reg_desc_t pfm_mck_pmd_desc[PMU_MAX_PMDS]={
2393 -/* pmd0 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(1),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
2394 -/* pmd1 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(0),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
2395 -/* pmd2 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
2396 -/* pmd3 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(2)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
2397 -/* pmd4 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(4),0UL, 0UL, 0UL}},
2398 -/* pmd5 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(5),0UL, 0UL, 0UL}},
2399 -/* pmd6 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(6),0UL, 0UL, 0UL}},
2400 -/* pmd7 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(7),0UL, 0UL, 0UL}},
2401 -/* pmd8 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
2402 -/* pmd9 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
2403 -/* pmd10 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
2404 -/* pmd11 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
2405 -/* pmd12 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
2406 -/* pmd13 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
2407 -/* pmd14 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
2408 -/* pmd15 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
2409 -/* pmd16 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
2410 -/* pmd17 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(2)|RDEP(3),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
2411 - { PFM_REG_END , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
2415 - * PMC reserved fields must have their power-up values preserved
2418 -pfm_mck_reserved(unsigned int cnum, unsigned long *val, struct pt_regs *regs)
2420 - unsigned long tmp1, tmp2, ival = *val;
2422 - /* remove reserved areas from user value */
2423 - tmp1 = ival & PMC_RSVD_MASK(cnum);
2425 - /* get reserved fields values */
2426 - tmp2 = PMC_DFL_VAL(cnum) & ~PMC_RSVD_MASK(cnum);
2428 - *val = tmp1 | tmp2;
2430 - DPRINT(("pmc[%d]=0x%lx, mask=0x%lx, reset=0x%lx, val=0x%lx\n",
2431 - cnum, ival, PMC_RSVD_MASK(cnum), PMC_DFL_VAL(cnum), *val));
2436 - * task can be NULL if the context is unloaded
2439 -pfm_mck_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs)
2441 - int ret = 0, check_case1 = 0;
2442 - unsigned long val8 = 0, val14 = 0, val13 = 0;
2445 - /* first preserve the reserved fields */
2446 - pfm_mck_reserved(cnum, val, regs);
2448 - /* sanitfy check */
2449 - if (ctx == NULL) return -EINVAL;
2451 - is_loaded = ctx->ctx_state == PFM_CTX_LOADED || ctx->ctx_state == PFM_CTX_MASKED;
2454 - * we must clear the debug registers if pmc13 has a value which enable
2455 - * memory pipeline event constraints. In this case we need to clear the
2456 - * the debug registers if they have not yet been accessed. This is required
2457 - * to avoid picking stale state.
2458 - * PMC13 is "active" if:
2459 - * one of the pmc13.cfg_dbrpXX field is different from 0x3
2461 - * at the corresponding pmc13.ena_dbrpXX is set.
2463 - DPRINT(("cnum=%u val=0x%lx, using_dbreg=%d loaded=%d\n", cnum, *val, ctx->ctx_fl_using_dbreg, is_loaded));
2465 - if (cnum == 13 && is_loaded
2466 - && (*val & 0x1e00000000000UL) && (*val & 0x18181818UL) != 0x18181818UL && ctx->ctx_fl_using_dbreg == 0) {
2468 - DPRINT(("pmc[%d]=0x%lx has active pmc13 settings, clearing dbr\n", cnum, *val));
2470 - /* don't mix debug with perfmon */
2471 - if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
2474 - * a count of 0 will mark the debug registers as in use and also
2475 - * ensure that they are properly cleared.
2477 - ret = pfm_write_ibr_dbr(PFM_DATA_RR, ctx, NULL, 0, regs);
2478 - if (ret) return ret;
2481 - * we must clear the (instruction) debug registers if any pmc14.ibrpX bit is enabled
2482 - * before they are (fl_using_dbreg==0) to avoid picking up stale information.
2484 - if (cnum == 14 && is_loaded && ((*val & 0x2222UL) != 0x2222UL) && ctx->ctx_fl_using_dbreg == 0) {
2486 - DPRINT(("pmc[%d]=0x%lx has active pmc14 settings, clearing ibr\n", cnum, *val));
2488 - /* don't mix debug with perfmon */
2489 - if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
2492 - * a count of 0 will mark the debug registers as in use and also
2493 - * ensure that they are properly cleared.
2495 - ret = pfm_write_ibr_dbr(PFM_CODE_RR, ctx, NULL, 0, regs);
2496 - if (ret) return ret;
2501 - case 4: *val |= 1UL << 23; /* force power enable bit */
2503 - case 8: val8 = *val;
2504 - val13 = ctx->ctx_pmcs[13];
2505 - val14 = ctx->ctx_pmcs[14];
2508 - case 13: val8 = ctx->ctx_pmcs[8];
2510 - val14 = ctx->ctx_pmcs[14];
2513 - case 14: val8 = ctx->ctx_pmcs[8];
2514 - val13 = ctx->ctx_pmcs[13];
2519 - /* check illegal configuration which can produce inconsistencies in tagging
2520 - * i-side events in L1D and L2 caches
2522 - if (check_case1) {
2523 - ret = ((val13 >> 45) & 0xf) == 0
2524 - && ((val8 & 0x1) == 0)
2525 - && ((((val14>>1) & 0x3) == 0x2 || ((val14>>1) & 0x3) == 0x0)
2526 - ||(((val14>>4) & 0x3) == 0x2 || ((val14>>4) & 0x3) == 0x0));
2528 - if (ret) DPRINT((KERN_DEBUG "perfmon: failure check_case1\n"));
2531 - return ret ? -EINVAL : 0;
2535 - * impl_pmcs, impl_pmds are computed at runtime to minimize errors!
2537 -static pmu_config_t pmu_conf_mck={
2538 - .pmu_name = "Itanium 2",
2539 - .pmu_family = 0x1f,
2540 - .flags = PFM_PMU_IRQ_RESEND,
2541 - .ovfl_val = (1UL << 47) - 1,
2542 - .pmd_desc = pfm_mck_pmd_desc,
2543 - .pmc_desc = pfm_mck_pmc_desc,
2546 - .use_rr_dbregs = 1 /* debug register are use for range restrictions */
2550 diff --git a/arch/ia64/kernel/perfmon_montecito.h b/arch/ia64/kernel/perfmon_montecito.h
2551 deleted file mode 100644
2552 index 7f8da4c..0000000
2553 --- a/arch/ia64/kernel/perfmon_montecito.h
2557 - * This file contains the Montecito PMU register description tables
2558 - * and pmc checker used by perfmon.c.
2560 - * Copyright (c) 2005-2006 Hewlett-Packard Development Company, L.P.
2561 - * Contributed by Stephane Eranian <eranian@hpl.hp.com>
2563 -static int pfm_mont_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
2565 -#define RDEP_MONT_ETB (RDEP(38)|RDEP(39)|RDEP(48)|RDEP(49)|RDEP(50)|RDEP(51)|RDEP(52)|RDEP(53)|RDEP(54)|\
2566 - RDEP(55)|RDEP(56)|RDEP(57)|RDEP(58)|RDEP(59)|RDEP(60)|RDEP(61)|RDEP(62)|RDEP(63))
2567 -#define RDEP_MONT_DEAR (RDEP(32)|RDEP(33)|RDEP(36))
2568 -#define RDEP_MONT_IEAR (RDEP(34)|RDEP(35))
2570 -static pfm_reg_desc_t pfm_mont_pmc_desc[PMU_MAX_PMCS]={
2571 -/* pmc0 */ { PFM_REG_CONTROL , 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {0,0, 0, 0}},
2572 -/* pmc1 */ { PFM_REG_CONTROL , 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {0,0, 0, 0}},
2573 -/* pmc2 */ { PFM_REG_CONTROL , 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {0,0, 0, 0}},
2574 -/* pmc3 */ { PFM_REG_CONTROL , 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {0,0, 0, 0}},
2575 -/* pmc4 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(4),0, 0, 0}, {0,0, 0, 0}},
2576 -/* pmc5 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(5),0, 0, 0}, {0,0, 0, 0}},
2577 -/* pmc6 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(6),0, 0, 0}, {0,0, 0, 0}},
2578 -/* pmc7 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(7),0, 0, 0}, {0,0, 0, 0}},
2579 -/* pmc8 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(8),0, 0, 0}, {0,0, 0, 0}},
2580 -/* pmc9 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(9),0, 0, 0}, {0,0, 0, 0}},
2581 -/* pmc10 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(10),0, 0, 0}, {0,0, 0, 0}},
2582 -/* pmc11 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(11),0, 0, 0}, {0,0, 0, 0}},
2583 -/* pmc12 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(12),0, 0, 0}, {0,0, 0, 0}},
2584 -/* pmc13 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(13),0, 0, 0}, {0,0, 0, 0}},
2585 -/* pmc14 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(14),0, 0, 0}, {0,0, 0, 0}},
2586 -/* pmc15 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(15),0, 0, 0}, {0,0, 0, 0}},
2587 -/* pmc16 */ { PFM_REG_NOTIMPL, },
2588 -/* pmc17 */ { PFM_REG_NOTIMPL, },
2589 -/* pmc18 */ { PFM_REG_NOTIMPL, },
2590 -/* pmc19 */ { PFM_REG_NOTIMPL, },
2591 -/* pmc20 */ { PFM_REG_NOTIMPL, },
2592 -/* pmc21 */ { PFM_REG_NOTIMPL, },
2593 -/* pmc22 */ { PFM_REG_NOTIMPL, },
2594 -/* pmc23 */ { PFM_REG_NOTIMPL, },
2595 -/* pmc24 */ { PFM_REG_NOTIMPL, },
2596 -/* pmc25 */ { PFM_REG_NOTIMPL, },
2597 -/* pmc26 */ { PFM_REG_NOTIMPL, },
2598 -/* pmc27 */ { PFM_REG_NOTIMPL, },
2599 -/* pmc28 */ { PFM_REG_NOTIMPL, },
2600 -/* pmc29 */ { PFM_REG_NOTIMPL, },
2601 -/* pmc30 */ { PFM_REG_NOTIMPL, },
2602 -/* pmc31 */ { PFM_REG_NOTIMPL, },
2603 -/* pmc32 */ { PFM_REG_CONFIG, 0, 0x30f01ffffffffffUL, 0x30f01ffffffffffUL, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}},
2604 -/* pmc33 */ { PFM_REG_CONFIG, 0, 0x0, 0x1ffffffffffUL, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}},
2605 -/* pmc34 */ { PFM_REG_CONFIG, 0, 0xf01ffffffffffUL, 0xf01ffffffffffUL, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}},
2606 -/* pmc35 */ { PFM_REG_CONFIG, 0, 0x0, 0x1ffffffffffUL, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}},
2607 -/* pmc36 */ { PFM_REG_CONFIG, 0, 0xfffffff0, 0xf, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}},
2608 -/* pmc37 */ { PFM_REG_MONITOR, 4, 0x0, 0x3fff, NULL, pfm_mont_pmc_check, {RDEP_MONT_IEAR, 0, 0, 0}, {0, 0, 0, 0}},
2609 -/* pmc38 */ { PFM_REG_CONFIG, 0, 0xdb6, 0x2492, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}},
2610 -/* pmc39 */ { PFM_REG_MONITOR, 6, 0x0, 0xffcf, NULL, pfm_mont_pmc_check, {RDEP_MONT_ETB,0, 0, 0}, {0,0, 0, 0}},
2611 -/* pmc40 */ { PFM_REG_MONITOR, 6, 0x2000000, 0xf01cf, NULL, pfm_mont_pmc_check, {RDEP_MONT_DEAR,0, 0, 0}, {0,0, 0, 0}},
2612 -/* pmc41 */ { PFM_REG_CONFIG, 0, 0x00002078fefefefeUL, 0x1e00018181818UL, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}},
2613 -/* pmc42 */ { PFM_REG_MONITOR, 6, 0x0, 0x7ff4f, NULL, pfm_mont_pmc_check, {RDEP_MONT_ETB,0, 0, 0}, {0,0, 0, 0}},
2614 - { PFM_REG_END , 0, 0x0, -1, NULL, NULL, {0,}, {0,}}, /* end marker */
2617 -static pfm_reg_desc_t pfm_mont_pmd_desc[PMU_MAX_PMDS]={
2618 -/* pmd0 */ { PFM_REG_NOTIMPL, },
2619 -/* pmd1 */ { PFM_REG_NOTIMPL, },
2620 -/* pmd2 */ { PFM_REG_NOTIMPL, },
2621 -/* pmd3 */ { PFM_REG_NOTIMPL, },
2622 -/* pmd4 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(4),0, 0, 0}},
2623 -/* pmd5 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(5),0, 0, 0}},
2624 -/* pmd6 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(6),0, 0, 0}},
2625 -/* pmd7 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(7),0, 0, 0}},
2626 -/* pmd8 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(8),0, 0, 0}},
2627 -/* pmd9 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(9),0, 0, 0}},
2628 -/* pmd10 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(10),0, 0, 0}},
2629 -/* pmd11 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(11),0, 0, 0}},
2630 -/* pmd12 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(12),0, 0, 0}},
2631 -/* pmd13 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(13),0, 0, 0}},
2632 -/* pmd14 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(14),0, 0, 0}},
2633 -/* pmd15 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(15),0, 0, 0}},
2634 -/* pmd16 */ { PFM_REG_NOTIMPL, },
2635 -/* pmd17 */ { PFM_REG_NOTIMPL, },
2636 -/* pmd18 */ { PFM_REG_NOTIMPL, },
2637 -/* pmd19 */ { PFM_REG_NOTIMPL, },
2638 -/* pmd20 */ { PFM_REG_NOTIMPL, },
2639 -/* pmd21 */ { PFM_REG_NOTIMPL, },
2640 -/* pmd22 */ { PFM_REG_NOTIMPL, },
2641 -/* pmd23 */ { PFM_REG_NOTIMPL, },
2642 -/* pmd24 */ { PFM_REG_NOTIMPL, },
2643 -/* pmd25 */ { PFM_REG_NOTIMPL, },
2644 -/* pmd26 */ { PFM_REG_NOTIMPL, },
2645 -/* pmd27 */ { PFM_REG_NOTIMPL, },
2646 -/* pmd28 */ { PFM_REG_NOTIMPL, },
2647 -/* pmd29 */ { PFM_REG_NOTIMPL, },
2648 -/* pmd30 */ { PFM_REG_NOTIMPL, },
2649 -/* pmd31 */ { PFM_REG_NOTIMPL, },
2650 -/* pmd32 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP(33)|RDEP(36),0, 0, 0}, {RDEP(40),0, 0, 0}},
2651 -/* pmd33 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP(32)|RDEP(36),0, 0, 0}, {RDEP(40),0, 0, 0}},
2652 -/* pmd34 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP(35),0, 0, 0}, {RDEP(37),0, 0, 0}},
2653 -/* pmd35 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP(34),0, 0, 0}, {RDEP(37),0, 0, 0}},
2654 -/* pmd36 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP(32)|RDEP(33),0, 0, 0}, {RDEP(40),0, 0, 0}},
2655 -/* pmd37 */ { PFM_REG_NOTIMPL, },
2656 -/* pmd38 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
2657 -/* pmd39 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
2658 -/* pmd40 */ { PFM_REG_NOTIMPL, },
2659 -/* pmd41 */ { PFM_REG_NOTIMPL, },
2660 -/* pmd42 */ { PFM_REG_NOTIMPL, },
2661 -/* pmd43 */ { PFM_REG_NOTIMPL, },
2662 -/* pmd44 */ { PFM_REG_NOTIMPL, },
2663 -/* pmd45 */ { PFM_REG_NOTIMPL, },
2664 -/* pmd46 */ { PFM_REG_NOTIMPL, },
2665 -/* pmd47 */ { PFM_REG_NOTIMPL, },
2666 -/* pmd48 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
2667 -/* pmd49 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
2668 -/* pmd50 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
2669 -/* pmd51 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
2670 -/* pmd52 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
2671 -/* pmd53 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
2672 -/* pmd54 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
2673 -/* pmd55 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
2674 -/* pmd56 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
2675 -/* pmd57 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
2676 -/* pmd58 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
2677 -/* pmd59 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
2678 -/* pmd60 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
2679 -/* pmd61 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
2680 -/* pmd62 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
2681 -/* pmd63 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
2682 - { PFM_REG_END , 0, 0x0, -1, NULL, NULL, {0,}, {0,}}, /* end marker */
2686 - * PMC reserved fields must have their power-up values preserved
2689 -pfm_mont_reserved(unsigned int cnum, unsigned long *val, struct pt_regs *regs)
2691 - unsigned long tmp1, tmp2, ival = *val;
2693 - /* remove reserved areas from user value */
2694 - tmp1 = ival & PMC_RSVD_MASK(cnum);
2696 - /* get reserved fields values */
2697 - tmp2 = PMC_DFL_VAL(cnum) & ~PMC_RSVD_MASK(cnum);
2699 - *val = tmp1 | tmp2;
2701 - DPRINT(("pmc[%d]=0x%lx, mask=0x%lx, reset=0x%lx, val=0x%lx\n",
2702 - cnum, ival, PMC_RSVD_MASK(cnum), PMC_DFL_VAL(cnum), *val));
2707 - * task can be NULL if the context is unloaded
2710 -pfm_mont_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs)
2713 - unsigned long val32 = 0, val38 = 0, val41 = 0;
2714 - unsigned long tmpval;
2715 - int check_case1 = 0;
2718 - /* first preserve the reserved fields */
2719 - pfm_mont_reserved(cnum, val, regs);
2723 - /* sanity check */
2724 - if (ctx == NULL) return -EINVAL;
2726 - is_loaded = ctx->ctx_state == PFM_CTX_LOADED || ctx->ctx_state == PFM_CTX_MASKED;
2729 - * we must clear the debug registers if pmc41 has a value which enable
2730 - * memory pipeline event constraints. In this case we need to clear the
2731 - * the debug registers if they have not yet been accessed. This is required
2732 - * to avoid picking stale state.
2733 - * PMC41 is "active" if:
2734 - * one of the pmc41.cfg_dtagXX field is different from 0x3
2736 - * at the corresponding pmc41.en_dbrpXX is set.
2738 - * ctx_fl_using_dbreg == 0 (i.e., dbr not yet used)
2740 - DPRINT(("cnum=%u val=0x%lx, using_dbreg=%d loaded=%d\n", cnum, tmpval, ctx->ctx_fl_using_dbreg, is_loaded));
2742 - if (cnum == 41 && is_loaded
2743 - && (tmpval & 0x1e00000000000UL) && (tmpval & 0x18181818UL) != 0x18181818UL && ctx->ctx_fl_using_dbreg == 0) {
2745 - DPRINT(("pmc[%d]=0x%lx has active pmc41 settings, clearing dbr\n", cnum, tmpval));
2747 - /* don't mix debug with perfmon */
2748 - if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
2751 - * a count of 0 will mark the debug registers if:
2754 - ret = pfm_write_ibr_dbr(PFM_DATA_RR, ctx, NULL, 0, regs);
2755 - if (ret) return ret;
2758 - * we must clear the (instruction) debug registers if:
2759 - * pmc38.ig_ibrpX is 0 (enabled)
2761 - * ctx_fl_using_dbreg == 0 (i.e., dbr not yet used)
2763 - if (cnum == 38 && is_loaded && ((tmpval & 0x492UL) != 0x492UL) && ctx->ctx_fl_using_dbreg == 0) {
2765 - DPRINT(("pmc38=0x%lx has active pmc38 settings, clearing ibr\n", tmpval));
2767 - /* don't mix debug with perfmon */
2768 - if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
2771 - * a count of 0 will mark the debug registers as in use and also
2772 - * ensure that they are properly cleared.
2774 - ret = pfm_write_ibr_dbr(PFM_CODE_RR, ctx, NULL, 0, regs);
2775 - if (ret) return ret;
2779 - case 32: val32 = *val;
2780 - val38 = ctx->ctx_pmcs[38];
2781 - val41 = ctx->ctx_pmcs[41];
2784 - case 38: val38 = *val;
2785 - val32 = ctx->ctx_pmcs[32];
2786 - val41 = ctx->ctx_pmcs[41];
2789 - case 41: val41 = *val;
2790 - val32 = ctx->ctx_pmcs[32];
2791 - val38 = ctx->ctx_pmcs[38];
2795 - /* check illegal configuration which can produce inconsistencies in tagging
2796 - * i-side events in L1D and L2 caches
2798 - if (check_case1) {
2799 - ret = (((val41 >> 45) & 0xf) == 0 && ((val32>>57) & 0x1) == 0)
2800 - && ((((val38>>1) & 0x3) == 0x2 || ((val38>>1) & 0x3) == 0)
2801 - || (((val38>>4) & 0x3) == 0x2 || ((val38>>4) & 0x3) == 0));
2803 - DPRINT(("invalid config pmc38=0x%lx pmc41=0x%lx pmc32=0x%lx\n", val38, val41, val32));
2812 - * impl_pmcs, impl_pmds are computed at runtime to minimize errors!
2814 -static pmu_config_t pmu_conf_mont={
2815 - .pmu_name = "Montecito",
2816 - .pmu_family = 0x20,
2817 - .flags = PFM_PMU_IRQ_RESEND,
2818 - .ovfl_val = (1UL << 47) - 1,
2819 - .pmd_desc = pfm_mont_pmd_desc,
2820 - .pmc_desc = pfm_mont_pmc_desc,
2823 - .use_rr_dbregs = 1 /* debug register are use for range retrictions */
2825 diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
2826 index 3ab8373..a7dfb39 100644
2827 --- a/arch/ia64/kernel/process.c
2828 +++ b/arch/ia64/kernel/process.c
2830 #include <linux/delay.h>
2831 #include <linux/kdebug.h>
2832 #include <linux/utsname.h>
2833 +#include <linux/perfmon_kern.h>
2835 #include <asm/cpu.h>
2836 #include <asm/delay.h>
2841 -#ifdef CONFIG_PERFMON
2842 -# include <asm/perfmon.h>
2845 #include "sigframe.h"
2847 void (*ia64_mark_idle)(int);
2848 @@ -162,10 +159,8 @@ show_regs (struct pt_regs *regs)
2850 void tsk_clear_notify_resume(struct task_struct *tsk)
2852 -#ifdef CONFIG_PERFMON
2853 - if (tsk->thread.pfm_needs_checking)
2854 + if (test_ti_thread_flag(task_thread_info(tsk), TIF_PERFMON_WORK))
2857 if (test_ti_thread_flag(task_thread_info(tsk), TIF_RESTORE_RSE))
2859 clear_ti_thread_flag(task_thread_info(tsk), TIF_NOTIFY_RESUME);
2860 @@ -188,14 +183,9 @@ do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall)
2864 -#ifdef CONFIG_PERFMON
2865 - if (current->thread.pfm_needs_checking)
2867 - * Note: pfm_handle_work() allow us to call it with interrupts
2868 - * disabled, and may enable interrupts within the function.
2870 - pfm_handle_work();
2872 + /* process perfmon asynchronous work (e.g. block thread or reset) */
2873 + if (test_thread_flag(TIF_PERFMON_WORK))
2874 + pfm_handle_work(task_pt_regs(current));
2876 /* deal with pending signal delivery */
2877 if (test_thread_flag(TIF_SIGPENDING)) {
2878 @@ -212,22 +202,15 @@ do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall)
2879 local_irq_disable(); /* force interrupt disable */
2882 -static int pal_halt = 1;
2883 static int can_do_pal_halt = 1;
2885 static int __init nohalt_setup(char * str)
2887 - pal_halt = can_do_pal_halt = 0;
2888 + can_do_pal_halt = 0;
2891 __setup("nohalt", nohalt_setup);
2894 -update_pal_halt_status(int status)
2896 - can_do_pal_halt = pal_halt && status;
2900 * We use this if we don't have any better idle routine..
2902 @@ -236,6 +219,22 @@ default_idle (void)
2905 while (!need_resched()) {
2906 +#ifdef CONFIG_PERFMON
2909 + * If requested, we stop the PMU to avoid
2910 + * measuring across the core idle loop.
2912 + * dcr.pp is not modified on purpose
2913 + * it is used when coming out of
2914 + * safe_halt() via interrupt
2916 + if ((__get_cpu_var(pfm_syst_info) & PFM_ITA_CPUINFO_IDLE_EXCL)) {
2917 + psr = ia64_getreg(_IA64_REG_PSR);
2918 + if (psr & IA64_PSR_PP)
2919 + ia64_rsm(IA64_PSR_PP);
2922 if (can_do_pal_halt) {
2923 local_irq_disable();
2924 if (!need_resched()) {
2925 @@ -244,6 +243,12 @@ default_idle (void)
2929 +#ifdef CONFIG_PERFMON
2930 + if ((__get_cpu_var(pfm_syst_info) & PFM_ITA_CPUINFO_IDLE_EXCL)) {
2931 + if (psr & IA64_PSR_PP)
2932 + ia64_ssm(IA64_PSR_PP);
2938 @@ -344,22 +349,9 @@ cpu_idle (void)
2940 ia64_save_extra (struct task_struct *task)
2942 -#ifdef CONFIG_PERFMON
2943 - unsigned long info;
2946 if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0)
2947 ia64_save_debug_regs(&task->thread.dbr[0]);
2949 -#ifdef CONFIG_PERFMON
2950 - if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0)
2951 - pfm_save_regs(task);
2953 - info = __get_cpu_var(pfm_syst_info);
2954 - if (info & PFM_CPUINFO_SYST_WIDE)
2955 - pfm_syst_wide_update_task(task, info, 0);
2958 #ifdef CONFIG_IA32_SUPPORT
2959 if (IS_IA32_PROCESS(task_pt_regs(task)))
2960 ia32_save_state(task);
2961 @@ -369,22 +361,9 @@ ia64_save_extra (struct task_struct *task)
2963 ia64_load_extra (struct task_struct *task)
2965 -#ifdef CONFIG_PERFMON
2966 - unsigned long info;
2969 if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0)
2970 ia64_load_debug_regs(&task->thread.dbr[0]);
2972 -#ifdef CONFIG_PERFMON
2973 - if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0)
2974 - pfm_load_regs(task);
2976 - info = __get_cpu_var(pfm_syst_info);
2977 - if (info & PFM_CPUINFO_SYST_WIDE)
2978 - pfm_syst_wide_update_task(task, info, 1);
2981 #ifdef CONFIG_IA32_SUPPORT
2982 if (IS_IA32_PROCESS(task_pt_regs(task)))
2983 ia32_load_state(task);
2984 @@ -510,8 +489,7 @@ copy_thread (int nr, unsigned long clone_flags,
2985 * call behavior where scratch registers are preserved across
2986 * system calls (unless used by the system call itself).
2988 -# define THREAD_FLAGS_TO_CLEAR (IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID \
2989 - | IA64_THREAD_PM_VALID)
2990 +# define THREAD_FLAGS_TO_CLEAR (IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID)
2991 # define THREAD_FLAGS_TO_SET 0
2992 p->thread.flags = ((current->thread.flags & ~THREAD_FLAGS_TO_CLEAR)
2993 | THREAD_FLAGS_TO_SET);
2994 @@ -533,10 +511,8 @@ copy_thread (int nr, unsigned long clone_flags,
2998 -#ifdef CONFIG_PERFMON
2999 - if (current->thread.pfm_context)
3000 - pfm_inherit(p, child_ptregs);
3002 + pfm_copy_thread(p);
3007 @@ -745,15 +721,13 @@ exit_thread (void)
3010 ia64_drop_fpu(current);
3011 -#ifdef CONFIG_PERFMON
3012 - /* if needed, stop monitoring and flush state to perfmon context */
3013 - if (current->thread.pfm_context)
3014 - pfm_exit_thread(current);
3016 + /* if needed, stop monitoring and flush state to perfmon context */
3017 + pfm_exit_thread();
3019 /* free debug register resources */
3020 - if (current->thread.flags & IA64_THREAD_DBG_VALID)
3021 - pfm_release_debug_registers(current);
3023 + pfm_release_dbregs(current);
3025 if (IS_IA32_PROCESS(task_pt_regs(current)))
3026 ia32_drop_ia64_partial_page_list(current);
3028 diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
3029 index 2a9943b..bb1ca1e 100644
3030 --- a/arch/ia64/kernel/ptrace.c
3031 +++ b/arch/ia64/kernel/ptrace.c
3033 #include <linux/security.h>
3034 #include <linux/audit.h>
3035 #include <linux/signal.h>
3036 +#include <linux/perfmon_kern.h>
3037 #include <linux/regset.h>
3038 #include <linux/elf.h>
3041 #include <asm/system.h>
3042 #include <asm/uaccess.h>
3043 #include <asm/unwind.h>
3044 -#ifdef CONFIG_PERFMON
3045 -#include <asm/perfmon.h>
3050 @@ -2124,7 +2122,6 @@ access_uarea(struct task_struct *child, unsigned long addr,
3051 "address 0x%lx\n", addr);
3054 -#ifdef CONFIG_PERFMON
3056 * Check if debug registers are used by perfmon. This
3057 * test must be done once we know that we can do the
3058 @@ -2142,9 +2139,8 @@ access_uarea(struct task_struct *child, unsigned long addr,
3059 * IA64_THREAD_DBG_VALID. The registers are restored
3060 * by the PMU context switch code.
3062 - if (pfm_use_debug_registers(child))
3063 + if (pfm_use_dbregs(child))
3067 if (!(child->thread.flags & IA64_THREAD_DBG_VALID)) {
3068 child->thread.flags |= IA64_THREAD_DBG_VALID;
3069 diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
3070 index de636b2..677fa68 100644
3071 --- a/arch/ia64/kernel/setup.c
3072 +++ b/arch/ia64/kernel/setup.c
3074 #include <linux/cpufreq.h>
3075 #include <linux/kexec.h>
3076 #include <linux/crash_dump.h>
3077 +#include <linux/perfmon_kern.h>
3079 #include <asm/ia32.h>
3080 #include <asm/machvec.h>
3081 @@ -1051,6 +1052,8 @@ cpu_init (void)
3083 platform_cpu_init();
3084 pm_idle = default_idle;
3086 + pfm_init_percpu();
3090 diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
3091 index d8f05e5..3d7a739 100644
3092 --- a/arch/ia64/kernel/smpboot.c
3093 +++ b/arch/ia64/kernel/smpboot.c
3095 #include <linux/efi.h>
3096 #include <linux/percpu.h>
3097 #include <linux/bitops.h>
3098 +#include <linux/perfmon_kern.h>
3100 #include <asm/atomic.h>
3101 #include <asm/cache.h>
3102 @@ -381,10 +382,6 @@ smp_callin (void)
3103 extern void ia64_init_itm(void);
3104 extern volatile int time_keeper_id;
3106 -#ifdef CONFIG_PERFMON
3107 - extern void pfm_init_percpu(void);
3110 cpuid = smp_processor_id();
3111 phys_id = hard_smp_processor_id();
3112 itc_master = time_keeper_id;
3113 @@ -410,10 +407,6 @@ smp_callin (void)
3115 ia64_mca_cmc_vector_setup(); /* Setup vector on AP */
3117 -#ifdef CONFIG_PERFMON
3118 - pfm_init_percpu();
3123 if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT)) {
3124 @@ -751,6 +744,7 @@ int __cpu_disable(void)
3125 cpu_clear(cpu, cpu_online_map);
3126 local_flush_tlb_all();
3127 cpu_clear(cpu, cpu_callin_map);
3128 + pfm_cpu_disable();
3132 diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c
3133 index bcbb6d8..a0ed33a 100644
3134 --- a/arch/ia64/kernel/sys_ia64.c
3135 +++ b/arch/ia64/kernel/sys_ia64.c
3136 @@ -284,3 +284,11 @@ sys_pciconfig_write (unsigned long bus, unsigned long dfn, unsigned long off, un
3139 #endif /* CONFIG_PCI */
3141 +#ifndef CONFIG_IA64_PERFMON_COMPAT
3143 +sys_perfmonctl (int fd, int cmd, void __user *arg, int count)
3148 diff --git a/arch/ia64/lib/Makefile b/arch/ia64/lib/Makefile
3149 index 98771e2..077fd09 100644
3150 --- a/arch/ia64/lib/Makefile
3151 +++ b/arch/ia64/lib/Makefile
3152 @@ -13,7 +13,6 @@ lib-y := __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \
3154 obj-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o
3155 obj-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o
3156 -lib-$(CONFIG_PERFMON) += carta_random.o
3159 AFLAGS___udivdi3.o = -DUNSIGNED
3160 diff --git a/arch/ia64/oprofile/init.c b/arch/ia64/oprofile/init.c
3161 index 125a602..892de6a 100644
3162 --- a/arch/ia64/oprofile/init.c
3163 +++ b/arch/ia64/oprofile/init.c
3165 #include <linux/init.h>
3166 #include <linux/errno.h>
3168 -extern int perfmon_init(struct oprofile_operations * ops);
3169 -extern void perfmon_exit(void);
3170 +extern int op_perfmon_init(struct oprofile_operations * ops);
3171 +extern void op_perfmon_exit(void);
3172 extern void ia64_backtrace(struct pt_regs * const regs, unsigned int depth);
3174 int __init oprofile_arch_init(struct oprofile_operations * ops)
3175 @@ -22,7 +22,7 @@ int __init oprofile_arch_init(struct oprofile_operations * ops)
3177 #ifdef CONFIG_PERFMON
3178 /* perfmon_init() can fail, but we have no way to report it */
3179 - ret = perfmon_init(ops);
3180 + ret = op_perfmon_init(ops);
3182 ops->backtrace = ia64_backtrace;
3184 @@ -33,6 +33,6 @@ int __init oprofile_arch_init(struct oprofile_operations * ops)
3185 void oprofile_arch_exit(void)
3187 #ifdef CONFIG_PERFMON
3189 + op_perfmon_exit();
3192 diff --git a/arch/ia64/oprofile/perfmon.c b/arch/ia64/oprofile/perfmon.c
3193 index bc41dd3..6fa9d17 100644
3194 --- a/arch/ia64/oprofile/perfmon.c
3195 +++ b/arch/ia64/oprofile/perfmon.c
3197 #include <linux/kernel.h>
3198 #include <linux/oprofile.h>
3199 #include <linux/sched.h>
3200 -#include <asm/perfmon.h>
3201 +#include <linux/module.h>
3202 +#include <linux/perfmon_kern.h>
3203 #include <asm/ptrace.h>
3204 #include <asm/errno.h>
3206 static int allow_ints;
3209 -perfmon_handler(struct task_struct *task, void *buf, pfm_ovfl_arg_t *arg,
3210 - struct pt_regs *regs, unsigned long stamp)
3211 +perfmon_handler(struct pfm_context *ctx,
3212 + unsigned long ip, u64 stamp, void *data)
3214 - int event = arg->pmd_eventid;
3215 + struct pt_regs *regs;
3216 + struct pfm_ovfl_arg *arg;
3219 + arg = &ctx->ovfl_arg;
3221 - arg->ovfl_ctrl.bits.reset_ovfl_pmds = 1;
3222 + arg->ovfl_ctrl = PFM_OVFL_CTRL_RESET;
3224 /* the owner of the oprofile event buffer may have exited
3225 * without perfmon being shutdown (e.g. SIGSEGV)
3228 - oprofile_add_sample(regs, event);
3229 + oprofile_add_sample(regs, arg->pmd_eventid);
3233 @@ -45,17 +50,13 @@ static void perfmon_stop(void)
3238 -#define OPROFILE_FMT_UUID { \
3239 - 0x77, 0x7a, 0x6e, 0x61, 0x20, 0x65, 0x73, 0x69, 0x74, 0x6e, 0x72, 0x20, 0x61, 0x65, 0x0a, 0x6c }
3241 -static pfm_buffer_fmt_t oprofile_fmt = {
3242 - .fmt_name = "oprofile_format",
3243 - .fmt_uuid = OPROFILE_FMT_UUID,
3244 - .fmt_handler = perfmon_handler,
3245 +static struct pfm_smpl_fmt oprofile_fmt = {
3246 + .fmt_name = "OProfile",
3247 + .fmt_handler = perfmon_handler,
3248 + .fmt_flags = PFM_FMT_BUILTIN_FLAG,
3249 + .owner = THIS_MODULE
3253 static char * get_cpu_type(void)
3255 __u8 family = local_cpu_data->family;
3256 @@ -75,9 +76,9 @@ static char * get_cpu_type(void)
3258 static int using_perfmon;
3260 -int perfmon_init(struct oprofile_operations * ops)
3261 +int __init op_perfmon_init(struct oprofile_operations * ops)
3263 - int ret = pfm_register_buffer_fmt(&oprofile_fmt);
3264 + int ret = pfm_fmt_register(&oprofile_fmt);
3268 @@ -90,10 +91,10 @@ int perfmon_init(struct oprofile_operations * ops)
3272 -void perfmon_exit(void)
3273 +void __exit op_perfmon_exit(void)
3278 - pfm_unregister_buffer_fmt(oprofile_fmt.fmt_uuid);
3279 + pfm_fmt_unregister(&oprofile_fmt);
3281 diff --git a/arch/ia64/perfmon/Kconfig b/arch/ia64/perfmon/Kconfig
3282 new file mode 100644
3283 index 0000000..99c68bd
3285 +++ b/arch/ia64/perfmon/Kconfig
3287 +menu "Hardware Performance Monitoring support"
3289 + bool "Perfmon2 performance monitoring interface"
3292 + Enables the perfmon2 interface to access the hardware
3293 + performance counters. See <http://perfmon2.sf.net/> for
3296 +config PERFMON_DEBUG
3297 + bool "Perfmon debugging"
3299 + depends on PERFMON
3301 + Enables perfmon debugging support
3303 +config PERFMON_DEBUG_FS
3304 + bool "Enable perfmon statistics reporting via debugfs"
3306 + depends on PERFMON && DEBUG_FS
3308 + Enable collection and reporting of perfmon timing statistics under
3309 + debugfs. This is used for debugging and performance analysis of the
3310 + subsystem. The debugfs filesystem must be mounted.
3312 +config IA64_PERFMON_COMPAT
3313 + bool "Enable old perfmon-2 compatbility mode"
3315 + depends on PERFMON
3317 + Enable this option to allow performance tools which used the old
3318 + perfmon-2 interface to continue to work. Old tools are those using
3319 + the obsolete commands and arguments. Check your programs and look
3320 + in include/asm-ia64/perfmon_compat.h for more information.
3322 +config IA64_PERFMON_GENERIC
3323 + tristate "Generic IA-64 PMU support"
3324 + depends on PERFMON
3327 + Enables generic IA-64 PMU support.
3328 + The generic PMU is defined by the IA-64 architecture document.
3329 + This option should only be necessary when running with a PMU that
3330 + is not yet explicitely supported. Even then, there is no guarantee
3331 + that this support will work.
3333 +config IA64_PERFMON_ITANIUM
3334 + tristate "Itanium (Merced) Performance Monitoring support"
3335 + depends on PERFMON
3338 + Enables Itanium (Merced) PMU support.
3340 +config IA64_PERFMON_MCKINLEY
3341 + tristate "Itanium 2 (McKinley) Performance Monitoring support"
3342 + depends on PERFMON
3345 + Enables Itanium 2 (McKinley, Madison, Deerfield) PMU support.
3347 +config IA64_PERFMON_MONTECITO
3348 + tristate "Itanium 2 9000 (Montecito) Performance Monitoring support"
3349 + depends on PERFMON
3352 + Enables support for Itanium 2 9000 (Montecito) PMU.
3354 diff --git a/arch/ia64/perfmon/Makefile b/arch/ia64/perfmon/Makefile
3355 new file mode 100644
3356 index 0000000..c9cdf9f
3358 +++ b/arch/ia64/perfmon/Makefile
3361 +# Copyright (c) 2005-2006 Hewlett-Packard Development Company, L.P.
3362 +# Contributed by Stephane Eranian <eranian@hpl.hp.com>
3364 +obj-$(CONFIG_PERFMON) += perfmon.o
3365 +obj-$(CONFIG_IA64_PERFMON_COMPAT) += perfmon_default_smpl.o \
3367 +obj-$(CONFIG_IA64_PERFMON_GENERIC) += perfmon_generic.o
3368 +obj-$(CONFIG_IA64_PERFMON_ITANIUM) += perfmon_itanium.o
3369 +obj-$(CONFIG_IA64_PERFMON_MCKINLEY) += perfmon_mckinley.o
3370 +obj-$(CONFIG_IA64_PERFMON_MONTECITO) += perfmon_montecito.o
3371 diff --git a/arch/ia64/perfmon/perfmon.c b/arch/ia64/perfmon/perfmon.c
3372 new file mode 100644
3373 index 0000000..3f59410
3375 +++ b/arch/ia64/perfmon/perfmon.c
3378 + * This file implements the IA-64 specific
3379 + * support for the perfmon2 interface
3381 + * Copyright (c) 1999-2006 Hewlett-Packard Development Company, L.P.
3382 + * Contributed by Stephane Eranian <eranian@hpl.hp.com>
3384 + * This program is free software; you can redistribute it and/or
3385 + * modify it under the terms of version 2 of the GNU General Public
3386 + * License as published by the Free Software Foundation.
3388 + * This program is distributed in the hope that it will be useful,
3389 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3390 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3391 + * General Public License for more details.
3393 + * You should have received a copy of the GNU General Public License
3394 + * along with this program; if not, write to the Free Software
3395 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
3398 +#include <linux/module.h>
3399 +#include <linux/perfmon_kern.h>
3401 +struct pfm_arch_session {
3402 + u32 pfs_sys_use_dbr; /* syswide session uses dbr */
3403 + u32 pfs_ptrace_use_dbr; /* a thread uses dbr via ptrace()*/
3406 +DEFINE_PER_CPU(u32, pfm_syst_info);
3408 +static struct pfm_arch_session pfm_arch_sessions;
3409 +static __cacheline_aligned_in_smp DEFINE_SPINLOCK(pfm_arch_sessions_lock);
3411 +static inline void pfm_clear_psr_pp(void)
3413 + ia64_rsm(IA64_PSR_PP);
3416 +static inline void pfm_set_psr_pp(void)
3418 + ia64_ssm(IA64_PSR_PP);
3421 +static inline void pfm_clear_psr_up(void)
3423 + ia64_rsm(IA64_PSR_UP);
3426 +static inline void pfm_set_psr_up(void)
3428 + ia64_ssm(IA64_PSR_UP);
3431 +static inline void pfm_set_psr_l(u64 val)