re-arrange ps3 tree
authorHamish Guthrie <hcg@openwrt.org>
Thu, 18 Dec 2008 11:46:28 +0000 (11:46 +0000)
committerHamish Guthrie <hcg@openwrt.org>
Thu, 18 Dec 2008 11:46:28 +0000 (11:46 +0000)
SVN-Revision: 13680

17 files changed:
target/linux/ps3/Makefile
target/linux/ps3/base-files/bin/login [deleted file]
target/linux/ps3/base-files/etc/banner [deleted file]
target/linux/ps3/base-files/etc/config/system [deleted file]
target/linux/ps3/base-files/etc/init.d/boot [deleted file]
target/linux/ps3/base-files/etc/inittab [deleted file]
target/linux/ps3/base-files/sbin/bl-option [deleted file]
target/linux/ps3/base-files/sbin/initrun [deleted file]
target/linux/ps3/patches-2.6.27/001-perfmon-2.6.27.patch [deleted file]
target/linux/ps3/petitboot/base-files/bin/login [new file with mode: 0755]
target/linux/ps3/petitboot/base-files/etc/banner [new file with mode: 0644]
target/linux/ps3/petitboot/base-files/etc/config/system [new file with mode: 0644]
target/linux/ps3/petitboot/base-files/etc/init.d/boot [new file with mode: 0755]
target/linux/ps3/petitboot/base-files/etc/inittab [new file with mode: 0644]
target/linux/ps3/petitboot/base-files/sbin/bl-option [new file with mode: 0755]
target/linux/ps3/petitboot/base-files/sbin/initrun [new file with mode: 0755]
target/linux/ps3/petitboot/target.mk [new file with mode: 0644]

index ebcc4a9cf00b486cbab8d27390ec050e98509c07..78fdfe2d70e2527a732657f0e602d50ed6d3d1c0 100644 (file)
@@ -9,8 +9,9 @@ include $(TOPDIR)/rules.mk
 ARCH:=powerpc
 BOARD:=ps3
 BOARDNAME:=Sony PS3 Game Console
+SUBTARGETS=petitboot
 
-LINUX_VERSION:=2.6.27.9
+LINUX_VERSION:=2.6.27.8
 
 KERNEL_CC:=
 
diff --git a/target/linux/ps3/base-files/bin/login b/target/linux/ps3/base-files/bin/login
deleted file mode 100755 (executable)
index 2e649f0..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/sh
-# Copyright (C) 2008 OpenWrt.org
-
-bl_option=/sbin/bl-option
-
-if [ ! -f $bl_option ] ||
-   [ ! `$bl_option --get-telnet-enabled` ] ||
-   [ `$bl_option --get-telnet-enabled` = "0" ]; then
-    echo \
-"
- === IMPORTANT ==========================
-  Telnet login is disabled for security
-  reasons. Enabling telnet login on the
-  host will allow any user connected to
-  the same network to login to the host.
-
-  You can enable telnet login with the
-  following command in the host console:
-
-  # $bl_option -T 1
-
-  You can disable telnet login with the
-  following command in the host console:
-
-  # $bl_option -T 0
- ----------------------------------------
-"
-    exit 0
-fi
-
-grep '^root:[^!]' /etc/passwd >&- 2>&-
-[ "$?" = "0" -a -z "$FAILSAFE" ]  &&
-{
-    echo "Login failed."
-    exit 0
-} || {
-cat << EOF
- === IMPORTANT ============================
-  Use 'passwd' to set your login password
-  this will disable telnet and enable SSH
- ------------------------------------------
-EOF
-}
-
-exec /bin/ash --login
diff --git a/target/linux/ps3/base-files/etc/banner b/target/linux/ps3/base-files/etc/banner
deleted file mode 100644 (file)
index 4d671c7..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-  _____  _____  _____
- |  _  ||  ___||___  |
- |   __||___  ||___  |
- |__|   |_____||_____|
-            L I N U X
-
diff --git a/target/linux/ps3/base-files/etc/config/system b/target/linux/ps3/base-files/etc/config/system
deleted file mode 100644 (file)
index 67ffe83..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-config system
-       option hostname ps3-linux
-       option log_file /var/log/messages
diff --git a/target/linux/ps3/base-files/etc/init.d/boot b/target/linux/ps3/base-files/etc/init.d/boot
deleted file mode 100755 (executable)
index 2897f3a..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/bin/sh /etc/rc.common
-# Copyright (C) 2006 OpenWrt.org
-
-START=10
-
-system_config() {
-       local cfg="$1"
-       local hostname
-       
-       config_get hostname "$cfg" hostname
-       echo "${hostname:-OpenWrt}" > /proc/sys/kernel/hostname
-
-       config_get conloglevel "$cfg" conloglevel
-       [ -n "$conloglevel" ] && dmesg -n "$conloglevel"
-       
-       config_get timezone "$cfg" timezone 
-       [ -z "$timezone" ] && timezone=UTC
-       echo "$timezone" > /tmp/TZ
-
-       config_get log_ip "$cfg" log_ip
-       config_get log_size "$cfg" log_size
-       config_get log_file "$cfg" log_file
-       # use a shared mem buffer for local default
-       [ -z $log_file -a -z "$log_size" ] && log_size=16
-       syslogd ${log_size:+-C $log_size} ${log_file:+-O $log_file} \
-               ${log_ip:+-L -R $log_ip}
-       klogd
-}
-
-apply_uci_config() {(
-       include /lib/config
-       uci_apply_defaults
-)}
-
-start() {
-       [ -f /proc/mounts ] || /sbin/mount_root
-       [ -f /proc/jffs2_bbc ] && echo "S" > /proc/jffs2_bbc
-       [ -f /proc/net/vlan/config ] && vconfig set_name_type DEV_PLUS_VID_NO_PAD
-
-       mkdir -p /var/run
-       mkdir -p /var/log
-       mkdir -p /var/lock
-       mkdir -p /var/state
-       mkdir -p /tmp/.uci
-
-       apply_uci_config
-       config_load system
-       config_foreach system_config system
-
-       chown 0700 /tmp/.uci
-       touch /var/log/wtmp
-       touch /var/log/lastlog
-       touch /tmp/resolv.conf.auto
-       ln -sf /tmp/resolv.conf.auto /tmp/resolv.conf
-       [ "$FAILSAFE" = "true" ] && touch /tmp/.failsafe
-
-       killall -q hotplug2
-       [ -x /sbin/hotplug2 ] && /sbin/hotplug2 --override --persistent \
-                       --max-children 1 --no-coldplug &
-
-       # the coldplugging of network interfaces needs to happen later, so we do it manually here
-       for iface in $(awk -F: '/:/ {print $1}' /proc/net/dev); do
-               /usr/bin/env -i ACTION=add INTERFACE="$iface" /sbin/hotplug-call net
-       done
-
-       # create /dev/root if it doesn't exist
-       [ -e /dev/root ] || {
-               rootdev=$(awk 'BEGIN { RS=" "; FS="="; } $1 == "root" { print $2 }' < /proc/cmdline)
-               [ -n "$rootdev" ] && ln -s "$rootdev" /dev/root
-       }
-
-       load_modules /etc/modules.d/*
-}
diff --git a/target/linux/ps3/base-files/etc/inittab b/target/linux/ps3/base-files/etc/inittab
deleted file mode 100644 (file)
index 96abea9..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-::sysinit:/etc/init.d/rcS S boot
-::shutdown:/etc/init.d/rcS K stop
-::ctrlaltdel:/sbin/reboot
-::restart:/sbin/init
-tty1::respawn:/sbin/initrun
-tty2::askfirst:/bin/ash --login
-tty3::askfirst:/bin/ash --login
diff --git a/target/linux/ps3/base-files/sbin/bl-option b/target/linux/ps3/base-files/sbin/bl-option
deleted file mode 100755 (executable)
index 8eea93d..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-#!/bin/sh
-#
-#  Copyright (C) 2008 Sony Computer Entertainment Inc.
-#  Copyright 2008 Sony Corp.
-#
-#  This program is free software; you can redistribute it and/or modify
-#  it under the terms of the GNU General Public License as published by
-#  the Free Software Foundation; version 2 of the License.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-#
-
-usage() {
-       echo "" >&2
-       echo "SYNOPSIS" >&2
-       echo "     bl-option [OPTION]" >&2
-       echo "" >&2
-       echo "DESCRIPTION" >&2
-       echo "     Get and set PS3 bootloader options in flash." >&2
-       echo "" >&2
-       echo "OPTIONS" >&2
-       echo "     -m, --get-video-mode" >&2
-       echo "             Get the bootloader video mode." >&2
-       echo "" >&2
-       echo "     -M, --set-video-mode value" >&2
-       echo "             Set the bootloader video mode." >&2
-       echo "" >&2
-       echo "     -p, --get-petitboot-default" >&2
-       echo "             Get the default Petitboot menu item." >&2
-       echo "" >&2
-       echo "     -P, --set-petitboot-default value" >&2
-       echo "             Set the default Petitboot menu item." >&2
-       echo "" >&2
-       echo "     -t, --get-telnet-enabled" >&2
-       echo "             Get the telnet enabled flag." >&2
-       echo "" >&2
-       echo "     -T, --set-telnet-enabled value" >&2
-       echo "             Set the telnet enabled flag." >&2
-       echo "" >&2
-       echo "     -h, --help" >&2
-       echo "             Print a help message." >&2
-       echo "" >&2
-       echo "SEE ALSO" >&2
-       echo "     ps3-flash-util(8)" >&2
-       echo "" >&2
-       exit 1
-}
-
-if [ "$#" -eq 0 ] ; then
-       echo "ERROR: bad arg" >&2;
-       usage
-fi
-
-get_flag() {
-       flags=`ps3-flash-util --db-print $1 $2`
-       echo $(( ${flags:-0} & $3 ))
-}
-
-set_flag() {
-       flags=`ps3-flash-util --db-print $1 $2`
-
-       if [ $4 -eq 0  ]; then
-               ps3-flash-util --db-write-half $1 $2 $(( ${flags:-0} & ~$3 ))
-       else
-               ps3-flash-util --db-write-half $1 $2 $(( ${flags:-0} | $3 ))
-       fi
-}
-
-# owners
-petitboot="3"
-
-# keys
-menu="1"
-video="2"
-flags="3"
-
-# flags
-telnet="1"
-
-case "$1" in
-       -m | --get-video-mode)
-               ps3-flash-util --db-print ${petitboot} ${video}
-               ;;
-       -M | --set-video-mode)
-               ps3-flash-util --db-write-half ${petitboot} ${video} $2
-               ;;
-       -p | --get-petitboot-default)
-               ps3-flash-util --db-print ${petitboot} ${menu}
-               ;;
-       -P | --set-petitboot-default)
-               ps3-flash-util --db-write-word ${petitboot} ${menu} $2
-               ;;
-       -t | --get-telnet-enabled)
-               get_flag ${petitboot} ${flags} ${telnet}
-               ;;
-       -T | --set-telnet-enabled)
-               set_flag ${petitboot} ${flags} ${telnet} $2
-               ;;
-       -h | --help)
-               usage
-               ;;
-       *)
-               echo "ERROR: bad arg $1" >&2;
-               usage
-               ;;
-esac
diff --git a/target/linux/ps3/base-files/sbin/initrun b/target/linux/ps3/base-files/sbin/initrun
deleted file mode 100755 (executable)
index e253c24..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-/bin/ash --login
diff --git a/target/linux/ps3/patches-2.6.27/001-perfmon-2.6.27.patch b/target/linux/ps3/patches-2.6.27/001-perfmon-2.6.27.patch
deleted file mode 100644 (file)
index 958416a..0000000
+++ /dev/null
@@ -1,31652 +0,0 @@
-diff --git a/Documentation/ABI/testing/sysfs-perfmon b/Documentation/ABI/testing/sysfs-perfmon
-new file mode 100644
-index 0000000..bde434c
---- /dev/null
-+++ b/Documentation/ABI/testing/sysfs-perfmon
-@@ -0,0 +1,87 @@
-+What:         /sys/kernel/perfmon
-+Date:         Nov 2007
-+KernelVersion:        2.6.24
-+Contact:      eranian@gmail.com
-+
-+Description:  provide the configuration interface for the perfmon2 subsystems.
-+              The tree contains information about the detected hardware, current
-+              state of the subsystem as well as some configuration parameters.
-+      
-+              The tree consists of the following entries:
-+
-+      /sys/kernel/perfmon/debug (read-write):
-+
-+              Enable perfmon2 debugging output via klogd. Debug messages produced during
-+              PMU interrupt handling are not controlled by this entry. The traces a rate-limited
-+              to avoid flooding of the console. It is possible to change the throttling
-+              via /proc/sys/kernel/printk_ratelimit. The value is interpreted as a bitmask.
-+              Each bit enables a particular type of debug messages. Refer to the file
-+              include/linux/perfmon_kern.h for more information
-+
-+      /sys/kernel/perfmon/pmc_max_fast_arg (read-only):
-+
-+              Number of perfmon2 syscall arguments copied directly onto the
-+              stack (copy_from_user) for pfm_write_pmcs(). Copying to the stack avoids
-+              having to allocate a buffer. The unit is the number of pfarg_pmc_t
-+              structures.
-+
-+      /sys/kernel/perfmon/pmd_max_fast_arg (read-only):
-+
-+              Number of perfmon2 syscall arguments copied directly onto the
-+              stack (copy_from_user) for pfm_write_pmds()/pfm_read_pmds(). Copying
-+              to the stack avoids having to allocate a buffer. The unit is the number
-+              of pfarg_pmd_t structures.
-+
-+
-+      /sys/kernel/perfmon/reset_stats (write-only):
-+
-+              Reset the statistics collected by perfmon2. Stats are available
-+              per-cpu via debugfs.
-+      
-+      /sys/kernel/perfmon/smpl_buffer_mem_cur (read-only):
-+
-+              Reports the amount of memory currently dedicated to sampling
-+              buffers by the kernel. The unit is byte.
-+
-+      /sys/kernel/perfmon/smpl_buffer_mem_max (read-write):
-+
-+              Maximum amount of kernel memory usable for sampling buffers. -1 means
-+              everything that is available. Unit is byte.
-+
-+      /sys/kernel/perfmon/smpl_buffer_mem_cur (read-only):
-+
-+              Current utilization of kernel memory in bytes.
-+
-+      /sys/kernel/perfmon/sys_group (read-write):
-+
-+              Users group allowed to create a system-wide perfmon2 context (session).
-+              -1 means any group. This control will be kept until we find a package
-+              able to control capabilities via PAM.
-+
-+      /sys/kernel/perfmon/task_group (read-write):
-+
-+              Users group allowed to create a per-thread context (session).
-+              -1 means any group. This control will be kept until we find a
-+              package able to control capabilities via PAM.
-+
-+      /sys/kernel/perfmon/sys_sessions_count (read-only):
-+
-+              Number of system-wide contexts currently attached to CPUs.
-+
-+      /sys/kernel/perfmon/task_sessions_count (read-only):
-+
-+              Number of per-thread contexts currently attached to threads.
-+
-+      /sys/kernel/perfmon/version (read-only):
-+
-+              Perfmon2 interface revision number.
-+
-+      /sys/kernel/perfmon/arg_mem_max(read-write):
-+
-+              Maximum size of vector arguments expressed in bytes. Can be modified
-+
-+      /sys/kernel/perfmon/mode(read-write):
-+
-+              Bitmask to enable/disable certain perfmon2 features.
-+              Currently defined:
-+              - bit 0: if set, then reserved bitfield are ignored on PMC writes
-diff --git a/Documentation/ABI/testing/sysfs-perfmon-fmt b/Documentation/ABI/testing/sysfs-perfmon-fmt
-new file mode 100644
-index 0000000..1b45270
---- /dev/null
-+++ b/Documentation/ABI/testing/sysfs-perfmon-fmt
-@@ -0,0 +1,18 @@
-+What:         /sys/kernel/perfmon/formats
-+Date:         2007
-+KernelVersion:        2.6.24
-+Contact:      eranian@gmail.com
-+
-+Description:  provide description of available perfmon2 custom sampling buffer formats
-+              which are implemented as independent kernel modules. Each formats gets
-+              a subdir which a few entries.
-+
-+              The name of the subdir is the name of the sampling format. The same name
-+              must be passed to pfm_create_context() to use the format.
-+
-+              Each subdir XX contains the following entries:
-+
-+      /sys/kernel/perfmon/formats/XX/version (read-only):
-+
-+              Version number of the format in clear text and null terminated.
-+
-diff --git a/Documentation/ABI/testing/sysfs-perfmon-pmu b/Documentation/ABI/testing/sysfs-perfmon-pmu
-new file mode 100644
-index 0000000..a1afc7e
---- /dev/null
-+++ b/Documentation/ABI/testing/sysfs-perfmon-pmu
-@@ -0,0 +1,46 @@
-+What:         /sys/kernel/perfmon/pmu
-+Date:         Nov 2007
-+KernelVersion:        2.6.24
-+Contact:      eranian@gmail.com
-+
-+Description:  provide information about the currently loaded PMU description module.
-+              The module contains the mapping of the actual performance counter registers
-+              onto the logical PMU exposed by perfmon.  There is at most one PMU description
-+              module loaded at any time.
-+
-+              The sysfs PMU tree provides a description of the mapping for each register.
-+              There is one subdir per config and data registers along an entry for the
-+              name of the PMU model.
-+
-+              The model entry is as follows:
-+
-+      /sys/kernel/perfmon/pmu_desc/model (read-only):
-+
-+              Name of the PMU model is clear text and zero terminated.
-+      
-+              Then for each logical PMU register, XX, gets a subtree with the following entries:
-+
-+      /sys/kernel/perfmon/pmu_desc/pm*XX/addr (read-only):
-+
-+              The physical address or index of the actual underlying hardware register.
-+              On Itanium, it corresponds to the index. But on X86 processor, this is
-+              the actual MSR address.
-+
-+      /sys/kernel/perfmon/pmu_desc/pm*XX/dfl_val (read-only):
-+
-+              The default value of the register in hexadecimal.
-+
-+      /sys/kernel/perfmon/pmu_desc/pm*XX/name (read-only):
-+
-+              The name of the hardware register.
-+
-+      /sys/kernel/perfmon/pmu_desc/pm*XX/rsvd_msk (read-only):
-+
-+              The bitmask of reserved bits, i.e., bits which cannot be changed by
-+              applications. When a bit is set, it means the corresponding bit in the
-+              actual register is reserved.
-+
-+      /sys/kernel/perfmon/pmu_desc/pm*XX/width (read-only):
-+
-+              the width in bits of the registers. This field is only relevant for counter
-+              registers.
-diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
-index 1150444..2652b6c 100644
---- a/Documentation/kernel-parameters.txt
-+++ b/Documentation/kernel-parameters.txt
-@@ -1643,6 +1643,9 @@ and is between 256 and 4096 characters. It is defined in the file
-                       Format: { 0 | 1 }
-                       See arch/parisc/kernel/pdc_chassis.c
-+      perfmon_debug   [PERFMON] Enables Perfmon debug messages. Needed
-+                      to see traces of the early startup startup phase.
-+
-       pf.             [PARIDE]
-                       See Documentation/paride.txt.
-diff --git a/Documentation/perfmon2-debugfs.txt b/Documentation/perfmon2-debugfs.txt
-new file mode 100644
-index 0000000..b30cae8
---- /dev/null
-+++ b/Documentation/perfmon2-debugfs.txt
-@@ -0,0 +1,126 @@
-+              The perfmon2 debug and statistics interface
-+                ------------------------------------------
-+                         Stephane Eranian
-+                        <eranian@gmail.com>
-+
-+The perfmon2 interfaces exports a set of statistics which are used to tune and
-+debug the implementation. The data is composed of a set of very simple metrics
-+mostly aggregated counts and durations. They instruments key points in the
-+perfmon2 code, such as context switch and interrupt handling.
-+
-+The data is accessible via the debug filesystem (debugfs). Thus you need to
-+have the filesystem support enabled in your kernel. Furthermore since, 2.6.25,
-+the perfmon2 statistics interface is an optional component. It needs to be
-+explicitely enabled in the kernel config file (CONFIG_PERFMON_DEBUG_FS).
-+
-+To access the data, the debugs filesystem must be mounted. Supposing the mount
-+point is /debugfs, you would need to do:
-+      $ mount -t debugs none /debugfs
-+
-+The data is located under the perfmon subdirectory and is organized per CPU.
-+For each CPU, the same set of metrics is available, one metric per file in
-+clear ASCII text.
-+
-+The metrics are as follows:
-+
-+      ctxswin_count (read-only):
-+      
-+              Number of PMU context switch in.
-+
-+      ctxswin_ns (read-only):
-+
-+              Number of nanoseconds spent in the PMU context switch in
-+              routine.  Dividing this number by the value of ctxswin_count,
-+              yields average cost of the PMU context switch in.
-+
-+      ctxswout_count (read-only):
-+
-+              Number of PMU context switch out.
-+
-+      ctxswout_ns (read-only):
-+
-+              Number of nanoseconds spent in the PMU context switch in
-+              routine. Dividing this number by the value of ctxswout_count,
-+              yields average cost of the PMU context switch out.
-+
-+      fmt_handler_calls (read-only):
-+
-+              Number of calls to the sampling format routine that handles
-+              PMU interrupts, i.e., typically the routine that records a
-+              sample.
-+
-+      fmt_handler_ns (read-only):
-+
-+              Number of nanoseconds spent in the routine that handle PMU
-+              interrupt in the sampling format. Dividing this number by
-+              the number of calls provided by fmt_handler_calls, yields
-+              average time spent in this routine.
-+
-+      ovfl_intr_all_count (read-only):
-+
-+              Number of PMU interrupts received by the kernel.
-+
-+
-+      ovfl_intr_nmi_count (read-only):
-+
-+              Number of Non Maskeable Interrupts (NMI) received by the kernel
-+              for perfmon. This is relevant only on X86 hardware.
-+      
-+      ovfl_intr_ns (read-only):
-+
-+              Number of nanoseconds spent in the perfmon2 PMU interrupt
-+              handler routine. Dividing this number of ovfl_intr_all_count
-+              yields the average time to handle one PMU interrupt.
-+
-+      ovfl_intr_regular_count (read-only):
-+
-+              Number of PMU interrupts which are actually processed by 
-+              the perfmon interrupt handler. There may be spurious or replay
-+              interrupts.
-+
-+      ovfl_intr_replay_count (read-only):
-+
-+              Number of PMU interrupts which were replayed on context switch  
-+              in or on event set switching. Interrupts get replayed when they
-+              were in flight at the time monitoring had to be stopped.
-+
-+      perfmon/ovfl_intr_spurious_count (read-only):
-+
-+              Number of PMU interrupts which were dropped because there was
-+              no active context (session).
-+
-+      ovfl_notify_count (read-only):
-+
-+              Number of user level notifications sent. Notifications are
-+              appended as messages to the context queue. Notifications may
-+              be sent on PMU interrupts.
-+
-+      pfm_restart_count (read-only):
-+
-+              Number of times pfm_restart() is called.
-+
-+      reset_pmds_count (read-only):
-+
-+              Number of times pfm_reset_pmds() is called.
-+
-+      set_switch_count (read-only):
-+
-+              Number of event set switches.
-+
-+      set_switch_ns (read-only):
-+
-+              Number of nanoseconds spent in the set switching routine.
-+              Dividing this number by set_switch_count yields the average
-+              cost of switching sets.
-+
-+      handle_timeout_count (read-only):
-+
-+              Number of times the pfm_handle_timeout() routine is called.
-+              It is used for timeout-based set switching.
-+
-+      handle_work_count (read-only):
-+
-+              Number of times pfm_handle_work() is called. The routine
-+              handles asynchronous perfmon2 work for per-thread contexts
-+              (sessions).
-+
-diff --git a/Documentation/perfmon2.txt b/Documentation/perfmon2.txt
-new file mode 100644
-index 0000000..4a8fada
---- /dev/null
-+++ b/Documentation/perfmon2.txt
-@@ -0,0 +1,213 @@
-+              The perfmon2 hardware monitoring interface
-+              ------------------------------------------
-+                         Stephane Eranian
-+                        <eranian@gmail.com>
-+
-+I/ Introduction
-+
-+   The perfmon2 interface provides access to the hardware performance counters of
-+   major processors. Nowadays, all processors implement some flavors of performance
-+   counters which capture micro-architectural level information such as the number
-+   of elapsed cycles, number of cache misses, and so on.
-+
-+   The interface is implemented as a set of new system calls and a set of config files
-+   in /sys.
-+
-+   It is possible to monitoring a single thread or a CPU. In either mode, applications
-+   can count or collect samples. System-wide monitoring is supported by running a
-+   monitoring session on each CPU. The interface support event-based sampling where the
-+   sampling period is expressed as the number of occurrences of event, instead of just a
-+   timeout.  This approach provides a much better granularity and flexibility.
-+
-+   For performance reason, it is possible to use a kernel-level sampling buffer to minimize
-+   the overhead incurred by sampling. The format of the buffer, i.e., what is recorded, how
-+   it is recorded, and how it is exported to user-land is controlled by a kernel module called
-+   a custom sampling format. The current implementation comes with a default format but
-+   it is possible to create additional formats. There is an in-kernel registration
-+   interface for formats. Each format is identified by a simple string which a tool
-+   can pass when a monitoring session is created.
-+
-+   The interface also provides support for event set and multiplexing to work around
-+   hardware limitations in the number of available counters or in how events can be 
-+   combined. Each set defines as many counters as the hardware can support. The kernel
-+   then multiplexes the sets. The interface supports time-base switching but also
-+   overflow based switching, i.e., after n overflows of designated counters.
-+
-+   Applications never manipulates the actual performance counter registers. Instead they see
-+   a logical Performance Monitoring Unit (PMU) composed of a set of config register (PMC)
-+   and a set of data registers (PMD). Note that PMD are not necessarily counters, they
-+   can be buffers. The logical PMU is then mapped onto the actual PMU using a mapping
-+   table which is implemented as a kernel module. The mapping is chosen once for each
-+   new processor. It is visible in /sys/kernel/perfmon/pmu_desc. The kernel module
-+   is automatically loaded on first use.
-+
-+   A monitoring session, or context, is uniquely identified by a file descriptor
-+   obtained when the context is created. File sharing semantics apply to access
-+   the context inside a process. A context is never inherited across fork. The file
-+   descriptor can be used to received counter overflow notifications or when the
-+   sampling buffer is full. It is possible to use poll/select on the descriptor 
-+   to wait for notifications from multiplex contexts. Similarly, the descriptor
-+   supports asynchronous notification via SIGIO.
-+
-+   Counters are always exported as being 64-bit wide regardless of what the underlying
-+   hardware implements.
-+
-+II/ Kernel compilation
-+
-+    To enable perfmon2, you need to enable CONFIG_PERFMON
-+
-+III/ OProfile interactions
-+
-+    The set of features offered by perfmon2 is rich enough to support migrating
-+    Oprofile on top of it. That means that PMU programming and low-level interrupt
-+    handling could be done by perfmon2. The Oprofile sampling buffer management code
-+    in the kernel as well as how samples are exported to users could remain through
-+    the use of a custom sampling buffer format. This is how Oprofile work on Itanium.
-+
-+    The current interactions with Oprofile are:
-+      - on X86: Both subsystems can be compiled into the same kernel. There is enforced
-+                mutual exclusion between the two subsystems. When there is an Oprofile
-+                session, no perfmon2 session can exist and vice-versa. Perfmon2 session
-+                encapsulates both per-thread and system-wide sessions here.
-+
-+      - On IA-64: Oprofile works on top of perfmon2. Oprofile being a system-wide monitoring
-+                  tool, the regular per-thread vs. system-wide session restrictions apply.
-+
-+      - on PPC: no integration yet. You need to enable/disble one of the two subsystems
-+      - on MIPS: no integration yet. You need to enable/disble one of the two subsystems
-+
-+IV/ User tools
-+
-+    We have released a simple monitoring tool to demonstrate the feature of the
-+    interface. The tool is called pfmon and it comes with a simple helper library
-+    called libpfm. The library comes with a set of examples to show how to use the
-+    kernel perfmon2 interface. Visit http://perfmon2.sf.net for details.
-+
-+    There maybe other tools available for perfmon2.
-+
-+V/ How to program?
-+
-+   The best way to learn how to program perfmon2, is to take a look at the source
-+   code for the examples in libpfm. The source code is available from:
-+              http://perfmon2.sf.net
-+
-+VI/ System calls overview
-+
-+   The interface is implemented by the following system calls:
-+
-+   * int pfm_create_context(pfarg_ctx_t *ctx, char *fmt, void *arg, size_t arg_size)
-+
-+      This function create a perfmon2 context. The type of context is per-thread by
-+      default unless PFM_FL_SYSTEM_WIDE is passed in ctx. The sampling format name
-+      is passed in fmt. Arguments to the format are passed in arg which is of size
-+      arg_size. Upon successful return, the file descriptor identifying the context
-+      is returned.
-+
-+   * int pfm_write_pmds(int fd, pfarg_pmd_t *pmds, int n)
-+   
-+      This function is used to program the PMD registers. It is possible to pass
-+      vectors of PMDs.
-+
-+   * int pfm_write_pmcs(int fd, pfarg_pmc_t *pmds, int n)
-+   
-+      This function is used to program the PMC registers. It is possible to pass
-+      vectors of PMDs.
-+
-+   * int pfm_read_pmds(int fd, pfarg_pmd_t *pmds, int n)
-+   
-+      This function is used to read the PMD registers. It is possible to pass
-+      vectors of PMDs.
-+
-+   * int pfm_load_context(int fd, pfarg_load_t *load)
-+   
-+      This function is used to attach the context to a thread or CPU.
-+      Thread means kernel-visible thread (NPTL). The thread identification
-+      as obtained by gettid must be passed to load->load_target.
-+
-+      To operate on another thread (not self), it is mandatory that the thread
-+      be stopped via ptrace().
-+
-+      To attach to a CPU, the CPU number must be specified in load->load_target
-+      AND the call must be issued on that CPU. To monitor a CPU, a thread MUST
-+      be pinned on that CPU.
-+
-+      Until the context is attached, the actual counters are not accessed.
-+
-+   * int pfm_unload_context(int fd)
-+
-+     The context is detached for the thread or CPU is was attached to.
-+     As a consequence monitoring is stopped.
-+
-+     When monitoring another thread, the thread MUST be stopped via ptrace()
-+     for this function to succeed.
-+
-+   * int pfm_start(int fd, pfarg_start_t *st)
-+
-+     Start monitoring. The context must be attached for this function to succeed.
-+     Optionally, it is possible to specify the event set on which to start using the
-+     st argument, otherwise just pass NULL.
-+
-+     When monitoring another thread, the thread MUST be stopped via ptrace()
-+     for this function to succeed.
-+
-+   * int pfm_stop(int fd)
-+
-+     Stop monitoring. The context must be attached for this function to succeed.
-+
-+     When monitoring another thread, the thread MUST be stopped via ptrace()
-+     for this function to succeed.
-+
-+
-+   * int pfm_create_evtsets(int fd, pfarg_setdesc_t *sets, int n)
-+
-+     This function is used to create or change event sets. By default set 0 exists.
-+     It is possible to create/change multiple sets in one call.
-+
-+     The context must be detached for this call to succeed.
-+
-+     Sets are identified by a 16-bit integer. They are sorted based on this
-+     set and switching occurs in a round-robin fashion.
-+
-+   * int pfm_delete_evtsets(int fd, pfarg_setdesc_t *sets, int n)
-+   
-+     Delete event sets. The context must be detached for this call to succeed.
-+
-+
-+   * int pfm_getinfo_evtsets(int fd, pfarg_setinfo_t *sets, int n)
-+
-+     Retrieve information about event sets. In particular it is possible
-+     to get the number of activation of a set. It is possible to retrieve
-+     information about multiple sets in one call.
-+
-+
-+   * int pfm_restart(int fd)
-+
-+     Indicate to the kernel that the application is done processing an overflow
-+     notification. A consequence of this call could be that monitoring resumes.
-+
-+   * int read(fd, pfm_msg_t *msg, sizeof(pfm_msg_t))
-+
-+   the regular read() system call can be used with the context file descriptor to
-+   receive overflow notification messages. Non-blocking read() is supported.
-+
-+   Each message carry information about the overflow such as which counter overflowed
-+   and where the program was (interrupted instruction pointer).
-+
-+   * int close(int fd)
-+
-+   To destroy a context, the regular close() system call is used.
-+
-+
-+VII/ /sys interface overview
-+
-+   Refer to Documentation/ABI/testing/sysfs-perfmon-* for a detailed description
-+   of the sysfs interface of perfmon2.
-+
-+VIII/ debugfs interface overview
-+
-+  Refer to Documentation/perfmon2-debugfs.txt for a detailed description of the
-+  debug and statistics interface of perfmon2.
-+
-+IX/ Documentation
-+
-+   Visit http://perfmon2.sf.net
-diff --git a/MAINTAINERS b/MAINTAINERS
-index 8dae455..fb38c2a 100644
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -3239,6 +3239,14 @@ M:      balbir@linux.vnet.ibm.com
- L:    linux-kernel@vger.kernel.org
- S:    Maintained
-+PERFMON SUBSYSTEM
-+P:    Stephane Eranian
-+M:    eranian@gmail.com
-+L:    perfmon2-devel@lists.sf.net
-+W:    http://perfmon2.sf.net
-+T:    git kernel.org:/pub/scm/linux/kernel/git/eranian/linux-2.6
-+S:    Maintained
-+
- PERSONALITY HANDLING
- P:    Christoph Hellwig
- M:    hch@infradead.org
-diff --git a/Makefile b/Makefile
-index 16e3fbb..7bb1320 100644
---- a/Makefile
-+++ b/Makefile
-@@ -620,6 +620,7 @@ export mod_strip_cmd
- ifeq ($(KBUILD_EXTMOD),)
- core-y                += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
-+core-$(CONFIG_PERFMON) += perfmon/
- vmlinux-dirs  := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
-                    $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
-diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
-index 48e496f..1d79b01 100644
---- a/arch/ia64/Kconfig
-+++ b/arch/ia64/Kconfig
-@@ -470,14 +470,6 @@ config COMPAT_FOR_U64_ALIGNMENT
- config IA64_MCA_RECOVERY
-       tristate "MCA recovery from errors other than TLB."
--config PERFMON
--      bool "Performance monitor support"
--      help
--        Selects whether support for the IA-64 performance monitor hardware
--        is included in the kernel.  This makes some kernel data-structures a
--        little bigger and slows down execution a bit, but it is generally
--        a good idea to turn this on.  If you're unsure, say Y.
--
- config IA64_PALINFO
-       tristate "/proc/pal support"
-       help
-@@ -549,6 +541,8 @@ source "drivers/firmware/Kconfig"
- source "fs/Kconfig.binfmt"
-+source "arch/ia64/perfmon/Kconfig"
-+
- endmenu
- menu "Power management and ACPI"
-diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile
-index 905d25b..9aa622d 100644
---- a/arch/ia64/Makefile
-+++ b/arch/ia64/Makefile
-@@ -57,6 +57,7 @@ core-$(CONFIG_IA64_GENERIC)  += arch/ia64/dig/
- core-$(CONFIG_IA64_HP_ZX1)    += arch/ia64/dig/
- core-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/dig/
- core-$(CONFIG_IA64_SGI_SN2)   += arch/ia64/sn/
-+core-$(CONFIG_PERFMON)                += arch/ia64/perfmon/
- core-$(CONFIG_IA64_SGI_UV)    += arch/ia64/uv/
- core-$(CONFIG_KVM)            += arch/ia64/kvm/
-diff --git a/arch/ia64/configs/generic_defconfig b/arch/ia64/configs/generic_defconfig
-index 9f48397..ff9572a 100644
---- a/arch/ia64/configs/generic_defconfig
-+++ b/arch/ia64/configs/generic_defconfig
-@@ -209,7 +209,6 @@ CONFIG_IA32_SUPPORT=y
- CONFIG_COMPAT=y
- CONFIG_COMPAT_FOR_U64_ALIGNMENT=y
- CONFIG_IA64_MCA_RECOVERY=y
--CONFIG_PERFMON=y
- CONFIG_IA64_PALINFO=y
- # CONFIG_IA64_MC_ERR_INJECT is not set
- CONFIG_SGI_SN=y
-@@ -234,6 +233,16 @@ CONFIG_BINFMT_ELF=y
- CONFIG_BINFMT_MISC=m
- #
-+# Hardware Performance Monitoring support
-+#
-+CONFIG_PERFMON=y
-+CONFIG_IA64_PERFMON_COMPAT=y
-+CONFIG_IA64_PERFMON_GENERIC=m
-+CONFIG_IA64_PERFMON_ITANIUM=y
-+CONFIG_IA64_PERFMON_MCKINLEY=y
-+CONFIG_IA64_PERFMON_MONTECITO=y
-+
-+#
- # Power management and ACPI
- #
- CONFIG_PM=y
-diff --git a/arch/ia64/include/asm/Kbuild b/arch/ia64/include/asm/Kbuild
-index ccbe8ae..cf64b3b 100644
---- a/arch/ia64/include/asm/Kbuild
-+++ b/arch/ia64/include/asm/Kbuild
-@@ -5,10 +5,12 @@ header-y += fpu.h
- header-y += fpswa.h
- header-y += ia64regs.h
- header-y += intel_intrin.h
--header-y += perfmon_default_smpl.h
- header-y += ptrace_offsets.h
- header-y += rse.h
- header-y += ucontext.h
-+header-y += perfmon.h
-+header-y += perfmon_compat.h
-+header-y += perfmon_default_smpl.h
- unifdef-y += gcc_intrin.h
- unifdef-y += intrinsics.h
-diff --git a/arch/ia64/include/asm/hw_irq.h b/arch/ia64/include/asm/hw_irq.h
-index 5c99cbc..4a45cb0 100644
---- a/arch/ia64/include/asm/hw_irq.h
-+++ b/arch/ia64/include/asm/hw_irq.h
-@@ -67,9 +67,9 @@ extern int ia64_last_device_vector;
- #define IA64_NUM_DEVICE_VECTORS               (IA64_LAST_DEVICE_VECTOR - IA64_FIRST_DEVICE_VECTOR + 1)
- #define IA64_MCA_RENDEZ_VECTOR                0xe8    /* MCA rendez interrupt */
--#define IA64_PERFMON_VECTOR           0xee    /* performance monitor interrupt vector */
- #define IA64_TIMER_VECTOR             0xef    /* use highest-prio group 15 interrupt for timer */
- #define       IA64_MCA_WAKEUP_VECTOR          0xf0    /* MCA wakeup (must be >MCA_RENDEZ_VECTOR) */
-+#define IA64_PERFMON_VECTOR           0xf1    /* performance monitor interrupt vector */
- #define IA64_IPI_LOCAL_TLB_FLUSH      0xfc    /* SMP flush local TLB */
- #define IA64_IPI_RESCHEDULE           0xfd    /* SMP reschedule */
- #define IA64_IPI_VECTOR                       0xfe    /* inter-processor interrupt vector */
-diff --git a/arch/ia64/include/asm/perfmon.h b/arch/ia64/include/asm/perfmon.h
-index 7f3333d..150c4b4 100644
---- a/arch/ia64/include/asm/perfmon.h
-+++ b/arch/ia64/include/asm/perfmon.h
-@@ -1,279 +1,59 @@
- /*
-- * Copyright (C) 2001-2003 Hewlett-Packard Co
-- *               Stephane Eranian <eranian@hpl.hp.com>
-- */
--
--#ifndef _ASM_IA64_PERFMON_H
--#define _ASM_IA64_PERFMON_H
--
--/*
-- * perfmon comamnds supported on all CPU models
-- */
--#define PFM_WRITE_PMCS                0x01
--#define PFM_WRITE_PMDS                0x02
--#define PFM_READ_PMDS         0x03
--#define PFM_STOP              0x04
--#define PFM_START             0x05
--#define PFM_ENABLE            0x06 /* obsolete */
--#define PFM_DISABLE           0x07 /* obsolete */
--#define PFM_CREATE_CONTEXT    0x08
--#define PFM_DESTROY_CONTEXT   0x09 /* obsolete use close() */
--#define PFM_RESTART           0x0a
--#define PFM_PROTECT_CONTEXT   0x0b /* obsolete */
--#define PFM_GET_FEATURES      0x0c
--#define PFM_DEBUG             0x0d
--#define PFM_UNPROTECT_CONTEXT 0x0e /* obsolete */
--#define PFM_GET_PMC_RESET_VAL 0x0f
--#define PFM_LOAD_CONTEXT      0x10
--#define PFM_UNLOAD_CONTEXT    0x11
--
--/*
-- * PMU model specific commands (may not be supported on all PMU models)
-- */
--#define PFM_WRITE_IBRS                0x20
--#define PFM_WRITE_DBRS                0x21
--
--/*
-- * context flags
-- */
--#define PFM_FL_NOTIFY_BLOCK            0x01   /* block task on user level notifications */
--#define PFM_FL_SYSTEM_WIDE     0x02   /* create a system wide context */
--#define PFM_FL_OVFL_NO_MSG     0x80   /* do not post overflow/end messages for notification */
--
--/*
-- * event set flags
-- */
--#define PFM_SETFL_EXCL_IDLE      0x01   /* exclude idle task (syswide only) XXX: DO NOT USE YET */
--
--/*
-- * PMC flags
-- */
--#define PFM_REGFL_OVFL_NOTIFY 0x1     /* send notification on overflow */
--#define PFM_REGFL_RANDOM      0x2     /* randomize sampling interval   */
--
--/*
-- * PMD/PMC/IBR/DBR return flags (ignored on input)
-+ * Copyright (c) 2001-2007 Hewlett-Packard Development Company, L.P.
-+ * Contributed by Stephane Eranian <eranian@hpl.hp.com>
-  *
-- * Those flags are used on output and must be checked in case EAGAIN is returned
-- * by any of the calls using a pfarg_reg_t or pfarg_dbreg_t structure.
-- */
--#define PFM_REG_RETFL_NOTAVAIL        (1UL<<31) /* set if register is implemented but not available */
--#define PFM_REG_RETFL_EINVAL  (1UL<<30) /* set if register entry is invalid */
--#define PFM_REG_RETFL_MASK    (PFM_REG_RETFL_NOTAVAIL|PFM_REG_RETFL_EINVAL)
--
--#define PFM_REG_HAS_ERROR(flag)       (((flag) & PFM_REG_RETFL_MASK) != 0)
--
--typedef unsigned char pfm_uuid_t[16]; /* custom sampling buffer identifier type */
--
--/*
-- * Request structure used to define a context
-- */
--typedef struct {
--      pfm_uuid_t     ctx_smpl_buf_id;  /* which buffer format to use (if needed) */
--      unsigned long  ctx_flags;        /* noblock/block */
--      unsigned short ctx_nextra_sets;  /* number of extra event sets (you always get 1) */
--      unsigned short ctx_reserved1;    /* for future use */
--      int            ctx_fd;           /* return arg: unique identification for context */
--      void           *ctx_smpl_vaddr;  /* return arg: virtual address of sampling buffer, is used */
--      unsigned long  ctx_reserved2[11];/* for future use */
--} pfarg_context_t;
--
--/*
-- * Request structure used to write/read a PMC or PMD
-- */
--typedef struct {
--      unsigned int    reg_num;           /* which register */
--      unsigned short  reg_set;           /* event set for this register */
--      unsigned short  reg_reserved1;     /* for future use */
--
--      unsigned long   reg_value;         /* initial pmc/pmd value */
--      unsigned long   reg_flags;         /* input: pmc/pmd flags, return: reg error */
--
--      unsigned long   reg_long_reset;    /* reset after buffer overflow notification */
--      unsigned long   reg_short_reset;   /* reset after counter overflow */
--
--      unsigned long   reg_reset_pmds[4]; /* which other counters to reset on overflow */
--      unsigned long   reg_random_seed;   /* seed value when randomization is used */
--      unsigned long   reg_random_mask;   /* bitmask used to limit random value */
--      unsigned long   reg_last_reset_val;/* return: PMD last reset value */
--
--      unsigned long   reg_smpl_pmds[4];  /* which pmds are accessed when PMC overflows */
--      unsigned long   reg_smpl_eventid;  /* opaque sampling event identifier */
--
--      unsigned long   reg_reserved2[3];   /* for future use */
--} pfarg_reg_t;
--
--typedef struct {
--      unsigned int    dbreg_num;              /* which debug register */
--      unsigned short  dbreg_set;              /* event set for this register */
--      unsigned short  dbreg_reserved1;        /* for future use */
--      unsigned long   dbreg_value;            /* value for debug register */
--      unsigned long   dbreg_flags;            /* return: dbreg error */
--      unsigned long   dbreg_reserved2[1];     /* for future use */
--} pfarg_dbreg_t;
--
--typedef struct {
--      unsigned int    ft_version;     /* perfmon: major [16-31], minor [0-15] */
--      unsigned int    ft_reserved;    /* reserved for future use */
--      unsigned long   reserved[4];    /* for future use */
--} pfarg_features_t;
--
--typedef struct {
--      pid_t           load_pid;          /* process to load the context into */
--      unsigned short  load_set;          /* first event set to load */
--      unsigned short  load_reserved1;    /* for future use */
--      unsigned long   load_reserved2[3]; /* for future use */
--} pfarg_load_t;
--
--typedef struct {
--      int             msg_type;               /* generic message header */
--      int             msg_ctx_fd;             /* generic message header */
--      unsigned long   msg_ovfl_pmds[4];       /* which PMDs overflowed */
--      unsigned short  msg_active_set;         /* active set at the time of overflow */
--      unsigned short  msg_reserved1;          /* for future use */
--      unsigned int    msg_reserved2;          /* for future use */
--      unsigned long   msg_tstamp;             /* for perf tuning/debug */
--} pfm_ovfl_msg_t;
--
--typedef struct {
--      int             msg_type;               /* generic message header */
--      int             msg_ctx_fd;             /* generic message header */
--      unsigned long   msg_tstamp;             /* for perf tuning */
--} pfm_end_msg_t;
--
--typedef struct {
--      int             msg_type;               /* type of the message */
--      int             msg_ctx_fd;             /* unique identifier for the context */
--      unsigned long   msg_tstamp;             /* for perf tuning */
--} pfm_gen_msg_t;
--
--#define PFM_MSG_OVFL  1       /* an overflow happened */
--#define PFM_MSG_END   2       /* task to which context was attached ended */
--
--typedef union {
--      pfm_ovfl_msg_t  pfm_ovfl_msg;
--      pfm_end_msg_t   pfm_end_msg;
--      pfm_gen_msg_t   pfm_gen_msg;
--} pfm_msg_t;
--
--/*
-- * Define the version numbers for both perfmon as a whole and the sampling buffer format.
-+ * This file contains Itanium Processor Family specific definitions
-+ * for the perfmon interface.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of version 2 of the GNU General Public
-+ * License as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ * 02111-1307 USA
-  */
--#define PFM_VERSION_MAJ                2U
--#define PFM_VERSION_MIN                0U
--#define PFM_VERSION            (((PFM_VERSION_MAJ&0xffff)<<16)|(PFM_VERSION_MIN & 0xffff))
--#define PFM_VERSION_MAJOR(x)   (((x)>>16) & 0xffff)
--#define PFM_VERSION_MINOR(x)   ((x) & 0xffff)
--
-+#ifndef _ASM_IA64_PERFMON_H_
-+#define _ASM_IA64_PERFMON_H_
- /*
-- * miscellaneous architected definitions
-+ * arch-specific user visible interface definitions
-  */
--#define PMU_FIRST_COUNTER     4       /* first counting monitor (PMC/PMD) */
--#define PMU_MAX_PMCS          256     /* maximum architected number of PMC registers */
--#define PMU_MAX_PMDS          256     /* maximum architected number of PMD registers */
--
--#ifdef __KERNEL__
--
--extern long perfmonctl(int fd, int cmd, void *arg, int narg);
--
--typedef struct {
--      void (*handler)(int irq, void *arg, struct pt_regs *regs);
--} pfm_intr_handler_desc_t;
--
--extern void pfm_save_regs (struct task_struct *);
--extern void pfm_load_regs (struct task_struct *);
--extern void pfm_exit_thread(struct task_struct *);
--extern int  pfm_use_debug_registers(struct task_struct *);
--extern int  pfm_release_debug_registers(struct task_struct *);
--extern void pfm_syst_wide_update_task(struct task_struct *, unsigned long info, int is_ctxswin);
--extern void pfm_inherit(struct task_struct *task, struct pt_regs *regs);
--extern void pfm_init_percpu(void);
--extern void pfm_handle_work(void);
--extern int  pfm_install_alt_pmu_interrupt(pfm_intr_handler_desc_t *h);
--extern int  pfm_remove_alt_pmu_interrupt(pfm_intr_handler_desc_t *h);
-+#define PFM_ARCH_MAX_PMCS     (256+64)
-+#define PFM_ARCH_MAX_PMDS     (256+64)
--
--
--/*
-- * Reset PMD register flags
-- */
--#define PFM_PMD_SHORT_RESET   0
--#define PFM_PMD_LONG_RESET    1
--
--typedef union {
--      unsigned int val;
--      struct {
--              unsigned int notify_user:1;     /* notify user program of overflow */
--              unsigned int reset_ovfl_pmds:1; /* reset overflowed PMDs */
--              unsigned int block_task:1;      /* block monitored task on kernel exit */
--              unsigned int mask_monitoring:1; /* mask monitors via PMCx.plm */
--              unsigned int reserved:28;       /* for future use */
--      } bits;
--} pfm_ovfl_ctrl_t;
--
--typedef struct {
--      unsigned char   ovfl_pmd;                       /* index of overflowed PMD  */
--      unsigned char   ovfl_notify;                    /* =1 if monitor requested overflow notification */
--      unsigned short  active_set;                     /* event set active at the time of the overflow */
--      pfm_ovfl_ctrl_t ovfl_ctrl;                      /* return: perfmon controls to set by handler */
--
--      unsigned long   pmd_last_reset;                 /* last reset value of of the PMD */
--      unsigned long   smpl_pmds[4];                   /* bitmask of other PMD of interest on overflow */
--      unsigned long   smpl_pmds_values[PMU_MAX_PMDS]; /* values for the other PMDs of interest */
--      unsigned long   pmd_value;                      /* current 64-bit value of the PMD */
--      unsigned long   pmd_eventid;                    /* eventid associated with PMD */
--} pfm_ovfl_arg_t;
--
--
--typedef struct {
--      char            *fmt_name;
--      pfm_uuid_t      fmt_uuid;
--      size_t          fmt_arg_size;
--      unsigned long   fmt_flags;
--
--      int             (*fmt_validate)(struct task_struct *task, unsigned int flags, int cpu, void *arg);
--      int             (*fmt_getsize)(struct task_struct *task, unsigned int flags, int cpu, void *arg, unsigned long *size);
--      int             (*fmt_init)(struct task_struct *task, void *buf, unsigned int flags, int cpu, void *arg);
--      int             (*fmt_handler)(struct task_struct *task, void *buf, pfm_ovfl_arg_t *arg, struct pt_regs *regs, unsigned long stamp);
--      int             (*fmt_restart)(struct task_struct *task, pfm_ovfl_ctrl_t *ctrl, void *buf, struct pt_regs *regs);
--      int             (*fmt_restart_active)(struct task_struct *task, pfm_ovfl_ctrl_t *ctrl, void *buf, struct pt_regs *regs);
--      int             (*fmt_exit)(struct task_struct *task, void *buf, struct pt_regs *regs);
--
--      struct list_head fmt_list;
--} pfm_buffer_fmt_t;
--
--extern int pfm_register_buffer_fmt(pfm_buffer_fmt_t *fmt);
--extern int pfm_unregister_buffer_fmt(pfm_uuid_t uuid);
-+#define PFM_ARCH_PMD_STK_ARG  8
-+#define PFM_ARCH_PMC_STK_ARG  8
- /*
-- * perfmon interface exported to modules
-+ * Itanium specific context flags
-+ *
-+ * bits[00-15]: generic flags (see asm/perfmon.h)
-+ * bits[16-31]: arch-specific flags
-  */
--extern int pfm_mod_read_pmds(struct task_struct *, void *req, unsigned int nreq, struct pt_regs *regs);
--extern int pfm_mod_write_pmcs(struct task_struct *, void *req, unsigned int nreq, struct pt_regs *regs);
--extern int pfm_mod_write_ibrs(struct task_struct *task, void *req, unsigned int nreq, struct pt_regs *regs);
--extern int pfm_mod_write_dbrs(struct task_struct *task, void *req, unsigned int nreq, struct pt_regs *regs);
-+#define PFM_ITA_FL_INSECURE 0x10000 /* clear psr.sp on non system, non self */
- /*
-- * describe the content of the local_cpu_date->pfm_syst_info field
-+ * Itanium specific public event set flags (set_flags)
-+ *
-+ * event set flags layout:
-+ * bits[00-15] : generic flags
-+ * bits[16-31] : arch-specific flags
-  */
--#define PFM_CPUINFO_SYST_WIDE 0x1     /* if set a system wide session exists */
--#define PFM_CPUINFO_DCR_PP    0x2     /* if set the system wide session has started */
--#define PFM_CPUINFO_EXCL_IDLE 0x4     /* the system wide session excludes the idle task */
-+#define PFM_ITA_SETFL_EXCL_INTR       0x10000  /* exclude interrupt execution */
-+#define PFM_ITA_SETFL_INTR_ONLY       0x20000  /* include only interrupt execution */
-+#define PFM_ITA_SETFL_IDLE_EXCL 0x40000  /* stop monitoring in idle loop */
- /*
-- * sysctl control structure. visible to sampling formats
-+ * compatibility for version v2.0 of the interface
-  */
--typedef struct {
--      int     debug;          /* turn on/off debugging via syslog */
--      int     debug_ovfl;     /* turn on/off debug printk in overflow handler */
--      int     fastctxsw;      /* turn on/off fast (unsecure) ctxsw */
--      int     expert_mode;    /* turn on/off value checking */
--} pfm_sysctl_t;
--extern pfm_sysctl_t pfm_sysctl;
--
--
--#endif /* __KERNEL__ */
-+#include <asm/perfmon_compat.h>
--#endif /* _ASM_IA64_PERFMON_H */
-+#endif /* _ASM_IA64_PERFMON_H_ */
-diff --git a/arch/ia64/include/asm/perfmon_compat.h b/arch/ia64/include/asm/perfmon_compat.h
-new file mode 100644
-index 0000000..5c14514
---- /dev/null
-+++ b/arch/ia64/include/asm/perfmon_compat.h
-@@ -0,0 +1,167 @@
-+/*
-+ * Copyright (c) 2001-2006 Hewlett-Packard Development Company, L.P.
-+ * Contributed by Stephane Eranian <eranian@hpl.hp.com>
-+ *
-+ * This header file contains perfmon interface definition
-+ * that are now obsolete and should be dropped in favor
-+ * of their equivalent functions as explained below.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of version 2 of the GNU General Public
-+ * License as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ * 02111-1307 USA
-+  */
-+
-+#ifndef _ASM_IA64_PERFMON_COMPAT_H_
-+#define _ASM_IA64_PERFMON_COMPAT_H_
-+
-+/*
-+ * custom sampling buffer identifier type
-+ */
-+typedef __u8 pfm_uuid_t[16];
-+
-+/*
-+ * obsolete perfmon commands. Supported only on IA-64 for
-+ * backward compatiblity reasons with perfmon v2.0.
-+ */
-+#define PFM_WRITE_PMCS                0x01 /* use pfm_write_pmcs */
-+#define PFM_WRITE_PMDS                0x02 /* use pfm_write_pmds */
-+#define PFM_READ_PMDS         0x03 /* use pfm_read_pmds */
-+#define PFM_STOP              0x04 /* use pfm_stop */
-+#define PFM_START             0x05 /* use pfm_start */
-+#define PFM_ENABLE            0x06 /* obsolete */
-+#define PFM_DISABLE           0x07 /* obsolete */
-+#define PFM_CREATE_CONTEXT    0x08 /* use pfm_create_context */
-+#define PFM_DESTROY_CONTEXT   0x09 /* use close() */
-+#define PFM_RESTART           0x0a /* use pfm_restart */
-+#define PFM_PROTECT_CONTEXT   0x0b /* obsolete */
-+#define PFM_GET_FEATURES      0x0c /* use /proc/sys/perfmon */
-+#define PFM_DEBUG             0x0d /* /proc/sys/kernel/perfmon/debug */
-+#define PFM_UNPROTECT_CONTEXT 0x0e /* obsolete */
-+#define PFM_GET_PMC_RESET_VAL 0x0f /* use /proc/perfmon_map */
-+#define PFM_LOAD_CONTEXT      0x10 /* use pfm_load_context */
-+#define PFM_UNLOAD_CONTEXT    0x11 /* use pfm_unload_context */
-+
-+/*
-+ * PMU model specific commands (may not be supported on all PMU models)
-+ */
-+#define PFM_WRITE_IBRS                0x20 /* obsolete: use PFM_WRITE_PMCS[256-263]*/
-+#define PFM_WRITE_DBRS                0x21 /* obsolete: use PFM_WRITE_PMCS[264-271]*/
-+
-+/*
-+ * argument to PFM_CREATE_CONTEXT
-+ */
-+struct pfarg_context {
-+      pfm_uuid_t     ctx_smpl_buf_id;  /* buffer format to use */
-+      unsigned long  ctx_flags;        /* noblock/block */
-+      unsigned int   ctx_reserved1;    /* for future use */
-+      int            ctx_fd;           /* return: fildesc */
-+      void           *ctx_smpl_vaddr;  /* return: vaddr of buffer */
-+      unsigned long  ctx_reserved3[11];/* for future use */
-+};
-+
-+/*
-+ * argument structure for PFM_WRITE_PMCS/PFM_WRITE_PMDS/PFM_WRITE_PMDS
-+ */
-+struct pfarg_reg {
-+      unsigned int    reg_num;           /* which register */
-+      unsigned short  reg_set;           /* event set for this register */
-+      unsigned short  reg_reserved1;     /* for future use */
-+
-+      unsigned long   reg_value;         /* initial pmc/pmd value */
-+      unsigned long   reg_flags;         /* input: flags, ret: error */
-+
-+      unsigned long   reg_long_reset;    /* reset value after notification */
-+      unsigned long   reg_short_reset;   /* reset after counter overflow */
-+
-+      unsigned long   reg_reset_pmds[4]; /* registers to reset on overflow */
-+      unsigned long   reg_random_seed;   /* seed for randomization */
-+      unsigned long   reg_random_mask;   /* random range limit */
-+      unsigned long   reg_last_reset_val;/* return: PMD last reset value */
-+
-+      unsigned long   reg_smpl_pmds[4];  /* pmds to be saved on overflow */
-+      unsigned long   reg_smpl_eventid;  /* opaque sampling event id */
-+      unsigned long   reg_ovfl_switch_cnt;/* #overflows to switch */
-+
-+      unsigned long   reg_reserved2[2];   /* for future use */
-+};
-+
-+/*
-+ * argument to PFM_WRITE_IBRS/PFM_WRITE_DBRS
-+ */
-+struct pfarg_dbreg {
-+      unsigned int    dbreg_num;              /* which debug register */
-+      unsigned short  dbreg_set;              /* event set */
-+      unsigned short  dbreg_reserved1;        /* for future use */
-+      unsigned long   dbreg_value;            /* value for debug register */
-+      unsigned long   dbreg_flags;            /* return: dbreg error */
-+      unsigned long   dbreg_reserved2[1];     /* for future use */
-+};
-+
-+/*
-+ * argument to PFM_GET_FEATURES
-+ */
-+struct pfarg_features {
-+      unsigned int    ft_version;     /* major [16-31], minor [0-15] */
-+      unsigned int    ft_reserved;    /* reserved for future use */
-+      unsigned long   reserved[4];    /* for future use */
-+};
-+
-+typedef struct {
-+      int             msg_type;               /* generic message header */
-+      int             msg_ctx_fd;             /* generic message header */
-+      unsigned long   msg_ovfl_pmds[4];       /* which PMDs overflowed */
-+      unsigned short  msg_active_set;         /* active set on overflow */
-+      unsigned short  msg_reserved1;          /* for future use */
-+      unsigned int    msg_reserved2;          /* for future use */
-+      unsigned long   msg_tstamp;             /* for perf tuning/debug */
-+} pfm_ovfl_msg_t;
-+
-+typedef struct {
-+      int             msg_type;               /* generic message header */
-+      int             msg_ctx_fd;             /* generic message header */
-+      unsigned long   msg_tstamp;             /* for perf tuning */
-+} pfm_end_msg_t;
-+
-+typedef struct {
-+      int             msg_type;               /* type of the message */
-+      int             msg_ctx_fd;             /* context file descriptor */
-+      unsigned long   msg_tstamp;             /* for perf tuning */
-+} pfm_gen_msg_t;
-+
-+typedef union {
-+      int type;
-+      pfm_ovfl_msg_t  pfm_ovfl_msg;
-+      pfm_end_msg_t   pfm_end_msg;
-+      pfm_gen_msg_t   pfm_gen_msg;
-+} pfm_msg_t;
-+
-+/*
-+ * PMD/PMC return flags in case of error (ignored on input)
-+ *
-+ * reg_flags layout:
-+ * bit 00-15 : generic flags
-+ * bits[16-23] : arch-specific flags (see asm/perfmon.h)
-+ * bit 24-31 : error codes
-+ *
-+ * Those flags are used on output and must be checked in case EINVAL is
-+ * returned by a command accepting a vector of values and each has a flag
-+ * field, such as pfarg_reg or pfarg_reg
-+ */
-+#define PFM_REG_RETFL_NOTAVAIL        (1<<31) /* not implemented or unaccessible */
-+#define PFM_REG_RETFL_EINVAL  (1<<30) /* entry is invalid */
-+#define PFM_REG_RETFL_MASK    (PFM_REG_RETFL_NOTAVAIL|\
-+                               PFM_REG_RETFL_EINVAL)
-+
-+#define PFM_REG_HAS_ERROR(flag)       (((flag) & PFM_REG_RETFL_MASK) != 0)
-+
-+#endif /* _ASM_IA64_PERFMON_COMPAT_H_ */
-diff --git a/arch/ia64/include/asm/perfmon_default_smpl.h b/arch/ia64/include/asm/perfmon_default_smpl.h
-index 48822c0..8234f32 100644
---- a/arch/ia64/include/asm/perfmon_default_smpl.h
-+++ b/arch/ia64/include/asm/perfmon_default_smpl.h
-@@ -1,83 +1,106 @@
- /*
-- * Copyright (C) 2002-2003 Hewlett-Packard Co
-- *               Stephane Eranian <eranian@hpl.hp.com>
-+ * Copyright (c) 2002-2006 Hewlett-Packard Development Company, L.P.
-+ * Contributed by Stephane Eranian <eranian@hpl.hp.com>
-  *
-- * This file implements the default sampling buffer format
-- * for Linux/ia64 perfmon subsystem.
-+ * This file implements the old default sampling buffer format
-+ * for the perfmon2 subsystem. For IA-64 only.
-+ *
-+ * It requires the use of the perfmon_compat.h header. It is recommended
-+ * that applications be ported to the new format instead.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of version 2 of the GNU General Public
-+ * License as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ * 02111-1307 USA
-  */
--#ifndef __PERFMON_DEFAULT_SMPL_H__
--#define __PERFMON_DEFAULT_SMPL_H__ 1
-+#ifndef __ASM_IA64_PERFMON_DEFAULT_SMPL_H__
-+#define __ASM_IA64_PERFMON_DEFAULT_SMPL_H__ 1
-+
-+#ifndef __ia64__
-+#error "this file must be used for compatibility reasons only on IA-64"
-+#endif
- #define PFM_DEFAULT_SMPL_UUID { \
--              0x4d, 0x72, 0xbe, 0xc0, 0x06, 0x64, 0x41, 0x43, 0x82, 0xb4, 0xd3, 0xfd, 0x27, 0x24, 0x3c, 0x97}
-+              0x4d, 0x72, 0xbe, 0xc0, 0x06, 0x64, 0x41, 0x43, 0x82,\
-+              0xb4, 0xd3, 0xfd, 0x27, 0x24, 0x3c, 0x97}
- /*
-  * format specific parameters (passed at context creation)
-  */
--typedef struct {
-+struct pfm_default_smpl_arg {
-       unsigned long buf_size;         /* size of the buffer in bytes */
-       unsigned int  flags;            /* buffer specific flags */
-       unsigned int  res1;             /* for future use */
-       unsigned long reserved[2];      /* for future use */
--} pfm_default_smpl_arg_t;
-+};
- /*
-  * combined context+format specific structure. Can be passed
-- * to PFM_CONTEXT_CREATE
-+ * to PFM_CONTEXT_CREATE (not PFM_CONTEXT_CREATE2)
-  */
--typedef struct {
--      pfarg_context_t         ctx_arg;
--      pfm_default_smpl_arg_t  buf_arg;
--} pfm_default_smpl_ctx_arg_t;
-+struct pfm_default_smpl_ctx_arg {
-+      struct pfarg_context            ctx_arg;
-+      struct pfm_default_smpl_arg     buf_arg;
-+};
- /*
-  * This header is at the beginning of the sampling buffer returned to the user.
-  * It is directly followed by the first record.
-  */
--typedef struct {
--      unsigned long   hdr_count;              /* how many valid entries */
--      unsigned long   hdr_cur_offs;           /* current offset from top of buffer */
--      unsigned long   hdr_reserved2;          /* reserved for future use */
-+struct pfm_default_smpl_hdr {
-+      u64     hdr_count;      /* how many valid entries */
-+      u64     hdr_cur_offs;   /* current offset from top of buffer */
-+      u64     dr_reserved2;   /* reserved for future use */
--      unsigned long   hdr_overflows;          /* how many times the buffer overflowed */
--      unsigned long   hdr_buf_size;           /* how many bytes in the buffer */
-+      u64     hdr_overflows;  /* how many times the buffer overflowed */
-+      u64     hdr_buf_size;   /* how many bytes in the buffer */
--      unsigned int    hdr_version;            /* contains perfmon version (smpl format diffs) */
--      unsigned int    hdr_reserved1;          /* for future use */
--      unsigned long   hdr_reserved[10];       /* for future use */
--} pfm_default_smpl_hdr_t;
-+      u32     hdr_version;    /* smpl format version*/
-+      u32     hdr_reserved1;          /* for future use */
-+      u64     hdr_reserved[10];       /* for future use */
-+};
- /*
-  * Entry header in the sampling buffer.  The header is directly followed
-- * with the values of the PMD registers of interest saved in increasing 
-- * index order: PMD4, PMD5, and so on. How many PMDs are present depends 
-+ * with the values of the PMD registers of interest saved in increasing
-+ * index order: PMD4, PMD5, and so on. How many PMDs are present depends
-  * on how the session was programmed.
-  *
-  * In the case where multiple counters overflow at the same time, multiple
-  * entries are written consecutively.
-  *
-- * last_reset_value member indicates the initial value of the overflowed PMD. 
-+ * last_reset_value member indicates the initial value of the overflowed PMD.
-  */
--typedef struct {
--        int             pid;                    /* thread id (for NPTL, this is gettid()) */
--        unsigned char   reserved1[3];           /* reserved for future use */
--        unsigned char   ovfl_pmd;               /* index of overflowed PMD */
--
--        unsigned long   last_reset_val;         /* initial value of overflowed PMD */
--        unsigned long   ip;                     /* where did the overflow interrupt happened  */
--        unsigned long   tstamp;                 /* ar.itc when entering perfmon intr. handler */
--
--        unsigned short  cpu;                    /* cpu on which the overfow occured */
--        unsigned short  set;                    /* event set active when overflow ocurred   */
--        int                   tgid;                   /* thread group id (for NPTL, this is getpid()) */
--} pfm_default_smpl_entry_t;
-+struct pfm_default_smpl_entry {
-+      pid_t   pid;            /* thread id (for NPTL, this is gettid()) */
-+      uint8_t reserved1[3];   /* for future use */
-+      uint8_t ovfl_pmd;       /* overflow pmd for this sample */
-+      u64     last_reset_val; /* initial value of overflowed PMD */
-+      unsigned long ip;       /* where did the overflow interrupt happened */
-+      u64     tstamp;         /* overflow timetamp */
-+      u16     cpu;            /* cpu on which the overfow occured */
-+      u16     set;            /* event set active when overflow ocurred   */
-+      pid_t   tgid;           /* thread group id (for NPTL, this is getpid()) */
-+};
--#define PFM_DEFAULT_MAX_PMDS          64 /* how many pmds supported by data structures (sizeof(unsigned long) */
--#define PFM_DEFAULT_MAX_ENTRY_SIZE    (sizeof(pfm_default_smpl_entry_t)+(sizeof(unsigned long)*PFM_DEFAULT_MAX_PMDS))
--#define PFM_DEFAULT_SMPL_MIN_BUF_SIZE (sizeof(pfm_default_smpl_hdr_t)+PFM_DEFAULT_MAX_ENTRY_SIZE)
-+#define PFM_DEFAULT_MAX_PMDS          64 /* #pmds supported  */
-+#define PFM_DEFAULT_MAX_ENTRY_SIZE    (sizeof(struct pfm_default_smpl_entry)+\
-+                                       (sizeof(u64)*PFM_DEFAULT_MAX_PMDS))
-+#define PFM_DEFAULT_SMPL_MIN_BUF_SIZE (sizeof(struct pfm_default_smpl_hdr)+\
-+                                       PFM_DEFAULT_MAX_ENTRY_SIZE)
- #define PFM_DEFAULT_SMPL_VERSION_MAJ  2U
--#define PFM_DEFAULT_SMPL_VERSION_MIN  0U
--#define PFM_DEFAULT_SMPL_VERSION      (((PFM_DEFAULT_SMPL_VERSION_MAJ&0xffff)<<16)|(PFM_DEFAULT_SMPL_VERSION_MIN & 0xffff))
-+#define PFM_DEFAULT_SMPL_VERSION_MIN 1U
-+#define PFM_DEFAULT_SMPL_VERSION (((PFM_DEFAULT_SMPL_VERSION_MAJ&0xffff)<<16)|\
-+                                  (PFM_DEFAULT_SMPL_VERSION_MIN & 0xffff))
--#endif /* __PERFMON_DEFAULT_SMPL_H__ */
-+#endif /* __ASM_IA64_PERFMON_DEFAULT_SMPL_H__ */
-diff --git a/arch/ia64/include/asm/perfmon_kern.h b/arch/ia64/include/asm/perfmon_kern.h
-new file mode 100644
-index 0000000..fb40459
---- /dev/null
-+++ b/arch/ia64/include/asm/perfmon_kern.h
-@@ -0,0 +1,356 @@
-+/*
-+ * Copyright (c) 2001-2007 Hewlett-Packard Development Company, L.P.
-+ * Contributed by Stephane Eranian <eranian@hpl.hp.com>
-+ *
-+ * This file contains Itanium Processor Family specific definitions
-+ * for the perfmon interface.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of version 2 of the GNU General Public
-+ * License as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ * 02111-1307 USA
-+  */
-+#ifndef _ASM_IA64_PERFMON_KERN_H_
-+#define _ASM_IA64_PERFMON_KERN_H_
-+
-+#ifdef __KERNEL__
-+
-+#ifdef CONFIG_PERFMON
-+#include <asm/unistd.h>
-+#include <asm/hw_irq.h>
-+
-+/*
-+ * describe the content of the pfm_syst_info field
-+ * layout:
-+ * bits[00-15] : generic flags
-+ * bits[16-31] : arch-specific flags
-+ */
-+#define PFM_ITA_CPUINFO_IDLE_EXCL 0x10000 /* stop monitoring in idle loop */
-+
-+/*
-+ * For some CPUs, the upper bits of a counter must be set in order for the
-+ * overflow interrupt to happen. On overflow, the counter has wrapped around,
-+ * and the upper bits are cleared. This function may be used to set them back.
-+ */
-+static inline void pfm_arch_ovfl_reset_pmd(struct pfm_context *ctx,
-+                                         unsigned int cnum)
-+{}
-+
-+/*
-+ * called from __pfm_interrupt_handler(). ctx is not NULL.
-+ * ctx is locked. PMU interrupt is masked.
-+ *
-+ * must stop all monitoring to ensure handler has consistent view.
-+ * must collect overflowed PMDs bitmask  into povfls_pmds and
-+ * npend_ovfls. If no interrupt detected then npend_ovfls
-+ * must be set to zero.
-+ */
-+static inline void pfm_arch_intr_freeze_pmu(struct pfm_context *ctx,
-+                                          struct pfm_event_set *set)
-+{
-+      u64 tmp;
-+
-+      /*
-+       * do not overwrite existing value, must
-+       * process those first (coming from context switch replay)
-+       */
-+      if (set->npend_ovfls)
-+              return;
-+
-+      ia64_srlz_d();
-+
-+      tmp =  ia64_get_pmc(0) & ~0xf;
-+
-+      set->povfl_pmds[0] = tmp;
-+
-+      set->npend_ovfls = ia64_popcnt(tmp);
-+}
-+
-+static inline int pfm_arch_init_pmu_config(void)
-+{
-+      return 0;
-+}
-+
-+static inline void pfm_arch_resend_irq(struct pfm_context *ctx)
-+{
-+      ia64_resend_irq(IA64_PERFMON_VECTOR);
-+}
-+
-+static inline void pfm_arch_clear_pmd_ovfl_cond(struct pfm_context *ctx,
-+                                              struct pfm_event_set *set)
-+{}
-+
-+static inline void pfm_arch_serialize(void)
-+{
-+      ia64_srlz_d();
-+}
-+
-+static inline void pfm_arch_intr_unfreeze_pmu(struct pfm_context *ctx)
-+{
-+      PFM_DBG_ovfl("state=%d", ctx->state);
-+      ia64_set_pmc(0, 0);
-+      /* no serialization */
-+}
-+
-+static inline void pfm_arch_write_pmc(struct pfm_context *ctx,
-+                                    unsigned int cnum, u64 value)
-+{
-+      if (cnum < 256) {
-+              ia64_set_pmc(pfm_pmu_conf->pmc_desc[cnum].hw_addr, value);
-+      } else if (cnum < 264) {
-+              ia64_set_ibr(cnum-256, value);
-+              ia64_dv_serialize_instruction();
-+      } else {
-+              ia64_set_dbr(cnum-264, value);
-+              ia64_dv_serialize_instruction();
-+      }
-+}
-+
-+/*
-+ * On IA-64, for per-thread context which have the ITA_FL_INSECURE
-+ * flag, it is possible to start/stop monitoring directly from user evel
-+ * without calling pfm_start()/pfm_stop. This allows very lightweight
-+ * control yet the kernel sometimes needs to know if monitoring is actually
-+ * on or off.
-+ *
-+ * Tracking of this information is normally done by pfm_start/pfm_stop
-+ * in flags.started. Here we need to compensate by checking actual
-+ * psr bit.
-+ */
-+static inline int pfm_arch_is_active(struct pfm_context *ctx)
-+{
-+      return ctx->flags.started
-+             || ia64_getreg(_IA64_REG_PSR) & (IA64_PSR_UP|IA64_PSR_PP);
-+}
-+
-+static inline void pfm_arch_write_pmd(struct pfm_context *ctx,
-+                                    unsigned int cnum, u64 value)
-+{
-+      /*
-+       * for a counting PMD, overflow bit must be cleared
-+       */
-+      if (pfm_pmu_conf->pmd_desc[cnum].type & PFM_REG_C64)
-+              value &= pfm_pmu_conf->ovfl_mask;
-+
-+      /*
-+       * for counters, write to upper bits are ignored, no need to mask
-+       */
-+      ia64_set_pmd(pfm_pmu_conf->pmd_desc[cnum].hw_addr, value);
-+}
-+
-+static inline u64 pfm_arch_read_pmd(struct pfm_context *ctx, unsigned int cnum)
-+{
-+      return ia64_get_pmd(pfm_pmu_conf->pmd_desc[cnum].hw_addr);
-+}
-+
-+static inline u64 pfm_arch_read_pmc(struct pfm_context *ctx, unsigned int cnum)
-+{
-+      return ia64_get_pmc(pfm_pmu_conf->pmc_desc[cnum].hw_addr);
-+}
-+
-+static inline void pfm_arch_ctxswout_sys(struct task_struct *task,
-+                                       struct pfm_context *ctx)
-+{
-+      struct pt_regs *regs;
-+
-+      regs = task_pt_regs(task);
-+      ia64_psr(regs)->pp = 0;
-+}
-+
-+static inline void pfm_arch_ctxswin_sys(struct task_struct *task,
-+                                      struct pfm_context *ctx)
-+{
-+      struct pt_regs *regs;
-+
-+      if (!(ctx->active_set->flags & PFM_ITA_SETFL_INTR_ONLY)) {
-+              regs = task_pt_regs(task);
-+              ia64_psr(regs)->pp = 1;
-+      }
-+}
-+
-+/*
-+ * On IA-64, the PMDs are NOT saved by pfm_arch_freeze_pmu()
-+ * when entering the PMU interrupt handler, thus, we need
-+ * to save them in pfm_switch_sets_from_intr()
-+ */
-+static inline void pfm_arch_save_pmds_from_intr(struct pfm_context *ctx,
-+                                         struct pfm_event_set *set)
-+{
-+      pfm_save_pmds(ctx, set);
-+}
-+
-+int pfm_arch_context_create(struct pfm_context *ctx, u32 ctx_flags);
-+
-+static inline void pfm_arch_context_free(struct pfm_context *ctx)
-+{}
-+
-+int pfm_arch_ctxswout_thread(struct task_struct *task, struct pfm_context *ctx);
-+void pfm_arch_ctxswin_thread(struct task_struct *task,
-+                           struct pfm_context *ctx);
-+
-+void pfm_arch_unload_context(struct pfm_context *ctx);
-+int pfm_arch_load_context(struct pfm_context *ctx);
-+int pfm_arch_setfl_sane(struct pfm_context *ctx, u32 flags);
-+
-+void pfm_arch_mask_monitoring(struct pfm_context *ctx,
-+                            struct pfm_event_set *set);
-+void pfm_arch_unmask_monitoring(struct pfm_context *ctx,
-+                              struct pfm_event_set *set);
-+
-+void pfm_arch_restore_pmds(struct pfm_context *ctx, struct pfm_event_set *set);
-+void pfm_arch_restore_pmcs(struct pfm_context *ctx, struct pfm_event_set *set);
-+
-+void pfm_arch_stop(struct task_struct *task, struct pfm_context *ctx);
-+void pfm_arch_start(struct task_struct *task, struct pfm_context *ctx);
-+
-+int  pfm_arch_init(void);
-+void pfm_arch_init_percpu(void);
-+char *pfm_arch_get_pmu_module_name(void);
-+
-+int __pfm_use_dbregs(struct task_struct *task);
-+int  __pfm_release_dbregs(struct task_struct *task);
-+int pfm_ia64_mark_dbregs_used(struct pfm_context *ctx,
-+                            struct pfm_event_set *set);
-+
-+void pfm_arch_show_session(struct seq_file *m);
-+
-+static inline int pfm_arch_pmu_acquire(u64 *unavail_pmcs, u64 *unavail_pmds)
-+{
-+      return 0;
-+}
-+
-+static inline void pfm_arch_pmu_release(void)
-+{}
-+
-+/* not necessary on IA-64 */
-+static inline void pfm_cacheflush(void *addr, unsigned int len)
-+{}
-+
-+/*
-+ * miscellaneous architected definitions
-+ */
-+#define PFM_ITA_FCNTR 4 /* first counting monitor (PMC/PMD) */
-+
-+/*
-+ * private event set flags  (set_priv_flags)
-+ */
-+#define PFM_ITA_SETFL_USE_DBR 0x1000000 /* set uses debug registers */
-+
-+
-+/*
-+ * Itanium-specific data structures
-+ */
-+struct pfm_ia64_context_flags {
-+      unsigned int use_dbr:1;  /* use range restrictions (debug registers) */
-+      unsigned int insecure:1; /* insecure monitoring for non-self session */
-+      unsigned int reserved:30;/* for future use */
-+};
-+
-+struct pfm_arch_context {
-+      struct pfm_ia64_context_flags flags;    /* arch specific ctx flags */
-+      u64                      ctx_saved_psr_up;/* storage for psr_up */
-+#ifdef CONFIG_IA64_PERFMON_COMPAT
-+      void                    *ctx_smpl_vaddr; /* vaddr of user mapping */
-+#endif
-+};
-+
-+#ifdef CONFIG_IA64_PERFMON_COMPAT
-+ssize_t pfm_arch_compat_read(struct pfm_context *ctx,
-+                           char __user *buf,
-+                           int non_block,
-+                           size_t size);
-+int pfm_ia64_compat_init(void);
-+int pfm_smpl_buf_alloc_compat(struct pfm_context *ctx,
-+                            size_t rsize, struct file *filp);
-+#else
-+static inline ssize_t pfm_arch_compat_read(struct pfm_context *ctx,
-+                           char __user *buf,
-+                           int non_block,
-+                           size_t size)
-+{
-+      return -EINVAL;
-+}
-+
-+static inline int pfm_smpl_buf_alloc_compat(struct pfm_context *ctx,
-+                                          size_t rsize, struct file *filp)
-+{
-+      return -EINVAL;
-+}
-+#endif
-+
-+static inline void pfm_arch_arm_handle_work(struct task_struct *task)
-+{
-+      /*
-+       * On IA-64, we ran out of bits in the bottom 7 bits of the
-+       * threadinfo bitmask.Thus we used a 2-stage approach by piggybacking
-+       * on NOTIFY_RESUME and then in do_notify_resume() we demultiplex and
-+       * call pfm_handle_work() if needed
-+       */
-+      set_tsk_thread_flag(task, TIF_NOTIFY_RESUME);
-+}
-+
-+static inline void pfm_arch_disarm_handle_work(struct task_struct *task)
-+{
-+      /*
-+       * we cannot just clear TIF_NOTIFY_RESUME because other TIF flags are
-+       * piggybackedonto it: TIF_PERFMON_WORK, TIF_RESTORE_RSE
-+       *
-+       * The tsk_clear_notify_resume() checks if any of those are set before
-+       * clearing the * bit
-+       */
-+      tsk_clear_notify_resume(task);
-+}
-+
-+static inline int pfm_arch_pmu_config_init(struct pfm_pmu_config *cfg)
-+{
-+      return 0;
-+}
-+
-+extern struct pfm_ia64_pmu_info *pfm_ia64_pmu_info;
-+
-+#define PFM_ARCH_CTX_SIZE     (sizeof(struct pfm_arch_context))
-+
-+/*
-+ * IA-64 does not need extra alignment requirements for the sampling buffer
-+ */
-+#define PFM_ARCH_SMPL_ALIGN_SIZE      0
-+
-+
-+static inline void pfm_release_dbregs(struct task_struct *task)
-+{
-+      if (task->thread.flags & IA64_THREAD_DBG_VALID)
-+              __pfm_release_dbregs(task);
-+}
-+
-+#define pfm_use_dbregs(_t)     __pfm_use_dbregs(_t)
-+
-+static inline int pfm_arch_get_base_syscall(void)
-+{
-+      return __NR_pfm_create_context;
-+}
-+
-+struct pfm_arch_pmu_info {
-+      unsigned long mask_pmcs[PFM_PMC_BV]; /* modify on when masking */
-+};
-+
-+DECLARE_PER_CPU(u32, pfm_syst_info);
-+#else /* !CONFIG_PERFMON */
-+/*
-+ * perfmon ia64-specific hooks
-+ */
-+#define pfm_release_dbregs(_t)                do { } while (0)
-+#define pfm_use_dbregs(_t)                    (0)
-+
-+#endif /* CONFIG_PERFMON */
-+
-+#endif /* __KERNEL__ */
-+#endif /* _ASM_IA64_PERFMON_KERN_H_ */
-diff --git a/arch/ia64/include/asm/processor.h b/arch/ia64/include/asm/processor.h
-index f88fa05..9d6af9c 100644
---- a/arch/ia64/include/asm/processor.h
-+++ b/arch/ia64/include/asm/processor.h
-@@ -42,7 +42,6 @@
- #define IA64_THREAD_FPH_VALID (__IA64_UL(1) << 0)     /* floating-point high state valid? */
- #define IA64_THREAD_DBG_VALID (__IA64_UL(1) << 1)     /* debug registers valid? */
--#define IA64_THREAD_PM_VALID  (__IA64_UL(1) << 2)     /* performance registers valid? */
- #define IA64_THREAD_UAC_NOPRINT       (__IA64_UL(1) << 3)     /* don't log unaligned accesses */
- #define IA64_THREAD_UAC_SIGBUS        (__IA64_UL(1) << 4)     /* generate SIGBUS on unaligned acc. */
- #define IA64_THREAD_MIGRATION (__IA64_UL(1) << 5)     /* require migration
-@@ -321,14 +320,6 @@ struct thread_struct {
- #else
- # define INIT_THREAD_IA32
- #endif /* CONFIG_IA32_SUPPORT */
--#ifdef CONFIG_PERFMON
--      void *pfm_context;                   /* pointer to detailed PMU context */
--      unsigned long pfm_needs_checking;    /* when >0, pending perfmon work on kernel exit */
--# define INIT_THREAD_PM               .pfm_context =          NULL,     \
--                              .pfm_needs_checking =   0UL,
--#else
--# define INIT_THREAD_PM
--#endif
-       __u64 dbr[IA64_NUM_DBG_REGS];
-       __u64 ibr[IA64_NUM_DBG_REGS];
-       struct ia64_fpreg fph[96];      /* saved/loaded on demand */
-@@ -343,7 +334,6 @@ struct thread_struct {
-       .task_size =    DEFAULT_TASK_SIZE,                      \
-       .last_fph_cpu =  -1,                                    \
-       INIT_THREAD_IA32                                        \
--      INIT_THREAD_PM                                          \
-       .dbr =          {0, },                                  \
-       .ibr =          {0, },                                  \
-       .fph =          {{{{0}}}, }                             \
-diff --git a/arch/ia64/include/asm/system.h b/arch/ia64/include/asm/system.h
-index 927a381..ab5aeea 100644
---- a/arch/ia64/include/asm/system.h
-+++ b/arch/ia64/include/asm/system.h
-@@ -217,6 +217,7 @@ struct task_struct;
- extern void ia64_save_extra (struct task_struct *task);
- extern void ia64_load_extra (struct task_struct *task);
-+
- #ifdef CONFIG_VIRT_CPU_ACCOUNTING
- extern void ia64_account_on_switch (struct task_struct *prev, struct task_struct *next);
- # define IA64_ACCOUNT_ON_SWITCH(p,n) ia64_account_on_switch(p,n)
-@@ -224,16 +225,9 @@ extern void ia64_account_on_switch (struct task_struct *prev, struct task_struct
- # define IA64_ACCOUNT_ON_SWITCH(p,n)
- #endif
--#ifdef CONFIG_PERFMON
--  DECLARE_PER_CPU(unsigned long, pfm_syst_info);
--# define PERFMON_IS_SYSWIDE() (__get_cpu_var(pfm_syst_info) & 0x1)
--#else
--# define PERFMON_IS_SYSWIDE() (0)
--#endif
--
--#define IA64_HAS_EXTRA_STATE(t)                                                       \
--      ((t)->thread.flags & (IA64_THREAD_DBG_VALID|IA64_THREAD_PM_VALID)       \
--       || IS_IA32_PROCESS(task_pt_regs(t)) || PERFMON_IS_SYSWIDE())
-+#define IA64_HAS_EXTRA_STATE(t)                                               \
-+      (((t)->thread.flags & IA64_THREAD_DBG_VALID)                    \
-+       || IS_IA32_PROCESS(task_pt_regs(t)))
- #define __switch_to(prev,next,last) do {                                                       \
-       IA64_ACCOUNT_ON_SWITCH(prev, next);                                                      \
-@@ -241,6 +235,10 @@ extern void ia64_account_on_switch (struct task_struct *prev, struct task_struct
-               ia64_save_extra(prev);                                                           \
-       if (IA64_HAS_EXTRA_STATE(next))                                                          \
-               ia64_load_extra(next);                                                           \
-+      if (test_tsk_thread_flag(prev, TIF_PERFMON_CTXSW))                                       \
-+              pfm_ctxsw_out(prev, next);                                                       \
-+      if (test_tsk_thread_flag(next, TIF_PERFMON_CTXSW))                                       \
-+              pfm_ctxsw_in(prev, next);                                                        \
-       ia64_psr(task_pt_regs(next))->dfh = !ia64_is_local_fpu_owner(next);                      \
-       (last) = ia64_switch_to((next));                                                         \
- } while (0)
-diff --git a/arch/ia64/include/asm/thread_info.h b/arch/ia64/include/asm/thread_info.h
-index 7c60fcd..3355332 100644
---- a/arch/ia64/include/asm/thread_info.h
-+++ b/arch/ia64/include/asm/thread_info.h
-@@ -110,6 +110,8 @@ extern void tsk_clear_notify_resume(struct task_struct *tsk);
- #define TIF_DB_DISABLED               19      /* debug trap disabled for fsyscall */
- #define TIF_FREEZE            20      /* is freezing for suspend */
- #define TIF_RESTORE_RSE               21      /* user RBS is newer than kernel RBS */
-+#define TIF_PERFMON_CTXSW     22      /* perfmon needs ctxsw calls */
-+#define TIF_PERFMON_WORK      23      /* work for pfm_handle_work() */
- #define _TIF_SYSCALL_TRACE    (1 << TIF_SYSCALL_TRACE)
- #define _TIF_SYSCALL_AUDIT    (1 << TIF_SYSCALL_AUDIT)
-@@ -123,6 +125,8 @@ extern void tsk_clear_notify_resume(struct task_struct *tsk);
- #define _TIF_DB_DISABLED      (1 << TIF_DB_DISABLED)
- #define _TIF_FREEZE           (1 << TIF_FREEZE)
- #define _TIF_RESTORE_RSE      (1 << TIF_RESTORE_RSE)
-+#define _TIF_PERFMON_CTXSW    (1 << TIF_PERFMON_CTXSW)
-+#define _TIF_PERFMON_WORK     (1 << TIF_PERFMON_WORK)
- /* "work to do on user-return" bits */
- #define TIF_ALLWORK_MASK      (_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SYSCALL_AUDIT|\
-diff --git a/arch/ia64/include/asm/unistd.h b/arch/ia64/include/asm/unistd.h
-index d535833..29a43bc 100644
---- a/arch/ia64/include/asm/unistd.h
-+++ b/arch/ia64/include/asm/unistd.h
-@@ -308,11 +308,23 @@
- #define __NR_dup3                     1316
- #define __NR_pipe2                    1317
- #define __NR_inotify_init1            1318
-+#define __NR_pfm_create_context               1319
-+#define __NR_pfm_write_pmcs           (__NR_pfm_create_context+1)
-+#define __NR_pfm_write_pmds           (__NR_pfm_create_context+2)
-+#define __NR_pfm_read_pmds            (__NR_pfm_create_context+3)
-+#define __NR_pfm_load_context         (__NR_pfm_create_context+4)
-+#define __NR_pfm_start                        (__NR_pfm_create_context+5)
-+#define __NR_pfm_stop                 (__NR_pfm_create_context+6)
-+#define __NR_pfm_restart              (__NR_pfm_create_context+7)
-+#define __NR_pfm_create_evtsets               (__NR_pfm_create_context+8)
-+#define __NR_pfm_getinfo_evtsets      (__NR_pfm_create_context+9)
-+#define __NR_pfm_delete_evtsets       (__NR_pfm_create_context+10)
-+#define __NR_pfm_unload_context               (__NR_pfm_create_context+11)
- #ifdef __KERNEL__
--#define NR_syscalls                   295 /* length of syscall table */
-+#define NR_syscalls                   307 /* length of syscall table */
- /*
-  * The following defines stop scripts/checksyscalls.sh from complaining about
-diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
-index 87fea11..b5ac54c 100644
---- a/arch/ia64/kernel/Makefile
-+++ b/arch/ia64/kernel/Makefile
-@@ -5,7 +5,7 @@
- extra-y       := head.o init_task.o vmlinux.lds
- obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o     \
--       irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o          \
-+       irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o ptrace.o sal.o            \
-        salinfo.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \
-        unwind.o mca.o mca_asm.o topology.o
-@@ -23,7 +23,6 @@ obj-$(CONFIG_IOSAPIC)                += iosapic.o
- obj-$(CONFIG_MODULES)         += module.o
- obj-$(CONFIG_SMP)             += smp.o smpboot.o
- obj-$(CONFIG_NUMA)            += numa.o
--obj-$(CONFIG_PERFMON)         += perfmon_default_smpl.o
- obj-$(CONFIG_IA64_CYCLONE)    += cyclone.o
- obj-$(CONFIG_CPU_FREQ)                += cpufreq/
- obj-$(CONFIG_IA64_MCA_RECOVERY)       += mca_recovery.o
-diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
-index 0dd6c14..f1c3e41 100644
---- a/arch/ia64/kernel/entry.S
-+++ b/arch/ia64/kernel/entry.S
-@@ -1697,6 +1697,18 @@ sys_call_table:
-       data8 sys_dup3
-       data8 sys_pipe2
-       data8 sys_inotify_init1
-+      data8 sys_pfm_create_context
-+      data8 sys_pfm_write_pmcs                // 1320
-+      data8 sys_pfm_write_pmds
-+      data8 sys_pfm_read_pmds
-+      data8 sys_pfm_load_context
-+      data8 sys_pfm_start
-+      data8 sys_pfm_stop                      // 1325
-+      data8 sys_pfm_restart
-+      data8 sys_pfm_create_evtsets
-+      data8 sys_pfm_getinfo_evtsets
-+      data8 sys_pfm_delete_evtsets
-+      data8 sys_pfm_unload_context            // 1330
-       .org sys_call_table + 8*NR_syscalls     // guard against failures to increase NR_syscalls
- #endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
-diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
-index 28d3d48..ede8024 100644
---- a/arch/ia64/kernel/irq_ia64.c
-+++ b/arch/ia64/kernel/irq_ia64.c
-@@ -40,10 +40,6 @@
- #include <asm/system.h>
- #include <asm/tlbflush.h>
--#ifdef CONFIG_PERFMON
--# include <asm/perfmon.h>
--#endif
--
- #define IRQ_DEBUG     0
- #define IRQ_VECTOR_UNASSIGNED (0)
-@@ -660,9 +656,6 @@ init_IRQ (void)
-       }
- #endif
- #endif
--#ifdef CONFIG_PERFMON
--      pfm_init_percpu();
--#endif
-       platform_irq_init();
- }
-diff --git a/arch/ia64/kernel/perfmon_default_smpl.c b/arch/ia64/kernel/perfmon_default_smpl.c
-deleted file mode 100644
-index 5f637bb..0000000
---- a/arch/ia64/kernel/perfmon_default_smpl.c
-+++ /dev/null
-@@ -1,296 +0,0 @@
--/*
-- * Copyright (C) 2002-2003 Hewlett-Packard Co
-- *               Stephane Eranian <eranian@hpl.hp.com>
-- *
-- * This file implements the default sampling buffer format
-- * for the Linux/ia64 perfmon-2 subsystem.
-- */
--#include <linux/kernel.h>
--#include <linux/types.h>
--#include <linux/module.h>
--#include <linux/init.h>
--#include <asm/delay.h>
--#include <linux/smp.h>
--
--#include <asm/perfmon.h>
--#include <asm/perfmon_default_smpl.h>
--
--MODULE_AUTHOR("Stephane Eranian <eranian@hpl.hp.com>");
--MODULE_DESCRIPTION("perfmon default sampling format");
--MODULE_LICENSE("GPL");
--
--#define DEFAULT_DEBUG 1
--
--#ifdef DEFAULT_DEBUG
--#define DPRINT(a) \
--      do { \
--              if (unlikely(pfm_sysctl.debug >0)) { printk("%s.%d: CPU%d ", __func__, __LINE__, smp_processor_id()); printk a; } \
--      } while (0)
--
--#define DPRINT_ovfl(a) \
--      do { \
--              if (unlikely(pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0)) { printk("%s.%d: CPU%d ", __func__, __LINE__, smp_processor_id()); printk a; } \
--      } while (0)
--
--#else
--#define DPRINT(a)
--#define DPRINT_ovfl(a)
--#endif
--
--static int
--default_validate(struct task_struct *task, unsigned int flags, int cpu, void *data)
--{
--      pfm_default_smpl_arg_t *arg = (pfm_default_smpl_arg_t*)data;
--      int ret = 0;
--
--      if (data == NULL) {
--              DPRINT(("[%d] no argument passed\n", task_pid_nr(task)));
--              return -EINVAL;
--      }
--
--      DPRINT(("[%d] validate flags=0x%x CPU%d\n", task_pid_nr(task), flags, cpu));
--
--      /*
--       * must hold at least the buffer header + one minimally sized entry
--       */
--      if (arg->buf_size < PFM_DEFAULT_SMPL_MIN_BUF_SIZE) return -EINVAL;
--
--      DPRINT(("buf_size=%lu\n", arg->buf_size));
--
--      return ret;
--}
--
--static int
--default_get_size(struct task_struct *task, unsigned int flags, int cpu, void *data, unsigned long *size)
--{
--      pfm_default_smpl_arg_t *arg = (pfm_default_smpl_arg_t *)data;
--
--      /*
--       * size has been validated in default_validate
--       */
--      *size = arg->buf_size;
--
--      return 0;
--}
--
--static int
--default_init(struct task_struct *task, void *buf, unsigned int flags, int cpu, void *data)
--{
--      pfm_default_smpl_hdr_t *hdr;
--      pfm_default_smpl_arg_t *arg = (pfm_default_smpl_arg_t *)data;
--
--      hdr = (pfm_default_smpl_hdr_t *)buf;
--
--      hdr->hdr_version      = PFM_DEFAULT_SMPL_VERSION;
--      hdr->hdr_buf_size     = arg->buf_size;
--      hdr->hdr_cur_offs     = sizeof(*hdr);
--      hdr->hdr_overflows    = 0UL;
--      hdr->hdr_count        = 0UL;
--
--      DPRINT(("[%d] buffer=%p buf_size=%lu hdr_size=%lu hdr_version=%u cur_offs=%lu\n",
--              task_pid_nr(task),
--              buf,
--              hdr->hdr_buf_size,
--              sizeof(*hdr),
--              hdr->hdr_version,
--              hdr->hdr_cur_offs));
--
--      return 0;
--}
--
--static int
--default_handler(struct task_struct *task, void *buf, pfm_ovfl_arg_t *arg, struct pt_regs *regs, unsigned long stamp)
--{
--      pfm_default_smpl_hdr_t *hdr;
--      pfm_default_smpl_entry_t *ent;
--      void *cur, *last;
--      unsigned long *e, entry_size;
--      unsigned int npmds, i;
--      unsigned char ovfl_pmd;
--      unsigned char ovfl_notify;
--
--      if (unlikely(buf == NULL || arg == NULL|| regs == NULL || task == NULL)) {
--              DPRINT(("[%d] invalid arguments buf=%p arg=%p\n", task->pid, buf, arg));
--              return -EINVAL;
--      }
--
--      hdr         = (pfm_default_smpl_hdr_t *)buf;
--      cur         = buf+hdr->hdr_cur_offs;
--      last        = buf+hdr->hdr_buf_size;
--      ovfl_pmd    = arg->ovfl_pmd;
--      ovfl_notify = arg->ovfl_notify;
--
--      /*
--       * precheck for sanity
--       */
--      if ((last - cur) < PFM_DEFAULT_MAX_ENTRY_SIZE) goto full;
--
--      npmds = hweight64(arg->smpl_pmds[0]);
--
--      ent = (pfm_default_smpl_entry_t *)cur;
--
--      prefetch(arg->smpl_pmds_values);
--
--      entry_size = sizeof(*ent) + (npmds << 3);
--
--      /* position for first pmd */
--      e = (unsigned long *)(ent+1);
--
--      hdr->hdr_count++;
--
--      DPRINT_ovfl(("[%d] count=%lu cur=%p last=%p free_bytes=%lu ovfl_pmd=%d ovfl_notify=%d npmds=%u\n",
--                      task->pid,
--                      hdr->hdr_count,
--                      cur, last,
--                      last-cur,
--                      ovfl_pmd,
--                      ovfl_notify, npmds));
--
--      /*
--       * current = task running at the time of the overflow.
--       *
--       * per-task mode:
--       *      - this is ususally the task being monitored.
--       *        Under certain conditions, it might be a different task
--       *
--       * system-wide:
--       *      - this is not necessarily the task controlling the session
--       */
--      ent->pid            = current->pid;
--      ent->ovfl_pmd       = ovfl_pmd;
--      ent->last_reset_val = arg->pmd_last_reset; //pmd[0].reg_last_reset_val;
--
--      /*
--       * where did the fault happen (includes slot number)
--       */
--      ent->ip = regs->cr_iip | ((regs->cr_ipsr >> 41) & 0x3);
--
--      ent->tstamp    = stamp;
--      ent->cpu       = smp_processor_id();
--      ent->set       = arg->active_set;
--      ent->tgid      = current->tgid;
--
--      /*
--       * selectively store PMDs in increasing index number
--       */
--      if (npmds) {
--              unsigned long *val = arg->smpl_pmds_values;
--              for(i=0; i < npmds; i++) {
--                      *e++ = *val++;
--              }
--      }
--
--      /*
--       * update position for next entry
--       */
--      hdr->hdr_cur_offs += entry_size;
--      cur               += entry_size;
--
--      /*
--       * post check to avoid losing the last sample
--       */
--      if ((last - cur) < PFM_DEFAULT_MAX_ENTRY_SIZE) goto full;
--
--      /*
--       * keep same ovfl_pmds, ovfl_notify
--       */
--      arg->ovfl_ctrl.bits.notify_user     = 0;
--      arg->ovfl_ctrl.bits.block_task      = 0;
--      arg->ovfl_ctrl.bits.mask_monitoring = 0;
--      arg->ovfl_ctrl.bits.reset_ovfl_pmds = 1; /* reset before returning from interrupt handler */
--
--      return 0;
--full:
--      DPRINT_ovfl(("sampling buffer full free=%lu, count=%lu, ovfl_notify=%d\n", last-cur, hdr->hdr_count, ovfl_notify));
--
--      /*
--       * increment number of buffer overflow.
--       * important to detect duplicate set of samples.
--       */
--      hdr->hdr_overflows++;
--
--      /*
--       * if no notification requested, then we saturate the buffer
--       */
--      if (ovfl_notify == 0) {
--              arg->ovfl_ctrl.bits.notify_user     = 0;
--              arg->ovfl_ctrl.bits.block_task      = 0;
--              arg->ovfl_ctrl.bits.mask_monitoring = 1;
--              arg->ovfl_ctrl.bits.reset_ovfl_pmds = 0;
--      } else {
--              arg->ovfl_ctrl.bits.notify_user     = 1;
--              arg->ovfl_ctrl.bits.block_task      = 1; /* ignored for non-blocking context */
--              arg->ovfl_ctrl.bits.mask_monitoring = 1;
--              arg->ovfl_ctrl.bits.reset_ovfl_pmds = 0; /* no reset now */
--      }
--      return -1; /* we are full, sorry */
--}
--
--static int
--default_restart(struct task_struct *task, pfm_ovfl_ctrl_t *ctrl, void *buf, struct pt_regs *regs)
--{
--      pfm_default_smpl_hdr_t *hdr;
--
--      hdr = (pfm_default_smpl_hdr_t *)buf;
--
--      hdr->hdr_count    = 0UL;
--      hdr->hdr_cur_offs = sizeof(*hdr);
--
--      ctrl->bits.mask_monitoring = 0;
--      ctrl->bits.reset_ovfl_pmds = 1; /* uses long-reset values */
--
--      return 0;
--}
--
--static int
--default_exit(struct task_struct *task, void *buf, struct pt_regs *regs)
--{
--      DPRINT(("[%d] exit(%p)\n", task_pid_nr(task), buf));
--      return 0;
--}
--
--static pfm_buffer_fmt_t default_fmt={
--      .fmt_name           = "default_format",
--      .fmt_uuid           = PFM_DEFAULT_SMPL_UUID,
--      .fmt_arg_size       = sizeof(pfm_default_smpl_arg_t),
--      .fmt_validate       = default_validate,
--      .fmt_getsize        = default_get_size,
--      .fmt_init           = default_init,
--      .fmt_handler        = default_handler,
--      .fmt_restart        = default_restart,
--      .fmt_restart_active = default_restart,
--      .fmt_exit           = default_exit,
--};
--
--static int __init
--pfm_default_smpl_init_module(void)
--{
--      int ret;
--
--      ret = pfm_register_buffer_fmt(&default_fmt);
--      if (ret == 0) {
--              printk("perfmon_default_smpl: %s v%u.%u registered\n",
--                      default_fmt.fmt_name,
--                      PFM_DEFAULT_SMPL_VERSION_MAJ,
--                      PFM_DEFAULT_SMPL_VERSION_MIN);
--      } else {
--              printk("perfmon_default_smpl: %s cannot register ret=%d\n",
--                      default_fmt.fmt_name,
--                      ret);
--      }
--
--      return ret;
--}
--
--static void __exit
--pfm_default_smpl_cleanup_module(void)
--{
--      int ret;
--      ret = pfm_unregister_buffer_fmt(default_fmt.fmt_uuid);
--
--      printk("perfmon_default_smpl: unregister %s=%d\n", default_fmt.fmt_name, ret);
--}
--
--module_init(pfm_default_smpl_init_module);
--module_exit(pfm_default_smpl_cleanup_module);
--
-diff --git a/arch/ia64/kernel/perfmon_generic.h b/arch/ia64/kernel/perfmon_generic.h
-deleted file mode 100644
-index 6748947..0000000
---- a/arch/ia64/kernel/perfmon_generic.h
-+++ /dev/null
-@@ -1,45 +0,0 @@
--/*
-- * This file contains the generic PMU register description tables
-- * and pmc checker used by perfmon.c.
-- *
-- * Copyright (C) 2002-2003  Hewlett Packard Co
-- *               Stephane Eranian <eranian@hpl.hp.com>
-- */
--
--static pfm_reg_desc_t pfm_gen_pmc_desc[PMU_MAX_PMCS]={
--/* pmc0  */ { PFM_REG_CONTROL , 0, 0x1UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc1  */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc2  */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc3  */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc4  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(4),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc5  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(5),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc6  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(6),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc7  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(7),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--          { PFM_REG_END     , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
--};
--
--static pfm_reg_desc_t pfm_gen_pmd_desc[PMU_MAX_PMDS]={
--/* pmd0  */ { PFM_REG_NOTIMPL , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}},
--/* pmd1  */ { PFM_REG_NOTIMPL , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}},
--/* pmd2  */ { PFM_REG_NOTIMPL , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}},
--/* pmd3  */ { PFM_REG_NOTIMPL , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}},
--/* pmd4  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(4),0UL, 0UL, 0UL}},
--/* pmd5  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(5),0UL, 0UL, 0UL}},
--/* pmd6  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(6),0UL, 0UL, 0UL}},
--/* pmd7  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(7),0UL, 0UL, 0UL}},
--          { PFM_REG_END     , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
--};
--
--/*
-- * impl_pmcs, impl_pmds are computed at runtime to minimize errors!
-- */
--static pmu_config_t pmu_conf_gen={
--      .pmu_name   = "Generic",
--      .pmu_family = 0xff, /* any */
--      .ovfl_val   = (1UL << 32) - 1,
--      .num_ibrs   = 0, /* does not use */
--      .num_dbrs   = 0, /* does not use */
--      .pmd_desc   = pfm_gen_pmd_desc,
--      .pmc_desc   = pfm_gen_pmc_desc
--};
--
-diff --git a/arch/ia64/kernel/perfmon_itanium.h b/arch/ia64/kernel/perfmon_itanium.h
-deleted file mode 100644
-index d1d508a..0000000
---- a/arch/ia64/kernel/perfmon_itanium.h
-+++ /dev/null
-@@ -1,115 +0,0 @@
--/*
-- * This file contains the Itanium PMU register description tables
-- * and pmc checker used by perfmon.c.
-- *
-- * Copyright (C) 2002-2003  Hewlett Packard Co
-- *               Stephane Eranian <eranian@hpl.hp.com>
-- */
--static int pfm_ita_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
--
--static pfm_reg_desc_t pfm_ita_pmc_desc[PMU_MAX_PMCS]={
--/* pmc0  */ { PFM_REG_CONTROL , 0, 0x1UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc1  */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc2  */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc3  */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc4  */ { PFM_REG_COUNTING, 6, 0x0UL, -1UL, NULL, NULL, {RDEP(4),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc5  */ { PFM_REG_COUNTING, 6, 0x0UL, -1UL, NULL, NULL, {RDEP(5),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc6  */ { PFM_REG_COUNTING, 6, 0x0UL, -1UL, NULL, NULL, {RDEP(6),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc7  */ { PFM_REG_COUNTING, 6, 0x0UL, -1UL, NULL, NULL, {RDEP(7),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc8  */ { PFM_REG_CONFIG  , 0, 0xf00000003ffffff8UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc9  */ { PFM_REG_CONFIG  , 0, 0xf00000003ffffff8UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc10 */ { PFM_REG_MONITOR , 6, 0x0UL, -1UL, NULL, NULL, {RDEP(0)|RDEP(1),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* 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}},
--/* 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}},
--/* pmc13 */ { PFM_REG_CONFIG  , 0, 0x0003ffff00000001UL, -1UL, NULL, pfm_ita_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--          { PFM_REG_END     , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
--};
--
--static pfm_reg_desc_t pfm_ita_pmd_desc[PMU_MAX_PMDS]={
--/* pmd0  */ { PFM_REG_BUFFER  , 0, 0UL, -1UL, NULL, NULL, {RDEP(1),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
--/* pmd1  */ { PFM_REG_BUFFER  , 0, 0UL, -1UL, NULL, NULL, {RDEP(0),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
--/* pmd2  */ { PFM_REG_BUFFER  , 0, 0UL, -1UL, NULL, NULL, {RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
--/* pmd3  */ { PFM_REG_BUFFER  , 0, 0UL, -1UL, NULL, NULL, {RDEP(2)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
--/* pmd4  */ { PFM_REG_COUNTING, 0, 0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(4),0UL, 0UL, 0UL}},
--/* pmd5  */ { PFM_REG_COUNTING, 0, 0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(5),0UL, 0UL, 0UL}},
--/* pmd6  */ { PFM_REG_COUNTING, 0, 0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(6),0UL, 0UL, 0UL}},
--/* pmd7  */ { PFM_REG_COUNTING, 0, 0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(7),0UL, 0UL, 0UL}},
--/* 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}},
--/* 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}},
--/* 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}},
--/* 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}},
--/* 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}},
--/* 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}},
--/* 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}},
--/* 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}},
--/* 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}},
--/* pmd17 */ { PFM_REG_BUFFER  , 0, 0UL, -1UL, NULL, NULL, {RDEP(2)|RDEP(3),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
--          { PFM_REG_END     , 0, 0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
--};
--
--static int
--pfm_ita_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs)
--{
--      int ret;
--      int is_loaded;
--
--      /* sanitfy check */
--      if (ctx == NULL) return -EINVAL;
--
--      is_loaded = ctx->ctx_state == PFM_CTX_LOADED || ctx->ctx_state == PFM_CTX_MASKED;
--
--      /*
--       * we must clear the (instruction) debug registers if pmc13.ta bit is cleared
--       * before they are written (fl_using_dbreg==0) to avoid picking up stale information.
--       */
--      if (cnum == 13 && is_loaded && ((*val & 0x1) == 0UL) && ctx->ctx_fl_using_dbreg == 0) {
--
--              DPRINT(("pmc[%d]=0x%lx has active pmc13.ta cleared, clearing ibr\n", cnum, *val));
--
--              /* don't mix debug with perfmon */
--              if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
--
--              /*
--               * a count of 0 will mark the debug registers as in use and also
--               * ensure that they are properly cleared.
--               */
--              ret = pfm_write_ibr_dbr(1, ctx, NULL, 0, regs);
--              if (ret) return ret;
--      }
--
--      /*
--       * we must clear the (data) debug registers if pmc11.pt bit is cleared
--       * before they are written (fl_using_dbreg==0) to avoid picking up stale information.
--       */
--      if (cnum == 11 && is_loaded && ((*val >> 28)& 0x1) == 0 && ctx->ctx_fl_using_dbreg == 0) {
--
--              DPRINT(("pmc[%d]=0x%lx has active pmc11.pt cleared, clearing dbr\n", cnum, *val));
--
--              /* don't mix debug with perfmon */
--              if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
--
--              /*
--               * a count of 0 will mark the debug registers as in use and also
--               * ensure that they are properly cleared.
--               */
--              ret = pfm_write_ibr_dbr(0, ctx, NULL, 0, regs);
--              if (ret) return ret;
--      }
--      return 0;
--}
--
--/*
-- * impl_pmcs, impl_pmds are computed at runtime to minimize errors!
-- */
--static pmu_config_t pmu_conf_ita={
--      .pmu_name      = "Itanium",
--      .pmu_family    = 0x7,
--      .ovfl_val      = (1UL << 32) - 1,
--      .pmd_desc      = pfm_ita_pmd_desc,
--      .pmc_desc      = pfm_ita_pmc_desc,
--      .num_ibrs      = 8,
--      .num_dbrs      = 8,
--      .use_rr_dbregs = 1, /* debug register are use for range retrictions */
--};
--
--
-diff --git a/arch/ia64/kernel/perfmon_mckinley.h b/arch/ia64/kernel/perfmon_mckinley.h
-deleted file mode 100644
-index c4bec7a..0000000
---- a/arch/ia64/kernel/perfmon_mckinley.h
-+++ /dev/null
-@@ -1,187 +0,0 @@
--/*
-- * This file contains the McKinley PMU register description tables
-- * and pmc checker used by perfmon.c.
-- *
-- * Copyright (C) 2002-2003  Hewlett Packard Co
-- *               Stephane Eranian <eranian@hpl.hp.com>
-- */
--static int pfm_mck_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
--
--static pfm_reg_desc_t pfm_mck_pmc_desc[PMU_MAX_PMCS]={
--/* pmc0  */ { PFM_REG_CONTROL , 0, 0x1UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc1  */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc2  */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc3  */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc4  */ { PFM_REG_COUNTING, 6, 0x0000000000800000UL, 0xfffff7fUL, NULL, pfm_mck_pmc_check, {RDEP(4),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc5  */ { PFM_REG_COUNTING, 6, 0x0UL, 0xfffff7fUL, NULL,  pfm_mck_pmc_check, {RDEP(5),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc6  */ { PFM_REG_COUNTING, 6, 0x0UL, 0xfffff7fUL, NULL,  pfm_mck_pmc_check, {RDEP(6),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc7  */ { PFM_REG_COUNTING, 6, 0x0UL, 0xfffff7fUL, NULL,  pfm_mck_pmc_check, {RDEP(7),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc8  */ { PFM_REG_CONFIG  , 0, 0xffffffff3fffffffUL, 0xffffffff3ffffffbUL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc9  */ { PFM_REG_CONFIG  , 0, 0xffffffff3ffffffcUL, 0xffffffff3ffffffbUL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc10 */ { PFM_REG_MONITOR , 4, 0x0UL, 0xffffUL, NULL, pfm_mck_pmc_check, {RDEP(0)|RDEP(1),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* 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}},
--/* 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}},
--/* pmc13 */ { PFM_REG_CONFIG  , 0, 0x00002078fefefefeUL, 0x1e00018181818UL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc14 */ { PFM_REG_CONFIG  , 0, 0x0db60db60db60db6UL, 0x2492UL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--/* pmc15 */ { PFM_REG_CONFIG  , 0, 0x00000000fffffff0UL, 0xfUL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
--          { PFM_REG_END     , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
--};
--
--static pfm_reg_desc_t pfm_mck_pmd_desc[PMU_MAX_PMDS]={
--/* pmd0  */ { PFM_REG_BUFFER  , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(1),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
--/* pmd1  */ { PFM_REG_BUFFER  , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(0),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
--/* pmd2  */ { PFM_REG_BUFFER  , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
--/* pmd3  */ { PFM_REG_BUFFER  , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(2)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
--/* pmd4  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(4),0UL, 0UL, 0UL}},
--/* pmd5  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(5),0UL, 0UL, 0UL}},
--/* pmd6  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(6),0UL, 0UL, 0UL}},
--/* pmd7  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(7),0UL, 0UL, 0UL}},
--/* 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}},
--/* 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}},
--/* 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}},
--/* 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}},
--/* 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}},
--/* 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}},
--/* 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}},
--/* 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}},
--/* 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}},
--/* pmd17 */ { PFM_REG_BUFFER  , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(2)|RDEP(3),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
--          { PFM_REG_END     , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
--};
--
--/*
-- * PMC reserved fields must have their power-up values preserved
-- */
--static int
--pfm_mck_reserved(unsigned int cnum, unsigned long *val, struct pt_regs *regs)
--{
--      unsigned long tmp1, tmp2, ival = *val;
--
--      /* remove reserved areas from user value */
--      tmp1 = ival & PMC_RSVD_MASK(cnum);
--
--      /* get reserved fields values */
--      tmp2 = PMC_DFL_VAL(cnum) & ~PMC_RSVD_MASK(cnum);
--
--      *val = tmp1 | tmp2;
--
--      DPRINT(("pmc[%d]=0x%lx, mask=0x%lx, reset=0x%lx, val=0x%lx\n",
--                cnum, ival, PMC_RSVD_MASK(cnum), PMC_DFL_VAL(cnum), *val));
--      return 0;
--}
--
--/*
-- * task can be NULL if the context is unloaded
-- */
--static int
--pfm_mck_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs)
--{
--      int ret = 0, check_case1 = 0;
--      unsigned long val8 = 0, val14 = 0, val13 = 0;
--      int is_loaded;
--
--      /* first preserve the reserved fields */
--      pfm_mck_reserved(cnum, val, regs);
--
--      /* sanitfy check */
--      if (ctx == NULL) return -EINVAL;
--
--      is_loaded = ctx->ctx_state == PFM_CTX_LOADED || ctx->ctx_state == PFM_CTX_MASKED;
--
--      /*
--       * we must clear the debug registers if pmc13 has a value which enable
--       * memory pipeline event constraints. In this case we need to clear the
--       * the debug registers if they have not yet been accessed. This is required
--       * to avoid picking stale state.
--       * PMC13 is "active" if:
--       *      one of the pmc13.cfg_dbrpXX field is different from 0x3
--       * AND
--       *      at the corresponding pmc13.ena_dbrpXX is set.
--       */
--      DPRINT(("cnum=%u val=0x%lx, using_dbreg=%d loaded=%d\n", cnum, *val, ctx->ctx_fl_using_dbreg, is_loaded));
--
--      if (cnum == 13 && is_loaded
--          && (*val & 0x1e00000000000UL) && (*val & 0x18181818UL) != 0x18181818UL && ctx->ctx_fl_using_dbreg == 0) {
--
--              DPRINT(("pmc[%d]=0x%lx has active pmc13 settings, clearing dbr\n", cnum, *val));
--
--              /* don't mix debug with perfmon */
--              if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
--
--              /*
--               * a count of 0 will mark the debug registers as in use and also
--               * ensure that they are properly cleared.
--               */
--              ret = pfm_write_ibr_dbr(PFM_DATA_RR, ctx, NULL, 0, regs);
--              if (ret) return ret;
--      }
--      /*
--       * we must clear the (instruction) debug registers if any pmc14.ibrpX bit is enabled
--       * before they are (fl_using_dbreg==0) to avoid picking up stale information.
--       */
--      if (cnum == 14 && is_loaded && ((*val & 0x2222UL) != 0x2222UL) && ctx->ctx_fl_using_dbreg == 0) {
--
--              DPRINT(("pmc[%d]=0x%lx has active pmc14 settings, clearing ibr\n", cnum, *val));
--
--              /* don't mix debug with perfmon */
--              if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
--
--              /*
--               * a count of 0 will mark the debug registers as in use and also
--               * ensure that they are properly cleared.
--               */
--              ret = pfm_write_ibr_dbr(PFM_CODE_RR, ctx, NULL, 0, regs);
--              if (ret) return ret;
--
--      }
--
--      switch(cnum) {
--              case  4: *val |= 1UL << 23; /* force power enable bit */
--                       break;
--              case  8: val8 = *val;
--                       val13 = ctx->ctx_pmcs[13];
--                       val14 = ctx->ctx_pmcs[14];
--                       check_case1 = 1;
--                       break;
--              case 13: val8  = ctx->ctx_pmcs[8];
--                       val13 = *val;
--                       val14 = ctx->ctx_pmcs[14];
--                       check_case1 = 1;
--                       break;
--              case 14: val8  = ctx->ctx_pmcs[8];
--                       val13 = ctx->ctx_pmcs[13];
--                       val14 = *val;
--                       check_case1 = 1;
--                       break;
--      }
--      /* check illegal configuration which can produce inconsistencies in tagging
--       * i-side events in L1D and L2 caches
--       */
--      if (check_case1) {
--              ret =   ((val13 >> 45) & 0xf) == 0
--                 && ((val8 & 0x1) == 0)
--                 && ((((val14>>1) & 0x3) == 0x2 || ((val14>>1) & 0x3) == 0x0)
--                     ||(((val14>>4) & 0x3) == 0x2 || ((val14>>4) & 0x3) == 0x0));
--
--              if (ret) DPRINT((KERN_DEBUG "perfmon: failure check_case1\n"));
--      }
--
--      return ret ? -EINVAL : 0;
--}
--
--/*
-- * impl_pmcs, impl_pmds are computed at runtime to minimize errors!
-- */
--static pmu_config_t pmu_conf_mck={
--      .pmu_name      = "Itanium 2",
--      .pmu_family    = 0x1f,
--      .flags         = PFM_PMU_IRQ_RESEND,
--      .ovfl_val      = (1UL << 47) - 1,
--      .pmd_desc      = pfm_mck_pmd_desc,
--      .pmc_desc      = pfm_mck_pmc_desc,
--      .num_ibrs       = 8,
--      .num_dbrs       = 8,
--      .use_rr_dbregs = 1 /* debug register are use for range restrictions */
--};
--
--
-diff --git a/arch/ia64/kernel/perfmon_montecito.h b/arch/ia64/kernel/perfmon_montecito.h
-deleted file mode 100644
-index 7f8da4c..0000000
---- a/arch/ia64/kernel/perfmon_montecito.h
-+++ /dev/null
-@@ -1,269 +0,0 @@
--/*
-- * This file contains the Montecito PMU register description tables
-- * and pmc checker used by perfmon.c.
-- *
-- * Copyright (c) 2005-2006 Hewlett-Packard Development Company, L.P.
-- *               Contributed by Stephane Eranian <eranian@hpl.hp.com>
-- */
--static int pfm_mont_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
--
--#define RDEP_MONT_ETB (RDEP(38)|RDEP(39)|RDEP(48)|RDEP(49)|RDEP(50)|RDEP(51)|RDEP(52)|RDEP(53)|RDEP(54)|\
--                       RDEP(55)|RDEP(56)|RDEP(57)|RDEP(58)|RDEP(59)|RDEP(60)|RDEP(61)|RDEP(62)|RDEP(63))
--#define RDEP_MONT_DEAR  (RDEP(32)|RDEP(33)|RDEP(36))
--#define RDEP_MONT_IEAR  (RDEP(34)|RDEP(35))
--
--static pfm_reg_desc_t pfm_mont_pmc_desc[PMU_MAX_PMCS]={
--/* pmc0  */ { PFM_REG_CONTROL , 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {0,0, 0, 0}},
--/* pmc1  */ { PFM_REG_CONTROL , 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {0,0, 0, 0}},
--/* pmc2  */ { PFM_REG_CONTROL , 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {0,0, 0, 0}},
--/* pmc3  */ { PFM_REG_CONTROL , 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {0,0, 0, 0}},
--/* pmc4  */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(4),0, 0, 0}, {0,0, 0, 0}},
--/* pmc5  */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(5),0, 0, 0}, {0,0, 0, 0}},
--/* pmc6  */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(6),0, 0, 0}, {0,0, 0, 0}},
--/* pmc7  */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(7),0, 0, 0}, {0,0, 0, 0}},
--/* pmc8  */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(8),0, 0, 0}, {0,0, 0, 0}},
--/* pmc9  */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(9),0, 0, 0}, {0,0, 0, 0}},
--/* pmc10 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(10),0, 0, 0}, {0,0, 0, 0}},
--/* pmc11 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(11),0, 0, 0}, {0,0, 0, 0}},
--/* pmc12 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(12),0, 0, 0}, {0,0, 0, 0}},
--/* pmc13 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(13),0, 0, 0}, {0,0, 0, 0}},
--/* pmc14 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(14),0, 0, 0}, {0,0, 0, 0}},
--/* pmc15 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(15),0, 0, 0}, {0,0, 0, 0}},
--/* pmc16 */ { PFM_REG_NOTIMPL, },
--/* pmc17 */ { PFM_REG_NOTIMPL, },
--/* pmc18 */ { PFM_REG_NOTIMPL, },
--/* pmc19 */ { PFM_REG_NOTIMPL, },
--/* pmc20 */ { PFM_REG_NOTIMPL, },
--/* pmc21 */ { PFM_REG_NOTIMPL, },
--/* pmc22 */ { PFM_REG_NOTIMPL, },
--/* pmc23 */ { PFM_REG_NOTIMPL, },
--/* pmc24 */ { PFM_REG_NOTIMPL, },
--/* pmc25 */ { PFM_REG_NOTIMPL, },
--/* pmc26 */ { PFM_REG_NOTIMPL, },
--/* pmc27 */ { PFM_REG_NOTIMPL, },
--/* pmc28 */ { PFM_REG_NOTIMPL, },
--/* pmc29 */ { PFM_REG_NOTIMPL, },
--/* pmc30 */ { PFM_REG_NOTIMPL, },
--/* pmc31 */ { PFM_REG_NOTIMPL, },
--/* pmc32 */ { PFM_REG_CONFIG,  0, 0x30f01ffffffffffUL, 0x30f01ffffffffffUL, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}},
--/* pmc33 */ { PFM_REG_CONFIG,  0, 0x0,  0x1ffffffffffUL, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}},
--/* pmc34 */ { PFM_REG_CONFIG,  0, 0xf01ffffffffffUL, 0xf01ffffffffffUL, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}},
--/* pmc35 */ { PFM_REG_CONFIG,  0, 0x0,  0x1ffffffffffUL, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}},
--/* pmc36 */ { PFM_REG_CONFIG,  0, 0xfffffff0, 0xf, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}},
--/* pmc37 */ { PFM_REG_MONITOR, 4, 0x0, 0x3fff, NULL, pfm_mont_pmc_check, {RDEP_MONT_IEAR, 0, 0, 0}, {0, 0, 0, 0}},
--/* pmc38 */ { PFM_REG_CONFIG,  0, 0xdb6, 0x2492, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}},
--/* pmc39 */ { PFM_REG_MONITOR, 6, 0x0, 0xffcf, NULL, pfm_mont_pmc_check, {RDEP_MONT_ETB,0, 0, 0}, {0,0, 0, 0}},
--/* pmc40 */ { PFM_REG_MONITOR, 6, 0x2000000, 0xf01cf, NULL, pfm_mont_pmc_check, {RDEP_MONT_DEAR,0, 0, 0}, {0,0, 0, 0}},
--/* pmc41 */ { PFM_REG_CONFIG,  0, 0x00002078fefefefeUL, 0x1e00018181818UL, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}},
--/* pmc42 */ { PFM_REG_MONITOR, 6, 0x0, 0x7ff4f, NULL, pfm_mont_pmc_check, {RDEP_MONT_ETB,0, 0, 0}, {0,0, 0, 0}},
--          { PFM_REG_END    , 0, 0x0, -1, NULL, NULL, {0,}, {0,}}, /* end marker */
--};
--
--static pfm_reg_desc_t pfm_mont_pmd_desc[PMU_MAX_PMDS]={
--/* pmd0  */ { PFM_REG_NOTIMPL, }, 
--/* pmd1  */ { PFM_REG_NOTIMPL, },
--/* pmd2  */ { PFM_REG_NOTIMPL, },
--/* pmd3  */ { PFM_REG_NOTIMPL, },
--/* pmd4  */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(4),0, 0, 0}},
--/* pmd5  */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(5),0, 0, 0}},
--/* pmd6  */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(6),0, 0, 0}},
--/* pmd7  */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(7),0, 0, 0}},
--/* pmd8  */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(8),0, 0, 0}}, 
--/* pmd9  */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(9),0, 0, 0}},
--/* pmd10 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(10),0, 0, 0}},
--/* pmd11 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(11),0, 0, 0}},
--/* pmd12 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(12),0, 0, 0}},
--/* pmd13 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(13),0, 0, 0}},
--/* pmd14 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(14),0, 0, 0}},
--/* pmd15 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(15),0, 0, 0}},
--/* pmd16 */ { PFM_REG_NOTIMPL, },
--/* pmd17 */ { PFM_REG_NOTIMPL, },
--/* pmd18 */ { PFM_REG_NOTIMPL, },
--/* pmd19 */ { PFM_REG_NOTIMPL, },
--/* pmd20 */ { PFM_REG_NOTIMPL, },
--/* pmd21 */ { PFM_REG_NOTIMPL, },
--/* pmd22 */ { PFM_REG_NOTIMPL, },
--/* pmd23 */ { PFM_REG_NOTIMPL, },
--/* pmd24 */ { PFM_REG_NOTIMPL, },
--/* pmd25 */ { PFM_REG_NOTIMPL, },
--/* pmd26 */ { PFM_REG_NOTIMPL, },
--/* pmd27 */ { PFM_REG_NOTIMPL, },
--/* pmd28 */ { PFM_REG_NOTIMPL, },
--/* pmd29 */ { PFM_REG_NOTIMPL, },
--/* pmd30 */ { PFM_REG_NOTIMPL, },
--/* pmd31 */ { PFM_REG_NOTIMPL, },
--/* pmd32 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP(33)|RDEP(36),0, 0, 0}, {RDEP(40),0, 0, 0}},
--/* pmd33 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP(32)|RDEP(36),0, 0, 0}, {RDEP(40),0, 0, 0}},
--/* pmd34 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP(35),0, 0, 0}, {RDEP(37),0, 0, 0}},
--/* pmd35 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP(34),0, 0, 0}, {RDEP(37),0, 0, 0}},
--/* pmd36 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP(32)|RDEP(33),0, 0, 0}, {RDEP(40),0, 0, 0}},
--/* pmd37 */ { PFM_REG_NOTIMPL, },
--/* pmd38 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
--/* pmd39 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
--/* pmd40 */ { PFM_REG_NOTIMPL, },
--/* pmd41 */ { PFM_REG_NOTIMPL, },
--/* pmd42 */ { PFM_REG_NOTIMPL, },
--/* pmd43 */ { PFM_REG_NOTIMPL, },
--/* pmd44 */ { PFM_REG_NOTIMPL, },
--/* pmd45 */ { PFM_REG_NOTIMPL, },
--/* pmd46 */ { PFM_REG_NOTIMPL, },
--/* pmd47 */ { PFM_REG_NOTIMPL, },
--/* pmd48 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
--/* pmd49 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
--/* pmd50 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
--/* pmd51 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
--/* pmd52 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
--/* pmd53 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
--/* pmd54 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
--/* pmd55 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
--/* pmd56 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
--/* pmd57 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
--/* pmd58 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
--/* pmd59 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
--/* pmd60 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
--/* pmd61 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
--/* pmd62 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
--/* pmd63 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}},
--          { PFM_REG_END   , 0, 0x0, -1, NULL, NULL, {0,}, {0,}}, /* end marker */
--};
--
--/*
-- * PMC reserved fields must have their power-up values preserved
-- */
--static int
--pfm_mont_reserved(unsigned int cnum, unsigned long *val, struct pt_regs *regs)
--{
--      unsigned long tmp1, tmp2, ival = *val;
--
--      /* remove reserved areas from user value */
--      tmp1 = ival & PMC_RSVD_MASK(cnum);
--
--      /* get reserved fields values */
--      tmp2 = PMC_DFL_VAL(cnum) & ~PMC_RSVD_MASK(cnum);
--
--      *val = tmp1 | tmp2;
--
--      DPRINT(("pmc[%d]=0x%lx, mask=0x%lx, reset=0x%lx, val=0x%lx\n",
--                cnum, ival, PMC_RSVD_MASK(cnum), PMC_DFL_VAL(cnum), *val));
--      return 0;
--}
--
--/*
-- * task can be NULL if the context is unloaded
-- */
--static int
--pfm_mont_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs)
--{
--      int ret = 0;
--      unsigned long val32 = 0, val38 = 0, val41 = 0;
--      unsigned long tmpval;
--      int check_case1 = 0;
--      int is_loaded;
--
--      /* first preserve the reserved fields */
--      pfm_mont_reserved(cnum, val, regs);
--
--      tmpval = *val;
--
--      /* sanity check */
--      if (ctx == NULL) return -EINVAL;
--
--      is_loaded = ctx->ctx_state == PFM_CTX_LOADED || ctx->ctx_state == PFM_CTX_MASKED;
--
--      /*
--       * we must clear the debug registers if pmc41 has a value which enable
--       * memory pipeline event constraints. In this case we need to clear the
--       * the debug registers if they have not yet been accessed. This is required
--       * to avoid picking stale state.
--       * PMC41 is "active" if:
--       *      one of the pmc41.cfg_dtagXX field is different from 0x3
--       * AND
--       *      at the corresponding pmc41.en_dbrpXX is set.
--       * AND
--       *      ctx_fl_using_dbreg == 0  (i.e., dbr not yet used)
--       */
--      DPRINT(("cnum=%u val=0x%lx, using_dbreg=%d loaded=%d\n", cnum, tmpval, ctx->ctx_fl_using_dbreg, is_loaded));
--
--      if (cnum == 41 && is_loaded 
--          && (tmpval & 0x1e00000000000UL) && (tmpval & 0x18181818UL) != 0x18181818UL && ctx->ctx_fl_using_dbreg == 0) {
--
--              DPRINT(("pmc[%d]=0x%lx has active pmc41 settings, clearing dbr\n", cnum, tmpval));
--
--              /* don't mix debug with perfmon */
--              if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
--
--              /*
--               * a count of 0 will mark the debug registers if:
--               * AND
--               */
--              ret = pfm_write_ibr_dbr(PFM_DATA_RR, ctx, NULL, 0, regs);
--              if (ret) return ret;
--      }
--      /*
--       * we must clear the (instruction) debug registers if:
--       *      pmc38.ig_ibrpX is 0 (enabled)
--       * AND
--       *      ctx_fl_using_dbreg == 0  (i.e., dbr not yet used)
--       */
--      if (cnum == 38 && is_loaded && ((tmpval & 0x492UL) != 0x492UL) && ctx->ctx_fl_using_dbreg == 0) {
--
--              DPRINT(("pmc38=0x%lx has active pmc38 settings, clearing ibr\n", tmpval));
--
--              /* don't mix debug with perfmon */
--              if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
--
--              /*
--               * a count of 0 will mark the debug registers as in use and also
--               * ensure that they are properly cleared.
--               */
--              ret = pfm_write_ibr_dbr(PFM_CODE_RR, ctx, NULL, 0, regs);
--              if (ret) return ret;
--
--      }
--      switch(cnum) {
--              case  32: val32 = *val;
--                        val38 = ctx->ctx_pmcs[38];
--                        val41 = ctx->ctx_pmcs[41];
--                        check_case1 = 1;
--                        break;
--              case  38: val38 = *val;
--                        val32 = ctx->ctx_pmcs[32];
--                        val41 = ctx->ctx_pmcs[41];
--                        check_case1 = 1;
--                        break;
--              case  41: val41 = *val;
--                        val32 = ctx->ctx_pmcs[32];
--                        val38 = ctx->ctx_pmcs[38];
--                        check_case1 = 1;
--                        break;
--      }
--      /* check illegal configuration which can produce inconsistencies in tagging
--       * i-side events in L1D and L2 caches
--       */
--      if (check_case1) {
--              ret =   (((val41 >> 45) & 0xf) == 0 && ((val32>>57) & 0x1) == 0)
--                   && ((((val38>>1) & 0x3) == 0x2 || ((val38>>1) & 0x3) == 0)
--                   ||  (((val38>>4) & 0x3) == 0x2 || ((val38>>4) & 0x3) == 0));
--              if (ret) {
--                      DPRINT(("invalid config pmc38=0x%lx pmc41=0x%lx pmc32=0x%lx\n", val38, val41, val32));
--                      return -EINVAL;
--              }
--      }
--      *val = tmpval;
--      return 0;
--}
--
--/*
-- * impl_pmcs, impl_pmds are computed at runtime to minimize errors!
-- */
--static pmu_config_t pmu_conf_mont={
--      .pmu_name        = "Montecito",
--      .pmu_family      = 0x20,
--      .flags           = PFM_PMU_IRQ_RESEND,
--      .ovfl_val        = (1UL << 47) - 1,
--      .pmd_desc        = pfm_mont_pmd_desc,
--      .pmc_desc        = pfm_mont_pmc_desc,
--      .num_ibrs        = 8,
--      .num_dbrs        = 8,
--      .use_rr_dbregs   = 1 /* debug register are use for range retrictions */
--};
-diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
-index 3ab8373..a7dfb39 100644
---- a/arch/ia64/kernel/process.c
-+++ b/arch/ia64/kernel/process.c
-@@ -28,6 +28,7 @@
- #include <linux/delay.h>
- #include <linux/kdebug.h>
- #include <linux/utsname.h>
-+#include <linux/perfmon_kern.h>
- #include <asm/cpu.h>
- #include <asm/delay.h>
-@@ -45,10 +46,6 @@
- #include "entry.h"
--#ifdef CONFIG_PERFMON
--# include <asm/perfmon.h>
--#endif
--
- #include "sigframe.h"
- void (*ia64_mark_idle)(int);
-@@ -162,10 +159,8 @@ show_regs (struct pt_regs *regs)
- void tsk_clear_notify_resume(struct task_struct *tsk)
- {
--#ifdef CONFIG_PERFMON
--      if (tsk->thread.pfm_needs_checking)
-+      if (test_ti_thread_flag(task_thread_info(tsk), TIF_PERFMON_WORK))
-               return;
--#endif
-       if (test_ti_thread_flag(task_thread_info(tsk), TIF_RESTORE_RSE))
-               return;
-       clear_ti_thread_flag(task_thread_info(tsk), TIF_NOTIFY_RESUME);
-@@ -188,14 +183,9 @@ do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall)
-               return;
-       }
--#ifdef CONFIG_PERFMON
--      if (current->thread.pfm_needs_checking)
--              /*
--               * Note: pfm_handle_work() allow us to call it with interrupts
--               * disabled, and may enable interrupts within the function.
--               */
--              pfm_handle_work();
--#endif
-+      /* process perfmon asynchronous work (e.g. block thread or reset) */
-+      if (test_thread_flag(TIF_PERFMON_WORK))
-+              pfm_handle_work(task_pt_regs(current));
-       /* deal with pending signal delivery */
-       if (test_thread_flag(TIF_SIGPENDING)) {
-@@ -212,22 +202,15 @@ do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall)
-       local_irq_disable();    /* force interrupt disable */
- }
--static int pal_halt        = 1;
- static int can_do_pal_halt = 1;
- static int __init nohalt_setup(char * str)
- {
--      pal_halt = can_do_pal_halt = 0;
-+      can_do_pal_halt = 0;
-       return 1;
- }
- __setup("nohalt", nohalt_setup);
--void
--update_pal_halt_status(int status)
--{
--      can_do_pal_halt = pal_halt && status;
--}
--
- /*
-  * We use this if we don't have any better idle routine..
-  */
-@@ -236,6 +219,22 @@ default_idle (void)
- {
-       local_irq_enable();
-       while (!need_resched()) {
-+#ifdef CONFIG_PERFMON
-+              u64 psr = 0;
-+              /*
-+               * If requested, we stop the PMU to avoid
-+               * measuring across the core idle loop.
-+               *
-+               * dcr.pp is not modified on purpose
-+               * it is used when coming out of
-+               * safe_halt() via interrupt
-+               */
-+              if ((__get_cpu_var(pfm_syst_info) & PFM_ITA_CPUINFO_IDLE_EXCL)) {
-+                      psr = ia64_getreg(_IA64_REG_PSR);
-+                      if (psr & IA64_PSR_PP)
-+                              ia64_rsm(IA64_PSR_PP);
-+              }
-+#endif
-               if (can_do_pal_halt) {
-                       local_irq_disable();
-                       if (!need_resched()) {
-@@ -244,6 +243,12 @@ default_idle (void)
-                       local_irq_enable();
-               } else
-                       cpu_relax();
-+#ifdef CONFIG_PERFMON
-+              if ((__get_cpu_var(pfm_syst_info) & PFM_ITA_CPUINFO_IDLE_EXCL)) {
-+                      if (psr & IA64_PSR_PP)
-+                              ia64_ssm(IA64_PSR_PP);
-+              }
-+#endif
-       }
- }
-@@ -344,22 +349,9 @@ cpu_idle (void)
- void
- ia64_save_extra (struct task_struct *task)
- {
--#ifdef CONFIG_PERFMON
--      unsigned long info;
--#endif
--
-       if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0)
-               ia64_save_debug_regs(&task->thread.dbr[0]);
--#ifdef CONFIG_PERFMON
--      if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0)
--              pfm_save_regs(task);
--
--      info = __get_cpu_var(pfm_syst_info);
--      if (info & PFM_CPUINFO_SYST_WIDE)
--              pfm_syst_wide_update_task(task, info, 0);
--#endif
--
- #ifdef CONFIG_IA32_SUPPORT
-       if (IS_IA32_PROCESS(task_pt_regs(task)))
-               ia32_save_state(task);
-@@ -369,22 +361,9 @@ ia64_save_extra (struct task_struct *task)
- void
- ia64_load_extra (struct task_struct *task)
- {
--#ifdef CONFIG_PERFMON
--      unsigned long info;
--#endif
--
-       if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0)
-               ia64_load_debug_regs(&task->thread.dbr[0]);
--#ifdef CONFIG_PERFMON
--      if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0)
--              pfm_load_regs(task);
--
--      info = __get_cpu_var(pfm_syst_info);
--      if (info & PFM_CPUINFO_SYST_WIDE) 
--              pfm_syst_wide_update_task(task, info, 1);
--#endif
--
- #ifdef CONFIG_IA32_SUPPORT
-       if (IS_IA32_PROCESS(task_pt_regs(task)))
-               ia32_load_state(task);
-@@ -510,8 +489,7 @@ copy_thread (int nr, unsigned long clone_flags,
-        * call behavior where scratch registers are preserved across
-        * system calls (unless used by the system call itself).
-        */
--#     define THREAD_FLAGS_TO_CLEAR    (IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID \
--                                       | IA64_THREAD_PM_VALID)
-+#     define THREAD_FLAGS_TO_CLEAR    (IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID)
- #     define THREAD_FLAGS_TO_SET      0
-       p->thread.flags = ((current->thread.flags & ~THREAD_FLAGS_TO_CLEAR)
-                          | THREAD_FLAGS_TO_SET);
-@@ -533,10 +511,8 @@ copy_thread (int nr, unsigned long clone_flags,
-       }
- #endif
--#ifdef CONFIG_PERFMON
--      if (current->thread.pfm_context)
--              pfm_inherit(p, child_ptregs);
--#endif
-+      pfm_copy_thread(p);
-+
-       return retval;
- }
-@@ -745,15 +721,13 @@ exit_thread (void)
- {
-       ia64_drop_fpu(current);
--#ifdef CONFIG_PERFMON
--       /* if needed, stop monitoring and flush state to perfmon context */
--      if (current->thread.pfm_context)
--              pfm_exit_thread(current);
-+
-+      /* if needed, stop monitoring and flush state to perfmon context */
-+      pfm_exit_thread();
-       /* free debug register resources */
--      if (current->thread.flags & IA64_THREAD_DBG_VALID)
--              pfm_release_debug_registers(current);
--#endif
-+      pfm_release_dbregs(current);
-+
-       if (IS_IA32_PROCESS(task_pt_regs(current)))
-               ia32_drop_ia64_partial_page_list(current);
- }
-diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
-index 2a9943b..bb1ca1e 100644
---- a/arch/ia64/kernel/ptrace.c
-+++ b/arch/ia64/kernel/ptrace.c
-@@ -20,6 +20,7 @@
- #include <linux/security.h>
- #include <linux/audit.h>
- #include <linux/signal.h>
-+#include <linux/perfmon_kern.h>
- #include <linux/regset.h>
- #include <linux/elf.h>
-@@ -30,9 +31,6 @@
- #include <asm/system.h>
- #include <asm/uaccess.h>
- #include <asm/unwind.h>
--#ifdef CONFIG_PERFMON
--#include <asm/perfmon.h>
--#endif
- #include "entry.h"
-@@ -2124,7 +2122,6 @@ access_uarea(struct task_struct *child, unsigned long addr,
-                               "address 0x%lx\n", addr);
-               return -1;
-       }
--#ifdef CONFIG_PERFMON
-       /*
-        * Check if debug registers are used by perfmon. This
-        * test must be done once we know that we can do the
-@@ -2142,9 +2139,8 @@ access_uarea(struct task_struct *child, unsigned long addr,
-        * IA64_THREAD_DBG_VALID. The registers are restored
-        * by the PMU context switch code.
-        */
--      if (pfm_use_debug_registers(child))
-+      if (pfm_use_dbregs(child))
-               return -1;
--#endif
-       if (!(child->thread.flags & IA64_THREAD_DBG_VALID)) {
-               child->thread.flags |= IA64_THREAD_DBG_VALID;
-diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
-index de636b2..677fa68 100644
---- a/arch/ia64/kernel/setup.c
-+++ b/arch/ia64/kernel/setup.c
-@@ -45,6 +45,7 @@
- #include <linux/cpufreq.h>
- #include <linux/kexec.h>
- #include <linux/crash_dump.h>
-+#include <linux/perfmon_kern.h>
- #include <asm/ia32.h>
- #include <asm/machvec.h>
-@@ -1051,6 +1052,8 @@ cpu_init (void)
-       }
-       platform_cpu_init();
-       pm_idle = default_idle;
-+
-+      pfm_init_percpu();
- }
- void __init
-diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
-index d8f05e5..3d7a739 100644
---- a/arch/ia64/kernel/smpboot.c
-+++ b/arch/ia64/kernel/smpboot.c
-@@ -39,6 +39,7 @@
- #include <linux/efi.h>
- #include <linux/percpu.h>
- #include <linux/bitops.h>
-+#include <linux/perfmon_kern.h>
- #include <asm/atomic.h>
- #include <asm/cache.h>
-@@ -381,10 +382,6 @@ smp_callin (void)
-       extern void ia64_init_itm(void);
-       extern volatile int time_keeper_id;
--#ifdef CONFIG_PERFMON
--      extern void pfm_init_percpu(void);
--#endif
--
-       cpuid = smp_processor_id();
-       phys_id = hard_smp_processor_id();
-       itc_master = time_keeper_id;
-@@ -410,10 +407,6 @@ smp_callin (void)
-       ia64_mca_cmc_vector_setup();    /* Setup vector on AP */
--#ifdef CONFIG_PERFMON
--      pfm_init_percpu();
--#endif
--
-       local_irq_enable();
-       if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT)) {
-@@ -751,6 +744,7 @@ int __cpu_disable(void)
-       cpu_clear(cpu, cpu_online_map);
-       local_flush_tlb_all();
-       cpu_clear(cpu, cpu_callin_map);
-+      pfm_cpu_disable();
-       return 0;
- }
-diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c
-index bcbb6d8..a0ed33a 100644
---- a/arch/ia64/kernel/sys_ia64.c
-+++ b/arch/ia64/kernel/sys_ia64.c
-@@ -284,3 +284,11 @@ sys_pciconfig_write (unsigned long bus, unsigned long dfn, unsigned long off, un
- }
- #endif /* CONFIG_PCI */
-+
-+#ifndef CONFIG_IA64_PERFMON_COMPAT
-+asmlinkage long
-+sys_perfmonctl (int fd, int cmd, void __user *arg, int count)
-+{
-+      return -ENOSYS;
-+}
-+#endif
-diff --git a/arch/ia64/lib/Makefile b/arch/ia64/lib/Makefile
-index 98771e2..077fd09 100644
---- a/arch/ia64/lib/Makefile
-+++ b/arch/ia64/lib/Makefile
-@@ -13,7 +13,6 @@ lib-y := __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o                       \
- obj-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o
- obj-$(CONFIG_MCKINLEY)        += copy_page_mck.o memcpy_mck.o
--lib-$(CONFIG_PERFMON) += carta_random.o
- AFLAGS___divdi3.o     =
- AFLAGS___udivdi3.o    = -DUNSIGNED
-diff --git a/arch/ia64/oprofile/init.c b/arch/ia64/oprofile/init.c
-index 125a602..892de6a 100644
---- a/arch/ia64/oprofile/init.c
-+++ b/arch/ia64/oprofile/init.c
-@@ -12,8 +12,8 @@
- #include <linux/init.h>
- #include <linux/errno.h>
-  
--extern int perfmon_init(struct oprofile_operations * ops);
--extern void perfmon_exit(void);
-+extern int op_perfmon_init(struct oprofile_operations * ops);
-+extern void op_perfmon_exit(void);
- extern void ia64_backtrace(struct pt_regs * const regs, unsigned int depth);
- int __init oprofile_arch_init(struct oprofile_operations * ops)
-@@ -22,7 +22,7 @@ int __init oprofile_arch_init(struct oprofile_operations * ops)
- #ifdef CONFIG_PERFMON
-       /* perfmon_init() can fail, but we have no way to report it */
--      ret = perfmon_init(ops);
-+      ret = op_perfmon_init(ops);
- #endif
-       ops->backtrace = ia64_backtrace;
-@@ -33,6 +33,6 @@ int __init oprofile_arch_init(struct oprofile_operations * ops)
- void oprofile_arch_exit(void)
- {
- #ifdef CONFIG_PERFMON
--      perfmon_exit();
-+      op_perfmon_exit();
- #endif
- }
-diff --git a/arch/ia64/oprofile/perfmon.c b/arch/ia64/oprofile/perfmon.c
-index bc41dd3..6fa9d17 100644
---- a/arch/ia64/oprofile/perfmon.c
-+++ b/arch/ia64/oprofile/perfmon.c
-@@ -10,25 +10,30 @@
- #include <linux/kernel.h>
- #include <linux/oprofile.h>
- #include <linux/sched.h>
--#include <asm/perfmon.h>
-+#include <linux/module.h>
-+#include <linux/perfmon_kern.h>
- #include <asm/ptrace.h>
- #include <asm/errno.h>
- static int allow_ints;
- static int
--perfmon_handler(struct task_struct *task, void *buf, pfm_ovfl_arg_t *arg,
--                struct pt_regs *regs, unsigned long stamp)
-+perfmon_handler(struct pfm_context *ctx,
-+              unsigned long ip, u64 stamp, void *data)
- {
--      int event = arg->pmd_eventid;
-+      struct pt_regs *regs;
-+      struct pfm_ovfl_arg *arg;
-+
-+      regs = data;
-+      arg = &ctx->ovfl_arg;
-  
--      arg->ovfl_ctrl.bits.reset_ovfl_pmds = 1;
-+      arg->ovfl_ctrl = PFM_OVFL_CTRL_RESET;
-       /* the owner of the oprofile event buffer may have exited
-        * without perfmon being shutdown (e.g. SIGSEGV)
-        */
-       if (allow_ints)
--              oprofile_add_sample(regs, event);
-+              oprofile_add_sample(regs, arg->pmd_eventid);
-       return 0;
- }
-@@ -45,17 +50,13 @@ static void perfmon_stop(void)
-       allow_ints = 0;
- }
--
--#define OPROFILE_FMT_UUID { \
--      0x77, 0x7a, 0x6e, 0x61, 0x20, 0x65, 0x73, 0x69, 0x74, 0x6e, 0x72, 0x20, 0x61, 0x65, 0x0a, 0x6c }
--
--static pfm_buffer_fmt_t oprofile_fmt = {
--      .fmt_name           = "oprofile_format",
--      .fmt_uuid           = OPROFILE_FMT_UUID,
--      .fmt_handler        = perfmon_handler,
-+static struct pfm_smpl_fmt oprofile_fmt = {
-+      .fmt_name = "OProfile",
-+      .fmt_handler = perfmon_handler,
-+      .fmt_flags = PFM_FMT_BUILTIN_FLAG,
-+      .owner = THIS_MODULE
- };
--
- static char * get_cpu_type(void)
- {
-       __u8 family = local_cpu_data->family;
-@@ -75,9 +76,9 @@ static char * get_cpu_type(void)
- static int using_perfmon;
--int perfmon_init(struct oprofile_operations * ops)
-+int __init op_perfmon_init(struct oprofile_operations * ops)
- {
--      int ret = pfm_register_buffer_fmt(&oprofile_fmt);
-+      int ret = pfm_fmt_register(&oprofile_fmt);
-       if (ret)
-               return -ENODEV;
-@@ -90,10 +91,10 @@ int perfmon_init(struct oprofile_operations * ops)
- }
--void perfmon_exit(void)
-+void __exit op_perfmon_exit(void)
- {
-       if (!using_perfmon)
-               return;
--      pfm_unregister_buffer_fmt(oprofile_fmt.fmt_uuid);
-+      pfm_fmt_unregister(&oprofile_fmt);
- }
-diff --git a/arch/ia64/perfmon/Kconfig b/arch/ia64/perfmon/Kconfig
-new file mode 100644
-index 0000000..99c68bd
---- /dev/null
-+++ b/arch/ia64/perfmon/Kconfig
-@@ -0,0 +1,67 @@
-+menu "Hardware Performance Monitoring support"
-+config PERFMON
-+      bool "Perfmon2 performance monitoring interface"
-+      default n
-+      help
-+      Enables the perfmon2 interface to access the hardware
-+      performance counters. See <http://perfmon2.sf.net/> for
-+      more details.
-+
-+config PERFMON_DEBUG
-+      bool "Perfmon debugging"
-+      default n
-+      depends on PERFMON
-+      help
-+      Enables perfmon debugging support
-+
-+config PERFMON_DEBUG_FS
-+      bool "Enable perfmon statistics reporting via debugfs"
-+      default y
-+      depends on PERFMON && DEBUG_FS
-+      help
-+      Enable collection and reporting of perfmon timing statistics under
-+      debugfs. This is used for debugging and performance analysis of the
-+      subsystem. The debugfs filesystem must be mounted.
-+
-+config IA64_PERFMON_COMPAT
-+      bool "Enable old perfmon-2 compatbility mode"
-+      default n
-+      depends on PERFMON
-+      help
-+      Enable this option to allow performance tools which used the old
-+      perfmon-2 interface to continue to work. Old tools are those using
-+      the obsolete commands and arguments. Check your programs and look
-+      in include/asm-ia64/perfmon_compat.h for more information.
-+
-+config IA64_PERFMON_GENERIC
-+      tristate "Generic IA-64 PMU support"
-+      depends on PERFMON
-+      default n
-+      help
-+      Enables generic IA-64 PMU support.
-+      The generic PMU is defined by the IA-64 architecture document.
-+      This option should only be necessary when running with a PMU that
-+      is not yet explicitely supported. Even then, there is no guarantee
-+      that this support will work.
-+
-+config IA64_PERFMON_ITANIUM
-+      tristate "Itanium (Merced) Performance Monitoring support"
-+      depends on PERFMON
-+      default n
-+      help
-+      Enables Itanium (Merced) PMU support.
-+
-+config IA64_PERFMON_MCKINLEY
-+      tristate "Itanium 2 (McKinley) Performance Monitoring  support"
-+      depends on PERFMON
-+      default n
-+      help
-+      Enables Itanium 2 (McKinley, Madison, Deerfield) PMU support.
-+
-+config IA64_PERFMON_MONTECITO
-+      tristate "Itanium 2 9000 (Montecito) Performance Monitoring  support"
-+      depends on PERFMON
-+      default n
-+      help
-+      Enables support for Itanium 2 9000 (Montecito) PMU.
-+endmenu
-diff --git a/arch/ia64/perfmon/Makefile b/arch/ia64/perfmon/Makefile
-new file mode 100644
-index 0000000..c9cdf9f
---- /dev/null
-+++ b/arch/ia64/perfmon/Makefile
-@@ -0,0 +1,11 @@
-+#
-+# Copyright (c) 2005-2006 Hewlett-Packard Development Company, L.P.
-+# Contributed by Stephane Eranian <eranian@hpl.hp.com>
-+#
-+obj-$(CONFIG_PERFMON)                 += perfmon.o
-+obj-$(CONFIG_IA64_PERFMON_COMPAT)     += perfmon_default_smpl.o \
-+                                         perfmon_compat.o
-+obj-$(CONFIG_IA64_PERFMON_GENERIC)    += perfmon_generic.o
-+obj-$(CONFIG_IA64_PERFMON_ITANIUM)    += perfmon_itanium.o
-+obj-$(CONFIG_IA64_PERFMON_MCKINLEY)   += perfmon_mckinley.o
-+obj-$(CONFIG_IA64_PERFMON_MONTECITO)  += perfmon_montecito.o
-diff --git a/arch/ia64/perfmon/perfmon.c b/arch/ia64/perfmon/perfmon.c
-new file mode 100644
-index 0000000..3f59410
---- /dev/null
-+++ b/arch/ia64/perfmon/perfmon.c
-@@ -0,0 +1,946 @@
-+/*
-+ * This file implements the IA-64 specific
-+ * support for the perfmon2 interface
-+ *
-+ * Copyright (c) 1999-2006 Hewlett-Packard Development Company, L.P.
-+ * Contributed by Stephane Eranian <eranian@hpl.hp.com>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of version 2 of the GNU General Public
-+ * License as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ * 02111-1307 USA
-+  */
-+#include <linux/module.h>
-+#include <linux/perfmon_kern.h>
-+
-+struct pfm_arch_session {
-+      u32     pfs_sys_use_dbr;    /* syswide session uses dbr */
-+      u32     pfs_ptrace_use_dbr; /* a thread uses dbr via ptrace()*/
-+};
-+
-+DEFINE_PER_CPU(u32, pfm_syst_info);
-+
-+static struct pfm_arch_session pfm_arch_sessions;
-+static __cacheline_aligned_in_smp DEFINE_SPINLOCK(pfm_arch_sessions_lock);
-+
-+static inline void pfm_clear_psr_pp(void)
-+{
-+      ia64_rsm(IA64_PSR_PP);
-+}
-+
-+static inline void pfm_set_psr_pp(void)
-+{
-+      ia64_ssm(IA64_PSR_PP);
-+}
-+
-+static inline void pfm_clear_psr_up(void)
-+{
-+      ia64_rsm(IA64_PSR_UP);
-+}
-+
-+static inline void pfm_set_psr_up(void)
-+{
-+      ia64_ssm(IA64_PSR_UP);
-+}
-+
-+static inline void pfm_set_psr_l(u64 val)
-+{
-+      ia64_setreg(_IA64_REG_PSR_L, val);
-+}
-+
-+static inline void pfm_restore_ibrs(u64 *ibrs, unsigned int nibrs)
-+{
-+      unsigned int i;
-+
-+      for (i = 0; i < nibrs; i++) {
-+              ia64_set_ibr(i, ibrs[i]);
-+              ia64_dv_serialize_instruction();
-+      }
-+      ia64_srlz_i();
-+}
-+
-+static inline void pfm_restore_dbrs(u64 *dbrs, unsigned int ndbrs)
-+{
-+      unsigned int i;
-+
-+      for (i = 0; i < ndbrs; i++) {
-+              ia64_set_dbr(i, dbrs[i]);
-+              ia64_dv_serialize_data();
-+      }
-+      ia64_srlz_d();
-+}
-+
-+irqreturn_t pmu_interrupt_handler(int irq, void *arg)
-+{
-+      struct pt_regs *regs;
-+      regs = get_irq_regs();
-+      irq_enter();
-+      pfm_interrupt_handler(instruction_pointer(regs), regs);
-+      irq_exit();
-+      return IRQ_HANDLED;
-+}
-+static struct irqaction perfmon_irqaction = {
-+      .handler = pmu_interrupt_handler,
-+      .flags = IRQF_DISABLED, /* means keep interrupts masked */
-+      .name = "perfmon"
-+};
-+
-+void pfm_arch_quiesce_pmu_percpu(void)
-+{
-+      u64 dcr;
-+      /*
-+       * make sure no measurement is active
-+       * (may inherit programmed PMCs from EFI).
-+       */
-+      pfm_clear_psr_pp();
-+      pfm_clear_psr_up();
-+
-+      /*
-+       * ensure dcr.pp is cleared
-+       */
-+      dcr = ia64_getreg(_IA64_REG_CR_DCR);
-+      ia64_setreg(_IA64_REG_CR_DCR, dcr & ~IA64_DCR_PP);
-+
-+      /*
-+       * we run with the PMU not frozen at all times
-+       */
-+      ia64_set_pmc(0, 0);
-+      ia64_srlz_d();
-+}
-+
-+void pfm_arch_init_percpu(void)
-+{
-+      pfm_arch_quiesce_pmu_percpu();
-+      /*
-+       * program PMU interrupt vector
-+       */
-+      ia64_setreg(_IA64_REG_CR_PMV, IA64_PERFMON_VECTOR);
-+      ia64_srlz_d();
-+}
-+
-+int pfm_arch_context_create(struct pfm_context *ctx, u32 ctx_flags)
-+{
-+      struct pfm_arch_context *ctx_arch;
-+
-+      ctx_arch = pfm_ctx_arch(ctx);
-+
-+      ctx_arch->flags.use_dbr = 0;
-+      ctx_arch->flags.insecure = (ctx_flags & PFM_ITA_FL_INSECURE) ? 1: 0;
-+
-+      PFM_DBG("insecure=%d", ctx_arch->flags.insecure);
-+
-+      return 0;
-+}
-+
-+/*
-+ * Called from pfm_ctxsw(). Task is guaranteed to be current.
-+ * Context is locked. Interrupts are masked. Monitoring may be active.
-+ * PMU access is guaranteed. PMC and PMD registers are live in PMU.
-+ *
-+ * Return:
-+ *    non-zero : did not save PMDs (as part of stopping the PMU)
-+ *           0 : saved PMDs (no need to save them in caller)
-+ */
-+int pfm_arch_ctxswout_thread(struct task_struct *task, struct pfm_context *ctx)
-+{
-+      struct pfm_arch_context *ctx_arch;
-+      struct pfm_event_set *set;
-+      u64 psr, tmp;
-+
-+      ctx_arch = pfm_ctx_arch(ctx);
-+      set = ctx->active_set;
-+
-+      /*
-+       * save current PSR: needed because we modify it
-+       */
-+      ia64_srlz_d();
-+      psr = ia64_getreg(_IA64_REG_PSR);
-+
-+      /*
-+       * stop monitoring:
-+       * This is the last instruction which may generate an overflow
-+       *
-+       * we do not clear ipsr.up
-+       */
-+      pfm_clear_psr_up();
-+      ia64_srlz_d();
-+
-+      /*
-+       * extract overflow status bits
-+       */
-+      tmp =  ia64_get_pmc(0) & ~0xf;
-+
-+      /*
-+       * keep a copy of psr.up (for reload)
-+       */
-+      ctx_arch->ctx_saved_psr_up = psr & IA64_PSR_UP;
-+
-+      /*
-+       * save overflow status bits
-+       */
-+      set->povfl_pmds[0] = tmp;
-+
-+      /*
-+       * record how many pending overflows
-+       * XXX: assume identity mapping for counters
-+       */
-+      set->npend_ovfls = ia64_popcnt(tmp);
-+
-+      /*
-+       * make sure the PMU is unfrozen for the next task
-+       */
-+      if (set->npend_ovfls) {
-+              ia64_set_pmc(0, 0);
-+              ia64_srlz_d();
-+      }
-+      return 1;
-+}
-+
-+/*
-+ * Called from pfm_ctxsw(). Task is guaranteed to be current.
-+ * set cannot be NULL. Context is locked. Interrupts are masked.
-+ * Caller has already restored all PMD and PMC registers.
-+ *
-+ * must reactivate monitoring
-+ */
-+void pfm_arch_ctxswin_thread(struct task_struct *task, struct pfm_context *ctx)
-+{
-+      struct pfm_arch_context *ctx_arch;
-+
-+      ctx_arch = pfm_ctx_arch(ctx);
-+
-+      /*
-+       * when monitoring is not explicitly started
-+       * then psr_up = 0, in which case we do not
-+       * need to restore
-+       */
-+      if (likely(ctx_arch->ctx_saved_psr_up)) {
-+              pfm_set_psr_up();
-+              ia64_srlz_d();
-+      }
-+}
-+
-+int pfm_arch_reserve_session(struct pfm_context *ctx, u32 cpu)
-+{
-+      struct pfm_arch_context *ctx_arch;
-+      int is_system;
-+      int ret = 0;
-+
-+      ctx_arch = pfm_ctx_arch(ctx);
-+      is_system = ctx->flags.system;
-+
-+      spin_lock(&pfm_arch_sessions_lock);
-+
-+      if (is_system && ctx_arch->flags.use_dbr) {
-+              PFM_DBG("syswide context uses dbregs");
-+
-+              if (pfm_arch_sessions.pfs_ptrace_use_dbr) {
-+                      PFM_DBG("cannot reserve syswide context: "
-+                                "dbregs in use by ptrace");
-+                      ret = -EBUSY;
-+              } else {
-+                      pfm_arch_sessions.pfs_sys_use_dbr++;
-+              }
-+      }
-+      spin_unlock(&pfm_arch_sessions_lock);
-+
-+      return ret;
-+}
-+
-+void pfm_arch_release_session(struct pfm_context *ctx, u32 cpu)
-+{
-+      struct pfm_arch_context *ctx_arch;
-+      int is_system;
-+
-+      ctx_arch = pfm_ctx_arch(ctx);
-+      is_system = ctx->flags.system;
-+
-+      spin_lock(&pfm_arch_sessions_lock);
-+
-+      if (is_system && ctx_arch->flags.use_dbr)
-+              pfm_arch_sessions.pfs_sys_use_dbr--;
-+      spin_unlock(&pfm_arch_sessions_lock);
-+}
-+
-+/*
-+ * function called from pfm_load_context_*(). Task is not guaranteed to be
-+ * current task. If not then other task is guaranteed stopped and off any CPU.
-+ * context is locked and interrupts are masked.
-+ *
-+ * On PFM_LOAD_CONTEXT, the interface guarantees monitoring is stopped.
-+ *
-+ * For system-wide task is NULL
-+ */
-+int pfm_arch_load_context(struct pfm_context *ctx)
-+{
-+      struct pfm_arch_context *ctx_arch;
-+      struct pt_regs *regs;
-+      int ret = 0;
-+
-+      ctx_arch = pfm_ctx_arch(ctx);
-+
-+      /*
-+       * cannot load a context which is using range restrictions,
-+       * into a thread that is being debugged.
-+       *
-+       * if one set out of several is using the debug registers, then
-+       * we assume the context as whole is using them.
-+       */
-+      if (ctx_arch->flags.use_dbr) {
-+              if (ctx->flags.system) {
-+                      spin_lock(&pfm_arch_sessions_lock);
-+
-+                      if (pfm_arch_sessions.pfs_ptrace_use_dbr) {
-+                              PFM_DBG("cannot reserve syswide context: "
-+                                      "dbregs in use by ptrace");
-+                              ret = -EBUSY;
-+                      } else {
-+                              pfm_arch_sessions.pfs_sys_use_dbr++;
-+                              PFM_DBG("pfs_sys_use_dbr=%u",
-+                                      pfm_arch_sessions.pfs_sys_use_dbr);
-+                      }
-+                      spin_unlock(&pfm_arch_sessions_lock);
-+
-+              } else if (ctx->task->thread.flags & IA64_THREAD_DBG_VALID) {
-+                      PFM_DBG("load_pid [%d] thread is debugged, cannot "
-+                                "use range restrictions", ctx->task->pid);
-+                      ret = -EBUSY;
-+              }
-+              if (ret)
-+                      return ret;
-+      }
-+
-+      /*
-+       * We need to intervene on context switch to toggle the
-+       * psr.pp bit in system-wide. As such, we set the TIF
-+       * flag so that pfm_arch_ctxswout_sys() and the
-+       * pfm_arch_ctxswin_sys() functions get called
-+       * from pfm_ctxsw_sys();
-+       */
-+      if (ctx->flags.system) {
-+              set_thread_flag(TIF_PERFMON_CTXSW);
-+              PFM_DBG("[%d] set TIF", current->pid);
-+              return 0;
-+      }
-+
-+      regs = task_pt_regs(ctx->task);
-+
-+      /*
-+       * self-monitoring systematically allows user level control
-+       */
-+      if (ctx->task != current) {
-+              /*
-+               * when not current, task is stopped, so this is safe
-+               */
-+              ctx_arch->ctx_saved_psr_up = 0;
-+              ia64_psr(regs)->up = ia64_psr(regs)->pp = 0;
-+      } else
-+              ctx_arch->flags.insecure = 1;
-+
-+      /*
-+       * allow user level control (start/stop/read pmd) if:
-+       *      - self-monitoring
-+       *      - requested at context creation (PFM_IA64_FL_INSECURE)
-+       *
-+       * There is not security hole with PFM_IA64_FL_INSECURE because
-+       * when not self-monitored, the caller must have permissions to
-+       * attached to the task.
-+       */
-+      if (ctx_arch->flags.insecure) {
-+              ia64_psr(regs)->sp = 0;
-+              PFM_DBG("clearing psr.sp for [%d]", ctx->task->pid);
-+      }
-+      return 0;
-+}
-+
-+int pfm_arch_setfl_sane(struct pfm_context *ctx, u32 flags)
-+{
-+#define PFM_SETFL_BOTH_SWITCH (PFM_SETFL_OVFL_SWITCH|PFM_SETFL_TIME_SWITCH)
-+#define PFM_ITA_SETFL_BOTH_INTR       (PFM_ITA_SETFL_INTR_ONLY|\
-+                               PFM_ITA_SETFL_EXCL_INTR)
-+
-+/* exclude return value field */
-+#define PFM_SETFL_ALL_MASK    (PFM_ITA_SETFL_BOTH_INTR \
-+                               | PFM_SETFL_BOTH_SWITCH        \
-+                               | PFM_ITA_SETFL_IDLE_EXCL)
-+
-+      if ((flags & ~PFM_SETFL_ALL_MASK)) {
-+              PFM_DBG("invalid flags=0x%x", flags);
-+              return -EINVAL;
-+      }
-+
-+      if ((flags & PFM_ITA_SETFL_BOTH_INTR) == PFM_ITA_SETFL_BOTH_INTR) {
-+              PFM_DBG("both excl intr and ontr only are set");
-+              return -EINVAL;
-+      }
-+
-+      if ((flags & PFM_ITA_SETFL_IDLE_EXCL) && !ctx->flags.system) {
-+              PFM_DBG("idle exclude flag only for system-wide context");
-+              return -EINVAL;
-+      }
-+      return 0;
-+}
-+
-+/*
-+ * function called from pfm_unload_context_*(). Context is locked.
-+ * interrupts are masked. task is not guaranteed to be current task.
-+ * Access to PMU is not guaranteed.
-+ *
-+ * function must do whatever arch-specific action is required on unload
-+ * of a context.
-+ *
-+ * called for both system-wide and per-thread. task is NULL for ssytem-wide
-+ */
-+void pfm_arch_unload_context(struct pfm_context *ctx)
-+{
-+      struct pfm_arch_context *ctx_arch;
-+      struct pt_regs *regs;
-+
-+      ctx_arch = pfm_ctx_arch(ctx);
-+
-+      if (ctx->flags.system) {
-+              /*
-+               * disable context switch hook
-+               */
-+              clear_thread_flag(TIF_PERFMON_CTXSW);
-+
-+              if (ctx_arch->flags.use_dbr) {
-+                      spin_lock(&pfm_arch_sessions_lock);
-+                      pfm_arch_sessions.pfs_sys_use_dbr--;
-+                      PFM_DBG("sys_use_dbr=%u", pfm_arch_sessions.pfs_sys_use_dbr);
-+                      spin_unlock(&pfm_arch_sessions_lock);
-+              }
-+      } else {
-+              regs = task_pt_regs(ctx->task);
-+
-+              /*
-+               * cancel user level control for per-task context
-+               */
-+              ia64_psr(regs)->sp = 1;
-+              PFM_DBG("setting psr.sp for [%d]", ctx->task->pid);
-+      }
-+}
-+
-+/*
-+ * mask monitoring by setting the privilege level to 0
-+ * we cannot use psr.pp/psr.up for this, it is controlled by
-+ * the user
-+ */
-+void pfm_arch_mask_monitoring(struct pfm_context *ctx, struct pfm_event_set *set)
-+{
-+      struct pfm_arch_pmu_info *arch_info;
-+      unsigned long mask;
-+      unsigned int i;
-+
-+      arch_info = pfm_pmu_info();
-+      /*
-+       * as an optimization we look at the first 64 PMC
-+       * registers only starting at PMC4.
-+       */
-+      mask = arch_info->mask_pmcs[0] >> PFM_ITA_FCNTR;
-+      for (i = PFM_ITA_FCNTR; mask; i++, mask >>= 1) {
-+              if (likely(mask & 0x1))
-+                      ia64_set_pmc(i, set->pmcs[i] & ~0xfUL);
-+      }
-+      /*
-+       * make changes visisble
-+       */
-+      ia64_srlz_d();
-+}
-+
-+/*
-+ * function called from pfm_switch_sets(), pfm_context_load_thread(),
-+ * pfm_context_load_sys(), pfm_ctxsw(), pfm_switch_sets()
-+ * context is locked. Interrupts are masked. set cannot be NULL.
-+ * Access to the PMU is guaranteed.
-+ *
-+ * function must restore all PMD registers from set.
-+ */
-+void pfm_arch_restore_pmds(struct pfm_context *ctx, struct pfm_event_set *set)
-+{
-+      struct pfm_arch_context *ctx_arch;
-+      unsigned long *mask;
-+      u16 i, num;
-+
-+      ctx_arch = pfm_ctx_arch(ctx);
-+
-+      if (ctx_arch->flags.insecure) {
-+              num = ctx->regs.num_rw_pmd;
-+              mask = ctx->regs.rw_pmds;
-+      } else {
-+              num = set->nused_pmds;
-+              mask = set->used_pmds;
-+      }
-+      /*
-+       * must restore all implemented read-write PMDS to avoid leaking
-+       * information especially when PFM_IA64_FL_INSECURE is set.
-+       *
-+       * XXX: should check PFM_IA64_FL_INSECURE==0 and use used_pmd instead
-+       */
-+      for (i = 0; num; i++) {
-+              if (likely(test_bit(i, mask))) {
-+                      pfm_arch_write_pmd(ctx, i, set->pmds[i].value);
-+                      num--;
-+              }
-+      }
-+      ia64_srlz_d();
-+}
-+
-+/*
-+ * function called from pfm_switch_sets(), pfm_context_load_thread(),
-+ * pfm_context_load_sys(), pfm_ctxsw(), pfm_switch_sets()
-+ * context is locked. Interrupts are masked. set cannot be NULL.
-+ * Access to the PMU is guaranteed.
-+ *
-+ * function must restore all PMC registers from set if needed
-+ */
-+void pfm_arch_restore_pmcs(struct pfm_context *ctx, struct pfm_event_set *set)
-+{
-+      struct pfm_arch_pmu_info *arch_info;
-+      u64 mask2 = 0, val, plm;
-+      unsigned long impl_mask, mask_pmcs;
-+      unsigned int i;
-+
-+      arch_info = pfm_pmu_info();
-+      /*
-+       * as an optimization we only look at the first 64
-+       * PMC registers. In fact, we should never scan the
-+       * entire impl_pmcs because ibr/dbr are implemented
-+       * separately.
-+       *
-+       * always skip PMC0-PMC3. PMC0 taken care of when saving
-+       * state. PMC1-PMC3 not used until we get counters in
-+       * the 60 and above index range.
-+       */
-+      impl_mask = ctx->regs.pmcs[0] >> PFM_ITA_FCNTR;
-+      mask_pmcs = arch_info->mask_pmcs[0] >> PFM_ITA_FCNTR;
-+      plm = ctx->state == PFM_CTX_MASKED ? ~0xf : ~0x0;
-+
-+      for (i = PFM_ITA_FCNTR;
-+           impl_mask;
-+           i++, impl_mask >>= 1, mask_pmcs >>= 1) {
-+              if (likely(impl_mask & 0x1)) {
-+                      mask2 = mask_pmcs & 0x1 ? plm : ~0;
-+                      val = set->pmcs[i] & mask2;
-+                      ia64_set_pmc(i, val);
-+                      PFM_DBG_ovfl("pmc%u=0x%lx", i, val);
-+              }
-+      }
-+      /*
-+       * restore DBR/IBR
-+       */
-+      if (set->priv_flags & PFM_ITA_SETFL_USE_DBR) {
-+              pfm_restore_ibrs(set->pmcs+256, 8);
-+              pfm_restore_dbrs(set->pmcs+264, 8);
-+      }
-+      ia64_srlz_d();
-+}
-+
-+void pfm_arch_unmask_monitoring(struct pfm_context *ctx, struct pfm_event_set *set)
-+{
-+      u64 psr;
-+      int is_system;
-+
-+      is_system = ctx->flags.system;
-+
-+      psr = ia64_getreg(_IA64_REG_PSR);
-+
-+      /*
-+       * monitoring is masked via the PMC.plm
-+       *
-+       * As we restore their value, we do not want each counter to
-+       * restart right away. We stop monitoring using the PSR,
-+       * restore the PMC (and PMD) and then re-establish the psr
-+       * as it was. Note that there can be no pending overflow at
-+       * this point, because monitoring is still MASKED.
-+       *
-+       * Because interrupts are masked we can avoid changing
-+       * DCR.pp.
-+       */
-+      if (is_system)
-+              pfm_clear_psr_pp();
-+      else
-+              pfm_clear_psr_up();
-+
-+      ia64_srlz_d();
-+
-+      pfm_arch_restore_pmcs(ctx, set);
-+
-+      /*
-+       * restore psr
-+       *
-+       * monitoring may start right now but interrupts
-+       * are still masked
-+       */
-+      pfm_set_psr_l(psr);
-+      ia64_srlz_d();
-+}
-+
-+/*
-+ * Called from pfm_stop()
-+ *
-+ * For per-thread:
-+ *   task is not necessarily current. If not current task, then
-+ *   task is guaranteed stopped and off any cpu. Access to PMU
-+ *   is not guaranteed. Interrupts are masked. Context is locked.
-+ *   Set is the active set.
-+ *
-+ * must disable active monitoring. ctx cannot be NULL
-+ */
-+void pfm_arch_stop(struct task_struct *task, struct pfm_context *ctx)
-+{
-+      struct pfm_arch_context *ctx_arch;
-+      struct pt_regs *regs;
-+      u64 dcr, psr;
-+
-+      ctx_arch = pfm_ctx_arch(ctx);
-+      regs = task_pt_regs(task);
-+
-+      if (!ctx->flags.system) {
-+              /*
-+               * in ZOMBIE state we always have task == current due to
-+               * pfm_exit_thread()
-+               */
-+              ia64_psr(regs)->up = 0;
-+              ctx_arch->ctx_saved_psr_up = 0;
-+
-+              /*
-+               * in case of ZOMBIE state, there is no unload to clear
-+               * insecure monitoring, so we do it in stop instead.
-+               */
-+              if (ctx->state == PFM_CTX_ZOMBIE)
-+                      ia64_psr(regs)->sp = 1;
-+
-+              if (task == current) {
-+                      pfm_clear_psr_up();
-+                      ia64_srlz_d();
-+              }
-+      } else if (ctx->flags.started) { /* do not stop twice */
-+              dcr = ia64_getreg(_IA64_REG_CR_DCR);
-+              psr = ia64_getreg(_IA64_REG_PSR);
-+
-+              ia64_psr(regs)->pp = 0;
-+              ia64_setreg(_IA64_REG_CR_DCR, dcr & ~IA64_DCR_PP);
-+              pfm_clear_psr_pp();
-+              ia64_srlz_d();
-+
-+              if (ctx->active_set->flags & PFM_ITA_SETFL_IDLE_EXCL) {
-+                      PFM_DBG("disabling idle exclude");
-+                      __get_cpu_var(pfm_syst_info) &= ~PFM_ITA_CPUINFO_IDLE_EXCL;
-+              }
-+      }
-+}
-+
-+/*
-+ * called from pfm_start()
-+ *
-+ * Interrupts are masked. Context is locked. Set is the active set.
-+ *
-+ * For per-thread:
-+ *    Task is not necessarily current. If not current task, then task
-+ *    is guaranteed stopped and off any cpu. No access to PMU is task
-+ *    is not current.
-+ *
-+ * For system-wide:
-+ *    task is always current
-+ *
-+ * must enable active monitoring.
-+ */
-+void pfm_arch_start(struct task_struct *task, struct pfm_context *ctx)
-+{
-+      struct pfm_arch_context *ctx_arch;
-+      struct pt_regs *regs;
-+      u64 dcr, dcr_pp, psr_pp;
-+      u32 flags;
-+
-+      ctx_arch = pfm_ctx_arch(ctx);
-+      regs = task_pt_regs(task);
-+      flags = ctx->active_set->flags;
-+
-+      /*
-+       * per-thread mode
-+       */
-+      if (!ctx->flags.system) {
-+
-+              ia64_psr(regs)->up = 1;
-+
-+              if (task == current) {
-+                      pfm_set_psr_up();
-+                      ia64_srlz_d();
-+              } else {
-+                      /*
-+                       * activate monitoring at next ctxswin
-+                       */
-+                      ctx_arch->ctx_saved_psr_up = IA64_PSR_UP;
-+              }
-+              return;
-+      }
-+
-+      /*
-+       * system-wide mode
-+       */
-+      dcr = ia64_getreg(_IA64_REG_CR_DCR);
-+      if (flags & PFM_ITA_SETFL_INTR_ONLY) {
-+              dcr_pp = 1;
-+              psr_pp = 0;
-+      } else if (flags & PFM_ITA_SETFL_EXCL_INTR) {
-+              dcr_pp = 0;
-+              psr_pp = 1;
-+      } else {
-+              dcr_pp = psr_pp = 1;
-+      }
-+      PFM_DBG("dcr_pp=%lu psr_pp=%lu", dcr_pp, psr_pp);
-+
-+      /*
-+       * update dcr_pp and psr_pp
-+       */
-+      if (dcr_pp)
-+              ia64_setreg(_IA64_REG_CR_DCR, dcr | IA64_DCR_PP);
-+      else
-+              ia64_setreg(_IA64_REG_CR_DCR, dcr & ~IA64_DCR_PP);
-+
-+      if (psr_pp) {
-+              pfm_set_psr_pp();
-+              ia64_psr(regs)->pp = 1;
-+      } else {
-+              pfm_clear_psr_pp();
-+              ia64_psr(regs)->pp = 0;
-+      }
-+      ia64_srlz_d();
-+
-+      if (ctx->active_set->flags & PFM_ITA_SETFL_IDLE_EXCL) {
-+              PFM_DBG("enable idle exclude");
-+              __get_cpu_var(pfm_syst_info) |= PFM_ITA_CPUINFO_IDLE_EXCL;
-+      }
-+}
-+
-+/*
-+ * Only call this function when a process is trying to
-+ * write the debug registers (reading is always allowed)
-+ * called from arch/ia64/kernel/ptrace.c:access_uarea()
-+ */
-+int __pfm_use_dbregs(struct task_struct *task)
-+{
-+      struct pfm_arch_context *ctx_arch;
-+      struct pfm_context *ctx;
-+      unsigned long flags;
-+      int ret = 0;
-+
-+      PFM_DBG("called for [%d]", task->pid);
-+
-+      ctx = task->pfm_context;
-+
-+      /*
-+       * do it only once
-+       */
-+      if (task->thread.flags & IA64_THREAD_DBG_VALID) {
-+              PFM_DBG("IA64_THREAD_DBG_VALID already set");
-+              return 0;
-+      }
-+      if (ctx) {
-+              spin_lock_irqsave(&ctx->lock, flags);
-+              ctx_arch = pfm_ctx_arch(ctx);
-+
-+              if (ctx_arch->flags.use_dbr == 1) {
-+                      PFM_DBG("PMU using dbregs already, no ptrace access");
-+                      ret = -1;
-+              }
-+              spin_unlock_irqrestore(&ctx->lock, flags);
-+              if (ret)
-+                      return ret;
-+      }
-+
-+      spin_lock(&pfm_arch_sessions_lock);
-+
-+      /*
-+       * We cannot allow setting breakpoints when system wide monitoring
-+       * sessions are using the debug registers.
-+       */
-+      if (!pfm_arch_sessions.pfs_sys_use_dbr)
-+              pfm_arch_sessions.pfs_ptrace_use_dbr++;
-+      else
-+              ret = -1;
-+
-+      PFM_DBG("ptrace_use_dbr=%u  sys_use_dbr=%u by [%d] ret = %d",
-+                pfm_arch_sessions.pfs_ptrace_use_dbr,
-+                pfm_arch_sessions.pfs_sys_use_dbr,
-+                task->pid, ret);
-+
-+      spin_unlock(&pfm_arch_sessions_lock);
-+      if (ret)
-+              return ret;
-+#ifndef CONFIG_SMP
-+      /*
-+       * in UP, we need to check whether the current
-+       * owner of the PMU is not using the debug registers
-+       * for monitoring. Because we are using a lazy
-+       * save on ctxswout, we must force a save in this
-+       * case because the debug registers are being
-+       * modified by another task. We save the current
-+       * PMD registers, and clear ownership. In ctxswin,
-+       * full state will be reloaded.
-+       *
-+       * Note: we overwrite task.
-+       */
-+      task = __get_cpu_var(pmu_owner);
-+      ctx = __get_cpu_var(pmu_ctx);
-+
-+      if (task == NULL)
-+              return 0;
-+
-+      ctx_arch = pfm_ctx_arch(ctx);
-+
-+      if (ctx_arch->flags.use_dbr)
-+              pfm_save_pmds_release(ctx);
-+#endif
-+      return 0;
-+}
-+
-+/*
-+ * This function is called for every task that exits with the
-+ * IA64_THREAD_DBG_VALID set. This indicates a task which was
-+ * able to use the debug registers for debugging purposes via
-+ * ptrace(). Therefore we know it was not using them for
-+ * perfmormance monitoring, so we only decrement the number
-+ * of "ptraced" debug register users to keep the count up to date
-+ */
-+int __pfm_release_dbregs(struct task_struct *task)
-+{
-+      int ret;
-+
-+      spin_lock(&pfm_arch_sessions_lock);
-+
-+      if (pfm_arch_sessions.pfs_ptrace_use_dbr == 0) {
-+              PFM_ERR("invalid release for [%d] ptrace_use_dbr=0", task->pid);
-+              ret = -1;
-+      }  else {
-+              pfm_arch_sessions.pfs_ptrace_use_dbr--;
-+              ret = 0;
-+      }
-+      spin_unlock(&pfm_arch_sessions_lock);
-+
-+      return ret;
-+}
-+
-+int pfm_ia64_mark_dbregs_used(struct pfm_context *ctx,
-+                            struct pfm_event_set *set)
-+{
-+      struct pfm_arch_context *ctx_arch;
-+      struct task_struct *task;
-+      struct thread_struct *thread;
-+      int ret = 0, state;
-+      int i, can_access_pmu = 0;
-+      int is_loaded, is_system;
-+
-+      ctx_arch = pfm_ctx_arch(ctx);
-+      state = ctx->state;
-+      task = ctx->task;
-+      is_loaded = state == PFM_CTX_LOADED || state == PFM_CTX_MASKED;
-+      is_system = ctx->flags.system;
-+      can_access_pmu = __get_cpu_var(pmu_owner) == task || is_system;
-+
-+      if (is_loaded == 0)
-+              goto done;
-+
-+      if (is_system == 0) {
-+              thread = &(task->thread);
-+
-+              /*
-+               * cannot use debug registers for montioring if they are
-+               * already used for debugging
-+               */
-+              if (thread->flags & IA64_THREAD_DBG_VALID) {
-+                      PFM_DBG("debug registers already in use for [%d]",
-+                                task->pid);
-+                      return -EBUSY;
-+              }
-+      }
-+
-+      /*
-+       * check for debug registers in system wide mode
-+       */
-+      spin_lock(&pfm_arch_sessions_lock);
-+
-+      if (is_system) {
-+              if (pfm_arch_sessions.pfs_ptrace_use_dbr)
-+                      ret = -EBUSY;
-+              else
-+                      pfm_arch_sessions.pfs_sys_use_dbr++;
-+      }
-+
-+      spin_unlock(&pfm_arch_sessions_lock);
-+
-+      if (ret != 0)
-+              return ret;
-+
-+      /*
-+       * clear hardware registers to make sure we don't
-+       * pick up stale state.
-+       */
-+      if (can_access_pmu) {
-+              PFM_DBG("clearing ibrs, dbrs");
-+              for (i = 0; i < 8; i++) {
-+                      ia64_set_ibr(i, 0);
-+                      ia64_dv_serialize_instruction();
-+              }
-+              ia64_srlz_i();
-+              for (i = 0; i < 8; i++) {
-+                      ia64_set_dbr(i, 0);
-+                      ia64_dv_serialize_data();
-+              }
-+              ia64_srlz_d();
-+      }
-+done:
-+      /*
-+       * debug registers are now in use
-+       */
-+      ctx_arch->flags.use_dbr = 1;
-+      set->priv_flags |= PFM_ITA_SETFL_USE_DBR;
-+      PFM_DBG("set%u use_dbr=1", set->id);
-+      return 0;
-+}
-+EXPORT_SYMBOL(pfm_ia64_mark_dbregs_used);
-+
-+char *pfm_arch_get_pmu_module_name(void)
-+{
-+      switch (local_cpu_data->family) {
-+      case 0x07:
-+              return "perfmon_itanium";
-+      case 0x1f:
-+              return "perfmon_mckinley";
-+      case 0x20:
-+              return "perfmon_montecito";
-+      default:
-+              return "perfmon_generic";
-+      }
-+      return NULL;
-+}
-+
-+/*
-+ * global arch-specific intialization, called only once
-+ */
-+int __init pfm_arch_init(void)
-+{
-+      int ret;
-+
-+      spin_lock_init(&pfm_arch_sessions_lock);
-+
-+#ifdef CONFIG_IA64_PERFMON_COMPAT
-+      ret = pfm_ia64_compat_init();
-+      if (ret)
-+              return ret;
-+#endif
-+      register_percpu_irq(IA64_PERFMON_VECTOR, &perfmon_irqaction);
-+
-+
-+      return 0;
-+}
-diff --git a/arch/ia64/perfmon/perfmon_compat.c b/arch/ia64/perfmon/perfmon_compat.c
-new file mode 100644
-index 0000000..2fd3d3c
---- /dev/null
-+++ b/arch/ia64/perfmon/perfmon_compat.c
-@@ -0,0 +1,1210 @@
-+/*
-+ * This file implements the IA-64 specific
-+ * support for the perfmon2 interface
-+ *
-+ * Copyright (c) 1999-2006 Hewlett-Packard Development Company, L.P.
-+ * Contributed by Stephane Eranian <eranian@hpl.hp.com>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of version 2 of the GNU General Public
-+ * License as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ * 02111-1307 USA
-+  */
-+#include <linux/interrupt.h>
-+#include <linux/module.h>
-+#include <linux/file.h>
-+#include <linux/fdtable.h>
-+#include <linux/seq_file.h>
-+#include <linux/vmalloc.h>
-+#include <linux/proc_fs.h>
-+#include <linux/perfmon_kern.h>
-+#include <linux/uaccess.h>
-+
-+asmlinkage long sys_pfm_stop(int fd);
-+asmlinkage long sys_pfm_start(int fd, struct pfarg_start __user *st);
-+asmlinkage long sys_pfm_unload_context(int fd);
-+asmlinkage long sys_pfm_restart(int fd);
-+asmlinkage long sys_pfm_load_context(int fd, struct pfarg_load __user *ld);
-+
-+ssize_t pfm_sysfs_res_show(char *buf, size_t sz, int what);
-+
-+extern ssize_t __pfm_read(struct pfm_context *ctx,
-+                        union pfarg_msg *msg_buf,
-+                        int non_block);
-+/*
-+ * function providing some help for backward compatiblity with old IA-64
-+ * applications. In the old model, certain attributes of a counter were
-+ * passed via the PMC, now they are passed via the PMD.
-+ */
-+static int pfm_compat_update_pmd(struct pfm_context *ctx, u16 set_id, u16 cnum,
-+                               u32 rflags,
-+                               unsigned long *smpl_pmds,
-+                               unsigned long *reset_pmds,
-+                               u64 eventid)
-+{
-+      struct pfm_event_set *set;
-+      int is_counting;
-+      unsigned long *impl_pmds;
-+      u32 flags = 0;
-+      u16 max_pmd;
-+
-+      impl_pmds = ctx->regs.pmds;
-+      max_pmd = ctx->regs.max_pmd;
-+
-+      /*
-+       * given that we do not maintain PMC ->PMD dependencies
-+       * we cannot figure out what to do in case PMCxx != PMDxx
-+       */
-+      if (cnum > max_pmd)
-+              return 0;
-+
-+      /*
-+       * assumes PMCxx controls PMDxx which is always true for counters
-+       * on Itanium PMUs.
-+       */
-+      is_counting = pfm_pmu_conf->pmd_desc[cnum].type & PFM_REG_C64;
-+      set = pfm_find_set(ctx, set_id, 0);
-+
-+      /*
-+       * for v2.0, we only allowed counting PMD to generate
-+       * user-level notifications. Same thing with randomization.
-+       */
-+      if (is_counting) {
-+              if (rflags & PFM_REGFL_OVFL_NOTIFY)
-+                      flags |= PFM_REGFL_OVFL_NOTIFY;
-+              if (rflags & PFM_REGFL_RANDOM)
-+                      flags |= PFM_REGFL_RANDOM;
-+              /*
-+               * verify validity of smpl_pmds
-+               */
-+              if (unlikely(bitmap_subset(smpl_pmds,
-+                                         impl_pmds, max_pmd) == 0)) {
-+                      PFM_DBG("invalid smpl_pmds=0x%llx for pmd%u",
-+                                (unsigned long long)smpl_pmds[0], cnum);
-+                      return -EINVAL;
-+              }
-+              /*
-+               * verify validity of reset_pmds
-+               */
-+              if (unlikely(bitmap_subset(reset_pmds,
-+                                         impl_pmds, max_pmd) == 0)) {
-+                      PFM_DBG("invalid reset_pmds=0x%lx for pmd%u",
-+                                reset_pmds[0], cnum);
-+                      return -EINVAL;
-+              }
-+              /*
-+               * ensures that a PFM_READ_PMDS succeeds with a
-+               * corresponding PFM_WRITE_PMDS
-+               */
-+              __set_bit(cnum, set->used_pmds);
-+
-+      } else if (rflags & (PFM_REGFL_OVFL_NOTIFY|PFM_REGFL_RANDOM)) {
-+              PFM_DBG("cannot set ovfl_notify or random on pmd%u", cnum);
-+              return -EINVAL;
-+      }
-+
-+      set->pmds[cnum].flags = flags;
-+
-+      if (is_counting) {
-+              bitmap_copy(set->pmds[cnum].reset_pmds,
-+                          reset_pmds,
-+                          max_pmd);
-+
-+              bitmap_copy(set->pmds[cnum].smpl_pmds,
-+                          smpl_pmds,
-+                          max_pmd);
-+
-+              set->pmds[cnum].eventid = eventid;
-+
-+              /*
-+               * update ovfl_notify
-+               */
-+              if (rflags & PFM_REGFL_OVFL_NOTIFY)
-+                      __set_bit(cnum, set->ovfl_notify);
-+              else
-+                      __clear_bit(cnum, set->ovfl_notify);
-+
-+      }
-+      PFM_DBG("pmd%u flags=0x%x eventid=0x%lx r_pmds=0x%lx s_pmds=0x%lx",
-+                cnum, flags,
-+                eventid,
-+                reset_pmds[0],
-+                smpl_pmds[0]);
-+
-+      return 0;
-+}
-+
-+
-+int __pfm_write_ibrs_old(struct pfm_context *ctx, void *arg, int count)
-+{
-+      struct pfarg_dbreg *req = arg;
-+      struct pfarg_pmc pmc;
-+      int i, ret = 0;
-+
-+      memset(&pmc, 0, sizeof(pmc));
-+
-+      for (i = 0; i < count; i++, req++) {
-+              pmc.reg_num   = 256+req->dbreg_num;
-+              pmc.reg_value = req->dbreg_value;
-+              pmc.reg_flags = 0;
-+              pmc.reg_set   = req->dbreg_set;
-+
-+              ret = __pfm_write_pmcs(ctx, &pmc, 1);
-+
-+              req->dbreg_flags &= ~PFM_REG_RETFL_MASK;
-+              req->dbreg_flags |= pmc.reg_flags;
-+
-+              if (ret)
-+                      return ret;
-+      }
-+      return 0;
-+}
-+
-+static long pfm_write_ibrs_old(int fd, void __user *ureq, int count)
-+{
-+      struct pfm_context *ctx;
-+      struct task_struct *task;
-+      struct file *filp;
-+      struct pfarg_dbreg *req = NULL;
-+      void *fptr, *resume;
-+      unsigned long flags;
-+      size_t sz;
-+      int ret, fput_needed;
-+
-+      if (count < 1 || count >= PFM_MAX_ARG_COUNT(req))
-+              return -EINVAL;
-+
-+      sz = count*sizeof(*req);
-+
-+      filp = fget_light(fd, &fput_needed);
-+      if (unlikely(filp == NULL)) {
-+              PFM_DBG("invalid fd %d", fd);
-+              return -EBADF;
-+      }
-+
-+      ctx = filp->private_data;
-+      ret = -EBADF;
-+
-+      if (unlikely(!ctx || filp->f_op != &pfm_file_ops)) {
-+              PFM_DBG("fd %d not related to perfmon", fd);
-+              goto error;
-+      }
-+
-+      ret = pfm_get_args(ureq, sz, 0, NULL, (void **)&req, &fptr);
-+      if (ret)
-+              goto error;
-+
-+      spin_lock_irqsave(&ctx->lock, flags);
-+
-+      task = ctx->task;
-+
-+      ret = pfm_check_task_state(ctx, PFM_CMD_STOPPED, &flags, &resume);
-+      if (ret == 0)
-+              ret = __pfm_write_ibrs_old(ctx, req, count);
-+
-+      spin_unlock_irqrestore(&ctx->lock, flags);
-+
-+      if (resume)
-+              pfm_resume_task(task, resume);
-+
-+      if (copy_to_user(ureq, req, sz))
-+              ret = -EFAULT;
-+
-+      kfree(fptr);
-+error:
-+      fput_light(filp, fput_needed);
-+      return ret;
-+}
-+
-+int __pfm_write_dbrs_old(struct pfm_context *ctx, void *arg, int count)
-+{
-+      struct pfarg_dbreg *req = arg;
-+      struct pfarg_pmc pmc;
-+      int i, ret = 0;
-+
-+      memset(&pmc, 0, sizeof(pmc));
-+
-+      for (i = 0; i < count; i++, req++) {
-+              pmc.reg_num   = 264+req->dbreg_num;
-+              pmc.reg_value = req->dbreg_value;
-+              pmc.reg_flags = 0;
-+              pmc.reg_set   = req->dbreg_set;
-+
-+              ret = __pfm_write_pmcs(ctx, &pmc, 1);
-+
-+              req->dbreg_flags &= ~PFM_REG_RETFL_MASK;
-+              req->dbreg_flags |= pmc.reg_flags;
-+              if (ret)
-+                      return ret;
-+      }
-+      return 0;
-+}
-+
-+static long pfm_write_dbrs_old(int fd, void __user *ureq, int count)
-+{
-+      struct pfm_context *ctx;
-+      struct task_struct *task;
-+      struct file *filp;
-+      struct pfarg_dbreg *req = NULL;
-+      void *fptr, *resume;
-+      unsigned long flags;
-+      size_t sz;
-+      int ret, fput_needed;
-+
-+      if (count < 1 || count >= PFM_MAX_ARG_COUNT(req))
-+              return -EINVAL;
-+
-+      sz = count*sizeof(*req);
-+
-+      filp = fget_light(fd, &fput_needed);
-+      if (unlikely(filp == NULL)) {
-+              PFM_DBG("invalid fd %d", fd);
-+              return -EBADF;
-+      }
-+
-+      ctx = filp->private_data;
-+      ret = -EBADF;
-+
-+      if (unlikely(!ctx || filp->f_op != &pfm_file_ops)) {
-+              PFM_DBG("fd %d not related to perfmon", fd);
-+              goto error;
-+      }
-+
-+      ret = pfm_get_args(ureq, sz, 0, NULL, (void **)&req, &fptr);
-+      if (ret)
-+              goto error;
-+
-+      spin_lock_irqsave(&ctx->lock, flags);
-+
-+      task = ctx->task;
-+
-+      ret = pfm_check_task_state(ctx, PFM_CMD_STOPPED, &flags, &resume);
-+      if (ret == 0)
-+              ret = __pfm_write_dbrs_old(ctx, req, count);
-+
-+      spin_unlock_irqrestore(&ctx->lock, flags);
-+
-+      if (resume)
-+              pfm_resume_task(task, resume);
-+
-+      if (copy_to_user(ureq, req, sz))
-+              ret = -EFAULT;
-+
-+      kfree(fptr);
-+error:
-+      fput_light(filp, fput_needed);
-+      return ret;
-+}
-+
-+int __pfm_write_pmcs_old(struct pfm_context *ctx, struct pfarg_reg *req_old,
-+                       int count)
-+{
-+      struct pfarg_pmc req;
-+      unsigned int i;
-+      int ret, error_code;
-+
-+      memset(&req, 0, sizeof(req));
-+
-+      for (i = 0; i < count; i++, req_old++) {
-+              req.reg_num   = req_old->reg_num;
-+              req.reg_set   = req_old->reg_set;
-+              req.reg_flags = 0;
-+              req.reg_value = req_old->reg_value;
-+
-+              ret = __pfm_write_pmcs(ctx, (void *)&req, 1);
-+              req_old->reg_flags &= ~PFM_REG_RETFL_MASK;
-+              req_old->reg_flags |= req.reg_flags;
-+
-+              if (ret)
-+                      return ret;
-+
-+              ret = pfm_compat_update_pmd(ctx, req_old->reg_set,
-+                                    req_old->reg_num,
-+                                    (u32)req_old->reg_flags,
-+                                    req_old->reg_smpl_pmds,
-+                                    req_old->reg_reset_pmds,
-+                                    req_old->reg_smpl_eventid);
-+
-+              error_code = ret ? PFM_REG_RETFL_EINVAL : 0;
-+              req_old->reg_flags &= ~PFM_REG_RETFL_MASK;
-+              req_old->reg_flags |= error_code;
-+
-+              if (ret)
-+                      return ret;
-+      }
-+      return 0;
-+}
-+
-+static long pfm_write_pmcs_old(int fd, void __user *ureq, int count)
-+{
-+      struct pfm_context *ctx;
-+      struct task_struct *task;
-+      struct file *filp;
-+      struct pfarg_reg *req = NULL;
-+      void *fptr, *resume;
-+      unsigned long flags;
-+      size_t sz;
-+      int ret, fput_needed;
-+
-+      if (count < 1 || count >= PFM_MAX_ARG_COUNT(req))
-+              return -EINVAL;
-+
-+      sz = count*sizeof(*req);
-+
-+      filp = fget_light(fd, &fput_needed);
-+      if (unlikely(filp == NULL)) {
-+              PFM_DBG("invalid fd %d", fd);
-+              return -EBADF;
-+      }
-+
-+      ctx = filp->private_data;
-+      ret = -EBADF;
-+
-+      if (unlikely(!ctx || filp->f_op != &pfm_file_ops)) {
-+              PFM_DBG("fd %d not related to perfmon", fd);
-+              goto error;
-+      }
-+
-+      ret = pfm_get_args(ureq, sz, 0, NULL, (void **)&req, &fptr);
-+      if (ret)
-+              goto error;
-+
-+      spin_lock_irqsave(&ctx->lock, flags);
-+
-+      task = ctx->task;
-+
-+      ret = pfm_check_task_state(ctx, PFM_CMD_STOPPED, &flags, &resume);
-+      if (ret == 0)
-+              ret = __pfm_write_pmcs_old(ctx, req, count);
-+
-+      spin_unlock_irqrestore(&ctx->lock, flags);
-+
-+      if (resume)
-+              pfm_resume_task(task, resume);
-+
-+      if (copy_to_user(ureq, req, sz))
-+              ret = -EFAULT;
-+
-+      kfree(fptr);
-+
-+error:
-+      fput_light(filp, fput_needed);
-+      return ret;
-+}
-+
-+int __pfm_write_pmds_old(struct pfm_context *ctx, struct pfarg_reg *req_old,
-+                       int count)
-+{
-+      struct pfarg_pmd req;
-+      int i, ret;
-+
-+      memset(&req, 0, sizeof(req));
-+
-+      for (i = 0; i < count; i++, req_old++) {
-+              req.reg_num   = req_old->reg_num;
-+              req.reg_set   = req_old->reg_set;
-+              req.reg_value = req_old->reg_value;
-+              /* flags passed with pmcs in v2.0 */
-+
-+              req.reg_long_reset  = req_old->reg_long_reset;
-+              req.reg_short_reset = req_old->reg_short_reset;
-+              req.reg_random_mask = req_old->reg_random_mask;
-+              /*
-+               * reg_random_seed is ignored since v2.3
-+               */
-+
-+              /*
-+               * skip last_reset_val not used for writing
-+               * skip smpl_pmds, reset_pmds, eventid, ovfl_swtch_cnt
-+               * as set in pfm_write_pmcs_old.
-+               *
-+               * ovfl_switch_cnt ignored, not implemented in v2.0
-+               */
-+              ret = __pfm_write_pmds(ctx, (void *)&req, 1, 1);
-+
-+              req_old->reg_flags &= ~PFM_REG_RETFL_MASK;
-+              req_old->reg_flags |= req.reg_flags;
-+
-+              if (ret)
-+                      return ret;
-+      }
-+      return 0;
-+}
-+
-+static long pfm_write_pmds_old(int fd, void __user *ureq, int count)
-+{
-+      struct pfm_context *ctx;
-+      struct task_struct *task;
-+      struct file *filp;
-+      struct pfarg_reg *req = NULL;
-+      void *fptr, *resume;
-+      unsigned long flags;
-+      size_t sz;
-+      int ret, fput_needed;
-+
-+      if (count < 1 || count >= PFM_MAX_ARG_COUNT(req))
-+              return -EINVAL;
-+
-+      sz = count*sizeof(*req);
-+
-+      filp = fget_light(fd, &fput_needed);
-+      if (unlikely(filp == NULL)) {
-+              PFM_DBG("invalid fd %d", fd);
-+              return -EBADF;
-+      }
-+
-+      ctx = filp->private_data;
-+      ret = -EBADF;
-+
-+      if (unlikely(!ctx || filp->f_op != &pfm_file_ops)) {
-+              PFM_DBG("fd %d not related to perfmon", fd);
-+              goto error;
-+      }
-+
-+      ret = pfm_get_args(ureq, sz, 0, NULL, (void **)&req, &fptr);
-+      if (ret)
-+              goto error;
-+
-+      spin_lock_irqsave(&ctx->lock, flags);
-+
-+      task = ctx->task;
-+
-+      ret = pfm_check_task_state(ctx, PFM_CMD_STOPPED, &flags, &resume);
-+      if (ret == 0)
-+              ret = __pfm_write_pmds_old(ctx, req, count);
-+
-+      spin_unlock_irqrestore(&ctx->lock, flags);
-+
-+      if (copy_to_user(ureq, req, sz))
-+              ret = -EFAULT;
-+
-+      if (resume)
-+              pfm_resume_task(task, resume);
-+
-+      kfree(fptr);
-+error:
-+      fput_light(filp, fput_needed);
-+      return ret;
-+}
-+
-+int __pfm_read_pmds_old(struct pfm_context *ctx, struct pfarg_reg *req_old,
-+                      int count)
-+{
-+      struct pfarg_pmd req;
-+      int i, ret;
-+
-+      memset(&req, 0, sizeof(req));
-+
-+      for (i = 0; i < count; i++, req_old++) {
-+              req.reg_num   = req_old->reg_num;
-+              req.reg_set   = req_old->reg_set;
-+
-+              /* skip value not used for reading */
-+              req.reg_flags = req_old->reg_flags;
-+
-+              /* skip short/long_reset not used for reading */
-+              /* skip last_reset_val not used for reading */
-+              /* skip ovfl_switch_cnt not used for reading */
-+
-+              ret = __pfm_read_pmds(ctx, (void *)&req, 1);
-+
-+              req_old->reg_flags &= ~PFM_REG_RETFL_MASK;
-+              req_old->reg_flags |= req.reg_flags;
-+              if (ret)
-+                      return ret;
-+
-+              /* update fields */
-+              req_old->reg_value = req.reg_value;
-+
-+              req_old->reg_last_reset_val  = req.reg_last_reset_val;
-+              req_old->reg_ovfl_switch_cnt = req.reg_ovfl_switch_cnt;
-+      }
-+      return 0;
-+}
-+
-+static long pfm_read_pmds_old(int fd, void __user *ureq, int count)
-+{
-+      struct pfm_context *ctx;
-+      struct task_struct *task;
-+      struct file *filp;
-+      struct pfarg_reg *req = NULL;
-+      void *fptr, *resume;
-+      unsigned long flags;
-+      size_t sz;
-+      int ret, fput_needed;
-+
-+      if (count < 1 || count >= PFM_MAX_ARG_COUNT(req))
-+              return -EINVAL;
-+
-+      sz = count*sizeof(*req);
-+
-+      filp = fget_light(fd, &fput_needed);
-+      if (unlikely(filp == NULL)) {
-+              PFM_DBG("invalid fd %d", fd);
-+              return -EBADF;
-+      }
-+
-+      ctx = filp->private_data;
-+      ret = -EBADF;
-+
-+      if (unlikely(!ctx || filp->f_op != &pfm_file_ops)) {
-+              PFM_DBG("fd %d not related to perfmon", fd);
-+              goto error;
-+      }
-+
-+      ret = pfm_get_args(ureq, sz, 0, NULL, (void **)&req, &fptr);
-+      if (ret)
-+              goto error;
-+
-+      spin_lock_irqsave(&ctx->lock, flags);
-+
-+      task = ctx->task;
-+
-+      ret = pfm_check_task_state(ctx, PFM_CMD_STOPPED, &flags, &resume);
-+      if (ret == 0)
-+              ret = __pfm_read_pmds_old(ctx, req, count);
-+
-+      spin_unlock_irqrestore(&ctx->lock, flags);
-+
-+      if (resume)
-+              pfm_resume_task(task, resume);
-+
-+      if (copy_to_user(ureq, req, sz))
-+              ret = -EFAULT;
-+
-+      kfree(fptr);
-+error:
-+      fput_light(filp, fput_needed);
-+      return ret;
-+}
-+
-+/*
-+ * OBSOLETE: use /proc/perfmon_map instead
-+ */
-+static long pfm_get_default_pmcs_old(int fd, void __user *ureq, int count)
-+{
-+      struct pfarg_reg *req = NULL;
-+      void *fptr;
-+      size_t sz;
-+      int ret, i;
-+      unsigned int cnum;
-+
-+      if (count < 1)
-+              return -EINVAL;
-+
-+      /*
-+       * ensure the pfm_pmu_conf does not disappear while
-+       * we use it
-+       */
-+      ret = pfm_pmu_conf_get(1);
-+      if (ret)
-+              return ret;
-+
-+      sz = count*sizeof(*ureq);
-+
-+      ret = pfm_get_args(ureq, sz, 0, NULL, (void **)&req, &fptr);
-+      if (ret)
-+              goto error;
-+
-+
-+      for (i = 0; i < count; i++, req++) {
-+              cnum   = req->reg_num;
-+
-+              if (i >= PFM_MAX_PMCS ||
-+                  (pfm_pmu_conf->pmc_desc[cnum].type & PFM_REG_I) == 0) {
-+                      req->reg_flags = PFM_REG_RETFL_EINVAL;
-+                      break;
-+              }
-+              req->reg_value = pfm_pmu_conf->pmc_desc[cnum].dfl_val;
-+              req->reg_flags = 0;
-+
-+              PFM_DBG("pmc[%u]=0x%lx", cnum, req->reg_value);
-+      }
-+
-+      if (copy_to_user(ureq, req, sz))
-+              ret = -EFAULT;
-+
-+      kfree(fptr);
-+error:
-+      pfm_pmu_conf_put();
-+
-+      return ret;
-+}
-+
-+/*
-+ * allocate a sampling buffer and remaps it into the user address space of
-+ * the task. This is only in compatibility mode
-+ *
-+ * function called ONLY on current task
-+ */
-+int pfm_smpl_buf_alloc_compat(struct pfm_context *ctx, size_t rsize,
-+                            struct file *filp)
-+{
-+      struct mm_struct *mm = current->mm;
-+      struct vm_area_struct *vma = NULL;
-+      struct pfm_arch_context *ctx_arch;
-+      size_t size;
-+      int ret;
-+      extern struct vm_operations_struct pfm_buf_map_vm_ops;
-+
-+      ctx_arch = pfm_ctx_arch(ctx);
-+
-+      /*
-+       * allocate buffer + map desc
-+       */
-+      ret = pfm_smpl_buf_alloc(ctx, rsize);
-+      if (ret)
-+              return ret;
-+
-+      size = ctx->smpl_size;
-+
-+
-+      /* allocate vma */
-+      vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
-+      if (!vma) {
-+              PFM_DBG("Cannot allocate vma");
-+              goto error_kmem;
-+      }
-+      memset(vma, 0, sizeof(*vma));
-+
-+      /*
-+       * partially initialize the vma for the sampling buffer
-+       */
-+      vma->vm_mm           = mm;
-+      vma->vm_flags        = VM_READ | VM_MAYREAD | VM_RESERVED;
-+      vma->vm_page_prot    = PAGE_READONLY;
-+      vma->vm_ops          = &pfm_buf_map_vm_ops;
-+      vma->vm_file         = filp;
-+      vma->vm_private_data = ctx;
-+      vma->vm_pgoff        = 0;
-+
-+      /*
-+       * simulate effect of mmap()
-+       */
-+      get_file(filp);
-+
-+      /*
-+       * Let's do the difficult operations next.
-+       *
-+       * now we atomically find some area in the address space and
-+       * remap the buffer into it.
-+       */
-+      down_write(&current->mm->mmap_sem);
-+
-+      /* find some free area in address space, must have mmap sem held */
-+      vma->vm_start = get_unmapped_area(NULL, 0, size, 0,
-+                                        MAP_PRIVATE|MAP_ANONYMOUS);
-+      if (vma->vm_start == 0) {
-+              PFM_DBG("cannot find unmapped area of size %zu", size);
-+              up_write(&current->mm->mmap_sem);
-+              goto error;
-+      }
-+      vma->vm_end = vma->vm_start + size;
-+
-+      PFM_DBG("aligned_size=%zu mapped @0x%lx", size, vma->vm_start);
-+      /*
-+       * now insert the vma in the vm list for the process, must be
-+       * done with mmap lock held
-+       */
-+      insert_vm_struct(mm, vma);
-+
-+      mm->total_vm  += size >> PAGE_SHIFT;
-+
-+      up_write(&current->mm->mmap_sem);
-+
-+      /*
-+       * IMPORTANT: we do not issue the fput()
-+       * because we want to increase the ref count
-+       * on the descriptor to simulate what mmap()
-+       * would do
-+       */
-+
-+      /*
-+       * used to propagate vaddr to syscall stub
-+       */
-+      ctx_arch->ctx_smpl_vaddr = (void *)vma->vm_start;
-+
-+      return 0;
-+error:
-+      kmem_cache_free(vm_area_cachep, vma);
-+error_kmem:
-+      pfm_smpl_buf_space_release(ctx, ctx->smpl_size);
-+      vfree(ctx->smpl_addr);
-+      return -ENOMEM;
-+}
-+
-+#define PFM_DEFAULT_SMPL_UUID { \
-+              0x4d, 0x72, 0xbe, 0xc0, 0x06, 0x64, 0x41, 0x43, 0x82,\
-+              0xb4, 0xd3, 0xfd, 0x27, 0x24, 0x3c, 0x97}
-+
-+static pfm_uuid_t old_default_uuid = PFM_DEFAULT_SMPL_UUID;
-+static pfm_uuid_t null_uuid;
-+
-+/*
-+ * function invoked in case, pfm_context_create fails
-+ * at the last operation, copy_to_user. It needs to
-+ * undo memory allocations and free the file descriptor
-+ */
-+static void pfm_undo_create_context_fd(int fd, struct pfm_context *ctx)
-+{
-+      struct files_struct *files = current->files;
-+      struct file *file;
-+      int fput_needed;
-+
-+      file = fget_light(fd, &fput_needed);
-+      /*
-+       * there is no fd_uninstall(), so we do it
-+       * here. put_unused_fd() does not remove the
-+       * effect of fd_install().
-+       */
-+
-+      spin_lock(&files->file_lock);
-+      files->fd_array[fd] = NULL;
-+      spin_unlock(&files->file_lock);
-+
-+      fput_light(file, fput_needed);
-+
-+      /*
-+       * decrement ref count and kill file
-+       */
-+      put_filp(file);
-+
-+      put_unused_fd(fd);
-+
-+      pfm_free_context(ctx);
-+}
-+
-+static int pfm_get_smpl_arg_old(pfm_uuid_t uuid, void __user *fmt_uarg,
-+                              size_t usize, void **arg,
-+                              struct pfm_smpl_fmt **fmt)
-+{
-+      struct pfm_smpl_fmt *f;
-+      void *addr = NULL;
-+      size_t sz;
-+      int ret;
-+
-+      if (!memcmp(uuid, null_uuid, sizeof(pfm_uuid_t)))
-+              return 0;
-+
-+      if (memcmp(uuid, old_default_uuid, sizeof(pfm_uuid_t))) {
-+              PFM_DBG("compatibility mode supports only default sampling format");
-+              return -EINVAL;
-+      }
-+      /*
-+       * find fmt and increase refcount
-+       */
-+      f = pfm_smpl_fmt_get("default-old");
-+      if (f == NULL) {
-+              PFM_DBG("default-old buffer format not found");
-+              return -EINVAL;
-+      }
-+
-+      /*
-+       * expected format argument size
-+       */
-+      sz = f->fmt_arg_size;
-+
-+      /*
-+       * check user size matches expected size
-+       * usize = -1 is for IA-64 backward compatibility
-+       */
-+      ret = -EINVAL;
-+      if (sz != usize && usize != -1) {
-+              PFM_DBG("invalid arg size %zu, format expects %zu",
-+                      usize, sz);
-+              goto error;
-+      }
-+
-+      ret = -ENOMEM;
-+      addr = kmalloc(sz, GFP_KERNEL);
-+      if (addr == NULL)
-+              goto error;
-+
-+      ret = -EFAULT;
-+      if (copy_from_user(addr, fmt_uarg, sz))
-+              goto error;
-+
-+      *arg = addr;
-+      *fmt = f;
-+      return 0;
-+
-+error:
-+      kfree(addr);
-+      pfm_smpl_fmt_put(f);
-+      return ret;
-+}
-+
-+static long pfm_create_context_old(int fd, void __user *ureq, int count)
-+{
-+      struct pfm_context *new_ctx;
-+      struct pfm_arch_context *ctx_arch;
-+      struct pfm_smpl_fmt *fmt = NULL;
-+      struct pfarg_context req_old;
-+      void __user *usmpl_arg;
-+      void *smpl_arg = NULL;
-+      struct pfarg_ctx req;
-+      int ret;
-+
-+      if (count != 1)
-+              return -EINVAL;
-+
-+      if (copy_from_user(&req_old, ureq, sizeof(req_old)))
-+              return -EFAULT;
-+
-+      memset(&req, 0, sizeof(req));
-+
-+      /*
-+       * sampling format args are following pfarg_context
-+       */
-+      usmpl_arg = ureq+sizeof(req_old);
-+
-+      ret = pfm_get_smpl_arg_old(req_old.ctx_smpl_buf_id, usmpl_arg, -1,
-+                                 &smpl_arg, &fmt);
-+      if (ret)
-+              return ret;
-+
-+      req.ctx_flags = req_old.ctx_flags;
-+
-+      /*
-+       * returns file descriptor if >=0, or error code */
-+      ret = __pfm_create_context(&req, fmt, smpl_arg, PFM_COMPAT, &new_ctx);
-+      if (ret >= 0) {
-+              ctx_arch = pfm_ctx_arch(new_ctx);
-+              req_old.ctx_fd = ret;
-+              req_old.ctx_smpl_vaddr = ctx_arch->ctx_smpl_vaddr;
-+      }
-+
-+      if (copy_to_user(ureq, &req_old, sizeof(req_old))) {
-+              pfm_undo_create_context_fd(req_old.ctx_fd, new_ctx);
-+              ret = -EFAULT;
-+      }
-+
-+      kfree(smpl_arg);
-+
-+      return ret;
-+}
-+
-+/*
-+ * obsolete call: use /proc/perfmon
-+ */
-+static long pfm_get_features_old(int fd, void __user *arg, int count)
-+{
-+      struct pfarg_features req;
-+      int ret = 0;
-+
-+      if (count != 1)
-+              return -EINVAL;
-+
-+      memset(&req, 0, sizeof(req));
-+
-+      req.ft_version = PFM_VERSION;
-+
-+      if (copy_to_user(arg, &req, sizeof(req)))
-+              ret = -EFAULT;
-+
-+      return ret;
-+}
-+
-+static long pfm_debug_old(int fd, void __user *arg, int count)
-+{
-+      int m;
-+
-+      if (count != 1)
-+              return -EINVAL;
-+
-+      if (get_user(m, (int __user *)arg))
-+              return -EFAULT;
-+
-+
-+      pfm_controls.debug = m == 0 ? 0 : 1;
-+
-+      PFM_INFO("debugging %s (timing reset)",
-+               pfm_controls.debug ? "on" : "off");
-+
-+      if (m == 0)
-+              for_each_online_cpu(m) {
-+                      memset(&per_cpu(pfm_stats, m), 0,
-+                             sizeof(struct pfm_stats));
-+              }
-+      return 0;
-+}
-+
-+static long pfm_unload_context_old(int fd, void __user *arg, int count)
-+{
-+      if (count)
-+              return -EINVAL;
-+
-+      return sys_pfm_unload_context(fd);
-+}
-+
-+static long pfm_restart_old(int fd, void __user *arg, int count)
-+{
-+      if (count)
-+              return -EINVAL;
-+
-+      return sys_pfm_restart(fd);
-+}
-+
-+static long pfm_stop_old(int fd, void __user *arg, int count)
-+{
-+      if (count)
-+              return -EINVAL;
-+
-+      return sys_pfm_stop(fd);
-+}
-+
-+static long pfm_start_old(int fd, void __user *arg, int count)
-+{
-+      if (count > 1)
-+              return -EINVAL;
-+
-+      return sys_pfm_start(fd, arg);
-+}
-+
-+static long pfm_load_context_old(int fd, void __user *ureq, int count)
-+{
-+      if (count != 1)
-+              return -EINVAL;
-+
-+      return sys_pfm_load_context(fd, ureq);
-+}
-+
-+/*
-+ * perfmon command descriptions
-+ */
-+struct pfm_cmd_desc {
-+      long (*cmd_func)(int fd, void __user *arg, int count);
-+};
-+
-+/*
-+ * functions MUST be listed in the increasing order of
-+ * their index (see permfon.h)
-+ */
-+#define PFM_CMD(name)  \
-+      { .cmd_func = name,  \
-+      }
-+#define PFM_CMD_NONE          \
-+      { .cmd_func = NULL   \
-+      }
-+
-+static struct pfm_cmd_desc pfm_cmd_tab[] = {
-+/* 0  */PFM_CMD_NONE,
-+/* 1  */PFM_CMD(pfm_write_pmcs_old),
-+/* 2  */PFM_CMD(pfm_write_pmds_old),
-+/* 3  */PFM_CMD(pfm_read_pmds_old),
-+/* 4  */PFM_CMD(pfm_stop_old),
-+/* 5  */PFM_CMD(pfm_start_old),
-+/* 6  */PFM_CMD_NONE,
-+/* 7  */PFM_CMD_NONE,
-+/* 8  */PFM_CMD(pfm_create_context_old),
-+/* 9  */PFM_CMD_NONE,
-+/* 10 */PFM_CMD(pfm_restart_old),
-+/* 11 */PFM_CMD_NONE,
-+/* 12 */PFM_CMD(pfm_get_features_old),
-+/* 13 */PFM_CMD(pfm_debug_old),
-+/* 14 */PFM_CMD_NONE,
-+/* 15 */PFM_CMD(pfm_get_default_pmcs_old),
-+/* 16 */PFM_CMD(pfm_load_context_old),
-+/* 17 */PFM_CMD(pfm_unload_context_old),
-+/* 18 */PFM_CMD_NONE,
-+/* 19 */PFM_CMD_NONE,
-+/* 20 */PFM_CMD_NONE,
-+/* 21 */PFM_CMD_NONE,
-+/* 22 */PFM_CMD_NONE,
-+/* 23 */PFM_CMD_NONE,
-+/* 24 */PFM_CMD_NONE,
-+/* 25 */PFM_CMD_NONE,
-+/* 26 */PFM_CMD_NONE,
-+/* 27 */PFM_CMD_NONE,
-+/* 28 */PFM_CMD_NONE,
-+/* 29 */PFM_CMD_NONE,
-+/* 30 */PFM_CMD_NONE,
-+/* 31 */PFM_CMD_NONE,
-+/* 32 */PFM_CMD(pfm_write_ibrs_old),
-+/* 33 */PFM_CMD(pfm_write_dbrs_old),
-+};
-+#define PFM_CMD_COUNT ARRAY_SIZE(pfm_cmd_tab)
-+
-+/*
-+ * system-call entry point (must return long)
-+ */
-+asmlinkage long sys_perfmonctl(int fd, int cmd, void __user *arg, int count)
-+{
-+      if (perfmon_disabled)
-+              return -ENOSYS;
-+
-+      if (unlikely(cmd < 0 || cmd >= PFM_CMD_COUNT
-+                   || pfm_cmd_tab[cmd].cmd_func == NULL)) {
-+              PFM_DBG("invalid cmd=%d", cmd);
-+              return -EINVAL;
-+      }
-+      return (long)pfm_cmd_tab[cmd].cmd_func(fd, arg, count);
-+}
-+
-+/*
-+ * Called from pfm_read() for a perfmon v2.0 context.
-+ *
-+ * compatibility mode pfm_read() routine. We need a separate
-+ * routine because the definition of the message has changed.
-+ * The pfm_msg and pfarg_msg structures are different.
-+ *
-+ * return: sizeof(pfm_msg_t) on success, -errno otherwise
-+ */
-+ssize_t pfm_arch_compat_read(struct pfm_context *ctx,
-+                           char __user *buf,
-+                           int non_block,
-+                           size_t size)
-+{
-+      union pfarg_msg msg_buf;
-+      pfm_msg_t old_msg_buf;
-+      pfm_ovfl_msg_t *o_msg;
-+      struct pfarg_ovfl_msg *n_msg;
-+      int ret;
-+
-+      PFM_DBG("msg=%p size=%zu", buf, size);
-+
-+      /*
-+       * cannot extract partial messages.
-+       * check even when there is no message
-+       *
-+       * cannot extract more than one message per call. Bytes
-+       * above sizeof(msg) are ignored.
-+       */
-+      if (size < sizeof(old_msg_buf)) {
-+              PFM_DBG("message is too small size=%zu must be >=%zu)",
-+                      size,
-+                      sizeof(old_msg_buf));
-+              return -EINVAL;
-+      }
-+
-+      ret =  __pfm_read(ctx, &msg_buf, non_block);
-+      if (ret < 1)
-+              return ret;
-+
-+      /*
-+       * force return value to old message size
-+       */
-+      ret = sizeof(old_msg_buf);
-+
-+      o_msg = &old_msg_buf.pfm_ovfl_msg;
-+      n_msg = &msg_buf.pfm_ovfl_msg;
-+
-+      switch (msg_buf.type) {
-+      case PFM_MSG_OVFL:
-+              o_msg->msg_type   = PFM_MSG_OVFL;
-+              o_msg->msg_ctx_fd = 0;
-+              o_msg->msg_active_set = n_msg->msg_active_set;
-+              o_msg->msg_tstamp = 0;
-+
-+              o_msg->msg_ovfl_pmds[0] = n_msg->msg_ovfl_pmds[0];
-+              o_msg->msg_ovfl_pmds[1] = n_msg->msg_ovfl_pmds[1];
-+              o_msg->msg_ovfl_pmds[2] = n_msg->msg_ovfl_pmds[2];
-+              o_msg->msg_ovfl_pmds[3] = n_msg->msg_ovfl_pmds[3];
-+              break;
-+      case PFM_MSG_END:
-+              o_msg->msg_type = PFM_MSG_END;
-+              o_msg->msg_ctx_fd = 0;
-+              o_msg->msg_tstamp = 0;
-+              break;
-+      default:
-+              PFM_DBG("unknown msg type=%d", msg_buf.type);
-+      }
-+      if (copy_to_user(buf, &old_msg_buf, sizeof(old_msg_buf)))
-+              ret = -EFAULT;
-+      PFM_DBG_ovfl("ret=%d", ret);
-+      return ret;
-+}
-+
-+/*
-+ * legacy /proc/perfmon simplified interface (we only maintain the
-+ * global information (no more per-cpu stats, use
-+ * /sys/devices/system/cpu/cpuXX/perfmon
-+ */
-+static struct proc_dir_entry  *perfmon_proc;
-+
-+static void *pfm_proc_start(struct seq_file *m, loff_t *pos)
-+{
-+      if (*pos == 0)
-+              return (void *)1;
-+
-+      return NULL;
-+}
-+
-+static void *pfm_proc_next(struct seq_file *m, void *v, loff_t *pos)
-+{
-+      ++*pos;
-+      return pfm_proc_start(m, pos);
-+}
-+
-+static void pfm_proc_stop(struct seq_file *m, void *v)
-+{
-+}
-+
-+/*
-+ * this is a simplified version of the legacy /proc/perfmon.
-+ * We have retained ONLY the key information that tools are actually
-+ * using
-+ */
-+static void pfm_proc_show_header(struct seq_file *m)
-+{
-+      char buf[128];
-+
-+      pfm_sysfs_res_show(buf, sizeof(buf), 3);
-+
-+      seq_printf(m, "perfmon version            : %u.%u\n",
-+              PFM_VERSION_MAJ, PFM_VERSION_MIN);
-+
-+      seq_printf(m, "model                      : %s", buf);
-+}
-+
-+static int pfm_proc_show(struct seq_file *m, void *v)
-+{
-+      pfm_proc_show_header(m);
-+      return 0;
-+}
-+
-+struct seq_operations pfm_proc_seq_ops = {
-+      .start = pfm_proc_start,
-+      .next = pfm_proc_next,
-+      .stop = pfm_proc_stop,
-+      .show = pfm_proc_show
-+};
-+
-+static int pfm_proc_open(struct inode *inode, struct file *file)
-+{
-+      return seq_open(file, &pfm_proc_seq_ops);
-+}
-+
-+
-+static struct file_operations pfm_proc_fops = {
-+      .open = pfm_proc_open,
-+      .read = seq_read,
-+      .llseek = seq_lseek,
-+      .release = seq_release,
-+};
-+
-+/*
-+ * called from pfm_arch_init(), global initialization, called once
-+ */
-+int __init pfm_ia64_compat_init(void)
-+{
-+      /*
-+       * create /proc/perfmon
-+       */
-+      perfmon_proc = create_proc_entry("perfmon", S_IRUGO, NULL);
-+      if (perfmon_proc == NULL) {
-+              PFM_ERR("cannot create /proc entry, perfmon disabled");
-+              return -1;
-+      }
-+      perfmon_proc->proc_fops = &pfm_proc_fops;
-+      return 0;
-+}
-diff --git a/arch/ia64/perfmon/perfmon_default_smpl.c b/arch/ia64/perfmon/perfmon_default_smpl.c
-new file mode 100644
-index 0000000..b408a13
---- /dev/null
-+++ b/arch/ia64/perfmon/perfmon_default_smpl.c
-@@ -0,0 +1,273 @@
-+/*
-+ * Copyright (c) 2002-2006 Hewlett-Packard Development Company, L.P.
-+ * Contributed by Stephane Eranian <eranian@hpl.hp.com>
-+ *
-+ * This file implements the old default sampling buffer format
-+ * for the Linux/ia64 perfmon-2 subsystem. This is for backward
-+ * compatibility only. use the new default format in perfmon/
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of version 2 of the GNU General Public
-+ * License as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ * 02111-1307 USA
-+  */
-+#include <linux/kernel.h>
-+#include <linux/types.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+#include <linux/smp.h>
-+#include <linux/sysctl.h>
-+
-+#ifdef MODULE
-+#define FMT_FLAGS     0
-+#else
-+#define FMT_FLAGS     PFM_FMTFL_IS_BUILTIN
-+#endif
-+
-+#include <linux/perfmon_kern.h>
-+#include <asm/perfmon_default_smpl.h>
-+
-+MODULE_AUTHOR("Stephane Eranian <eranian@hpl.hp.com>");
-+MODULE_DESCRIPTION("perfmon old default sampling format");
-+MODULE_LICENSE("GPL");
-+
-+static int pfm_default_fmt_validate(u32 flags, u16 npmds, void *data)
-+{
-+      struct pfm_default_smpl_arg *arg = data;
-+      size_t min_buf_size;
-+
-+      if (data == NULL) {
-+              PFM_DBG("no argument passed");
-+              return -EINVAL;
-+      }
-+
-+      /*
-+       * compute min buf size. All PMD are manipulated as 64bit entities
-+       */
-+      min_buf_size = sizeof(struct pfm_default_smpl_hdr)
-+           + (sizeof(struct pfm_default_smpl_entry) + (npmds*sizeof(u64)));
-+
-+      PFM_DBG("validate flags=0x%x npmds=%u min_buf_size=%lu "
-+                "buf_size=%lu CPU%d", flags, npmds, min_buf_size,
-+                arg->buf_size, smp_processor_id());
-+
-+      /*
-+       * must hold at least the buffer header + one minimally sized entry
-+       */
-+      if (arg->buf_size < min_buf_size)
-+              return -EINVAL;
-+
-+      return 0;
-+}
-+
-+static int pfm_default_fmt_get_size(unsigned int flags, void *data,
-+                                  size_t *size)
-+{
-+      struct pfm_default_smpl_arg *arg = data;
-+
-+      /*
-+       * size has been validated in default_validate
-+       */
-+      *size = arg->buf_size;
-+
-+      return 0;
-+}
-+
-+static int pfm_default_fmt_init(struct pfm_context *ctx, void *buf,
-+                              u32 flags, u16 npmds, void *data)
-+{
-+      struct pfm_default_smpl_hdr *hdr;
-+      struct pfm_default_smpl_arg *arg = data;
-+
-+      hdr = buf;
-+
-+      hdr->hdr_version      = PFM_DEFAULT_SMPL_VERSION;
-+      hdr->hdr_buf_size     = arg->buf_size;
-+      hdr->hdr_cur_offs     = sizeof(*hdr);
-+      hdr->hdr_overflows    = 0;
-+      hdr->hdr_count        = 0;
-+
-+      PFM_DBG("buffer=%p buf_size=%lu hdr_size=%lu "
-+                "hdr_version=%u cur_offs=%lu",
-+                buf,
-+                hdr->hdr_buf_size,
-+                sizeof(*hdr),
-+                hdr->hdr_version,
-+                hdr->hdr_cur_offs);
-+
-+      return 0;
-+}
-+
-+static int pfm_default_fmt_handler(struct pfm_context *ctx,
-+                                 unsigned long ip, u64 tstamp, void *data)
-+{
-+      struct pfm_default_smpl_hdr *hdr;
-+      struct pfm_default_smpl_entry *ent;
-+      void *cur, *last, *buf;
-+      u64 *e;
-+      size_t entry_size;
-+      u16 npmds, i, ovfl_pmd;
-+      struct pfm_ovfl_arg *arg;
-+
-+      hdr = ctx->smpl_addr;
-+      arg = &ctx->ovfl_arg;
-+
-+      buf = hdr;
-+      cur = buf+hdr->hdr_cur_offs;
-+      last = buf+hdr->hdr_buf_size;
-+      ovfl_pmd = arg->ovfl_pmd;
-+
-+      /*
-+       * precheck for sanity
-+       */
-+      if ((last - cur) < PFM_DEFAULT_MAX_ENTRY_SIZE)
-+              goto full;
-+
-+      npmds = arg->num_smpl_pmds;
-+
-+      ent = cur;
-+
-+      prefetch(arg->smpl_pmds_values);
-+
-+      entry_size = sizeof(*ent) + (npmds << 3);
-+
-+      /* position for first pmd */
-+      e = (unsigned long *)(ent+1);
-+
-+      hdr->hdr_count++;
-+
-+      PFM_DBG_ovfl("count=%lu cur=%p last=%p free_bytes=%lu "
-+                     "ovfl_pmd=%d npmds=%u",
-+                     hdr->hdr_count,
-+                     cur, last,
-+                     last-cur,
-+                     ovfl_pmd,
-+                     npmds);
-+
-+      /*
-+       * current = task running at the time of the overflow.
-+       *
-+       * per-task mode:
-+       *      - this is ususally the task being monitored.
-+       *        Under certain conditions, it might be a different task
-+       *
-+       * system-wide:
-+       *      - this is not necessarily the task controlling the session
-+       */
-+      ent->pid            = current->pid;
-+      ent->ovfl_pmd       = ovfl_pmd;
-+      ent->last_reset_val = arg->pmd_last_reset;
-+
-+      /*
-+       * where did the fault happen (includes slot number)
-+       */
-+      ent->ip = ip;
-+
-+      ent->tstamp    = tstamp;
-+      ent->cpu       = smp_processor_id();
-+      ent->set       = arg->active_set;
-+      ent->tgid      = current->tgid;
-+
-+      /*
-+       * selectively store PMDs in increasing index number
-+       */
-+      if (npmds) {
-+              u64 *val = arg->smpl_pmds_values;
-+              for (i = 0; i < npmds; i++)
-+                      *e++ = *val++;
-+      }
-+
-+      /*
-+       * update position for next entry
-+       */
-+      hdr->hdr_cur_offs += entry_size;
-+      cur               += entry_size;
-+
-+      /*
-+       * post check to avoid losing the last sample
-+       */
-+      if ((last - cur) < PFM_DEFAULT_MAX_ENTRY_SIZE)
-+              goto full;
-+
-+      /*
-+       * reset before returning from interrupt handler
-+       */
-+      arg->ovfl_ctrl = PFM_OVFL_CTRL_RESET;
-+      return 0;
-+full:
-+      PFM_DBG_ovfl("smpl buffer full free=%lu, count=%lu",
-+                     last-cur, hdr->hdr_count);
-+
-+      /*
-+       * increment number of buffer overflow.
-+       * important to detect duplicate set of samples.
-+       */
-+      hdr->hdr_overflows++;
-+
-+      /*
-+       * request notification and masking of monitoring.
-+       * Notification is still subject to the overflowed
-+       */
-+      arg->ovfl_ctrl = PFM_OVFL_CTRL_NOTIFY | PFM_OVFL_CTRL_MASK;
-+
-+      return -ENOBUFS; /* we are full, sorry */
-+}
-+
-+static int pfm_default_fmt_restart(int is_active, u32 *ovfl_ctrl, void *buf)
-+{
-+      struct pfm_default_smpl_hdr *hdr;
-+
-+      hdr = buf;
-+
-+      hdr->hdr_count    = 0;
-+      hdr->hdr_cur_offs = sizeof(*hdr);
-+
-+      *ovfl_ctrl = PFM_OVFL_CTRL_RESET;
-+
-+      return 0;
-+}
-+
-+static int pfm_default_fmt_exit(void *buf)
-+{
-+      return 0;
-+}
-+
-+static struct pfm_smpl_fmt default_fmt = {
-+      .fmt_name = "default-old",
-+      .fmt_version = 0x10000,
-+      .fmt_arg_size = sizeof(struct pfm_default_smpl_arg),
-+      .fmt_validate = pfm_default_fmt_validate,
-+      .fmt_getsize = pfm_default_fmt_get_size,
-+      .fmt_init = pfm_default_fmt_init,
-+      .fmt_handler = pfm_default_fmt_handler,
-+      .fmt_restart = pfm_default_fmt_restart,
-+      .fmt_exit = pfm_default_fmt_exit,
-+      .fmt_flags = FMT_FLAGS,
-+      .owner = THIS_MODULE
-+};
-+
-+static int pfm_default_fmt_init_module(void)
-+{
-+      int ret;
-+
-+      return pfm_fmt_register(&default_fmt);
-+      return ret;
-+}
-+
-+static void pfm_default_fmt_cleanup_module(void)
-+{
-+      pfm_fmt_unregister(&default_fmt);
-+}
-+
-+module_init(pfm_default_fmt_init_module);
-+module_exit(pfm_default_fmt_cleanup_module);
-diff --git a/arch/ia64/perfmon/perfmon_generic.c b/arch/ia64/perfmon/perfmon_generic.c
-new file mode 100644
-index 0000000..47b1870
---- /dev/null
-+++ b/arch/ia64/perfmon/perfmon_generic.c
-@@ -0,0 +1,148 @@
-+/*
-+ * This file contains the generic PMU register description tables
-+ * and pmc checker used by perfmon.c.
-+ *
-+ * Copyright (c) 2002-2006 Hewlett-Packard Development Company, L.P.
-+ * contributed by Stephane Eranian <eranian@hpl.hp.com>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of version 2 of the GNU General Public
-+ * License as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ * 02111-1307 USA
-+  */
-+#include <linux/module.h>
-+#include <linux/perfmon_kern.h>
-+#include <asm/pal.h>
-+
-+MODULE_AUTHOR("Stephane Eranian <eranian@hpl.hp.com>");
-+MODULE_DESCRIPTION("Generic IA-64 PMU description tables");
-+MODULE_LICENSE("GPL");
-+
-+#define RDEP(x)       (1UL << (x))
-+
-+#define PFM_IA64GEN_MASK_PMCS (RDEP(4)|RDEP(5)|RDEP(6)|RDEP(7))
-+#define PFM_IA64GEN_RSVD      (0xffffffffffff0080UL)
-+#define PFM_IA64GEN_NO64      (1UL<<5)
-+
-+/* forward declaration */
-+static struct pfm_pmu_config pfm_ia64gen_pmu_conf;
-+
-+static struct pfm_arch_pmu_info pfm_ia64gen_pmu_info = {
-+      .mask_pmcs = {PFM_IA64GEN_MASK_PMCS,},
-+};
-+
-+static struct pfm_regmap_desc pfm_ia64gen_pmc_desc[] = {
-+/* pmc0  */ PMX_NA,
-+/* pmc1  */ PMX_NA,
-+/* pmc2  */ PMX_NA,
-+/* pmc3  */ PMX_NA,
-+/* pmc4  */ PMC_D(PFM_REG_W64, "PMC4", 0x0, PFM_IA64GEN_RSVD, PFM_IA64GEN_NO64, 4),
-+/* pmc5  */ PMC_D(PFM_REG_W64, "PMC5", 0x0, PFM_IA64GEN_RSVD, PFM_IA64GEN_NO64, 5),
-+/* pmc6  */ PMC_D(PFM_REG_W64, "PMC6", 0x0, PFM_IA64GEN_RSVD, PFM_IA64GEN_NO64, 6),
-+/* pmc7  */ PMC_D(PFM_REG_W64, "PMC7", 0x0, PFM_IA64GEN_RSVD, PFM_IA64GEN_NO64, 7)
-+};
-+#define PFM_IA64GEN_NUM_PMCS ARRAY_SIZE(pfm_ia64gen_pmc_desc)
-+
-+static struct pfm_regmap_desc pfm_ia64gen_pmd_desc[] = {
-+/* pmd0  */ PMX_NA,
-+/* pmd1  */ PMX_NA,
-+/* pmd2  */ PMX_NA,
-+/* pmd3  */ PMX_NA,
-+/* pmd4  */ PMD_DP(PFM_REG_C, "PMD4", 4, 1ull << 4),
-+/* pmd5  */ PMD_DP(PFM_REG_C, "PMD5", 5, 1ull << 5),
-+/* pmd6  */ PMD_DP(PFM_REG_C, "PMD6", 6, 1ull << 6),
-+/* pmd7  */ PMD_DP(PFM_REG_C, "PMD7", 7, 1ull << 7)
-+};
-+#define PFM_IA64GEN_NUM_PMDS ARRAY_SIZE(pfm_ia64gen_pmd_desc)
-+
-+static int pfm_ia64gen_pmc_check(struct pfm_context *ctx,
-+                               struct pfm_event_set *set,
-+                               struct pfarg_pmc *req)
-+{
-+#define PFM_IA64GEN_PMC_PM_POS6       (1UL<<6)
-+      u64 tmpval;
-+      int is_system;
-+
-+      is_system = ctx->flags.system;
-+      tmpval = req->reg_value;
-+
-+      switch (req->reg_num) {
-+      case  4:
-+      case  5:
-+      case  6:
-+      case  7:
-+              /* set pmc.oi for 64-bit emulation */
-+              tmpval |= 1UL << 5;
-+
-+              if (is_system)
-+                      tmpval |= PFM_IA64GEN_PMC_PM_POS6;
-+              else
-+                      tmpval &= ~PFM_IA64GEN_PMC_PM_POS6;
-+              break;
-+
-+      }
-+      req->reg_value = tmpval;
-+
-+      return 0;
-+}
-+
-+/*
-+ * matches anything
-+ */
-+static int pfm_ia64gen_probe_pmu(void)
-+{
-+      u64 pm_buffer[16];
-+      pal_perf_mon_info_u_t pm_info;
-+
-+      /*
-+       * call PAL_PERFMON_INFO to retrieve counter width which
-+       * is implementation specific
-+       */
-+      if (ia64_pal_perf_mon_info(pm_buffer, &pm_info))
-+              return -1;
-+
-+      pfm_ia64gen_pmu_conf.counter_width = pm_info.pal_perf_mon_info_s.width;
-+
-+      return 0;
-+}
-+
-+/*
-+ * impl_pmcs, impl_pmds are computed at runtime to minimize errors!
-+ */
-+static struct pfm_pmu_config pfm_ia64gen_pmu_conf = {
-+      .pmu_name = "Generic IA-64",
-+      .counter_width = 0, /* computed from PAL_PERFMON_INFO */
-+      .pmd_desc = pfm_ia64gen_pmd_desc,
-+      .pmc_desc = pfm_ia64gen_pmc_desc,
-+      .probe_pmu = pfm_ia64gen_probe_pmu,
-+      .num_pmc_entries = PFM_IA64GEN_NUM_PMCS,
-+      .num_pmd_entries = PFM_IA64GEN_NUM_PMDS,
-+      .pmc_write_check = pfm_ia64gen_pmc_check,
-+      .version = "1.0",
-+      .flags = PFM_PMU_BUILTIN_FLAG,
-+      .owner = THIS_MODULE,
-+      .pmu_info = &pfm_ia64gen_pmu_info
-+      /* no read/write checkers */
-+};
-+
-+static int __init pfm_gen_pmu_init_module(void)
-+{
-+      return pfm_pmu_register(&pfm_ia64gen_pmu_conf);
-+}
-+
-+static void __exit pfm_gen_pmu_cleanup_module(void)
-+{
-+      pfm_pmu_unregister(&pfm_ia64gen_pmu_conf);
-+}
-+
-+module_init(pfm_gen_pmu_init_module);
-+module_exit(pfm_gen_pmu_cleanup_module);
-diff --git a/arch/ia64/perfmon/perfmon_itanium.c b/arch/ia64/perfmon/perfmon_itanium.c
-new file mode 100644
-index 0000000..094b31b
---- /dev/null
-+++ b/arch/ia64/perfmon/perfmon_itanium.c
-@@ -0,0 +1,232 @@
-+/*
-+ * This file contains the Itanium PMU register description tables
-+ * and pmc checker used by perfmon.c.
-+ *
-+ * Copyright (c) 2002-2006 Hewlett-Packard Development Company, L.P.
-+ * Contributed by Stephane Eranian <eranian@hpl.hp.com>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of version 2 of the GNU General Public
-+ * License as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ * 02111-1307 USA
-+  */
-+#include <linux/module.h>
-+#include <linux/perfmon_kern.h>
-+
-+MODULE_AUTHOR("Stephane Eranian <eranian@hpl.hp.com>");
-+MODULE_DESCRIPTION("Itanium (Merced) PMU description tables");
-+MODULE_LICENSE("GPL");
-+
-+#define RDEP(x)       (1ULL << (x))
-+
-+#define PFM_ITA_MASK_PMCS (RDEP(4)|RDEP(5)|RDEP(6)|RDEP(7)|RDEP(10)|RDEP(11)|\
-+                         RDEP(12))
-+
-+#define PFM_ITA_NO64  (1ULL<<5)
-+
-+static struct pfm_arch_pmu_info pfm_ita_pmu_info = {
-+      .mask_pmcs = {PFM_ITA_MASK_PMCS,},
-+};
-+/* reserved bits are 1 in the mask */
-+#define PFM_ITA_RSVD 0xfffffffffc8000a0UL
-+/*
-+ * For debug registers, writing xBR(y) means we use also xBR(y+1). Hence using
-+ * PMC256+y means we use PMC256+y+1.  Yet, we do not have dependency information
-+ * but this is fine because they are handled separately in the IA-64 specific
-+ * code.
-+ */
-+static struct pfm_regmap_desc pfm_ita_pmc_desc[] = {
-+/* pmc0  */ PMX_NA,
-+/* pmc1  */ PMX_NA,
-+/* pmc2  */ PMX_NA,
-+/* pmc3  */ PMX_NA,
-+/* pmc4  */ PMC_D(PFM_REG_W64, "PMC4" , 0x20, PFM_ITA_RSVD, PFM_ITA_NO64, 4),
-+/* pmc5  */ PMC_D(PFM_REG_W64, "PMC5" , 0x20, PFM_ITA_RSVD, PFM_ITA_NO64, 5),
-+/* pmc6  */ PMC_D(PFM_REG_W64, "PMC6" , 0x20, PFM_ITA_RSVD, PFM_ITA_NO64, 6),
-+/* pmc7  */ PMC_D(PFM_REG_W64, "PMC7" , 0x20, PFM_ITA_RSVD, PFM_ITA_NO64, 7),
-+/* pmc8  */ PMC_D(PFM_REG_W  , "PMC8" , 0xfffffffe3ffffff8UL, 0xfff00000001c0000UL, 0, 8),
-+/* pmc9  */ PMC_D(PFM_REG_W  , "PMC9" , 0xfffffffe3ffffff8UL, 0xfff00000001c0000UL, 0, 9),
-+/* pmc10 */ PMC_D(PFM_REG_W  , "PMC10", 0x0, 0xfffffffff3f0ff30UL, 0, 10),
-+/* pmc11 */ PMC_D(PFM_REG_W  , "PMC11", 0x10000000UL, 0xffffffffecf0ff30UL, 0, 11),
-+/* pmc12 */ PMC_D(PFM_REG_W  , "PMC12", 0x0, 0xffffffffffff0030UL, 0, 12),
-+/* pmc13 */ PMC_D(PFM_REG_W  , "PMC13", 0x3ffff00000001UL, 0xfffffffffffffffeUL, 0, 13),
-+/* pmc14 */ PMX_NA,
-+/* pmc15 */ PMX_NA,
-+/* pmc16 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc24 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc32 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc40 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc48 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc56 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc64 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc72 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc80 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc88 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc96 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc104 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc112 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc120 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc128 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc136 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc144 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc152 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc160 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc168 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc176 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc184 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc192 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc200 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc208 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc216 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc224 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc232 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc240 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc248 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc256 */ PMC_D(PFM_REG_W  , "IBR0", 0x0, 0, 0, 0),
-+/* pmc257 */ PMC_D(PFM_REG_W  , "IBR1", 0x0, 0x8000000000000000UL, 0, 1),
-+/* pmc258 */ PMC_D(PFM_REG_W  , "IBR2", 0x0, 0, 0, 2),
-+/* pmc259 */ PMC_D(PFM_REG_W  , "IBR3", 0x0, 0x8000000000000000UL, 0, 3),
-+/* pmc260 */ PMC_D(PFM_REG_W  , "IBR4", 0x0, 0, 0, 4),
-+/* pmc261 */ PMC_D(PFM_REG_W  , "IBR5", 0x0, 0x8000000000000000UL, 0, 5),
-+/* pmc262 */ PMC_D(PFM_REG_W  , "IBR6", 0x0, 0, 0, 6),
-+/* pmc263 */ PMC_D(PFM_REG_W  , "IBR7", 0x0, 0x8000000000000000UL, 0, 7),
-+/* pmc264 */ PMC_D(PFM_REG_W  , "DBR0", 0x0, 0, 0, 0),
-+/* pmc265 */ PMC_D(PFM_REG_W  , "DBR1", 0x0, 0xc000000000000000UL, 0, 1),
-+/* pmc266 */ PMC_D(PFM_REG_W  , "DBR2", 0x0, 0, 0, 2),
-+/* pmc267 */ PMC_D(PFM_REG_W  , "DBR3", 0x0, 0xc000000000000000UL, 0, 3),
-+/* pmc268 */ PMC_D(PFM_REG_W  , "DBR4", 0x0, 0, 0, 4),
-+/* pmc269 */ PMC_D(PFM_REG_W  , "DBR5", 0x0, 0xc000000000000000UL, 0, 5),
-+/* pmc270 */ PMC_D(PFM_REG_W  , "DBR6", 0x0, 0, 0, 6),
-+/* pmc271 */ PMC_D(PFM_REG_W  , "DBR7", 0x0, 0xc000000000000000UL, 0, 7)
-+};
-+#define PFM_ITA_NUM_PMCS ARRAY_SIZE(pfm_ita_pmc_desc)
-+
-+static struct pfm_regmap_desc pfm_ita_pmd_desc[] = {
-+/* pmd0  */ PMD_DP(PFM_REG_I , "PMD0", 0, 1ull << 10),
-+/* pmd1  */ PMD_DP(PFM_REG_I , "PMD1", 1, 1ull << 10),
-+/* pmd2  */ PMD_DP(PFM_REG_I , "PMD2", 2, 1ull << 11),
-+/* pmd3  */ PMD_DP(PFM_REG_I , "PMD3", 3, 1ull << 11),
-+/* pmd4  */ PMD_DP(PFM_REG_C , "PMD4", 4, 1ull << 4),
-+/* pmd5  */ PMD_DP(PFM_REG_C , "PMD5", 5, 1ull << 5),
-+/* pmd6  */ PMD_DP(PFM_REG_C , "PMD6", 6, 1ull << 6),
-+/* pmd7  */ PMD_DP(PFM_REG_C , "PMD7", 7, 1ull << 7),
-+/* pmd8  */ PMD_DP(PFM_REG_I , "PMD8", 8, 1ull << 12),
-+/* pmd9  */ PMD_DP(PFM_REG_I , "PMD9", 9, 1ull << 12),
-+/* pmd10 */ PMD_DP(PFM_REG_I , "PMD10", 10, 1ull << 12),
-+/* pmd11 */ PMD_DP(PFM_REG_I , "PMD11", 11, 1ull << 12),
-+/* pmd12 */ PMD_DP(PFM_REG_I , "PMD12", 12, 1ull << 12),
-+/* pmd13 */ PMD_DP(PFM_REG_I , "PMD13", 13, 1ull << 12),
-+/* pmd14 */ PMD_DP(PFM_REG_I , "PMD14", 14, 1ull << 12),
-+/* pmd15 */ PMD_DP(PFM_REG_I , "PMD15", 15, 1ull << 12),
-+/* pmd16 */ PMD_DP(PFM_REG_I , "PMD16", 16, 1ull << 12),
-+/* pmd17 */ PMD_DP(PFM_REG_I , "PMD17", 17, 1ull << 11)
-+};
-+#define PFM_ITA_NUM_PMDS ARRAY_SIZE(pfm_ita_pmd_desc)
-+
-+static int pfm_ita_pmc_check(struct pfm_context *ctx,
-+                           struct pfm_event_set *set,
-+                           struct pfarg_pmc *req)
-+{
-+#define PFM_ITA_PMC_PM_POS6   (1UL<<6)
-+      struct pfm_arch_context *ctx_arch;
-+      u64 tmpval;
-+      u16 cnum;
-+      int ret = 0, is_system;
-+
-+      tmpval = req->reg_value;
-+      cnum   = req->reg_num;
-+      ctx_arch = pfm_ctx_arch(ctx);
-+      is_system = ctx->flags.system;
-+
-+      switch (cnum) {
-+      case  4:
-+      case  5:
-+      case  6:
-+      case  7:
-+      case 10:
-+      case 11:
-+      case 12:
-+              if (is_system)
-+                      tmpval |= PFM_ITA_PMC_PM_POS6;
-+              else
-+                      tmpval &= ~PFM_ITA_PMC_PM_POS6;
-+              break;
-+      }
-+
-+      /*
-+       * we must clear the (instruction) debug registers if pmc13.ta bit is
-+       * cleared before they are written (fl_using_dbreg==0) to avoid
-+       * picking up stale information.
-+       */
-+      if (cnum == 13 && ((tmpval & 0x1) == 0)
-+              && ctx_arch->flags.use_dbr == 0) {
-+              PFM_DBG("pmc13 has pmc13.ta cleared, clearing ibr");
-+              ret = pfm_ia64_mark_dbregs_used(ctx, set);
-+              if (ret)
-+                      return ret;
-+      }
-+
-+      /*
-+       * we must clear the (data) debug registers if pmc11.pt bit is cleared
-+       * before they are written (fl_using_dbreg==0) to avoid picking up
-+       * stale information.
-+       */
-+      if (cnum == 11 && ((tmpval >> 28) & 0x1) == 0
-+              && ctx_arch->flags.use_dbr == 0) {
-+              PFM_DBG("pmc11 has pmc11.pt cleared, clearing dbr");
-+              ret = pfm_ia64_mark_dbregs_used(ctx, set);
-+              if (ret)
-+                      return ret;
-+      }
-+
-+      req->reg_value = tmpval;
-+
-+      return 0;
-+}
-+
-+static int pfm_ita_probe_pmu(void)
-+{
-+      return local_cpu_data->family == 0x7 && !ia64_platform_is("hpsim")
-+              ? 0 : -1;
-+}
-+
-+/*
-+ * impl_pmcs, impl_pmds are computed at runtime to minimize errors!
-+ */
-+static struct pfm_pmu_config pfm_ita_pmu_conf = {
-+      .pmu_name = "Itanium",
-+      .counter_width = 32,
-+      .pmd_desc = pfm_ita_pmd_desc,
-+      .pmc_desc = pfm_ita_pmc_desc,
-+      .pmc_write_check = pfm_ita_pmc_check,
-+      .num_pmc_entries = PFM_ITA_NUM_PMCS,
-+      .num_pmd_entries = PFM_ITA_NUM_PMDS,
-+      .probe_pmu = pfm_ita_probe_pmu,
-+      .version = "1.0",
-+      .flags = PFM_PMU_BUILTIN_FLAG,
-+      .owner = THIS_MODULE,
-+      .pmu_info = &pfm_ita_pmu_info
-+};
-+
-+static int __init pfm_ita_pmu_init_module(void)
-+{
-+      return pfm_pmu_register(&pfm_ita_pmu_conf);
-+}
-+
-+static void __exit pfm_ita_pmu_cleanup_module(void)
-+{
-+      pfm_pmu_unregister(&pfm_ita_pmu_conf);
-+}
-+
-+module_init(pfm_ita_pmu_init_module);
-+module_exit(pfm_ita_pmu_cleanup_module);
-+
-diff --git a/arch/ia64/perfmon/perfmon_mckinley.c b/arch/ia64/perfmon/perfmon_mckinley.c
-new file mode 100644
-index 0000000..dc59092
---- /dev/null
-+++ b/arch/ia64/perfmon/perfmon_mckinley.c
-@@ -0,0 +1,290 @@
-+/*
-+ * This file contains the McKinley PMU register description tables
-+ * and pmc checker used by perfmon.c.
-+ *
-+ * Copyright (c) 2002-2006 Hewlett-Packard Development Company, L.P.
-+ * Contributed by Stephane Eranian <eranian@hpl.hp.com>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of version 2 of the GNU General Public
-+ * License as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ * 02111-1307 USA
-+  */
-+#include <linux/module.h>
-+#include <linux/perfmon_kern.h>
-+
-+MODULE_AUTHOR("Stephane Eranian <eranian@hpl.hp.com>");
-+MODULE_DESCRIPTION("Itanium 2 (McKinley) PMU description tables");
-+MODULE_LICENSE("GPL");
-+
-+#define RDEP(x)       (1UL << (x))
-+
-+#define PFM_MCK_MASK_PMCS (RDEP(4)|RDEP(5)|RDEP(6)|RDEP(7)|RDEP(10)|RDEP(11)|\
-+                         RDEP(12))
-+
-+#define PFM_MCK_NO64  (1UL<<5)
-+
-+static struct pfm_arch_pmu_info pfm_mck_pmu_info = {
-+      .mask_pmcs = {PFM_MCK_MASK_PMCS,},
-+};
-+
-+/* reserved bits are 1 in the mask */
-+#define PFM_ITA2_RSVD 0xfffffffffc8000a0UL
-+
-+/*
-+ * For debug registers, writing xBR(y) means we use also xBR(y+1). Hence using
-+ * PMC256+y means we use PMC256+y+1.  Yet, we do not have dependency information
-+ * but this is fine because they are handled separately in the IA-64 specific
-+ * code.
-+ */
-+static struct pfm_regmap_desc pfm_mck_pmc_desc[] = {
-+/* pmc0  */ PMX_NA,
-+/* pmc1  */ PMX_NA,
-+/* pmc2  */ PMX_NA,
-+/* pmc3  */ PMX_NA,
-+/* pmc4  */ PMC_D(PFM_REG_W64, "PMC4" , 0x800020UL, 0xfffffffffc8000a0, PFM_MCK_NO64, 4),
-+/* pmc5  */ PMC_D(PFM_REG_W64, "PMC5" , 0x20UL, PFM_ITA2_RSVD, PFM_MCK_NO64, 5),
-+/* pmc6  */ PMC_D(PFM_REG_W64, "PMC6" , 0x20UL, PFM_ITA2_RSVD, PFM_MCK_NO64, 6),
-+/* pmc7  */ PMC_D(PFM_REG_W64, "PMC7" , 0x20UL, PFM_ITA2_RSVD, PFM_MCK_NO64, 7),
-+/* pmc8  */ PMC_D(PFM_REG_W  , "PMC8" , 0xffffffff3fffffffUL, 0xc0000004UL, 0, 8),
-+/* pmc9  */ PMC_D(PFM_REG_W  , "PMC9" , 0xffffffff3ffffffcUL, 0xc0000004UL, 0, 9),
-+/* pmc10 */ PMC_D(PFM_REG_W  , "PMC10", 0x0, 0xffffffffffff0000UL, 0, 10),
-+/* pmc11 */ PMC_D(PFM_REG_W  , "PMC11", 0x0, 0xfffffffffcf0fe30UL, 0, 11),
-+/* pmc12 */ PMC_D(PFM_REG_W  , "PMC12", 0x0, 0xffffffffffff0000UL, 0, 12),
-+/* pmc13 */ PMC_D(PFM_REG_W  , "PMC13", 0x2078fefefefeUL, 0xfffe1fffe7e7e7e7UL, 0, 13),
-+/* pmc14 */ PMC_D(PFM_REG_W  , "PMC14", 0x0db60db60db60db6UL, 0xffffffffffffdb6dUL, 0, 14),
-+/* pmc15 */ PMC_D(PFM_REG_W  , "PMC15", 0xfffffff0UL, 0xfffffffffffffff0UL, 0, 15),
-+/* pmc16 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc24 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc32 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc40 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc48 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc56 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc64 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc72 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc80 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc88 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc96 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc104 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc112 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc120 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc128 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc136 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc144 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc152 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc160 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc168 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc176 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc184 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc192 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc200 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc208 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc216 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc224 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc232 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc240 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc248 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc256 */ PMC_D(PFM_REG_W  , "IBR0", 0x0, 0, 0, 0),
-+/* pmc257 */ PMC_D(PFM_REG_W  , "IBR1", 0x0, 0x8000000000000000UL, 0, 1),
-+/* pmc258 */ PMC_D(PFM_REG_W  , "IBR2", 0x0, 0, 0, 2),
-+/* pmc259 */ PMC_D(PFM_REG_W  , "IBR3", 0x0, 0x8000000000000000UL, 0, 3),
-+/* pmc260 */ PMC_D(PFM_REG_W  , "IBR4", 0x0, 0, 0, 4),
-+/* pmc261 */ PMC_D(PFM_REG_W  , "IBR5", 0x0, 0x8000000000000000UL, 0, 5),
-+/* pmc262 */ PMC_D(PFM_REG_W  , "IBR6", 0x0, 0, 0, 6),
-+/* pmc263 */ PMC_D(PFM_REG_W  , "IBR7", 0x0, 0x8000000000000000UL, 0, 7),
-+/* pmc264 */ PMC_D(PFM_REG_W  , "DBR0", 0x0, 0, 0, 0),
-+/* pmc265 */ PMC_D(PFM_REG_W  , "DBR1", 0x0, 0xc000000000000000UL, 0, 1),
-+/* pmc266 */ PMC_D(PFM_REG_W  , "DBR2", 0x0, 0, 0, 2),
-+/* pmc267 */ PMC_D(PFM_REG_W  , "DBR3", 0x0, 0xc000000000000000UL, 0, 3),
-+/* pmc268 */ PMC_D(PFM_REG_W  , "DBR4", 0x0, 0, 0, 4),
-+/* pmc269 */ PMC_D(PFM_REG_W  , "DBR5", 0x0, 0xc000000000000000UL, 0, 5),
-+/* pmc270 */ PMC_D(PFM_REG_W  , "DBR6", 0x0, 0, 0, 6),
-+/* pmc271 */ PMC_D(PFM_REG_W  , "DBR7", 0x0, 0xc000000000000000UL, 0, 7)
-+};
-+#define PFM_MCK_NUM_PMCS ARRAY_SIZE(pfm_mck_pmc_desc)
-+
-+static struct pfm_regmap_desc pfm_mck_pmd_desc[] = {
-+/* pmd0  */ PMD_DP(PFM_REG_I, "PMD0", 0, 1ull << 10),
-+/* pmd1  */ PMD_DP(PFM_REG_I, "PMD1", 1, 1ull << 10),
-+/* pmd2  */ PMD_DP(PFM_REG_I, "PMD2", 2, 1ull << 11),
-+/* pmd3  */ PMD_DP(PFM_REG_I, "PMD3", 3, 1ull << 11),
-+/* pmd4  */ PMD_DP(PFM_REG_C, "PMD4", 4, 1ull << 4),
-+/* pmd5  */ PMD_DP(PFM_REG_C, "PMD5", 5, 1ull << 5),
-+/* pmd6  */ PMD_DP(PFM_REG_C, "PMD6", 6, 1ull << 6),
-+/* pmd7  */ PMD_DP(PFM_REG_C, "PMD7", 7, 1ull << 7),
-+/* pmd8  */ PMD_DP(PFM_REG_I, "PMD8", 8, 1ull << 12),
-+/* pmd9  */ PMD_DP(PFM_REG_I, "PMD9", 9, 1ull << 12),
-+/* pmd10 */ PMD_DP(PFM_REG_I, "PMD10", 10, 1ull << 12),
-+/* pmd11 */ PMD_DP(PFM_REG_I, "PMD11", 11, 1ull << 12),
-+/* pmd12 */ PMD_DP(PFM_REG_I, "PMD12", 12, 1ull << 12),
-+/* pmd13 */ PMD_DP(PFM_REG_I, "PMD13", 13, 1ull << 12),
-+/* pmd14 */ PMD_DP(PFM_REG_I, "PMD14", 14, 1ull << 12),
-+/* pmd15 */ PMD_DP(PFM_REG_I, "PMD15", 15, 1ull << 12),
-+/* pmd16 */ PMD_DP(PFM_REG_I, "PMD16", 16, 1ull << 12),
-+/* pmd17 */ PMD_DP(PFM_REG_I, "PMD17", 17, 1ull << 11)
-+};
-+#define PFM_MCK_NUM_PMDS ARRAY_SIZE(pfm_mck_pmd_desc)
-+
-+static int pfm_mck_pmc_check(struct pfm_context *ctx,
-+                           struct pfm_event_set *set,
-+                           struct pfarg_pmc *req)
-+{
-+      struct pfm_arch_context *ctx_arch;
-+      u64 val8 = 0, val14 = 0, val13 = 0;
-+      u64 tmpval;
-+      u16 cnum;
-+      int ret = 0, check_case1 = 0;
-+      int is_system;
-+
-+      tmpval = req->reg_value;
-+      cnum = req->reg_num;
-+      ctx_arch = pfm_ctx_arch(ctx);
-+      is_system = ctx->flags.system;
-+
-+#define PFM_MCK_PMC_PM_POS6   (1UL<<6)
-+#define PFM_MCK_PMC_PM_POS4   (1UL<<4)
-+
-+      switch (cnum) {
-+      case  4:
-+      case  5:
-+      case  6:
-+      case  7:
-+      case 11:
-+      case 12:
-+              if (is_system)
-+                      tmpval |= PFM_MCK_PMC_PM_POS6;
-+              else
-+                      tmpval &= ~PFM_MCK_PMC_PM_POS6;
-+              break;
-+
-+      case  8:
-+              val8 = tmpval;
-+              val13 = set->pmcs[13];
-+              val14 = set->pmcs[14];
-+              check_case1 = 1;
-+              break;
-+
-+      case 10:
-+              if (is_system)
-+                      tmpval |= PFM_MCK_PMC_PM_POS4;
-+              else
-+                      tmpval &= ~PFM_MCK_PMC_PM_POS4;
-+              break;
-+
-+      case 13:
-+              val8 = set->pmcs[8];
-+              val13 = tmpval;
-+              val14 = set->pmcs[14];
-+              check_case1 = 1;
-+              break;
-+
-+      case 14:
-+              val8 = set->pmcs[8];
-+              val13 = set->pmcs[13];
-+              val14 = tmpval;
-+              check_case1 = 1;
-+              break;
-+      }
-+
-+      /*
-+       * check illegal configuration which can produce inconsistencies
-+       * in tagging i-side events in L1D and L2 caches
-+       */
-+      if (check_case1) {
-+              ret = (((val13 >> 45) & 0xf) == 0 && ((val8 & 0x1) == 0))
-+                      && ((((val14>>1) & 0x3) == 0x2 || ((val14>>1) & 0x3) == 0x0)
-+                      || (((val14>>4) & 0x3) == 0x2 || ((val14>>4) & 0x3) == 0x0));
-+
-+              if (ret) {
-+                      PFM_DBG("perfmon: invalid config pmc8=0x%lx "
-+                              "pmc13=0x%lx pmc14=0x%lx",
-+                              val8, val13, val14);
-+                      return -EINVAL;
-+              }
-+      }
-+
-+      /*
-+       * check if configuration implicitely activates the use of
-+       * the debug registers. If true, then we ensure that this is
-+       * possible and that we do not pick up stale value in the HW
-+       * registers.
-+       *
-+       * We postpone the checks of pmc13 and pmc14 to avoid side effects
-+       * in case of errors
-+       */
-+
-+      /*
-+       * pmc13 is "active" if:
-+       *      one of the pmc13.cfg_dbrpXX field is different from 0x3
-+       * AND
-+       *      at the corresponding pmc13.ena_dbrpXX is set.
-+       */
-+      if (cnum == 13 && (tmpval & 0x1e00000000000UL)
-+          && (tmpval & 0x18181818UL) != 0x18181818UL
-+              && ctx_arch->flags.use_dbr == 0) {
-+              PFM_DBG("pmc13=0x%lx active", tmpval);
-+              ret = pfm_ia64_mark_dbregs_used(ctx, set);
-+              if (ret)
-+                      return ret;
-+      }
-+
-+      /*
-+       *  if any pmc14.ibrpX bit is enabled we must clear the ibrs
-+       */
-+      if (cnum == 14 && ((tmpval & 0x2222UL) != 0x2222UL)
-+              && ctx_arch->flags.use_dbr == 0) {
-+              PFM_DBG("pmc14=0x%lx active", tmpval);
-+              ret = pfm_ia64_mark_dbregs_used(ctx, set);
-+              if (ret)
-+                      return ret;
-+      }
-+
-+      req->reg_value = tmpval;
-+
-+      return 0;
-+}
-+
-+static int pfm_mck_probe_pmu(void)
-+{
-+      return local_cpu_data->family == 0x1f ? 0 : -1;
-+}
-+
-+/*
-+ * impl_pmcs, impl_pmds are computed at runtime to minimize errors!
-+ */
-+static struct pfm_pmu_config pfm_mck_pmu_conf = {
-+      .pmu_name = "Itanium 2",
-+      .counter_width = 47,
-+      .pmd_desc = pfm_mck_pmd_desc,
-+      .pmc_desc = pfm_mck_pmc_desc,
-+      .pmc_write_check = pfm_mck_pmc_check,
-+      .num_pmc_entries = PFM_MCK_NUM_PMCS,
-+      .num_pmd_entries = PFM_MCK_NUM_PMDS,
-+      .probe_pmu = pfm_mck_probe_pmu,
-+      .version = "1.0",
-+      .flags = PFM_PMU_BUILTIN_FLAG,
-+      .owner = THIS_MODULE,
-+      .pmu_info = &pfm_mck_pmu_info,
-+};
-+
-+static int __init pfm_mck_pmu_init_module(void)
-+{
-+      return pfm_pmu_register(&pfm_mck_pmu_conf);
-+}
-+
-+static void __exit pfm_mck_pmu_cleanup_module(void)
-+{
-+      pfm_pmu_unregister(&pfm_mck_pmu_conf);
-+}
-+
-+module_init(pfm_mck_pmu_init_module);
-+module_exit(pfm_mck_pmu_cleanup_module);
-diff --git a/arch/ia64/perfmon/perfmon_montecito.c b/arch/ia64/perfmon/perfmon_montecito.c
-new file mode 100644
-index 0000000..3f76f73
---- /dev/null
-+++ b/arch/ia64/perfmon/perfmon_montecito.c
-@@ -0,0 +1,412 @@
-+/*
-+ * This file contains the McKinley PMU register description tables
-+ * and pmc checker used by perfmon.c.
-+ *
-+ * Copyright (c) 2005-2006 Hewlett-Packard Development Company, L.P.
-+ * Contributed Stephane Eranian <eranian@hpl.hp.com>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of version 2 of the GNU General Public
-+ * License as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ * 02111-1307 USA
-+  */
-+#include <linux/module.h>
-+#include <linux/smp.h>
-+#include <linux/perfmon_kern.h>
-+
-+MODULE_AUTHOR("Stephane Eranian <eranian@hpl.hp.com>");
-+MODULE_DESCRIPTION("Dual-Core Itanium 2 (Montecito) PMU description table");
-+MODULE_LICENSE("GPL");
-+
-+#define RDEP(x)       (1UL << (x))
-+
-+#define PFM_MONT_MASK_PMCS (RDEP(4)|RDEP(5)|RDEP(6)|RDEP(7)|\
-+                          RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|\
-+                          RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|\
-+                          RDEP(37)|RDEP(39)|RDEP(40)|RDEP(42))
-+
-+#define PFM_MONT_NO64 (1UL<<5)
-+
-+static struct pfm_arch_pmu_info pfm_mont_pmu_info = {
-+      .mask_pmcs = {PFM_MONT_MASK_PMCS,},
-+};
-+
-+#define PFM_MONT_RSVD 0xffffffff838000a0UL
-+/*
-+ *
-+ * For debug registers, writing xBR(y) means we use also xBR(y+1). Hence using
-+ * PMC256+y means we use PMC256+y+1.  Yet, we do not have dependency information
-+ * but this is fine because they are handled separately in the IA-64 specific
-+ * code.
-+ *
-+ * For PMC4-PMC15, PMC40: we force pmc.ism=2 (IA-64 mode only)
-+ */
-+static struct pfm_regmap_desc pfm_mont_pmc_desc[] = {
-+/* pmc0  */ PMX_NA,
-+/* pmc1  */ PMX_NA,
-+/* pmc2  */ PMX_NA,
-+/* pmc3  */ PMX_NA,
-+/* pmc4  */ PMC_D(PFM_REG_W64, "PMC4" , 0x2000020UL, PFM_MONT_RSVD, PFM_MONT_NO64, 4),
-+/* pmc5  */ PMC_D(PFM_REG_W64, "PMC5" , 0x2000020UL, PFM_MONT_RSVD, PFM_MONT_NO64, 5),
-+/* pmc6  */ PMC_D(PFM_REG_W64, "PMC6" , 0x2000020UL, PFM_MONT_RSVD, PFM_MONT_NO64, 6),
-+/* pmc7  */ PMC_D(PFM_REG_W64, "PMC7" , 0x2000020UL, PFM_MONT_RSVD, PFM_MONT_NO64, 7),
-+/* pmc8  */ PMC_D(PFM_REG_W64, "PMC8" , 0x2000020UL, PFM_MONT_RSVD, PFM_MONT_NO64, 8),
-+/* pmc9  */ PMC_D(PFM_REG_W64, "PMC9" , 0x2000020UL, PFM_MONT_RSVD, PFM_MONT_NO64, 9),
-+/* pmc10 */ PMC_D(PFM_REG_W64, "PMC10", 0x2000020UL, PFM_MONT_RSVD, PFM_MONT_NO64, 10),
-+/* pmc11 */ PMC_D(PFM_REG_W64, "PMC11", 0x2000020UL, PFM_MONT_RSVD, PFM_MONT_NO64, 11),
-+/* pmc12 */ PMC_D(PFM_REG_W64, "PMC12", 0x2000020UL, PFM_MONT_RSVD, PFM_MONT_NO64, 12),
-+/* pmc13 */ PMC_D(PFM_REG_W64, "PMC13", 0x2000020UL, PFM_MONT_RSVD, PFM_MONT_NO64, 13),
-+/* pmc14 */ PMC_D(PFM_REG_W64, "PMC14", 0x2000020UL, PFM_MONT_RSVD, PFM_MONT_NO64, 14),
-+/* pmc15 */ PMC_D(PFM_REG_W64, "PMC15", 0x2000020UL, PFM_MONT_RSVD, PFM_MONT_NO64, 15),
-+/* pmc16 */ PMX_NA,
-+/* pmc17 */ PMX_NA,
-+/* pmc18 */ PMX_NA,
-+/* pmc19 */ PMX_NA,
-+/* pmc20 */ PMX_NA,
-+/* pmc21 */ PMX_NA,
-+/* pmc22 */ PMX_NA,
-+/* pmc23 */ PMX_NA,
-+/* pmc24 */ PMX_NA,
-+/* pmc25 */ PMX_NA,
-+/* pmc26 */ PMX_NA,
-+/* pmc27 */ PMX_NA,
-+/* pmc28 */ PMX_NA,
-+/* pmc29 */ PMX_NA,
-+/* pmc30 */ PMX_NA,
-+/* pmc31 */ PMX_NA,
-+/* pmc32 */ PMC_D(PFM_REG_W , "PMC32", 0x30f01ffffffffffUL, 0xfcf0fe0000000000UL, 0, 32),
-+/* pmc33 */ PMC_D(PFM_REG_W , "PMC33", 0x0, 0xfffffe0000000000UL, 0, 33),
-+/* pmc34 */ PMC_D(PFM_REG_W , "PMC34", 0xf01ffffffffffUL, 0xfff0fe0000000000UL, 0, 34),
-+/* pmc35 */ PMC_D(PFM_REG_W , "PMC35", 0x0,  0x1ffffffffffUL, 0, 35),
-+/* pmc36 */ PMC_D(PFM_REG_W , "PMC36", 0xfffffff0UL, 0xfffffffffffffff0UL, 0, 36),
-+/* pmc37 */ PMC_D(PFM_REG_W , "PMC37", 0x0, 0xffffffffffffc000UL, 0, 37),
-+/* pmc38 */ PMC_D(PFM_REG_W , "PMC38", 0xdb6UL, 0xffffffffffffdb6dUL, 0, 38),
-+/* pmc39 */ PMC_D(PFM_REG_W , "PMC39", 0x0, 0xffffffffffff0030UL, 0, 39),
-+/* pmc40 */ PMC_D(PFM_REG_W , "PMC40", 0x2000000UL, 0xfffffffffff0fe30UL, 0, 40),
-+/* pmc41 */ PMC_D(PFM_REG_W , "PMC41", 0x00002078fefefefeUL, 0xfffe1fffe7e7e7e7UL, 0, 41),
-+/* pmc42 */ PMC_D(PFM_REG_W , "PMC42", 0x0, 0xfff800b0UL, 0, 42),
-+/* pmc43 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc48 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc56 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc64 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc72 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc80 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc88 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc96 */  PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc104 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc112 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc120 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc128 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc136 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc144 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc152 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc160 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc168 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc176 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc184 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc192 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc200 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc208 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc216 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc224 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc232 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc240 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc248 */ PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA, PMX_NA,
-+/* pmc256 */ PMC_D(PFM_REG_W, "IBR0", 0x0, 0, 0, 0),
-+/* pmc257 */ PMC_D(PFM_REG_W, "IBR1", 0x0, 0x8000000000000000UL, 0, 1),
-+/* pmc258 */ PMC_D(PFM_REG_W, "IBR2", 0x0, 0, 0, 2),
-+/* pmc259 */ PMC_D(PFM_REG_W, "IBR3", 0x0, 0x8000000000000000UL, 0, 3),
-+/* pmc260 */ PMC_D(PFM_REG_W, "IBR4", 0x0, 0, 0, 4),
-+/* pmc261 */ PMC_D(PFM_REG_W, "IBR5", 0x0, 0x8000000000000000UL, 0, 5),
-+/* pmc262 */ PMC_D(PFM_REG_W, "IBR6", 0x0, 0, 0, 6),
-+/* pmc263 */ PMC_D(PFM_REG_W, "IBR7", 0x0, 0x8000000000000000UL, 0, 7),
-+/* pmc264 */ PMC_D(PFM_REG_W, "DBR0", 0x0, 0, 0, 0),
-+/* pmc265 */ PMC_D(PFM_REG_W, "DBR1", 0x0, 0xc000000000000000UL, 0, 1),
-+/* pmc266 */ PMC_D(PFM_REG_W, "DBR2", 0x0, 0, 0, 2),
-+/* pmc267 */ PMC_D(PFM_REG_W, "DBR3", 0x0, 0xc000000000000000UL, 0, 3),
-+/* pmc268 */ PMC_D(PFM_REG_W, "DBR4", 0x0, 0, 0, 4),
-+/* pmc269 */ PMC_D(PFM_REG_W, "DBR5", 0x0, 0xc000000000000000UL, 0, 5),
-+/* pmc270 */ PMC_D(PFM_REG_W, "DBR6", 0x0, 0, 0, 6),
-+/* pmc271 */ PMC_D(PFM_REG_W, "DBR7", 0x0, 0xc000000000000000UL, 0, 7)
-+};
-+#define PFM_MONT_NUM_PMCS ARRAY_SIZE(pfm_mont_pmc_desc)
-+
-+static struct pfm_regmap_desc pfm_mont_pmd_desc[] = {
-+/* pmd0  */ PMX_NA,
-+/* pmd1  */ PMX_NA,
-+/* pmd2  */ PMX_NA,
-+/* pmd3  */ PMX_NA,
-+/* pmd4  */ PMD_DP(PFM_REG_C, "PMD4", 4, 1ull << 4),
-+/* pmd5  */ PMD_DP(PFM_REG_C, "PMD5", 5, 1ull << 5),
-+/* pmd6  */ PMD_DP(PFM_REG_C, "PMD6", 6, 1ull << 6),
-+/* pmd7  */ PMD_DP(PFM_REG_C, "PMD7", 7, 1ull << 7),
-+/* pmd8  */ PMD_DP(PFM_REG_C, "PMD8", 8, 1ull << 8),
-+/* pmd9  */ PMD_DP(PFM_REG_C, "PMD9", 9, 1ull << 9),
-+/* pmd10 */ PMD_DP(PFM_REG_C, "PMD10", 10, 1ull << 10),
-+/* pmd11 */ PMD_DP(PFM_REG_C, "PMD11", 11, 1ull << 11),
-+/* pmd12 */ PMD_DP(PFM_REG_C, "PMD12", 12, 1ull << 12),
-+/* pmd13 */ PMD_DP(PFM_REG_C, "PMD13", 13, 1ull << 13),
-+/* pmd14 */ PMD_DP(PFM_REG_C, "PMD14", 14, 1ull << 14),
-+/* pmd15 */ PMD_DP(PFM_REG_C, "PMD15", 15, 1ull << 15),
-+/* pmd16 */ PMX_NA,
-+/* pmd17 */ PMX_NA,
-+/* pmd18 */ PMX_NA,
-+/* pmd19 */ PMX_NA,
-+/* pmd20 */ PMX_NA,
-+/* pmd21 */ PMX_NA,
-+/* pmd22 */ PMX_NA,
-+/* pmd23 */ PMX_NA,
-+/* pmd24 */ PMX_NA,
-+/* pmd25 */ PMX_NA,
-+/* pmd26 */ PMX_NA,
-+/* pmd27 */ PMX_NA,
-+/* pmd28 */ PMX_NA,
-+/* pmd29 */ PMX_NA,
-+/* pmd30 */ PMX_NA,
-+/* pmd31 */ PMX_NA,
-+/* pmd32 */ PMD_DP(PFM_REG_I, "PMD32", 32, 1ull << 40),
-+/* pmd33 */ PMD_DP(PFM_REG_I, "PMD33", 33, 1ull << 40),
-+/* pmd34 */ PMD_DP(PFM_REG_I, "PMD34", 34, 1ull << 37),
-+/* pmd35 */ PMD_DP(PFM_REG_I, "PMD35", 35, 1ull << 37),
-+/* pmd36 */ PMD_DP(PFM_REG_I, "PMD36", 36, 1ull << 40),
-+/* pmd37 */ PMX_NA,
-+/* pmd38 */ PMD_DP(PFM_REG_I, "PMD38", 38, (1ull<<39)|(1ull<<42)),
-+/* pmd39 */ PMD_DP(PFM_REG_I, "PMD39", 39, (1ull<<39)|(1ull<<42)),
-+/* pmd40 */ PMX_NA,
-+/* pmd41 */ PMX_NA,
-+/* pmd42 */ PMX_NA,
-+/* pmd43 */ PMX_NA,
-+/* pmd44 */ PMX_NA,
-+/* pmd45 */ PMX_NA,
-+/* pmd46 */ PMX_NA,
-+/* pmd47 */ PMX_NA,
-+/* pmd48 */ PMD_DP(PFM_REG_I, "PMD48", 48, (1ull<<39)|(1ull<<42)),
-+/* pmd49 */ PMD_DP(PFM_REG_I, "PMD49", 49, (1ull<<39)|(1ull<<42)),
-+/* pmd50 */ PMD_DP(PFM_REG_I, "PMD50", 50, (1ull<<39)|(1ull<<42)),
-+/* pmd51 */ PMD_DP(PFM_REG_I, "PMD51", 51, (1ull<<39)|(1ull<<42)),
-+/* pmd52 */ PMD_DP(PFM_REG_I, "PMD52", 52, (1ull<<39)|(1ull<<42)),
-+/* pmd53 */ PMD_DP(PFM_REG_I, "PMD53", 53, (1ull<<39)|(1ull<<42)),
-+/* pmd54 */ PMD_DP(PFM_REG_I, "PMD54", 54, (1ull<<39)|(1ull<<42)),
-+/* pmd55 */ PMD_DP(PFM_REG_I, "PMD55", 55, (1ull<<39)|(1ull<<42)),
-+/* pmd56 */ PMD_DP(PFM_REG_I, "PMD56", 56, (1ull<<39)|(1ull<<42)),
-+/* pmd57 */ PMD_DP(PFM_REG_I, "PMD57", 57, (1ull<<39)|(1ull<<42)),
-+/* pmd58 */ PMD_DP(PFM_REG_I, "PMD58", 58, (1ull<<39)|(1ull<<42)),
-+/* pmd59 */ PMD_DP(PFM_REG_I, "PMD59", 59, (1ull<<39)|(1ull<<42)),
-+/* pmd60 */ PMD_DP(PFM_REG_I, "PMD60", 60, (1ull<<39)|(1ull<<42)),
-+/* pmd61 */ PMD_DP(PFM_REG_I, "PMD61", 61, (1ull<<39)|(1ull<<42)),
-+/* pmd62 */ PMD_DP(PFM_REG_I, "PMD62", 62, (1ull<<39)|(1ull<<42)),
-+/* pmd63 */ PMD_DP(PFM_REG_I, "PMD63", 63, (1ull<<39)|(1ull<<42))
-+};
-+#define PFM_MONT_NUM_PMDS ARRAY_SIZE(pfm_mont_pmd_desc)
-+
-+static int pfm_mont_has_ht;
-+
-+static int pfm_mont_pmc_check(struct pfm_context *ctx,
-+                            struct pfm_event_set *set,
-+                            struct pfarg_pmc *req)
-+{
-+      struct pfm_arch_context *ctx_arch;
-+      u64 val32 = 0, val38 = 0, val41 = 0;
-+      u64 tmpval;
-+      u16 cnum;
-+      int ret = 0, check_case1 = 0;
-+      int is_system;
-+
-+      tmpval = req->reg_value;
-+      cnum = req->reg_num;
-+      ctx_arch = pfm_ctx_arch(ctx);
-+      is_system = ctx->flags.system;
-+
-+#define PFM_MONT_PMC_PM_POS6  (1UL<<6)
-+#define PFM_MONT_PMC_PM_POS4  (1UL<<4)
-+
-+      switch (cnum) {
-+      case  4:
-+      case  5:
-+      case  6:
-+      case  7:
-+      case  8:
-+      case  9:
-+              if (is_system)
-+                      tmpval |= PFM_MONT_PMC_PM_POS6;
-+              else
-+                      tmpval &= ~PFM_MONT_PMC_PM_POS6;
-+              break;
-+      case 10:
-+      case 11:
-+      case 12:
-+      case 13:
-+      case 14:
-+      case 15:
-+              if ((req->reg_flags & PFM_REGFL_NO_EMUL64) == 0) {
-+                      if (pfm_mont_has_ht) {
-+                              PFM_INFO("perfmon: Errata 121 PMD10/PMD15 cannot be used to overflow"
-+                                       "when threads on on");
-+                              return -EINVAL;
-+                      }
-+              }
-+              if (is_system)
-+                      tmpval |= PFM_MONT_PMC_PM_POS6;
-+              else
-+                      tmpval &= ~PFM_MONT_PMC_PM_POS6;
-+              break;
-+      case 39:
-+      case 40:
-+      case 42:
-+              if (pfm_mont_has_ht && ((req->reg_value >> 8) & 0x7) == 4) {
-+                      PFM_INFO("perfmon: Errata 120: IP-EAR not available when threads are on");
-+                      return -EINVAL;
-+              }
-+              if (is_system)
-+                      tmpval |= PFM_MONT_PMC_PM_POS6;
-+              else
-+                      tmpval &= ~PFM_MONT_PMC_PM_POS6;
-+              break;
-+
-+      case  32:
-+              val32 = tmpval;
-+              val38 = set->pmcs[38];
-+              val41 = set->pmcs[41];
-+              check_case1 = 1;
-+              break;
-+
-+      case  37:
-+              if (is_system)
-+                      tmpval |= PFM_MONT_PMC_PM_POS4;
-+              else
-+                      tmpval &= ~PFM_MONT_PMC_PM_POS4;
-+              break;
-+
-+      case  38:
-+              val38 = tmpval;
-+              val32 = set->pmcs[32];
-+              val41 = set->pmcs[41];
-+              check_case1 = 1;
-+              break;
-+      case  41:
-+              val41 = tmpval;
-+              val32 = set->pmcs[32];
-+              val38 = set->pmcs[38];
-+              check_case1 = 1;
-+              break;
-+      }
-+
-+      if (check_case1) {
-+              ret = (((val41 >> 45) & 0xf) == 0 && ((val32>>57) & 0x1) == 0)
-+                   && ((((val38>>1) & 0x3) == 0x2 || ((val38>>1) & 0x3) == 0)
-+                   || (((val38>>4) & 0x3) == 0x2 || ((val38>>4) & 0x3) == 0));
-+              if (ret) {
-+                      PFM_DBG("perfmon: invalid config pmc38=0x%lx "
-+                              "pmc41=0x%lx pmc32=0x%lx",
-+                              val38, val41, val32);
-+                      return -EINVAL;
-+              }
-+      }
-+
-+      /*
-+       * check if configuration implicitely activates the use of the
-+       * debug registers. If true, then we ensure that this is possible
-+       * and that we do not pick up stale value in the HW registers.
-+       */
-+
-+      /*
-+       *
-+       * pmc41 is "active" if:
-+       *      one of the pmc41.cfgdtagXX field is different from 0x3
-+       * AND
-+       *      the corsesponding pmc41.en_dbrpXX is set.
-+       * AND
-+       *      ctx_fl_use_dbr (dbr not yet used)
-+       */
-+      if (cnum == 41
-+          && (tmpval & 0x1e00000000000)
-+              && (tmpval & 0x18181818) != 0x18181818
-+              && ctx_arch->flags.use_dbr == 0) {
-+              PFM_DBG("pmc41=0x%lx active, clearing dbr", tmpval);
-+              ret = pfm_ia64_mark_dbregs_used(ctx, set);
-+              if (ret)
-+                      return ret;
-+      }
-+      /*
-+       * we must clear the (instruction) debug registers if:
-+       *      pmc38.ig_ibrpX is 0 (enabled)
-+       * and
-+       *      fl_use_dbr == 0 (dbr not yet used)
-+       */
-+      if (cnum == 38 && ((tmpval & 0x492) != 0x492)
-+              && ctx_arch->flags.use_dbr == 0) {
-+              PFM_DBG("pmc38=0x%lx active pmc38, clearing ibr", tmpval);
-+              ret = pfm_ia64_mark_dbregs_used(ctx, set);
-+              if (ret)
-+                      return ret;
-+
-+      }
-+      req->reg_value = tmpval;
-+      return 0;
-+}
-+
-+static void pfm_handle_errata(void)
-+{
-+      pfm_mont_has_ht = 1;
-+
-+      PFM_INFO("activating workaround for errata 120 "
-+               "(Disable IP-EAR when threads are on)");
-+
-+      PFM_INFO("activating workaround for Errata 121 "
-+               "(PMC10-PMC15 cannot be used to overflow"
-+               " when threads are on");
-+}
-+static int pfm_mont_probe_pmu(void)
-+{
-+      if (local_cpu_data->family != 0x20)
-+              return -1;
-+
-+      /*
-+       * the 2 errata must be activated when
-+       * threads are/can be enabled
-+       */
-+      if (is_multithreading_enabled())
-+              pfm_handle_errata();
-+
-+      return 0;
-+}
-+
-+/*
-+ * impl_pmcs, impl_pmds are computed at runtime to minimize errors!
-+ */
-+static struct pfm_pmu_config pfm_mont_pmu_conf = {
-+      .pmu_name = "Montecito",
-+      .counter_width = 47,
-+      .pmd_desc = pfm_mont_pmd_desc,
-+      .pmc_desc = pfm_mont_pmc_desc,
-+      .num_pmc_entries = PFM_MONT_NUM_PMCS,
-+      .num_pmd_entries = PFM_MONT_NUM_PMDS,
-+      .pmc_write_check = pfm_mont_pmc_check,
-+      .probe_pmu = pfm_mont_probe_pmu,
-+      .version = "1.0",
-+      .pmu_info = &pfm_mont_pmu_info,
-+      .flags = PFM_PMU_BUILTIN_FLAG,
-+      .owner = THIS_MODULE
-+};
-+
-+static int __init pfm_mont_pmu_init_module(void)
-+{
-+      return pfm_pmu_register(&pfm_mont_pmu_conf);
-+}
-+
-+static void __exit pfm_mont_pmu_cleanup_module(void)
-+{
-+      pfm_pmu_unregister(&pfm_mont_pmu_conf);
-+}
-+
-+module_init(pfm_mont_pmu_init_module);
-+module_exit(pfm_mont_pmu_cleanup_module);
-diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
-index 1e06d23..b87f445 100644
---- a/arch/mips/Kconfig
-+++ b/arch/mips/Kconfig
-@@ -1857,6 +1857,8 @@ config SECCOMP
-         If unsure, say Y. Only embedded should say N here.
-+source "arch/mips/perfmon/Kconfig"
-+
- endmenu
- config RWSEM_GENERIC_SPINLOCK
-diff --git a/arch/mips/Makefile b/arch/mips/Makefile
-index 9aab51c..712acf7 100644
---- a/arch/mips/Makefile
-+++ b/arch/mips/Makefile
-@@ -154,6 +154,12 @@ endif
- endif
- #
-+# Perfmon support
-+#
-+
-+core-$(CONFIG_PERFMON)                += arch/mips/perfmon/
-+
-+#
- # Firmware support
- #
- libs-$(CONFIG_ARC)            += arch/mips/fw/arc/
-diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
-index 22fc19b..4467361 100644
---- a/arch/mips/kernel/process.c
-+++ b/arch/mips/kernel/process.c
-@@ -27,6 +27,7 @@
- #include <linux/completion.h>
- #include <linux/kallsyms.h>
- #include <linux/random.h>
-+#include <linux/perfmon_kern.h>
- #include <asm/asm.h>
- #include <asm/bootinfo.h>
-@@ -94,6 +95,7 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
- void exit_thread(void)
- {
-+  pfm_exit_thread();
- }
- void flush_thread(void)
-@@ -162,6 +164,8 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
-       if (clone_flags & CLONE_SETTLS)
-               ti->tp_value = regs->regs[7];
-+      pfm_copy_thread(p);
-+
-       return 0;
- }
-diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
-index 5e75a31..e96ddd6 100644
---- a/arch/mips/kernel/scall32-o32.S
-+++ b/arch/mips/kernel/scall32-o32.S
-@@ -653,6 +653,18 @@ einval:   li      v0, -EINVAL
-       sys     sys_dup3                3
-       sys     sys_pipe2               2
-       sys     sys_inotify_init1       1
-+      sys     sys_pfm_create_context  4       /* 4330 */
-+      sys     sys_pfm_write_pmcs      3
-+      sys     sys_pfm_write_pmds      4
-+      sys     sys_pfm_read_pmds       3
-+      sys     sys_pfm_load_context    2
-+      sys     sys_pfm_start           2       /* 4335 */
-+      sys     sys_pfm_stop            1
-+      sys     sys_pfm_restart         1
-+      sys     sys_pfm_create_evtsets  3
-+      sys     sys_pfm_getinfo_evtsets 3
-+      sys     sys_pfm_delete_evtsets  3       /* 4340 */
-+      sys     sys_pfm_unload_context  1
-       .endm
-       /* We pre-compute the number of _instruction_ bytes needed to
-diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
-index 3d58204..adb2ba9 100644
---- a/arch/mips/kernel/scall64-64.S
-+++ b/arch/mips/kernel/scall64-64.S
-@@ -487,4 +487,16 @@ sys_call_table:
-       PTR     sys_dup3
-       PTR     sys_pipe2
-       PTR     sys_inotify_init1
-+      PTR     sys_pfm_create_context
-+      PTR     sys_pfm_write_pmcs              /* 5290 */
-+      PTR     sys_pfm_write_pmds
-+      PTR     sys_pfm_read_pmds
-+      PTR     sys_pfm_load_context
-+      PTR     sys_pfm_start
-+      PTR     sys_pfm_stop                    /* 5295 */
-+      PTR     sys_pfm_restart
-+      PTR     sys_pfm_create_evtsets
-+      PTR     sys_pfm_getinfo_evtsets
-+      PTR     sys_pfm_delete_evtsets
-+      PTR     sys_pfm_unload_context          /* 5300 */
-       .size   sys_call_table,.-sys_call_table
-diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
-index da7f1b6..6d12095 100644
---- a/arch/mips/kernel/scall64-n32.S
-+++ b/arch/mips/kernel/scall64-n32.S
-@@ -400,12 +400,12 @@ EXPORT(sysn32_call_table)
-       PTR     sys_ioprio_set
-       PTR     sys_ioprio_get
-       PTR     compat_sys_utimensat
--      PTR     compat_sys_signalfd             /* 5280 */
-+      PTR     compat_sys_signalfd             /* 6280 */
-       PTR     sys_ni_syscall
-       PTR     sys_eventfd
-       PTR     sys_fallocate
-       PTR     sys_timerfd_create
--      PTR     sys_timerfd_gettime             /* 5285 */
-+      PTR     sys_timerfd_gettime             /* 6285 */
-       PTR     sys_timerfd_settime
-       PTR     sys_signalfd4
-       PTR     sys_eventfd2
-@@ -413,4 +413,16 @@ EXPORT(sysn32_call_table)
-       PTR     sys_dup3                        /* 5290 */
-       PTR     sys_pipe2
-       PTR     sys_inotify_init1
-+      PTR     sys_pfm_create_context
-+      PTR     sys_pfm_write_pmcs
-+      PTR     sys_pfm_write_pmds              /* 6295 */
-+      PTR     sys_pfm_read_pmds
-+      PTR     sys_pfm_load_context
-+      PTR     sys_pfm_start
-+      PTR     sys_pfm_stop
-+      PTR     sys_pfm_restart                 /* 6300 */
-+      PTR     sys_pfm_create_evtsets
-+      PTR     sys_pfm_getinfo_evtsets
-+      PTR     sys_pfm_delete_evtsets
-+      PTR     sys_pfm_unload_context
-       .size   sysn32_call_table,.-sysn32_call_table
-diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
-index d7cd1aa..e77f55a 100644
---- a/arch/mips/kernel/scall64-o32.S
-+++ b/arch/mips/kernel/scall64-o32.S
-@@ -535,4 +535,16 @@ sys_call_table:
-       PTR     sys_dup3
-       PTR     sys_pipe2
-       PTR     sys_inotify_init1
-+      PTR     sys_pfm_create_context          /* 4330 */
-+      PTR     sys_pfm_write_pmcs
-+      PTR     sys_pfm_write_pmds
-+      PTR     sys_pfm_read_pmds
-+      PTR     sys_pfm_load_context
-+      PTR     sys_pfm_start                   /* 4335 */
-+      PTR     sys_pfm_stop
-+      PTR     sys_pfm_restart
-+      PTR     sys_pfm_create_evtsets
-+      PTR     sys_pfm_getinfo_evtsets
-+      PTR     sys_pfm_delete_evtsets          /* 4340 */
-+      PTR     sys_pfm_unload_context
-       .size   sys_call_table,.-sys_call_table
-diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
-index a4e106c..6a7e60c 100644
---- a/arch/mips/kernel/signal.c
-+++ b/arch/mips/kernel/signal.c
-@@ -20,6 +20,7 @@
- #include <linux/unistd.h>
- #include <linux/compiler.h>
- #include <linux/uaccess.h>
-+#include <linux/perfmon_kern.h>
- #include <asm/abi.h>
- #include <asm/asm.h>
-@@ -694,8 +695,11 @@ static void do_signal(struct pt_regs *regs)
-  * - triggered by the TIF_WORK_MASK flags
-  */
- asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused,
--      __u32 thread_info_flags)
-+                               __u32 thread_info_flags)
- {
-+      if (thread_info_flags & _TIF_PERFMON_WORK)
-+              pfm_handle_work(regs);
-+
-       /* deal with pending signal delivery */
-       if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
-               do_signal(regs);
-diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
-index 1f467d5..163dfe4 100644
---- a/arch/mips/kernel/time.c
-+++ b/arch/mips/kernel/time.c
-@@ -49,10 +49,11 @@ int update_persistent_clock(struct timespec now)
-       return rtc_mips_set_mmss(now.tv_sec);
- }
--static int null_perf_irq(void)
-+int null_perf_irq(void)
- {
-       return 0;
- }
-+EXPORT_SYMBOL(null_perf_irq);
- int (*perf_irq)(void) = null_perf_irq;
-diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
-index b602ac6..9cbd75f 100644
---- a/arch/mips/kernel/traps.c
-+++ b/arch/mips/kernel/traps.c
-@@ -92,17 +92,15 @@ static void show_raw_backtrace(unsigned long reg29)
- #ifdef CONFIG_KALLSYMS
-       printk("\n");
- #endif
--      while (!kstack_end(sp)) {
--              unsigned long __user *p =
--                      (unsigned long __user *)(unsigned long)sp++;
--              if (__get_user(addr, p)) {
--                      printk(" (Bad stack address)");
--                      break;
-+#define IS_KVA01(a) ((((unsigned long)a) & 0xc0000000) == 0x80000000)
-+      if (IS_KVA01(sp)) {
-+              while (!kstack_end(sp)) {
-+                      addr = *sp++;
-+                      if (__kernel_text_address(addr))
-+                              print_ip_sym(addr);
-               }
--              if (__kernel_text_address(addr))
--                      print_ip_sym(addr);
-+              printk("\n");
-       }
--      printk("\n");
- }
- #ifdef CONFIG_KALLSYMS
-diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c
-index 0b97d47..d8f36b5 100644
---- a/arch/mips/mti-malta/malta-time.c
-+++ b/arch/mips/mti-malta/malta-time.c
-@@ -27,6 +27,7 @@
- #include <linux/time.h>
- #include <linux/timex.h>
- #include <linux/mc146818rtc.h>
-+#include <linux/perfmon_kern.h>
- #include <asm/mipsregs.h>
- #include <asm/mipsmtregs.h>
-diff --git a/arch/mips/perfmon/Kconfig b/arch/mips/perfmon/Kconfig
-new file mode 100644
-index 0000000..b426eea
---- /dev/null
-+++ b/arch/mips/perfmon/Kconfig
-@@ -0,0 +1,61 @@
-+menu "Hardware Performance Monitoring support"
-+config PERFMON
-+      bool "Perfmon2 performance monitoring interface"
-+      default n
-+      help
-+      Enables the perfmon2 interface to access the hardware
-+      performance counters. See <http://perfmon2.sf.net/> for
-+      more details.
-+
-+config PERFMON_DEBUG
-+      bool "Perfmon debugging"
-+      default n
-+      depends on PERFMON
-+      help
-+      Enables perfmon debugging support
-+
-+config PERFMON_DEBUG_FS
-+      bool "Enable perfmon statistics reporting via debugfs"
-+      default y
-+      depends on PERFMON && DEBUG_FS
-+      help
-+      Enable collection and reporting of perfmon timing statistics under
-+      debugfs. This is used for debugging and performance analysis of the
-+      subsystem. The debugfs filesystem must be mounted.
-+
-+config PERFMON_FLUSH
-+      bool "Flush sampling buffer when modified"
-+      depends on PERFMON
-+      default n
-+      help
-+      On some MIPS models, cache aliasing may cause invalid
-+      data to be read from the perfmon sampling buffer. Use this option
-+      to flush the buffer when it is modified to ensure valid data is
-+      visible at the user level.
-+
-+config PERFMON_ALIGN
-+      bool "Align sampling buffer to avoid cache aliasing"
-+      depends on PERFMON
-+      default n
-+      help
-+      On some MIPS models, cache aliasing may cause invalid
-+      data to be read from the perfmon sampling buffer. By forcing a bigger
-+      page alignment (4-page), one can guarantee the buffer virtual address
-+      will conflict in the cache with the user level mapping of the buffer
-+      thereby ensuring a consistent view by user programs.
-+
-+config PERFMON_DEBUG
-+      bool "Perfmon debugging"
-+      depends on PERFMON
-+      default n
-+      depends on PERFMON
-+      help
-+      Enables perfmon debugging support
-+
-+config PERFMON_MIPS64
-+      tristate "Support for MIPS64 hardware performance counters"
-+      depends on PERFMON
-+      default n
-+      help
-+      Enables support for the MIPS64 hardware performance counters"
-+endmenu
-diff --git a/arch/mips/perfmon/Makefile b/arch/mips/perfmon/Makefile
-new file mode 100644
-index 0000000..153b83f
---- /dev/null
-+++ b/arch/mips/perfmon/Makefile
-@@ -0,0 +1,2 @@
-+obj-$(CONFIG_PERFMON)         += perfmon.o
-+obj-$(CONFIG_PERFMON_MIPS64)  += perfmon_mips64.o
-diff --git a/arch/mips/perfmon/perfmon.c b/arch/mips/perfmon/perfmon.c
-new file mode 100644
-index 0000000..6615a77
---- /dev/null
-+++ b/arch/mips/perfmon/perfmon.c
-@@ -0,0 +1,313 @@
-+/*
-+ * This file implements the MIPS64 specific
-+ * support for the perfmon2 interface
-+ *
-+ * Copyright (c) 2005 Philip J. Mucci
-+ *
-+ * based on versions for other architectures:
-+ * Copyright (c) 2005 Hewlett-Packard Development Company, L.P.
-+ * Contributed by Stephane Eranian <eranian@htrpl.hp.com>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of version 2 of the GNU General Public
-+ * License as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ * 02111-1307 USA
-+  */
-+#include <linux/interrupt.h>
-+#include <linux/module.h>
-+#include <linux/perfmon_kern.h>
-+
-+/*
-+ * collect pending overflowed PMDs. Called from pfm_ctxsw()
-+ * and from PMU interrupt handler. Must fill in set->povfl_pmds[]
-+ * and set->npend_ovfls. Interrupts are masked
-+ */
-+static void __pfm_get_ovfl_pmds(struct pfm_context *ctx, struct pfm_event_set *set)
-+{
-+      u64 new_val, wmask;
-+      u64 *used_mask, *intr_pmds;
-+      u64 mask[PFM_PMD_BV];
-+      unsigned int i, max;
-+
-+      max = ctx->regs.max_intr_pmd;
-+      intr_pmds = ctx->regs.intr_pmds;
-+      used_mask = set->used_pmds;
-+
-+      wmask = 1ULL << pfm_pmu_conf->counter_width;
-+
-+      bitmap_and(cast_ulp(mask),
-+                 cast_ulp(intr_pmds),
-+                 cast_ulp(used_mask),
-+                 max);
-+
-+      /*
-+       * check all PMD that can generate interrupts
-+       * (that includes counters)
-+       */
-+      for (i = 0; i < max; i++) {
-+              if (test_bit(i, mask)) {
-+                      new_val = pfm_arch_read_pmd(ctx, i);
-+
-+                      PFM_DBG_ovfl("pmd%u new_val=0x%llx bit=%d\n",
-+                                   i, (unsigned long long)new_val,
-+                                   (new_val&wmask) ? 1 : 0);
-+
-+                      if (new_val & wmask) {
-+                              __set_bit(i, set->povfl_pmds);
-+                              set->npend_ovfls++;
-+                      }
-+              }
-+      }
-+}
-+
-+static void pfm_stop_active(struct task_struct *task, struct pfm_context *ctx,
-+                          struct pfm_event_set *set)
-+{
-+      unsigned int i, max;
-+
-+      max = ctx->regs.max_pmc;
-+
-+      /*
-+       * clear enable bits, assume all pmcs are enable pmcs
-+       */
-+      for (i = 0; i < max; i++) {
-+              if (test_bit(i, set->used_pmcs))
-+                      pfm_arch_write_pmc(ctx, i, 0);
-+      }
-+
-+      if (set->npend_ovfls)
-+              return;
-+
-+      __pfm_get_ovfl_pmds(ctx, set);
-+}
-+
-+/*
-+ * Called from pfm_ctxsw(). Task is guaranteed to be current.
-+ * Context is locked. Interrupts are masked. Monitoring is active.
-+ * PMU access is guaranteed. PMC and PMD registers are live in PMU.
-+ *
-+ * for per-thread:
-+ *    must stop monitoring for the task
-+ *
-+ * Return:
-+ *    non-zero : did not save PMDs (as part of stopping the PMU)
-+ *           0 : saved PMDs (no need to save them in caller)
-+ */
-+int pfm_arch_ctxswout_thread(struct task_struct *task, struct pfm_context *ctx)
-+{
-+      /*
-+       * disable lazy restore of PMC registers.
-+       */
-+      ctx->active_set->priv_flags |= PFM_SETFL_PRIV_MOD_PMCS;
-+
-+      /*
-+       * if masked, monitoring is stopped, thus there is no
-+       * need to stop the PMU again and there is no need to
-+       * check for pending overflows. This is not just an
-+       * optimization, this is also for correctness as you
-+       * may end up detecting overflows twice.
-+       */
-+      if (ctx->state == PFM_CTX_MASKED)
-+              return 1;
-+
-+      pfm_stop_active(task, ctx, ctx->active_set);
-+
-+      return 1;
-+}
-+
-+/*
-+ * Called from pfm_stop() and pfm_ctxsw()
-+ * Interrupts are masked. Context is locked. Set is the active set.
-+ *
-+ * For per-thread:
-+ *   task is not necessarily current. If not current task, then
-+ *   task is guaranteed stopped and off any cpu. Access to PMU
-+ *   is not guaranteed. Interrupts are masked. Context is locked.
-+ *   Set is the active set.
-+ *
-+ * For system-wide:
-+ *    task is current
-+ *
-+ * must disable active monitoring. ctx cannot be NULL
-+ */
-+void pfm_arch_stop(struct task_struct *task, struct pfm_context *ctx)
-+{
-+      /*
-+       * no need to go through stop_save()
-+       * if we are already stopped
-+       */
-+      if (!ctx->flags.started || ctx->state == PFM_CTX_MASKED)
-+              return;
-+
-+      /*
-+       * stop live registers and collect pending overflow
-+       */
-+      if (task == current)
-+              pfm_stop_active(task, ctx, ctx->active_set);
-+}
-+
-+/*
-+ * called from pfm_start() or pfm_ctxsw() when idle task and
-+ * EXCL_IDLE is on.
-+ *
-+ * Interrupts are masked. Context is locked. Set is the active set.
-+ *
-+ * For per-trhead:
-+ *    Task is not necessarily current. If not current task, then task
-+ *    is guaranteed stopped and off any cpu. Access to PMU is not guaranteed.
-+ *
-+ * For system-wide:
-+ *    task is always current
-+ *
-+ * must enable active monitoring.
-+ */
-+void pfm_arch_start(struct task_struct *task, struct pfm_context *ctx)
-+{
-+      struct pfm_event_set *set;
-+      unsigned int i, max_pmc;
-+
-+      if (task != current)
-+              return;
-+
-+      set = ctx->active_set;
-+      max_pmc = ctx->regs.max_pmc;
-+
-+      for (i = 0; i < max_pmc; i++) {
-+              if (test_bit(i, set->used_pmcs))
-+                      pfm_arch_write_pmc(ctx, i, set->pmcs[i]);
-+      }
-+}
-+
-+/*
-+ * function called from pfm_switch_sets(), pfm_context_load_thread(),
-+ * pfm_context_load_sys(), pfm_ctxsw(), pfm_switch_sets()
-+ * context is locked. Interrupts are masked. set cannot be NULL.
-+ * Access to the PMU is guaranteed.
-+ *
-+ * function must restore all PMD registers from set.
-+ */
-+void pfm_arch_restore_pmds(struct pfm_context *ctx, struct pfm_event_set *set)
-+{
-+      u64 ovfl_mask, val;
-+      u64 *impl_pmds;
-+      unsigned int i;
-+      unsigned int max_pmd;
-+
-+      max_pmd = ctx->regs.max_pmd;
-+      ovfl_mask = pfm_pmu_conf->ovfl_mask;
-+      impl_pmds = ctx->regs.pmds;
-+
-+      /*
-+       * must restore all pmds to avoid leaking
-+       * information to user.
-+       */
-+      for (i = 0; i < max_pmd; i++) {
-+
-+              if (test_bit(i, impl_pmds) == 0)
-+                      continue;
-+
-+              val = set->pmds[i].value;
-+
-+              /*
-+               * set upper bits for counter to ensure
-+               * overflow will trigger
-+               */
-+              val &= ovfl_mask;
-+
-+              pfm_arch_write_pmd(ctx, i, val);
-+      }
-+}
-+
-+/*
-+ * function called from pfm_switch_sets(), pfm_context_load_thread(),
-+ * pfm_context_load_sys(), pfm_ctxsw().
-+ * Context is locked. Interrupts are masked. set cannot be NULL.
-+ * Access to the PMU is guaranteed.
-+ *
-+ * function must restore all PMC registers from set, if needed.
-+ */
-+void pfm_arch_restore_pmcs(struct pfm_context *ctx, struct pfm_event_set *set)
-+{
-+      u64 *impl_pmcs;
-+      unsigned int i, max_pmc;
-+
-+      max_pmc = ctx->regs.max_pmc;
-+      impl_pmcs = ctx->regs.pmcs;
-+
-+      /*
-+       * - by default no PMCS measures anything
-+       * - on ctxswout, all used PMCs are disabled (cccr enable bit cleared)
-+       * hence when masked we do not need to restore anything
-+       */
-+      if (ctx->state == PFM_CTX_MASKED || ctx->flags.started == 0)
-+              return;
-+
-+      /*
-+       * restore all pmcs
-+       */
-+      for (i = 0; i < max_pmc; i++)
-+              if (test_bit(i, impl_pmcs))
-+                      pfm_arch_write_pmc(ctx, i, set->pmcs[i]);
-+}
-+
-+char *pfm_arch_get_pmu_module_name(void)
-+{
-+      switch (cpu_data->cputype) {
-+#ifndef CONFIG_SMP
-+      case CPU_34K:
-+#if defined(CPU_74K)
-+      case CPU_74K:
-+#endif
-+#endif
-+      case CPU_SB1:
-+      case CPU_SB1A:
-+      case CPU_R12000:
-+      case CPU_25KF:
-+      case CPU_24K:
-+      case CPU_20KC:
-+      case CPU_5KC:
-+              return "perfmon_mips64";
-+      default:
-+              return NULL;
-+      }
-+      return NULL;
-+}
-+
-+int perfmon_perf_irq(void)
-+{
-+      /* BLATANTLY STOLEN FROM OPROFILE, then modified */
-+      struct pt_regs *regs;
-+      unsigned int counters = pfm_pmu_conf->regs_all.max_pmc;
-+      unsigned int control;
-+      unsigned int counter;
-+
-+      regs = get_irq_regs();
-+      switch (counters) {
-+#define HANDLE_COUNTER(n)                                             \
-+      case n + 1:                                                     \
-+              control = read_c0_perfctrl ## n();                      \
-+              counter = read_c0_perfcntr ## n();                      \
-+              if ((control & MIPS64_PMC_INT_ENABLE_MASK) &&           \
-+                  (counter & MIPS64_PMD_INTERRUPT)) {                 \
-+                      pfm_interrupt_handler(instruction_pointer(regs),\
-+                                            regs);                    \
-+                      return(1);                                      \
-+              }
-+              HANDLE_COUNTER(3)
-+              HANDLE_COUNTER(2)
-+              HANDLE_COUNTER(1)
-+              HANDLE_COUNTER(0)
-+      }
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL(perfmon_perf_irq);
-diff --git a/arch/mips/perfmon/perfmon_mips64.c b/arch/mips/perfmon/perfmon_mips64.c
-new file mode 100644
-index 0000000..78cb43d
---- /dev/null
-+++ b/arch/mips/perfmon/perfmon_mips64.c
-@@ -0,0 +1,218 @@
-+/*
-+ * This file contains the MIPS64 and decendent PMU register description tables
-+ * and pmc checker used by perfmon.c.
-+ *
-+ * Copyright (c) 2005 Philip Mucci
-+ *
-+ * Based on perfmon_p6.c:
-+ * Copyright (c) 2005-2006 Hewlett-Packard Development Company, L.P.
-+ * Contributed by Stephane Eranian <eranian@hpl.hp.com>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of version 2 of the GNU General Public
-+ * License as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ * 02111-1307 USA
-+ */
-+#include <linux/module.h>
-+#include <linux/perfmon_kern.h>
-+
-+MODULE_AUTHOR("Philip Mucci <mucci@cs.utk.edu>");
-+MODULE_DESCRIPTION("MIPS64 PMU description tables");
-+MODULE_LICENSE("GPL");
-+
-+/*
-+ * reserved:
-+ *    - bit 63-9
-+ * RSVD: reserved bits must be 1
-+ */
-+#define PFM_MIPS64_PMC_RSVD 0xfffffffffffff810ULL
-+#define PFM_MIPS64_PMC_VAL  (1ULL<<4)
-+
-+extern int null_perf_irq(struct pt_regs *regs);
-+extern int (*perf_irq)(struct pt_regs *regs);
-+extern int perfmon_perf_irq(struct pt_regs *regs);
-+
-+static struct pfm_arch_pmu_info pfm_mips64_pmu_info;
-+
-+static struct pfm_regmap_desc pfm_mips64_pmc_desc[] = {
-+/* pmc0 */  PMC_D(PFM_REG_I64, "CP0_25_0", PFM_MIPS64_PMC_VAL, PFM_MIPS64_PMC_RSVD, 0, 0),
-+/* pmc1 */  PMC_D(PFM_REG_I64, "CP0_25_1", PFM_MIPS64_PMC_VAL, PFM_MIPS64_PMC_RSVD, 0, 1),
-+/* pmc2 */  PMC_D(PFM_REG_I64, "CP0_25_2", PFM_MIPS64_PMC_VAL, PFM_MIPS64_PMC_RSVD, 0, 2),
-+/* pmc3 */  PMC_D(PFM_REG_I64, "CP0_25_3", PFM_MIPS64_PMC_VAL, PFM_MIPS64_PMC_RSVD, 0, 3)
-+};
-+#define PFM_MIPS64_NUM_PMCS ARRAY_SIZE(pfm_mips64_pmc_desc)
-+
-+static struct pfm_regmap_desc pfm_mips64_pmd_desc[] = {
-+/* pmd0 */ PMD_D(PFM_REG_C, "CP0_25_0", 0),
-+/* pmd1 */ PMD_D(PFM_REG_C, "CP0_25_1", 1),
-+/* pmd2 */ PMD_D(PFM_REG_C, "CP0_25_2", 2),
-+/* pmd3 */ PMD_D(PFM_REG_C, "CP0_25_3", 3)
-+};
-+#define PFM_MIPS64_NUM_PMDS ARRAY_SIZE(pfm_mips64_pmd_desc)
-+
-+static int pfm_mips64_probe_pmu(void)
-+{
-+      struct cpuinfo_mips *c = &current_cpu_data;
-+
-+      switch (c->cputype) {
-+#ifndef CONFIG_SMP
-+      case CPU_34K:
-+#if defined(CPU_74K)
-+      case CPU_74K:
-+#endif
-+#endif
-+      case CPU_SB1:
-+      case CPU_SB1A:
-+      case CPU_R12000:
-+      case CPU_25KF:
-+      case CPU_24K:
-+      case CPU_20KC:
-+      case CPU_5KC:
-+              return 0;
-+              break;
-+      default:
-+              PFM_INFO("Unknown cputype 0x%x", c->cputype);
-+      }
-+      return -1;
-+}
-+
-+/*
-+ * impl_pmcs, impl_pmds are computed at runtime to minimize errors!
-+ */
-+static struct pfm_pmu_config pfm_mips64_pmu_conf = {
-+      .pmu_name = "MIPS", /* placeholder */
-+      .counter_width = 31,
-+      .pmd_desc = pfm_mips64_pmd_desc,
-+      .pmc_desc = pfm_mips64_pmc_desc,
-+      .num_pmc_entries = PFM_MIPS64_NUM_PMCS,
-+      .num_pmd_entries = PFM_MIPS64_NUM_PMDS,
-+      .probe_pmu = pfm_mips64_probe_pmu,
-+      .flags = PFM_PMU_BUILTIN_FLAG,
-+      .owner = THIS_MODULE,
-+      .pmu_info = &pfm_mips64_pmu_info
-+};
-+
-+static inline int n_counters(void)
-+{
-+      if (!(read_c0_config1() & MIPS64_CONFIG_PMC_MASK))
-+              return 0;
-+      if (!(read_c0_perfctrl0() & MIPS64_PMC_CTR_MASK))
-+              return 1;
-+      if (!(read_c0_perfctrl1() & MIPS64_PMC_CTR_MASK))
-+              return 2;
-+      if (!(read_c0_perfctrl2() & MIPS64_PMC_CTR_MASK))
-+              return 3;
-+      return 4;
-+}
-+
-+static int __init pfm_mips64_pmu_init_module(void)
-+{
-+      struct cpuinfo_mips *c = &current_cpu_data;
-+      int i, ret, num;
-+      u64 temp_mask;
-+
-+      switch (c->cputype) {
-+      case CPU_5KC:
-+              pfm_mips64_pmu_conf.pmu_name = "MIPS5KC";
-+              break;
-+      case CPU_R12000:
-+              pfm_mips64_pmu_conf.pmu_name = "MIPSR12000";
-+              break;
-+      case CPU_20KC:
-+              pfm_mips64_pmu_conf.pmu_name = "MIPS20KC";
-+              break;
-+      case CPU_24K:
-+              pfm_mips64_pmu_conf.pmu_name = "MIPS24K";
-+              break;
-+      case CPU_25KF:
-+              pfm_mips64_pmu_conf.pmu_name = "MIPS25KF";
-+              break;
-+      case CPU_SB1:
-+              pfm_mips64_pmu_conf.pmu_name = "SB1";
-+              break;
-+      case CPU_SB1A:
-+      pfm_mips64_pmu_conf.pmu_name = "SB1A";
-+              break;
-+#ifndef CONFIG_SMP
-+      case CPU_34K:
-+              pfm_mips64_pmu_conf.pmu_name = "MIPS34K";
-+              break;
-+#if defined(CPU_74K)
-+      case CPU_74K:
-+              pfm_mips64_pmu_conf.pmu_name = "MIPS74K";
-+              break;
-+#endif
-+#endif
-+      default:
-+              PFM_INFO("Unknown cputype 0x%x", c->cputype);
-+              return -1;
-+      }
-+
-+      /* The R14k and older performance counters have to          */
-+      /* be hard-coded, as there is no support for auto-detection */
-+      if ((c->cputype == CPU_R12000) || (c->cputype == CPU_R14000))
-+              num = 4;
-+      else if (c->cputype == CPU_R10000)
-+              num = 2;
-+      else
-+              num = n_counters();
-+
-+      if (num == 0) {
-+              PFM_INFO("cputype 0x%x has no counters", c->cputype);
-+              return -1;
-+      }
-+      /* mark remaining counters unavailable */
-+      for (i = num; i < PFM_MIPS64_NUM_PMCS; i++)
-+              pfm_mips64_pmc_desc[i].type = PFM_REG_NA;
-+
-+      for (i = num; i < PFM_MIPS64_NUM_PMDS; i++)
-+              pfm_mips64_pmd_desc[i].type = PFM_REG_NA;
-+
-+      /* set the PMC_RSVD mask */
-+      switch (c->cputype) {
-+      case CPU_5KC:
-+      case CPU_R10000:
-+      case CPU_20KC:
-+         /* 4-bits for event */
-+         temp_mask = 0xfffffffffffffe10ULL;
-+         break;
-+      case CPU_R12000:
-+      case CPU_R14000:
-+         /* 5-bits for event */
-+         temp_mask = 0xfffffffffffffc10ULL;
-+         break;
-+      default:
-+         /* 6-bits for event */
-+         temp_mask = 0xfffffffffffff810ULL;
-+      }
-+      for (i = 0; i < PFM_MIPS64_NUM_PMCS; i++)
-+              pfm_mips64_pmc_desc[i].rsvd_msk = temp_mask;
-+
-+      pfm_mips64_pmu_conf.num_pmc_entries = num;
-+      pfm_mips64_pmu_conf.num_pmd_entries = num;
-+
-+      pfm_mips64_pmu_info.pmu_style = c->cputype;
-+
-+      ret = pfm_pmu_register(&pfm_mips64_pmu_conf);
-+      if (ret == 0)
-+              perf_irq = perfmon_perf_irq;
-+      return ret;
-+}
-+
-+static void __exit pfm_mips64_pmu_cleanup_module(void)
-+{
-+      pfm_pmu_unregister(&pfm_mips64_pmu_conf);
-+      perf_irq = null_perf_irq;
-+}
-+
-+module_init(pfm_mips64_pmu_init_module);
-+module_exit(pfm_mips64_pmu_cleanup_module);
-diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
-index 587da5e..a411389 100644
---- a/arch/powerpc/Kconfig
-+++ b/arch/powerpc/Kconfig
-@@ -230,6 +230,8 @@ source "init/Kconfig"
- source "arch/powerpc/sysdev/Kconfig"
- source "arch/powerpc/platforms/Kconfig"
-+source "arch/powerpc/perfmon/Kconfig"
-+
- menu "Kernel options"
- config HIGHMEM
-diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
-index c6be19e..7ea20cb 100644
---- a/arch/powerpc/Makefile
-+++ b/arch/powerpc/Makefile
-@@ -146,6 +146,7 @@ core-y                             += arch/powerpc/kernel/ \
-                                  arch/powerpc/platforms/
- core-$(CONFIG_MATH_EMULATION) += arch/powerpc/math-emu/
- core-$(CONFIG_XMON)           += arch/powerpc/xmon/
-+core-$(CONFIG_PERFMON)                += arch/powerpc/perfmon/
- core-$(CONFIG_KVM)            += arch/powerpc/kvm/
- drivers-$(CONFIG_OPROFILE)    += arch/powerpc/oprofile/
-diff --git a/arch/powerpc/include/asm/Kbuild b/arch/powerpc/include/asm/Kbuild
-index 5ab7d7f..88cb533 100644
---- a/arch/powerpc/include/asm/Kbuild
-+++ b/arch/powerpc/include/asm/Kbuild
-@@ -21,6 +21,7 @@ header-y += resource.h
- header-y += sigcontext.h
- header-y += statfs.h
- header-y += ps3fb.h
-+header-y += perfmon.h
- unifdef-y += bootx.h
- unifdef-y += byteorder.h
-diff --git a/arch/powerpc/include/asm/cell-pmu.h b/arch/powerpc/include/asm/cell-pmu.h
-index 8066eed..981db26 100644
---- a/arch/powerpc/include/asm/cell-pmu.h
-+++ b/arch/powerpc/include/asm/cell-pmu.h
-@@ -61,6 +61,11 @@
- /* Macros for the pm_status register. */
- #define CBE_PM_CTR_OVERFLOW_INTR(ctr)      (1 << (31 - ((ctr) & 7)))
-+#define CBE_PM_OVERFLOW_CTRS(pm_status)    (((pm_status) >> 24) & 0xff)
-+#define CBE_PM_ALL_OVERFLOW_INTR           0xff000000
-+#define CBE_PM_INTERVAL_INTR               0x00800000
-+#define CBE_PM_TRACE_BUFFER_FULL_INTR      0x00400000
-+#define CBE_PM_TRACE_BUFFER_UNDERFLOW_INTR 0x00200000
- enum pm_reg_name {
-       group_control,
-diff --git a/arch/powerpc/include/asm/cell-regs.h b/arch/powerpc/include/asm/cell-regs.h
-index fd6fd00..580786d 100644
---- a/arch/powerpc/include/asm/cell-regs.h
-+++ b/arch/powerpc/include/asm/cell-regs.h
-@@ -117,8 +117,9 @@ struct cbe_pmd_regs {
-       u8      pad_0x0c1c_0x0c20 [4];                          /* 0x0c1c */
- #define CBE_PMD_FIR_MODE_M8           0x00800
-       u64     fir_enable_mask;                                /* 0x0c20 */
--
--      u8      pad_0x0c28_0x0ca8 [0x0ca8 - 0x0c28];            /* 0x0c28 */
-+      u8      pad_0x0c28_0x0c98 [0x0c98 - 0x0c28];            /* 0x0c28 */
-+      u64     on_ramp_trace;                                  /* 0x0c98 */
-+      u64     pad_0x0ca0;                                     /* 0x0ca0 */
-       u64     ras_esc_0;                                      /* 0x0ca8 */
-       u8      pad_0x0cb0_0x1000 [0x1000 - 0x0cb0];            /* 0x0cb0 */
- };
-@@ -218,7 +219,11 @@ extern struct cbe_iic_regs __iomem *cbe_get_cpu_iic_regs(int cpu);
- struct cbe_mic_tm_regs {
--      u8      pad_0x0000_0x0040[0x0040 - 0x0000];             /* 0x0000 */
-+      u8      pad_0x0000_0x0010[0x0010 - 0x0000];             /* 0x0000 */
-+
-+      u64     MBL_debug;                                      /* 0x0010 */
-+
-+      u8      pad_0x0018_0x0040[0x0040 - 0x0018];             /* 0x0018 */
-       u64     mic_ctl_cnfg2;                                  /* 0x0040 */
- #define CBE_MIC_ENABLE_AUX_TRC                0x8000000000000000LL
-@@ -303,6 +308,25 @@ struct cbe_mic_tm_regs {
- extern struct cbe_mic_tm_regs __iomem *cbe_get_mic_tm_regs(struct device_node *np);
- extern struct cbe_mic_tm_regs __iomem *cbe_get_cpu_mic_tm_regs(int cpu);
-+/*
-+ *
-+ *  PPE Privileged MMIO Registers definition. (offset 0x500000 - 0x500fff)
-+ *
-+ */
-+struct cbe_ppe_priv_regs {
-+      u8      pad_0x0000_0x0858[0x0858 - 0x0000];             /* 0x0000 */
-+
-+      u64     L2_debug1;                                      /* 0x0858 */
-+
-+      u8      pad_0x0860_0x0958[0x0958 - 0x0860];             /* 0x0860 */
-+
-+      u64     ciu_dr1;                                        /* 0x0958 */
-+
-+      u8      pad_0x0960_0x1000[0x1000 - 0x0960];             /* 0x0960 */
-+};
-+
-+extern struct cbe_ppe_priv_regs __iomem *cbe_get_cpu_ppe_priv_regs(int cpu);
-+
- /* some utility functions to deal with SMT */
- extern u32 cbe_get_hw_thread_id(int cpu);
- extern u32 cbe_cpu_to_node(int cpu);
-diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
-index 6493a39..ba9ead4 100644
---- a/arch/powerpc/include/asm/paca.h
-+++ b/arch/powerpc/include/asm/paca.h
-@@ -97,6 +97,10 @@ struct paca_struct {
-       u8 soft_enabled;                /* irq soft-enable flag */
-       u8 hard_enabled;                /* set if irqs are enabled in MSR */
-       u8 io_sync;                     /* writel() needs spin_unlock sync */
-+#ifdef CONFIG_PERFMON
-+      u8 pmu_except_pending;          /* PMU exception occurred while soft
-+                                       * disabled */
-+#endif
-       /* Stuff for accurate time accounting */
-       u64 user_time;                  /* accumulated usermode TB ticks */
-diff --git a/arch/powerpc/include/asm/perfmon.h b/arch/powerpc/include/asm/perfmon.h
-new file mode 100644
-index 0000000..da0ae3b
---- /dev/null
-+++ b/arch/powerpc/include/asm/perfmon.h
-@@ -0,0 +1,33 @@
-+/*
-+ * Copyright (c) 2007 Hewlett-Packard Development Company, L.P.
-+ * Contributed by Stephane Eranian <eranian@hpl.hp.com>
-+ *
-+ * This file contains powerpc specific definitions for the perfmon
-+ * interface.
-+ *
-+ * This file MUST never be included directly. Use linux/perfmon.h.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of version 2 of the GNU General Public
-+ * License as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ * 02111-1307 USA
-+ */
-+#ifndef _ASM_POWERPC_PERFMON_H_
-+#define _ASM_POWERPC_PERFMON_H_
-+
-+/*
-+ * arch-specific user visible interface definitions
-+ */
-+#define PFM_ARCH_MAX_PMCS     (256+64) /* 256 HW 64 SW */
-+#define PFM_ARCH_MAX_PMDS     (256+64) /* 256 HW 64 SW */
-+
-+#endif /* _ASM_POWERPC_PERFMON_H_ */
-diff --git a/arch/powerpc/include/asm/perfmon_kern.h b/arch/powerpc/include/asm/perfmon_kern.h
-new file mode 100644
-index 0000000..65ec984
---- /dev/null
-+++ b/arch/powerpc/include/asm/perfmon_kern.h
-@@ -0,0 +1,390 @@
-+/*
-+ * Copyright (c) 2005 David Gibson, IBM Corporation.
-+ *
-+ * Based on other versions:
-+ * Copyright (c) 2005 Hewlett-Packard Development Company, L.P.
-+ * Contributed by Stephane Eranian <eranian@hpl.hp.com>
-+ *
-+ * This file contains powerpc specific definitions for the perfmon
-+ * interface.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of version 2 of the GNU General Public
-+ * License as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ * 02111-1307 USA
-+ */
-+#ifndef _ASM_POWERPC_PERFMON_KERN_H_
-+#define _ASM_POWERPC_PERFMON_KERN_H_
-+
-+#ifdef __KERNEL__
-+
-+#ifdef CONFIG_PERFMON
-+
-+#include <asm/pmc.h>
-+#include <asm/unistd.h>
-+
-+#define HID0_PMC5_6_GR_MODE (1UL << (63 - 40))
-+
-+enum powerpc_pmu_type {
-+      PFM_POWERPC_PMU_NONE,
-+      PFM_POWERPC_PMU_604,
-+      PFM_POWERPC_PMU_604e,
-+      PFM_POWERPC_PMU_750,    /* XXX: Minor event set diffs between IBM and Moto. */
-+      PFM_POWERPC_PMU_7400,
-+      PFM_POWERPC_PMU_7450,
-+      PFM_POWERPC_PMU_POWER4,
-+      PFM_POWERPC_PMU_POWER5,
-+      PFM_POWERPC_PMU_POWER5p,
-+      PFM_POWERPC_PMU_POWER6,
-+      PFM_POWERPC_PMU_CELL,
-+};
-+
-+struct pfm_arch_pmu_info {
-+      enum powerpc_pmu_type pmu_style;
-+
-+      void (*write_pmc)(unsigned int cnum, u64 value);
-+      void (*write_pmd)(unsigned int cnum, u64 value);
-+
-+      u64 (*read_pmd)(unsigned int cnum);
-+
-+      void (*enable_counters)(struct pfm_context *ctx,
-+                              struct pfm_event_set *set);
-+      void (*disable_counters)(struct pfm_context *ctx,
-+                               struct pfm_event_set *set);
-+
-+      void (*irq_handler)(struct pt_regs *regs, struct pfm_context *ctx);
-+      void (*get_ovfl_pmds)(struct pfm_context *ctx,
-+                            struct pfm_event_set *set);
-+
-+      /* The following routines are optional. */
-+      void (*restore_pmcs)(struct pfm_context *ctx,
-+                           struct pfm_event_set *set);
-+      void (*restore_pmds)(struct pfm_context *ctx,
-+                           struct pfm_event_set *set);
-+
-+      int  (*ctxswout_thread)(struct task_struct *task,
-+                              struct pfm_context *ctx,
-+                              struct pfm_event_set *set);
-+      void (*ctxswin_thread)(struct task_struct *task,
-+                             struct pfm_context *ctx,
-+                             struct pfm_event_set *set);
-+      int  (*load_context)(struct pfm_context *ctx);
-+      void (*unload_context)(struct pfm_context *ctx);
-+      int  (*acquire_pmu)(u64 *unavail_pmcs, u64 *unavail_pmds);
-+      void (*release_pmu)(void);
-+      void *platform_info;
-+      void (*resend_irq)(struct pfm_context *ctx);
-+};
-+
-+#ifdef CONFIG_PPC32
-+#define PFM_ARCH_PMD_STK_ARG  6 /* conservative value */
-+#define PFM_ARCH_PMC_STK_ARG  6 /* conservative value */
-+#else
-+#define PFM_ARCH_PMD_STK_ARG  8 /* conservative value */
-+#define PFM_ARCH_PMC_STK_ARG  8 /* conservative value */
-+#endif
-+
-+static inline void pfm_arch_resend_irq(struct pfm_context *ctx)
-+{
-+      struct pfm_arch_pmu_info *arch_info;
-+
-+      arch_info = pfm_pmu_info();
-+      arch_info->resend_irq(ctx);
-+}
-+
-+static inline void pfm_arch_serialize(void)
-+{}
-+
-+static inline void pfm_arch_write_pmc(struct pfm_context *ctx,
-+                                    unsigned int cnum,
-+                                    u64 value)
-+{
-+      struct pfm_arch_pmu_info *arch_info;
-+
-+      arch_info =  pfm_pmu_info();
-+
-+      /*
-+       * we only write to the actual register when monitoring is
-+       * active (pfm_start was issued)
-+       */
-+      if (ctx && ctx->flags.started == 0)
-+              return;
-+
-+      BUG_ON(!arch_info->write_pmc);
-+
-+      arch_info->write_pmc(cnum, value);
-+}
-+
-+static inline void pfm_arch_write_pmd(struct pfm_context *ctx,
-+                                    unsigned int cnum, u64 value)
-+{
-+      struct pfm_arch_pmu_info *arch_info;
-+
-+      arch_info = pfm_pmu_info();
-+
-+      value &= pfm_pmu_conf->ovfl_mask;
-+
-+      BUG_ON(!arch_info->write_pmd);
-+
-+      arch_info->write_pmd(cnum, value);
-+}
-+
-+static inline u64 pfm_arch_read_pmd(struct pfm_context *ctx, unsigned int cnum)
-+{
-+      struct pfm_arch_pmu_info *arch_info;
-+
-+      arch_info = pfm_pmu_info();
-+
-+      BUG_ON(!arch_info->read_pmd);
-+
-+      return arch_info->read_pmd(cnum);
-+}
-+
-+/*
-+ * For some CPUs, the upper bits of a counter must be set in order for the
-+ * overflow interrupt to happen. On overflow, the counter has wrapped around,
-+ * and the upper bits are cleared. This function may be used to set them back.
-+ */
-+static inline void pfm_arch_ovfl_reset_pmd(struct pfm_context *ctx,
-+                                         unsigned int cnum)
-+{
-+      u64 val = pfm_arch_read_pmd(ctx, cnum);
-+
-+      /* This masks out overflow bit 31 */
-+      pfm_arch_write_pmd(ctx, cnum, val);
-+}
-+
-+/*
-+ * At certain points, perfmon needs to know if monitoring has been
-+ * explicitely started/stopped by user via pfm_start/pfm_stop. The
-+ * information is tracked in flags.started. However on certain
-+ * architectures, it may be possible to start/stop directly from
-+ * user level with a single assembly instruction bypassing
-+ * the kernel. This function must be used to determine by
-+ * an arch-specific mean if monitoring is actually started/stopped.
-+ */
-+static inline int pfm_arch_is_active(struct pfm_context *ctx)
-+{
-+      return ctx->flags.started;
-+}
-+
-+static inline void pfm_arch_ctxswout_sys(struct task_struct *task,
-+                                       struct pfm_context *ctx)
-+{}
-+
-+static inline void pfm_arch_ctxswin_sys(struct task_struct *task,
-+                                      struct pfm_context *ctx)
-+{}
-+
-+void pfm_arch_init_percpu(void);
-+int  pfm_arch_is_monitoring_active(struct pfm_context *ctx);
-+int  pfm_arch_ctxswout_thread(struct task_struct *task, struct pfm_context *ctx);
-+void pfm_arch_ctxswin_thread(struct task_struct *task, struct pfm_context *ctx);
-+void pfm_arch_stop(struct task_struct *task, struct pfm_context *ctx);
-+void pfm_arch_start(struct task_struct *task, struct pfm_context *ctx);
-+void pfm_arch_restore_pmds(struct pfm_context *ctx, struct pfm_event_set *set);
-+void pfm_arch_restore_pmcs(struct pfm_context *ctx, struct pfm_event_set *set);
-+void pfm_arch_clear_pmd_ovfl_cond(struct pfm_context *ctx, struct pfm_event_set *set);
-+int  pfm_arch_get_ovfl_pmds(struct pfm_context *ctx,
-+                          struct pfm_event_set *set);
-+char *pfm_arch_get_pmu_module_name(void);
-+/*
-+ * called from __pfm_interrupt_handler(). ctx is not NULL.
-+ * ctx is locked. PMU interrupt is masked.
-+ *
-+ * must stop all monitoring to ensure handler has consistent view.
-+ * must collect overflowed PMDs bitmask  into povfls_pmds and
-+ * npend_ovfls. If no interrupt detected then npend_ovfls
-+ * must be set to zero.
-+ */
-+static inline void pfm_arch_intr_freeze_pmu(struct pfm_context *ctx, struct pfm_event_set *set)
-+{
-+      pfm_arch_stop(current, ctx);
-+}
-+
-+void powerpc_irq_handler(struct pt_regs *regs);
-+
-+/*
-+ * unfreeze PMU from pfm_do_interrupt_handler()
-+ * ctx may be NULL for spurious
-+ */
-+static inline void pfm_arch_intr_unfreeze_pmu(struct pfm_context *ctx)
-+{
-+      struct pfm_arch_pmu_info *arch_info;
-+
-+      if (!ctx)
-+              return;
-+
-+      PFM_DBG_ovfl("state=%d", ctx->state);
-+
-+      ctx->flags.started = 1;
-+
-+      if (ctx->state == PFM_CTX_MASKED)
-+              return;
-+
-+      arch_info = pfm_pmu_info();
-+      BUG_ON(!arch_info->enable_counters);
-+      arch_info->enable_counters(ctx, ctx->active_set);
-+}
-+
-+/*
-+ * PowerPC does not save the PMDs during pfm_arch_intr_freeze_pmu(), thus
-+ * this routine needs to do it when switching sets on overflow
-+ */
-+static inline void pfm_arch_save_pmds_from_intr(struct pfm_context *ctx,
-+                                         struct pfm_event_set *set)
-+{
-+      pfm_save_pmds(ctx, set);
-+}
-+
-+/*
-+ * this function is called from the PMU interrupt handler ONLY.
-+ * On PPC, the PMU is frozen via arch_stop, masking would be implemented
-+ * via arch-stop as well. Given that the PMU is already stopped when
-+ * entering the interrupt handler, we do not need to stop it again, so
-+ * this function is a nop.
-+ */
-+static inline void pfm_arch_mask_monitoring(struct pfm_context *ctx,
-+                                          struct pfm_event_set *set)
-+{}
-+
-+/*
-+ * Simply need to start the context in order to unmask.
-+ */
-+static inline void pfm_arch_unmask_monitoring(struct pfm_context *ctx,
-+                                            struct pfm_event_set *set)
-+{
-+      pfm_arch_start(current, ctx);
-+}
-+
-+
-+static inline int pfm_arch_pmu_config_init(struct pfm_pmu_config *cfg)
-+{
-+      return 0;
-+}
-+
-+static inline int pfm_arch_context_create(struct pfm_context *ctx,
-+                                        u32 ctx_flags)
-+{
-+      return 0;
-+}
-+
-+static inline void pfm_arch_context_free(struct pfm_context *ctx)
-+{}
-+
-+/* not necessary on PowerPC */
-+static inline void pfm_cacheflush(void *addr, unsigned int len)
-+{}
-+
-+/*
-+ * function called from pfm_setfl_sane(). Context is locked
-+ * and interrupts are masked.
-+ * The value of flags is the value of ctx_flags as passed by
-+ * user.
-+ *
-+ * function must check arch-specific set flags.
-+ * Return:
-+ *    1 when flags are valid
-+ *      0 on error
-+ */
-+static inline int pfm_arch_setfl_sane(struct pfm_context *ctx, u32 flags)
-+{
-+      return 0;
-+}
-+
-+static inline int pfm_arch_init(void)
-+{
-+      return 0;
-+}
-+
-+static inline int pfm_arch_load_context(struct pfm_context *ctx)
-+{
-+      struct pfm_arch_pmu_info *arch_info;
-+      int rc = 0;
-+
-+      arch_info = pfm_pmu_info();
-+      if (arch_info->load_context)
-+              rc = arch_info->load_context(ctx);
-+
-+      return rc;
-+}
-+
-+static inline void pfm_arch_unload_context(struct pfm_context *ctx)
-+{
-+      struct pfm_arch_pmu_info *arch_info;
-+
-+      arch_info = pfm_pmu_info();
-+      if (arch_info->unload_context)
-+              arch_info->unload_context(ctx);
-+}
-+
-+static inline int pfm_arch_pmu_acquire(u64 *unavail_pmcs, u64 *unavail_pmds)
-+{
-+      struct pfm_arch_pmu_info *arch_info;
-+      int rc = 0;
-+
-+      arch_info = pfm_pmu_info();
-+      if (arch_info->acquire_pmu) {
-+              rc = arch_info->acquire_pmu(unavail_pmcs, unavail_pmds);
-+              if (rc)
-+                      return rc;
-+      }
-+
-+      return reserve_pmc_hardware(powerpc_irq_handler);
-+}
-+
-+static inline void pfm_arch_pmu_release(void)
-+{
-+      struct pfm_arch_pmu_info *arch_info;
-+
-+      arch_info = pfm_pmu_info();
-+      if (arch_info->release_pmu)
-+              arch_info->release_pmu();
-+
-+      release_pmc_hardware();
-+}
-+
-+static inline void pfm_arch_arm_handle_work(struct task_struct *task)
-+{}
-+
-+static inline void pfm_arch_disarm_handle_work(struct task_struct *task)
-+{}
-+
-+static inline int pfm_arch_get_base_syscall(void)
-+{
-+      return __NR_pfm_create_context;
-+}
-+
-+struct pfm_arch_context {
-+      /* Cell: Most recent value of the pm_status
-+       * register read by the interrupt handler.
-+       *
-+       * Interrupt handler sets last_read_updated if it
-+       * just read and updated last_read_pm_status
-+       */
-+      u32 last_read_pm_status;
-+      u32 last_read_updated;
-+      u64 powergs_pmc5, powergs_pmc6;
-+      u64 delta_tb, delta_tb_start;
-+      u64 delta_purr, delta_purr_start;
-+};
-+
-+#define PFM_ARCH_CTX_SIZE sizeof(struct pfm_arch_context)
-+/*
-+ * PowerPC does not need extra alignment requirements for the sampling buffer
-+ */
-+#define PFM_ARCH_SMPL_ALIGN_SIZE      0
-+
-+#endif /* CONFIG_PERFMON */
-+
-+#endif /* __KERNEL__ */
-+#endif /* _ASM_POWERPC_PERFMON_KERN_H_ */
-diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
-index c6d1ab6..a9f3ad0 100644
---- a/arch/powerpc/include/asm/reg.h
-+++ b/arch/powerpc/include/asm/reg.h
-@@ -698,6 +698,7 @@
- #define PV_POWER5     0x003A
- #define PV_POWER5p    0x003B
- #define PV_970FX      0x003C
-+#define PV_POWER6     0x003E
- #define PV_630                0x0040
- #define PV_630p       0x0041
- #define PV_970MP      0x0044
-diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h
-index f6cc7a4..0164841 100644
---- a/arch/powerpc/include/asm/systbl.h
-+++ b/arch/powerpc/include/asm/systbl.h
-@@ -322,3 +322,15 @@ SYSCALL_SPU(epoll_create1)
- SYSCALL_SPU(dup3)
- SYSCALL_SPU(pipe2)
- SYSCALL(inotify_init1)
-+SYSCALL(pfm_create_context)
-+SYSCALL(pfm_write_pmcs)
-+SYSCALL(pfm_write_pmds)
-+SYSCALL(pfm_read_pmds)
-+SYSCALL(pfm_load_context)
-+SYSCALL(pfm_start)
-+SYSCALL(pfm_stop)
-+SYSCALL(pfm_restart)
-+SYSCALL(pfm_create_evtsets)
-+SYSCALL(pfm_getinfo_evtsets)
-+SYSCALL(pfm_delete_evtsets)
-+SYSCALL(pfm_unload_context)
-diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h
-index 9665a26..6cda9f9 100644
---- a/arch/powerpc/include/asm/thread_info.h
-+++ b/arch/powerpc/include/asm/thread_info.h
-@@ -130,10 +130,12 @@ static inline struct thread_info *current_thread_info(void)
- #define _TIF_FREEZE           (1<<TIF_FREEZE)
- #define _TIF_RUNLATCH         (1<<TIF_RUNLATCH)
- #define _TIF_ABI_PENDING      (1<<TIF_ABI_PENDING)
-+#define _TIF_PERFMON_WORK     (1<<TIF_PERFMON_WORK)
-+#define _TIF_PERFMON_CTXSW    (1<<TIF_PERFMON_CTXSW)
- #define _TIF_SYSCALL_T_OR_A   (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
- #define _TIF_USER_WORK_MASK   (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
--                               _TIF_NOTIFY_RESUME)
-+                               _TIF_NOTIFY_RESUME | _TIF_PERFMON_WORK)
- #define _TIF_PERSYSCALL_MASK  (_TIF_RESTOREALL|_TIF_NOERROR)
- /* Bits in local_flags */
-diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
-index e07d0c7..6226cba 100644
---- a/arch/powerpc/include/asm/unistd.h
-+++ b/arch/powerpc/include/asm/unistd.h
-@@ -341,10 +341,22 @@
- #define __NR_dup3             316
- #define __NR_pipe2            317
- #define __NR_inotify_init1    318
-+#define __NR_pfm_create_context       319
-+#define __NR_pfm_write_pmcs   320
-+#define __NR_pfm_write_pmds   321
-+#define __NR_pfm_read_pmds    322
-+#define __NR_pfm_load_context 323
-+#define __NR_pfm_start                324
-+#define __NR_pfm_stop         325
-+#define __NR_pfm_restart      326
-+#define __NR_pfm_create_evtsets       327
-+#define __NR_pfm_getinfo_evtsets 328
-+#define __NR_pfm_delete_evtsets 329
-+#define __NR_pfm_unload_context       330
- #ifdef __KERNEL__
--#define __NR_syscalls         319
-+#define __NR_syscalls         331
- #define __NR__exit __NR_exit
- #define NR_syscalls   __NR_syscalls
-diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
-index 1cbbf70..198645f 100644
---- a/arch/powerpc/kernel/entry_32.S
-+++ b/arch/powerpc/kernel/entry_32.S
-@@ -39,7 +39,7 @@
-  * MSR_KERNEL is > 0x10000 on 4xx/Book-E since it include MSR_CE.
-  */
- #if MSR_KERNEL >= 0x10000
--#define LOAD_MSR_KERNEL(r, x) lis r,(x)@h; ori r,r,(x)@l
-+#define LOAD_MSR_KERNEL(r, x) lis r,(x)@ha; ori r,r,(x)@l
- #else
- #define LOAD_MSR_KERNEL(r, x) li r,(x)
- #endif
-diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
-index 2d802e9..77a090d 100644
---- a/arch/powerpc/kernel/entry_64.S
-+++ b/arch/powerpc/kernel/entry_64.S
-@@ -643,6 +643,10 @@ user_work:
-       b       .ret_from_except_lite
- 1:    bl      .save_nvgprs
-+#ifdef CONFIG_PERFMON
-+      addi    r3,r1,STACK_FRAME_OVERHEAD
-+      bl      .pfm_handle_work
-+#endif /* CONFIG_PERFMON */
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      .do_signal
-       b       .ret_from_except
-diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
-index d972dec..b255fba 100644
---- a/arch/powerpc/kernel/irq.c
-+++ b/arch/powerpc/kernel/irq.c
-@@ -104,6 +104,24 @@ static inline notrace void set_soft_enabled(unsigned long enable)
-       : : "r" (enable), "i" (offsetof(struct paca_struct, soft_enabled)));
- }
-+#ifdef CONFIG_PERFMON
-+static inline unsigned long get_pmu_except_pending(void)
-+{
-+      unsigned long pending;
-+
-+      __asm__ __volatile__("lbz %0,%1(13)"
-+      : "=r" (pending) : "i" (offsetof(struct paca_struct, pmu_except_pending)));
-+
-+      return pending;
-+}
-+
-+static inline void set_pmu_except_pending(unsigned long pending)
-+{
-+      __asm__ __volatile__("stb %0,%1(13)"
-+      : : "r" (pending), "i" (offsetof(struct paca_struct, pmu_except_pending)));
-+}
-+#endif /* CONFIG_PERFMON */
-+
- notrace void raw_local_irq_restore(unsigned long en)
- {
-       /*
-@@ -162,6 +180,19 @@ notrace void raw_local_irq_restore(unsigned long en)
-               lv1_get_version_info(&tmp);
-       }
-+#ifdef CONFIG_PERFMON
-+      /*
-+       * If a PMU exception occurred while interrupts were soft disabled,
-+       * force a PMU exception.
-+       */
-+      if (get_pmu_except_pending()) {
-+              set_pmu_except_pending(0);
-+              /* Make sure we trigger the edge detection circuitry */
-+              mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~MMCR0_PMAO);
-+              mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) | MMCR0_PMAO);
-+      }
-+#endif /* CONFIG_PERFMON */
-+
-       __hard_irq_enable();
- }
- EXPORT_SYMBOL(raw_local_irq_restore);
-diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
-index 957bded..32dbc8e 100644
---- a/arch/powerpc/kernel/process.c
-+++ b/arch/powerpc/kernel/process.c
-@@ -33,6 +33,7 @@
- #include <linux/mqueue.h>
- #include <linux/hardirq.h>
- #include <linux/utsname.h>
-+#include <linux/perfmon_kern.h>
- #include <asm/pgtable.h>
- #include <asm/uaccess.h>
-@@ -393,9 +394,14 @@ struct task_struct *__switch_to(struct task_struct *prev,
-               new_thread->start_tb = current_tb;
-       }
- #endif
--
-       local_irq_save(flags);
-+      if (test_tsk_thread_flag(prev, TIF_PERFMON_CTXSW))
-+              pfm_ctxsw_out(prev, new);
-+
-+      if (test_tsk_thread_flag(new, TIF_PERFMON_CTXSW))
-+              pfm_ctxsw_in(prev, new);
-+
-       account_system_vtime(current);
-       account_process_vtime(current);
-       calculate_steal_time();
-@@ -544,6 +550,7 @@ void show_regs(struct pt_regs * regs)
- void exit_thread(void)
- {
-       discard_lazy_cpu_state();
-+      pfm_exit_thread();
- }
- void flush_thread(void)
-@@ -669,6 +676,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
- #else
-       kregs->nip = (unsigned long)ret_from_fork;
- #endif
-+      pfm_copy_thread(p);
-       return 0;
- }
-diff --git a/arch/powerpc/perfmon/Kconfig b/arch/powerpc/perfmon/Kconfig
-new file mode 100644
-index 0000000..3f4bbf2
---- /dev/null
-+++ b/arch/powerpc/perfmon/Kconfig
-@@ -0,0 +1,67 @@
-+menu "Hardware Performance Monitoring support"
-+config PERFMON
-+      bool "Perfmon2 performance monitoring interface"
-+      default n
-+      help
-+      Enables the perfmon2 interface to access the hardware
-+      performance counters. See <http://perfmon2.sf.net/> for
-+      more details.
-+
-+config PERFMON_DEBUG
-+      bool "Perfmon debugging"
-+      default n
-+      depends on PERFMON
-+      help
-+      Enables perfmon debugging support
-+
-+config PERFMON_DEBUG_FS
-+      bool "Enable perfmon statistics reporting via debugfs"
-+      default y
-+      depends on PERFMON && DEBUG_FS
-+      help
-+      Enable collection and reporting of perfmon timing statistics under
-+      debugfs. This is used for debugging and performance analysis of the
-+      subsystem. The debugfs filesystem must be mounted.
-+
-+config PERFMON_POWER4
-+      tristate "Support for Power4 hardware performance counters"
-+      depends on PERFMON && PPC64
-+      default n
-+      help
-+      Enables support for the Power 4 hardware performance counters
-+      If unsure, say M.
-+
-+config PERFMON_POWER5
-+      tristate "Support for Power5 hardware performance counters"
-+      depends on PERFMON && PPC64
-+      default n
-+      help
-+      Enables support for the Power 5 hardware performance counters
-+      If unsure, say M.
-+
-+config PERFMON_POWER6
-+      tristate "Support for Power6 hardware performance counters"
-+      depends on PERFMON && PPC64
-+      default n
-+      help
-+      Enables support for the Power 6 hardware performance counters
-+      If unsure, say M.
-+
-+config PERFMON_PPC32
-+      tristate "Support for PPC32 hardware performance counters"
-+      depends on PERFMON && PPC32
-+      default n
-+      help
-+      Enables support for the PPC32 hardware performance counters
-+      If unsure, say M.
-+
-+config PERFMON_CELL
-+      tristate "Support for Cell hardware performance counters"
-+      depends on PERFMON && PPC_CELL
-+      select PS3_LPM if PPC_PS3
-+      default n
-+      help
-+      Enables support for the Cell hardware performance counters.
-+      If unsure, say M.
-+
-+endmenu
-diff --git a/arch/powerpc/perfmon/Makefile b/arch/powerpc/perfmon/Makefile
-new file mode 100644
-index 0000000..300661f
---- /dev/null
-+++ b/arch/powerpc/perfmon/Makefile
-@@ -0,0 +1,6 @@
-+obj-$(CONFIG_PERFMON)         += perfmon.o
-+obj-$(CONFIG_PERFMON_POWER4)  += perfmon_power4.o
-+obj-$(CONFIG_PERFMON_POWER5)  += perfmon_power5.o
-+obj-$(CONFIG_PERFMON_POWER6)  += perfmon_power6.o
-+obj-$(CONFIG_PERFMON_PPC32)   += perfmon_ppc32.o
-+obj-$(CONFIG_PERFMON_CELL)    += perfmon_cell.o
-diff --git a/arch/powerpc/perfmon/perfmon.c b/arch/powerpc/perfmon/perfmon.c
-new file mode 100644
-index 0000000..51a8b6a
---- /dev/null
-+++ b/arch/powerpc/perfmon/perfmon.c
-@@ -0,0 +1,334 @@
-+/*
-+ * This file implements the powerpc specific
-+ * support for the perfmon2 interface
-+ *
-+ * Copyright (c) 2005 David Gibson, IBM Corporation.
-+ *
-+ * based on versions for other architectures:
-+ * Copyright (c) 2005-2006 Hewlett-Packard Development Company, L.P.
-+ * Contributed by Stephane Eranian <eranian@hpl.hp.com>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of version 2 of the GNU General Public
-+ * License as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ * 02111-1307 USA
-+ */
-+#include <linux/interrupt.h>
-+#include <linux/perfmon_kern.h>
-+
-+static void pfm_stop_active(struct task_struct *task,
-+                          struct pfm_context *ctx, struct pfm_event_set *set)
-+{
-+      struct pfm_arch_pmu_info *arch_info;
-+
-+      arch_info = pfm_pmu_info();
-+      BUG_ON(!arch_info->disable_counters || !arch_info->get_ovfl_pmds);
-+
-+      arch_info->disable_counters(ctx, set);
-+
-+      if (set->npend_ovfls)
-+              return;
-+
-+      arch_info->get_ovfl_pmds(ctx, set);
-+}
-+
-+/*
-+ * Called from pfm_save_pmds(). Interrupts are masked.  Registers are
-+ * already saved away.
-+ */
-+void pfm_arch_clear_pmd_ovfl_cond(struct pfm_context *ctx,
-+                                struct pfm_event_set *set)
-+{
-+      int i, num;
-+      u64 *used_pmds, *intr_pmds;
-+
-+      num = set->nused_pmds;
-+      used_pmds = set->used_pmds;
-+      intr_pmds = ctx->regs.intr_pmds;
-+
-+      for (i = 0; num; i++)
-+              if (likely(test_bit(i, used_pmds))) {
-+                      if (likely(test_bit(i, intr_pmds)))
-+                              pfm_write_pmd(ctx, i, 0);
-+                      num--;
-+              }
-+}
-+
-+/*
-+ * Called from pfm_ctxsw(). Task is guaranteed to be current.
-+ * Context is locked. Interrupts are masked. Monitoring is active.
-+ * PMU access is guaranteed. PMC and PMD registers are live in PMU.
-+ *
-+ * for per-thread:
-+ *    must stop monitoring for the task
-+ * Return:
-+ *    non-zero : did not save PMDs (as part of stopping the PMU)
-+ *           0 : saved PMDs (no need to save them in caller)
-+ */
-+int pfm_arch_ctxswout_thread(struct task_struct *task, struct pfm_context *ctx)
-+{
-+      struct pfm_arch_pmu_info *arch_info;
-+
-+      arch_info = pfm_pmu_info();
-+      /*
-+       * disable lazy restore of the PMC/PMD registers.
-+       */
-+      ctx->active_set->priv_flags |= PFM_SETFL_PRIV_MOD_BOTH;
-+
-+      if (ctx->state == PFM_CTX_MASKED)
-+              return 1;
-+
-+      pfm_stop_active(task, ctx, ctx->active_set);
-+
-+      if (arch_info->ctxswout_thread)
-+              arch_info->ctxswout_thread(task, ctx, ctx->active_set);
-+
-+      return pfm_arch_is_active(ctx);
-+}
-+
-+/*
-+ * Called from pfm_ctxsw
-+ */
-+void pfm_arch_ctxswin_thread(struct task_struct *task, struct pfm_context *ctx)
-+{
-+      struct pfm_arch_pmu_info *arch_info;
-+
-+      arch_info = pfm_pmu_info();
-+      if (ctx->state != PFM_CTX_MASKED && ctx->flags.started == 1) {
-+              BUG_ON(!arch_info->enable_counters);
-+              arch_info->enable_counters(ctx, ctx->active_set);
-+      }
-+
-+      if (arch_info->ctxswin_thread)
-+              arch_info->ctxswin_thread(task, ctx, ctx->active_set);
-+}
-+
-+/*
-+ * Called from pfm_stop() and idle notifier
-+ *
-+ * Interrupts are masked. Context is locked. Set is the active set.
-+ *
-+ * For per-thread:
-+ *   task is not necessarily current. If not current task, then
-+ *   task is guaranteed stopped and off any cpu. Access to PMU
-+ *   is not guaranteed. Interrupts are masked. Context is locked.
-+ *   Set is the active set.
-+ *
-+ * For system-wide:
-+ *    task is current
-+ *
-+ * must disable active monitoring. ctx cannot be NULL
-+ */
-+void pfm_arch_stop(struct task_struct *task, struct pfm_context *ctx)
-+{
-+      /*
-+       * no need to go through stop_save()
-+       * if we are already stopped
-+       */
-+      if (!ctx->flags.started || ctx->state == PFM_CTX_MASKED)
-+              return;
-+
-+      /*
-+       * stop live registers and collect pending overflow
-+       */
-+      if (task == current)
-+              pfm_stop_active(task, ctx, ctx->active_set);
-+}
-+
-+/*
-+ * Enable active monitoring. Called from pfm_start() and
-+ * pfm_arch_unmask_monitoring().
-+ *
-+ * Interrupts are masked. Context is locked. Set is the active set.
-+ *
-+ * For per-thread:
-+ *    Task is not necessarily current. If not current task, then task
-+ *    is guaranteed stopped and off any cpu. No access to PMU if task
-+ *    is not current.
-+ *
-+ * For system-wide:
-+ *    Task is always current
-+ */
-+void pfm_arch_start(struct task_struct *task, struct pfm_context *ctx)
-+{
-+      struct pfm_arch_pmu_info *arch_info;
-+
-+      arch_info = pfm_pmu_info();
-+      if (task != current)
-+              return;
-+
-+      BUG_ON(!arch_info->enable_counters);
-+
-+      arch_info->enable_counters(ctx, ctx->active_set);
-+}
-+
-+/*
-+ * function called from pfm_switch_sets(), pfm_context_load_thread(),
-+ * pfm_context_load_sys(), pfm_ctxsw(), pfm_switch_sets()
-+ * context is locked. Interrupts are masked. set cannot be NULL.
-+ * Access to the PMU is guaranteed.
-+ *
-+ * function must restore all PMD registers from set.
-+ */
-+void pfm_arch_restore_pmds(struct pfm_context *ctx, struct pfm_event_set *set)
-+{
-+      struct pfm_arch_pmu_info *arch_info;
-+      u64 *used_pmds;
-+      u16 i, num;
-+
-+      arch_info = pfm_pmu_info();
-+
-+      /* The model-specific module can override the default
-+       * restore-PMD method.
-+       */
-+      if (arch_info->restore_pmds)
-+              return arch_info->restore_pmds(ctx, set);
-+
-+      num = set->nused_pmds;
-+      used_pmds = set->used_pmds;
-+
-+      for (i = 0; num; i++) {
-+              if (likely(test_bit(i, used_pmds))) {
-+                      pfm_write_pmd(ctx, i, set->pmds[i].value);
-+                      num--;
-+              }
-+      }
-+}
-+
-+/*
-+ * function called from pfm_switch_sets(), pfm_context_load_thread(),
-+ * pfm_context_load_sys(), pfm_ctxsw(), pfm_switch_sets()
-+ * context is locked. Interrupts are masked. set cannot be NULL.
-+ * Access to the PMU is guaranteed.
-+ *
-+ * function must restore all PMC registers from set, if needed.
-+ */
-+void pfm_arch_restore_pmcs(struct pfm_context *ctx, struct pfm_event_set *set)
-+{
-+      struct pfm_arch_pmu_info *arch_info;
-+      u64 *impl_pmcs;
-+      unsigned int i, max_pmc, reg;
-+
-+      arch_info = pfm_pmu_info();
-+      /* The model-specific module can override the default
-+       * restore-PMC method.
-+       */
-+      if (arch_info->restore_pmcs)
-+              return arch_info->restore_pmcs(ctx, set);
-+
-+      /* The "common" powerpc model's enable the counters simply by writing
-+       * all the control registers. Therefore, if we're masked or stopped we
-+       * don't need to bother restoring the PMCs now.
-+       */
-+      if (ctx->state == PFM_CTX_MASKED || ctx->flags.started == 0)
-+              return;
-+
-+      max_pmc = ctx->regs.max_pmc;
-+      impl_pmcs = ctx->regs.pmcs;
-+
-+      /*
-+       * Restore all pmcs in reverse order to ensure the counters aren't
-+       * enabled before their event selectors are set correctly.
-+       */
-+      reg = max_pmc - 1;
-+      for (i = 0; i < max_pmc; i++) {
-+              if (test_bit(reg, impl_pmcs))
-+                      pfm_arch_write_pmc(ctx, reg, set->pmcs[reg]);
-+              reg--;
-+      }
-+}
-+
-+char *pfm_arch_get_pmu_module_name(void)
-+{
-+      unsigned int pvr = mfspr(SPRN_PVR);
-+
-+      switch (PVR_VER(pvr)) {
-+      case 0x0004: /* 604 */
-+      case 0x0009: /* 604e;  */
-+      case 0x000A: /* 604ev */
-+      case 0x0008: /* 750/740 */
-+      case 0x7000: /* 750FX */
-+      case 0x7001:
-+      case 0x7002: /* 750GX */
-+      case 0x000C: /* 7400 */
-+      case 0x800C: /* 7410 */
-+      case 0x8000: /* 7451/7441 */
-+      case 0x8001: /* 7455/7445 */
-+      case 0x8002: /* 7457/7447 */
-+      case 0x8003: /* 7447A */
-+      case 0x8004: /* 7448 */
-+              return("perfmon_ppc32");
-+      case PV_POWER4:
-+      case PV_POWER4p:
-+              return "perfmon_power4";
-+      case PV_POWER5:
-+              return "perfmon_power5";
-+      case PV_POWER5p:
-+              if (PVR_REV(pvr) < 0x300)
-+                      /* PMU behaves like POWER5 */
-+                      return "perfmon_power5";
-+              else
-+                      /* PMU behaves like POWER6 */
-+                      return "perfmon_power6";
-+      case PV_POWER6:
-+              return "perfmon_power6";
-+      case PV_970:
-+      case PV_970FX:
-+      case PV_970MP:
-+              return "perfmon_ppc970";
-+      case PV_BE:
-+              return "perfmon_cell";
-+      }
-+      return NULL;
-+}
-+
-+void pfm_arch_init_percpu(void)
-+{
-+#ifdef CONFIG_PPC64
-+      extern void ppc64_enable_pmcs(void);
-+      ppc64_enable_pmcs();
-+#endif
-+}
-+
-+/**
-+ * powerpc_irq_handler
-+ *
-+ * Get the perfmon context that belongs to the current CPU, and call the
-+ * model-specific interrupt handler.
-+ **/
-+void powerpc_irq_handler(struct pt_regs *regs)
-+{
-+      struct pfm_arch_pmu_info *arch_info;
-+      struct pfm_context *ctx;
-+
-+      if (! regs->softe) {
-+              /*
-+               * We got a PMU interrupt while interrupts were soft
-+               * disabled.  Disable hardware interrupts by clearing
-+               * MSR_EE and also clear PMAO because we will need to set
-+               * that again later when interrupts are re-enabled and
-+               * raw_local_irq_restore() sees that the pmu_except_pending
-+               * flag is set.
-+               */
-+              regs->msr &= ~MSR_EE;
-+              get_paca()->pmu_except_pending = 1;
-+              mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~MMCR0_PMAO);
-+              return;
-+      }
-+
-+      arch_info = pfm_pmu_info();
-+      if (arch_info->irq_handler) {
-+              ctx = __get_cpu_var(pmu_ctx);
-+              if (likely(ctx))
-+                      arch_info->irq_handler(regs, ctx);
-+      }
-+}
-diff --git a/arch/powerpc/perfmon/perfmon_cell.c b/arch/powerpc/perfmon/perfmon_cell.c
-new file mode 100644
-index 0000000..e1ae12c
---- /dev/null
-+++ b/arch/powerpc/perfmon/perfmon_cell.c
-@@ -0,0 +1,1449 @@
-+/*
-+ * This file contains the Cell PMU register description tables
-+ * and pmc checker used by perfmon.c.
-+ *
-+ * Copyright IBM Corporation 2007
-+ * (C) Copyright 2007 TOSHIBA CORPORATION
-+ *
-+ * Based on other Perfmon2 PMU modules.
-+ * Copyright (c) 2005-2006 Hewlett-Packard Development Company, L.P.
-+ * Contributed by Stephane Eranian <eranian@hpl.hp.com>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of version 2 of the GNU General Public
-+ * License as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ * 02111-1307 USA
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/perfmon_kern.h>
-+#include <linux/io.h>
-+#include <asm/cell-pmu.h>
-+#include <asm/cell-regs.h>
-+#include <asm/machdep.h>
-+#include <asm/rtas.h>
-+#include <asm/ps3.h>
-+#include <asm/spu.h>
-+
-+MODULE_AUTHOR("Kevin Corry <kevcorry@us.ibm.com>, "
-+            "Carl Love <carll@us.ibm.com>");
-+MODULE_DESCRIPTION("Cell PMU description table");
-+MODULE_LICENSE("GPL");
-+
-+struct pfm_cell_platform_pmu_info {
-+      u32  (*read_ctr)(u32 cpu, u32 ctr);
-+      void (*write_ctr)(u32 cpu, u32 ctr, u32 val);
-+      void (*write_pm07_control)(u32 cpu, u32 ctr, u32 val);
-+      void (*write_pm)(u32 cpu, enum pm_reg_name reg, u32 val);
-+      void (*enable_pm)(u32 cpu);
-+      void (*disable_pm)(u32 cpu);
-+      void (*enable_pm_interrupts)(u32 cpu, u32 thread, u32 mask);
-+      u32  (*get_and_clear_pm_interrupts)(u32 cpu);
-+      u32  (*get_hw_thread_id)(int cpu);
-+      struct cbe_ppe_priv_regs __iomem *(*get_cpu_ppe_priv_regs)(int cpu);
-+      struct cbe_pmd_regs __iomem *(*get_cpu_pmd_regs)(int cpu);
-+      struct cbe_mic_tm_regs __iomem *(*get_cpu_mic_tm_regs)(int cpu);
-+      int (*rtas_token)(const char *service);
-+      int (*rtas_call)(int token, int param1, int param2, int *param3, ...);
-+};
-+
-+/*
-+ * Mapping from Perfmon logical control registers to Cell hardware registers.
-+ */
-+static struct pfm_regmap_desc pfm_cell_pmc_desc[] = {
-+      /* Per-counter control registers. */
-+      PMC_D(PFM_REG_I, "pm0_control",       0, 0, 0, 0),
-+      PMC_D(PFM_REG_I, "pm1_control",       0, 0, 0, 0),
-+      PMC_D(PFM_REG_I, "pm2_control",       0, 0, 0, 0),
-+      PMC_D(PFM_REG_I, "pm3_control",       0, 0, 0, 0),
-+      PMC_D(PFM_REG_I, "pm4_control",       0, 0, 0, 0),
-+      PMC_D(PFM_REG_I, "pm5_control",       0, 0, 0, 0),
-+      PMC_D(PFM_REG_I, "pm6_control",       0, 0, 0, 0),
-+      PMC_D(PFM_REG_I, "pm7_control",       0, 0, 0, 0),
-+
-+      /* Per-counter RTAS arguments. Each of these registers has three fields.
-+       *   bits 63-48: debug-bus word
-+       *   bits 47-32: sub-unit
-+       *   bits 31-0 : full signal number
-+       *   (MSB = 63, LSB = 0)
-+       */
-+      PMC_D(PFM_REG_I, "pm0_event",         0, 0, 0, 0),
-+      PMC_D(PFM_REG_I, "pm1_event",         0, 0, 0, 0),
-+      PMC_D(PFM_REG_I, "pm2_event",         0, 0, 0, 0),
-+      PMC_D(PFM_REG_I, "pm3_event",         0, 0, 0, 0),
-+      PMC_D(PFM_REG_I, "pm4_event",         0, 0, 0, 0),
-+      PMC_D(PFM_REG_I, "pm5_event",         0, 0, 0, 0),
-+      PMC_D(PFM_REG_I, "pm6_event",         0, 0, 0, 0),
-+      PMC_D(PFM_REG_I, "pm7_event",         0, 0, 0, 0),
-+
-+      /* Global control registers. Same order as enum pm_reg_name. */
-+      PMC_D(PFM_REG_I, "group_control",     0, 0, 0, 0),
-+      PMC_D(PFM_REG_I, "debug_bus_control", 0, 0, 0, 0),
-+      PMC_D(PFM_REG_I, "trace_address",     0, 0, 0, 0),
-+      PMC_D(PFM_REG_I, "ext_trace_timer",   0, 0, 0, 0),
-+      PMC_D(PFM_REG_I, "pm_status",         0, 0, 0, 0),
-+      /* set the interrupt overflow bit for the four 32 bit counters
-+       * that is currently supported.  Will need to fix when 32 and 16
-+       * bit counters are supported.
-+       */
-+      PMC_D(PFM_REG_I, "pm_control",        0xF0000000, 0xF0000000, 0, 0),
-+      PMC_D(PFM_REG_I, "pm_interval",       0, 0, 0, 0), /* FIX: Does user-space also need read access to this one? */
-+      PMC_D(PFM_REG_I, "pm_start_stop",     0, 0, 0, 0),
-+};
-+#define PFM_PM_NUM_PMCS       ARRAY_SIZE(pfm_cell_pmc_desc)
-+
-+#define CELL_PMC_GROUP_CONTROL    16
-+#define CELL_PMC_PM_STATUS        20
-+#define CELL_PMC_PM_CONTROL       21
-+#define CELL_PMC_PM_CONTROL_CNTR_MASK   0x01E00000UL
-+#define CELL_PMC_PM_CONTROL_CNTR_16     0x01E00000UL
-+
-+/*
-+ * Mapping from Perfmon logical data counters to Cell hardware counters.
-+ */
-+static struct pfm_regmap_desc pfm_cell_pmd_desc[] = {
-+      PMD_D(PFM_REG_C, "pm0", 0),
-+      PMD_D(PFM_REG_C, "pm1", 0),
-+      PMD_D(PFM_REG_C, "pm2", 0),
-+      PMD_D(PFM_REG_C, "pm3", 0),
-+      PMD_D(PFM_REG_C, "pm4", 0),
-+      PMD_D(PFM_REG_C, "pm5", 0),
-+      PMD_D(PFM_REG_C, "pm6", 0),
-+      PMD_D(PFM_REG_C, "pm7", 0),
-+};
-+#define PFM_PM_NUM_PMDS       ARRAY_SIZE(pfm_cell_pmd_desc)
-+
-+#define PFM_EVENT_PMC_BUS_WORD(x)      (((x) >> 48) & 0x00ff)
-+#define PFM_EVENT_PMC_FULL_SIGNAL_NUMBER(x) ((x) & 0xffffffff)
-+#define PFM_EVENT_PMC_SIGNAL_GROUP(x) (((x) & 0xffffffff) / 100)
-+#define PFM_PM_CTR_INPUT_MUX_BIT(pm07_control) (((pm07_control) >> 26) & 0x1f)
-+#define PFM_PM_CTR_INPUT_MUX_GROUP_INDEX(pm07_control) ((pm07_control) >> 31)
-+#define PFM_GROUP_CONTROL_GROUP0_WORD(grp_ctrl) ((grp_ctrl) >> 30)
-+#define PFM_GROUP_CONTROL_GROUP1_WORD(grp_ctrl) (((grp_ctrl) >> 28) & 0x3)
-+#define PFM_NUM_OF_GROUPS 2
-+#define PFM_PPU_IU1_THREAD1_BASE_BIT 19
-+#define PFM_PPU_XU_THREAD1_BASE_BIT  16
-+#define PFM_COUNTER_CTRL_PMC_PPU_TH0 0x100000000ULL
-+#define PFM_COUNTER_CTRL_PMC_PPU_TH1 0x200000000ULL
-+
-+/*
-+ * Debug-bus signal handling.
-+ *
-+ * Some Cell systems have firmware that can handle the debug-bus signal
-+ * routing. For systems without this firmware, we have a minimal in-kernel
-+ * implementation as well.
-+ */
-+
-+/* The firmware only sees physical CPUs, so divide by 2 if SMT is on. */
-+#ifdef CONFIG_SCHED_SMT
-+#define RTAS_CPU(cpu) ((cpu) / 2)
-+#else
-+#define RTAS_CPU(cpu) (cpu)
-+#endif
-+#define RTAS_BUS_WORD(x)      (u16)(((x) >> 48) & 0x0000ffff)
-+#define RTAS_SUB_UNIT(x)      (u16)(((x) >> 32) & 0x0000ffff)
-+#define RTAS_SIGNAL_NUMBER(x) (s32)( (x)        & 0xffffffff)
-+#define RTAS_SIGNAL_GROUP(x)  (RTAS_SIGNAL_NUMBER(x) / 100)
-+
-+#define subfunc_RESET         1
-+#define subfunc_ACTIVATE      2
-+
-+#define passthru_ENABLE               1
-+#define passthru_DISABLE      2
-+
-+/**
-+ * struct cell_rtas_arg
-+ *
-+ * @cpu: Processor to modify. Linux numbers CPUs based on SMT IDs, but the
-+ *       firmware only sees the physical CPUs. So this value should be the
-+ *       SMT ID (from smp_processor_id() or get_cpu()) divided by 2.
-+ * @sub_unit: Hardware subunit this applies to (if applicable).
-+ * @signal_group: Signal group to enable/disable on the trace bus.
-+ * @bus_word: For signal groups that propagate via the trace bus, this trace
-+ *            bus word will be used. This is a mask of (1 << TraceBusWord).
-+ *            For other signal groups, this specifies the trigger or event bus.
-+ * @bit: Trigger/Event bit, if applicable for the signal group.
-+ *
-+ * An array of these structures are passed to rtas_call() to set up the
-+ * signals on the debug bus.
-+ **/
-+struct cell_rtas_arg {
-+      u16 cpu;
-+      u16 sub_unit;
-+      s16 signal_group;
-+      u8 bus_word;
-+      u8 bit;
-+};
-+
-+/**
-+ * rtas_reset_signals
-+ *
-+ * Use the firmware RTAS call to disable signal pass-thru and to reset the
-+ * debug-bus signals.
-+ **/
-+static int rtas_reset_signals(u32 cpu)
-+{
-+      struct cell_rtas_arg signal;
-+      u64 real_addr = virt_to_phys(&signal);
-+      int rc;
-+      struct pfm_cell_platform_pmu_info *info =
-+              ((struct pfm_arch_pmu_info *)
-+               (pfm_pmu_conf->pmu_info))->platform_info;
-+
-+      memset(&signal, 0, sizeof(signal));
-+      signal.cpu = RTAS_CPU(cpu);
-+      rc = info->rtas_call(info->rtas_token("ibm,cbe-perftools"),
-+                     5, 1, NULL,
-+                     subfunc_RESET,
-+                     passthru_DISABLE,
-+                     real_addr >> 32,
-+                     real_addr & 0xffffffff,
-+                     sizeof(signal));
-+
-+      return rc;
-+}
-+
-+/**
-+ * rtas_activate_signals
-+ *
-+ * Use the firmware RTAS call to enable signal pass-thru and to activate the
-+ * desired signal groups on the debug-bus.
-+ **/
-+static int rtas_activate_signals(struct cell_rtas_arg *signals,
-+                               int num_signals)
-+{
-+      u64 real_addr = virt_to_phys(signals);
-+      int rc;
-+      struct pfm_cell_platform_pmu_info *info =
-+              ((struct pfm_arch_pmu_info *)
-+               (pfm_pmu_conf->pmu_info))->platform_info;
-+
-+      rc = info->rtas_call(info->rtas_token("ibm,cbe-perftools"),
-+                     5, 1, NULL,
-+                     subfunc_ACTIVATE,
-+                     passthru_ENABLE,
-+                     real_addr >> 32,
-+                     real_addr & 0xffffffff,
-+                     num_signals * sizeof(*signals));
-+
-+      return rc;
-+}
-+
-+#define HID1_RESET_MASK                       (~0x00000001ffffffffUL)
-+#define PPU_IU1_WORD0_HID1_EN_MASK    (~0x00000001f0c0802cUL)
-+#define PPU_IU1_WORD0_HID1_EN_WORD    ( 0x00000001f0400000UL)
-+#define PPU_IU1_WORD1_HID1_EN_MASK    (~0x000000010fc08023UL)
-+#define PPU_IU1_WORD1_HID1_EN_WORD    ( 0x000000010f400001UL)
-+#define PPU_XU_WORD0_HID1_EN_MASK     (~0x00000001f038402cUL)
-+#define PPU_XU_WORD0_HID1_EN_WORD     ( 0x00000001f0080008UL)
-+#define PPU_XU_WORD1_HID1_EN_MASK     (~0x000000010f074023UL)
-+#define PPU_XU_WORD1_HID1_EN_WORD     ( 0x000000010f030002UL)
-+
-+/* The bus_word field in the cell_rtas_arg structure is a bit-mask
-+ * indicating which debug-bus word(s) to use.
-+ */
-+enum {
-+      BUS_WORD_0 = 1,
-+      BUS_WORD_1 = 2,
-+      BUS_WORD_2 = 4,
-+      BUS_WORD_3 = 8,
-+};
-+
-+/* Definitions of the signal-groups that the built-in signal-activation
-+ * code can handle.
-+ */
-+enum {
-+      SIG_GROUP_NONE = 0,
-+
-+      /* 2.x PowerPC Processor Unit (PPU) Signal Groups */
-+      SIG_GROUP_PPU_BASE = 20,
-+      SIG_GROUP_PPU_IU1 = 21,
-+      SIG_GROUP_PPU_XU = 22,
-+
-+      /* 3.x PowerPC Storage Subsystem (PPSS) Signal Groups */
-+      SIG_GROUP_PPSS_BASE = 30,
-+
-+      /* 4.x Synergistic Processor Unit (SPU) Signal Groups */
-+      SIG_GROUP_SPU_BASE = 40,
-+
-+      /* 5.x Memory Flow Controller (MFC) Signal Groups */
-+      SIG_GROUP_MFC_BASE = 50,
-+
-+      /* 6.x Element )nterconnect Bus (EIB) Signal Groups */
-+      SIG_GROUP_EIB_BASE = 60,
-+
-+      /* 7.x Memory Interface Controller (MIC) Signal