Patches contributed by Eötvös Lorand University


commit f65cb45cba63f249458b669aa67069eabc37b2f5
Author: Ingo Molnar <mingo@elte.hu>
Date:   Tue Dec 16 13:40:44 2008 +0100

    perfcounters: flush on setuid exec
    
    Pavel Machek pointed out that performance counters should be flushed
    when crossing protection domains on setuid execution.
    
    Reported-by: Pavel Machek <pavel@suse.cz>
    Acked-by: Pavel Machek <pavel@suse.cz>
    Signed-off-by: Ingo Molnar <mingo@elte.hu>

diff --git a/fs/exec.c b/fs/exec.c
index ec5df9a38313..d5165d899a49 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -33,6 +33,7 @@
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/pagemap.h>
+#include <linux/perf_counter.h>
 #include <linux/highmem.h>
 #include <linux/spinlock.h>
 #include <linux/key.h>
@@ -1017,6 +1018,13 @@ int flush_old_exec(struct linux_binprm * bprm)
 		set_dumpable(current->mm, suid_dumpable);
 	}
 
+	/*
+	 * Flush performance counters when crossing a
+	 * security domain:
+	 */
+	if (!get_dumpable(current->mm))
+		perf_counter_exit_task(current);
+
 	/* An exec changes our domain. We are no longer part of the thread
 	   group */
 

commit c3895b01e80d120e8d19435f7cb1fa4c60c4e269
Merge: 3c68b4a8071f 968ea6d80e39
Author: Ingo Molnar <mingo@elte.hu>
Date:   Tue Dec 16 12:24:38 2008 +0100

    Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-ingo into cpus4096

commit 3c68b4a8071fb11d905570d9b0e23034adc6c2bb
Merge: 8299608f140a 5279585ff2be
Author: Ingo Molnar <mingo@elte.hu>
Date:   Tue Dec 16 12:24:26 2008 +0100

    Merge branch 'linus' into cpus4096

commit 9dfc3bc7d21864d47797d64b8d531d4dbbc0b618
Merge: da485e0cb167 cbc34ed1ac36 2bed8446819a ffc2238af843
Author: Ingo Molnar <mingo@elte.hu>
Date:   Tue Dec 16 12:03:38 2008 +0100

    Merge branches 'tracing/fastboot', 'tracing/ftrace', 'tracing/function-graph-tracer' and 'tracing/hw-branch-tracing' into tracing/core

commit 0cc0c027d4e028632933f1be2dc4cd730358183b
Author: Ingo Molnar <mingo@elte.hu>
Date:   Sun Dec 14 23:20:36 2008 +0100

    perfcounters: release CPU context when exiting task counters
    
    If counters are exiting via do_exit() not via filp close, then
    the CPU context needs to be released - otherwise future percpu
    counter creations might fail.
    
    Signed-off-by: Ingo Molnar <mingo@elte.hu>

diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c
index 539fa8283a06..16396e9406fa 100644
--- a/kernel/perf_counter.c
+++ b/kernel/perf_counter.c
@@ -1273,8 +1273,19 @@ __perf_counter_exit_task(struct task_struct *child,
 	local_irq_disable();
 	perf_flags = hw_perf_save_disable();
 
-	if (child_counter->state == PERF_COUNTER_STATE_ACTIVE)
+	if (child_counter->state == PERF_COUNTER_STATE_ACTIVE) {
+		struct perf_cpu_context *cpuctx;
+
+		cpuctx = &__get_cpu_var(perf_cpu_context);
+
 		child_counter->hw_ops->hw_perf_counter_disable(child_counter);
+		child_counter->state = PERF_COUNTER_STATE_INACTIVE;
+		child_counter->oncpu = -1;
+
+		cpuctx->active_oncpu--;
+		child_ctx->nr_active--;
+	}
+
 	list_del_init(&child_counter->list_entry);
 
 	hw_perf_restore(perf_flags);
@@ -1539,4 +1550,3 @@ static int __init perf_counter_sysfs_init(void)
 				  &perfclass_attr_group);
 }
 device_initcall(perf_counter_sysfs_init);
-

commit 029af8c753bb5a7432aa1ed38bf61fe2c2f66d17
Merge: 75f224cf7700 5279585ff2be
Author: Ingo Molnar <mingo@elte.hu>
Date:   Sun Dec 14 21:58:33 2008 +0100

    Merge branch 'linus' into perfcounters/core

commit 75f224cf7700ed6006574dc3f2efa29860727570
Author: Ingo Molnar <mingo@elte.hu>
Date:   Sun Dec 14 21:58:46 2008 +0100

    perfcounters: fix lapic initialization
    
    Fix non-working NMI sampling in certain bootup scenarios.
    
    Signed-off-by: Ingo Molnar <mingo@elte.hu>

diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c
index 6d30f603b62c..8a154bd7ba94 100644
--- a/arch/x86/kernel/cpu/perf_counter.c
+++ b/arch/x86/kernel/cpu/perf_counter.c
@@ -557,10 +557,10 @@ void __init init_hw_perf_counters(void)
 	printk(KERN_INFO "... bit_width:    %d\n", eax.split.bit_width);
 	printk(KERN_INFO "... mask_length:  %d\n", eax.split.mask_length);
 
+	perf_counters_initialized = true;
+
 	perf_counters_lapic_init(0);
 	register_die_notifier(&perf_counter_nmi_notifier);
-
-	perf_counters_initialized = true;
 }
 
 static void x86_perf_counter_read(struct perf_counter *counter)

commit 088e2852c858159d47f71ee8da38e0fb1b21f806
Author: Ingo Molnar <mingo@elte.hu>
Date:   Sun Dec 14 20:21:00 2008 +0100

    perfcounters, x86: fix sw counters on non-PMC CPUs
    
    Make perf_max_counters default to at least 1 - this allows the sw
    counters to be used.
    
    Signed-off-by: Ingo Molnar <mingo@elte.hu>

diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c
index 59c52f9ee431..539fa8283a06 100644
--- a/kernel/perf_counter.c
+++ b/kernel/perf_counter.c
@@ -25,7 +25,7 @@
  */
 DEFINE_PER_CPU(struct perf_cpu_context, perf_cpu_context);
 
-int perf_max_counters __read_mostly;
+int perf_max_counters __read_mostly = 1;
 static int perf_reserved_percpu __read_mostly;
 static int perf_overcommit __read_mostly = 1;
 

commit 2b9ff0db19b5e2c77000b7201525f9c3d6e8328d
Author: Ingo Molnar <mingo@elte.hu>
Date:   Sun Dec 14 18:36:30 2008 +0100

    perfcounters: fix non-intel-perfmon CPUs
    
    Do not write MSR_CORE_PERF_GLOBAL_CTRL on CPUs where it does not exist.
    
    Signed-off-by: Ingo Molnar <mingo@elte.hu>

diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c
index 5afae13d8d59..6d30f603b62c 100644
--- a/arch/x86/kernel/cpu/perf_counter.c
+++ b/arch/x86/kernel/cpu/perf_counter.c
@@ -157,6 +157,9 @@ static int __hw_perf_counter_init(struct perf_counter *counter)
 
 void hw_perf_enable_all(void)
 {
+	if (unlikely(!perf_counters_initialized))
+		return;
+
 	wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, perf_counter_mask, 0);
 }
 
@@ -164,14 +167,21 @@ u64 hw_perf_save_disable(void)
 {
 	u64 ctrl;
 
+	if (unlikely(!perf_counters_initialized))
+		return 0;
+
 	rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, ctrl);
 	wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, 0, 0);
+
 	return ctrl;
 }
 EXPORT_SYMBOL_GPL(hw_perf_save_disable);
 
 void hw_perf_restore(u64 ctrl)
 {
+	if (unlikely(!perf_counters_initialized))
+		return;
+
 	wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, ctrl, 0);
 }
 EXPORT_SYMBOL_GPL(hw_perf_restore);

commit e06c61a879910869aa5bf3f8f634abfee1a7bebc
Author: Ingo Molnar <mingo@elte.hu>
Date:   Sun Dec 14 14:44:31 2008 +0100

    perfcounters: add nr-of-faults counter
    
    Impact: add new feature, new sw counter
    
    Add a counter that counts the number of pagefaults a task
    is experiencing.
    
    Signed-off-by: Ingo Molnar <mingo@elte.hu>

diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c
index fb11e351e44e..59c52f9ee431 100644
--- a/kernel/perf_counter.c
+++ b/kernel/perf_counter.c
@@ -888,6 +888,54 @@ static const struct hw_perf_counter_ops perf_ops_task_clock = {
 	.hw_perf_counter_read		= task_clock_perf_counter_read,
 };
 
+static u64 get_page_faults(void)
+{
+	struct task_struct *curr = current;
+
+	return curr->maj_flt + curr->min_flt;
+}
+
+static void page_faults_perf_counter_update(struct perf_counter *counter)
+{
+	u64 prev, now;
+	s64 delta;
+
+	prev = atomic64_read(&counter->hw.prev_count);
+	now = get_page_faults();
+
+	atomic64_set(&counter->hw.prev_count, now);
+
+	delta = now - prev;
+	if (WARN_ON_ONCE(delta < 0))
+		delta = 0;
+
+	atomic64_add(delta, &counter->count);
+}
+
+static void page_faults_perf_counter_read(struct perf_counter *counter)
+{
+	page_faults_perf_counter_update(counter);
+}
+
+static void page_faults_perf_counter_enable(struct perf_counter *counter)
+{
+	/*
+	 * page-faults is a per-task value already,
+	 * so we dont have to clear it on switch-in.
+	 */
+}
+
+static void page_faults_perf_counter_disable(struct perf_counter *counter)
+{
+	page_faults_perf_counter_update(counter);
+}
+
+static const struct hw_perf_counter_ops perf_ops_page_faults = {
+	.hw_perf_counter_enable		= page_faults_perf_counter_enable,
+	.hw_perf_counter_disable	= page_faults_perf_counter_disable,
+	.hw_perf_counter_read		= page_faults_perf_counter_read,
+};
+
 static u64 get_context_switches(void)
 {
 	struct task_struct *curr = current;
@@ -994,6 +1042,9 @@ sw_perf_counter_init(struct perf_counter *counter)
 	case PERF_COUNT_TASK_CLOCK:
 		hw_ops = &perf_ops_task_clock;
 		break;
+	case PERF_COUNT_PAGE_FAULTS:
+		hw_ops = &perf_ops_page_faults;
+		break;
 	case PERF_COUNT_CONTEXT_SWITCHES:
 		hw_ops = &perf_ops_context_switches;
 		break;