Patches contributed by Eötvös Lorand University


commit 9fd87545c97b91cf9cfa52e914d66863878efe60
Merge: 14e2acd86865 2075eb8d9561
Author: Ingo Molnar <mingo@elte.hu>
Date:   Thu Oct 9 14:33:00 2008 +0200

    Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/arjan/linux-2.6-hrtimer into timers/range-hrtimers

commit cdbb92b31d3c465aa96bd09f2d42c39b87b32bee
Merge: 2ec2b482b10a 69849375d6b1
Author: Ingo Molnar <mingo@elte.hu>
Date:   Thu Oct 9 00:17:25 2008 +0200

    Merge branch 'linus' into core/rcu

commit 990d0f2ced23052abc7efa09bd05bff34e00cf73
Merge: 85ba94ba0592 34b3ede23536 e545a6140b69 d294eb83d8d3
Author: Ingo Molnar <mingo@elte.hu>
Date:   Wed Oct 8 11:31:02 2008 +0200

    Merge branches 'sched/devel', 'sched/cpu-hotplug', 'sched/cpusets' and 'sched/urgent' into sched/core

commit 8d89adf44cf750e49691ba5b744b2ad77a05e997
Author: Ingo Molnar <mingo@elte.hu>
Date:   Tue Oct 7 06:47:52 2008 +0200

    x86: SB450: deprioritize DMI quirks
    
    This PCI ID based quick should be a full solution for the IRQ0 override
    related slowdown problem on SB450 based systems:
    
      33fb0e4: x86: SB450: skip IRQ0 override if it is not routed to INT2 of IOAPIC
    
    Emit a warning in those cases where the DMI quirk triggers but
    the PCI ID based quirk didnt.
    
    If this warning does not trigger then we can phase out the DMI quirks.
    
    Signed-off-by: Ingo Molnar <mingo@elte.hu>

diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index c102af85df9c..096102d9b24e 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -1421,8 +1421,16 @@ static int __init force_acpi_ht(const struct dmi_system_id *d)
  */
 static int __init dmi_ignore_irq0_timer_override(const struct dmi_system_id *d)
 {
-	pr_notice("%s detected: Ignoring BIOS IRQ0 pin2 override\n", d->ident);
-	acpi_skip_timer_override = 1;
+	/*
+	 * The ati_ixp4x0_rev() early PCI quirk should have set
+	 * the acpi_skip_timer_override flag already:
+	 */
+	if (!acpi_skip_timer_override) {
+		WARN(1, KERN_ERR "ati_ixp4x0 quirk not complete.\n");
+		pr_notice("%s detected: Ignoring BIOS IRQ0 pin2 override\n",
+			d->ident);
+		acpi_skip_timer_override = 1;
+	}
 	return 0;
 }
 

commit e496e3d645c93206faf61ff6005995ebd08cc39c
Merge: b159d7a989e5 5bbd4c372400 175e438f7a2d 516cbf3730c4 af2d237bf574 9b1568458a3e 5b7e41ff3726 1befdefcf476 a03352d2c1dc 7b22ff5344fd 2c7e9fd4c6cb 91030ca1e739 dd5523552c28 b3e15bdef689 20211e4d3447 efd327a2d412 c7ffa6c26277 e51a1ac2dfca 5df455155124 d99e90164e6c e621bd18958e
Author: Ingo Molnar <mingo@elte.hu>
Date:   Mon Oct 6 18:17:07 2008 +0200

    Merge branches 'x86/alternatives', 'x86/cleanups', 'x86/commandline', 'x86/crashdump', 'x86/debug', 'x86/defconfig', 'x86/doc', 'x86/exports', 'x86/fpu', 'x86/gart', 'x86/idle', 'x86/mm', 'x86/mtrr', 'x86/nmi-watchdog', 'x86/oprofile', 'x86/paravirt', 'x86/reboot', 'x86/sparse-fixes', 'x86/tsc', 'x86/urgent' and 'x86/vmalloc' into x86-v28-for-linus-phase1

diff --cc arch/x86/Kconfig
index ebfd7ff82ade,ac2fb0641a04,8e5e45a265d4,fbcb79bbafd2,ed92864d1325,ed92864d1325,962388cffa89,765ef6ae64e7,ed92864d1325,ac2fb0641a04,ed92864d1325,ed92864d1325,09f6b7fa29ac,ed92864d1325,68d91c8233f4,3d0f2b6a5a16,68d91c8233f4,ed92864d1325,ed92864d1325,ed92864d1325,68d91c8233f4..97f0d2b6dc0c
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@@@@@@@@@@@@@@@@@@@@@ -587,11 -585,17 -586,11 -585,17 -586,11 -586,11 -586,11 -585,17 -586,11 -585,17 -586,11 -586,11 -586,11 -586,11 -585,17 -586,17 -585,17 -586,11 -586,11 -586,11 -585,17 +587,11 @@@@@@@@@@@@@@@@@@@@@@ config MAXSM
                     	  Configure maximum number of CPUS and NUMA Nodes for this architecture.
                     	  If unsure, say N.
                     
 - -   - -    ---   -if MAXSMP
   -                 config NR_CPUS
   -                 	int
   -                 	default "4096"
   -                 endif
   -                 
   -                 if !MAXSMP
                     config NR_CPUS
 -     - -    ---   -	int
 -     - -    ---   -	default "4096"
 -     - -    ---   -endif
 -     - -    ---   -
 -     - -    ---   -if !MAXSMP
 -     - -    ---   -config NR_CPUS
 - -   - -    ---   -	int "Maximum number of CPUs (2-4096)"
 - -   - -    ---   -	range 2 4096
 + +   + +    +++   +	int "Maximum number of CPUs (2-512)" if !MAXSMP
 + +   + +    +++   +	range 2 512
                     	depends on SMP
 + +   + +    +++   +	default "4096" if MAXSMP
                     	default "32" if X86_NUMAQ || X86_SUMMIT || X86_BIGSMP || X86_ES7000
                     	default "8"
                     	help
@@@@@@@@@@@@@@@@@@@@@@ -1118,10 -1131,10 -1117,10 -1131,10 -1117,10 -1117,10 -1117,10 -1131,10 -1117,10 -1131,10 -1117,10 -1117,10 -1117,10 -1117,10 -1131,10 -1132,10 -1131,10 -1117,10 -1117,10 -1117,10 -1131,10 +1118,10 @@@@@@@@@@@@@@@@@@@@@@ config MTR
                     	  You can safely say Y even if your machine doesn't have MTRRs, you'll
                     	  just add about 9 KB to your kernel.
                     
------- -------------	  See <file:Documentation/mtrr.txt> for more information.
+++++++ +++++++++++++	  See <file:Documentation/x86/mtrr.txt> for more information.
                     
                     config MTRR_SANITIZER
------------ --------	bool
++++++++++++ ++++++++	def_bool y
                     	prompt "MTRR cleanup support"
                     	depends on MTRR
                     	help
diff --cc arch/x86/kernel/cpu/mtrr/main.c
index 5df16d818371,6f23969c8faf,8a7c79234be6,6f23969c8faf,b117d7f8a564,b117d7f8a564,b117d7f8a564,6f23969c8faf,b117d7f8a564,6f23969c8faf,b117d7f8a564,b117d7f8a564,5994a9f78f3d,b117d7f8a564,6f23969c8faf,6f23969c8faf,b117d7f8a564,b117d7f8a564,b117d7f8a564,885c8265e6b5,6f23969c8faf..c78c04821ea1
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@@@@@@@@@@@@@@@@@@@@@ -834,8 -834,8 -834,8 -834,8 -834,8 -834,8 -834,8 -834,8 -834,8 -834,8 -834,8 -834,8 -835,15 -834,8 -834,8 -834,8 -834,8 -834,8 -834,8 -834,8 -834,8 +835,15 @@@@@@@@@@@@@@@@@@@@@@ static int __init enable_mtrr_cleanup_s
                     		enable_mtrr_cleanup = 1;
                     	return 0;
                     }
 ------------------ -early_param("enble_mtrr_cleanup", enable_mtrr_cleanup_setup);
 ++++++++++++++++++ +early_param("enable_mtrr_cleanup", enable_mtrr_cleanup_setup);
 +++++++++++ ++++++ +
++++++++++++ ++++++++static int __init mtrr_cleanup_debug_setup(char *str)
++++++++++++ ++++++++{
++++++++++++ ++++++++	debug_print = 1;
++++++++++++ ++++++++	return 0;
++++++++++++ ++++++++}
++++++++++++ ++++++++early_param("mtrr_cleanup_debug", mtrr_cleanup_debug_setup);
+                  + 
                     struct var_mtrr_state {
                     	unsigned long	range_startk;
                     	unsigned long	range_sizek;
@@@@@@@@@@@@@@@@@@@@@@ -996,50 -996,50 -996,50 -996,50 -996,50 -996,50 -996,50 -996,50 -996,50 -996,50 -996,50 -996,50 -1062,28 -996,50 -996,50 -996,50 -996,50 -996,50 -996,50 -996,50 -996,50 +1062,28 @@@@@@@@@@@@@@@@@@@@@@ second_try
                     				(range0_basek + range0_sizek)<<10);
                     		state->reg = range_to_mtrr(state->reg, range0_basek,
                     				range0_sizek, MTRR_TYPE_WRBACK);
-   --- - -- -  ---- 
-   --- - -- -  ---- 	}
-   --- - -- -  ---- 
-   --- - -- -  ---- 	range_basek = range0_basek + range0_sizek;
-   --- - -- -  ---- 	range_sizek = chunk_sizek;
------------ --------
-   --- - -- -  ---- 	if (range_basek + range_sizek > basek &&
-   --- - -- -  ---- 	    range_basek + range_sizek <= (basek + sizek)) {
-   --- - -- -  ---- 		/* one hole */
-   --- - -- -  ---- 		second_basek = basek;
-   --- - -- -  ---- 		second_sizek = range_basek + range_sizek - basek;
                     	}
                     
 ---   - -    --    -	range_basek = range0_basek + range0_sizek;
 ---   - -    --    -	range_sizek = chunk_sizek;
 ---   - -    --    -
 ---   - -    --    -	if (range_basek + range_sizek > basek &&
 ---   - -    --    -	    range_basek + range_sizek <= (basek + sizek)) {
 ---   - -    --    -		/* one hole */
 ---   - -    --    -		second_basek = basek;
 ---   - -    --    -		second_sizek = range_basek + range_sizek - basek;
 ---   - -    --    -	}
 ---   - -    --    -
------------ --------	/* if last piece, only could one hole near end */
------------ --------	if ((second_basek || !basek) &&
------------ --------	    range_sizek - (state->range_sizek - range0_sizek) - second_sizek <
------------ --------	    (chunk_sizek >> 1)) {
------------ --------		/*
------------ --------		 * one hole in middle (second_sizek is 0) or at end
------------ --------		 * (second_sizek is 0 )
------------ --------		 */
------------ --------		hole_sizek = range_sizek - (state->range_sizek - range0_sizek)
------------ --------				 - second_sizek;
------------ --------		hole_basek = range_basek + range_sizek - hole_sizek
------------ --------				 - second_sizek;
------------ --------	} else {
------------ --------		/* fallback for big hole, or several holes */
++++++++++++ ++++++++	if (range0_sizek < state->range_sizek) {
++++++++++++ ++++++++		/* need to handle left over */
                     		range_sizek = state->range_sizek - range0_sizek;
------------ --------		second_basek = 0;
------------ --------		second_sizek = 0;
++++++++++++ ++++++++
++++++++++++ ++++++++		if (debug_print)
++++++++++++ ++++++++			printk(KERN_DEBUG "range: %016lx - %016lx\n",
++++++++++++ ++++++++				 range_basek<<10,
++++++++++++ ++++++++				 (range_basek + range_sizek)<<10);
++++++++++++ ++++++++		state->reg = range_to_mtrr(state->reg, range_basek,
++++++++++++ ++++++++				 range_sizek, MTRR_TYPE_WRBACK);
                     	}
                     
------------ --------	if (debug_print)
------------ --------		printk(KERN_DEBUG "range: %016lx - %016lx\n", range_basek<<10,
------------ --------			 (range_basek + range_sizek)<<10);
------------ --------	state->reg = range_to_mtrr(state->reg, range_basek, range_sizek,
------------ --------					 MTRR_TYPE_WRBACK);
                     	if (hole_sizek) {
++++++++++++ ++++++++		hole_basek = range_basek - hole_sizek - second_sizek;
                     		if (debug_print)
                     			printk(KERN_DEBUG "hole: %016lx - %016lx\n",
------------ --------				 hole_basek<<10, (hole_basek + hole_sizek)<<10);
------------ --------		state->reg = range_to_mtrr(state->reg, hole_basek, hole_sizek,
------------ --------						 MTRR_TYPE_UNCACHABLE);
------------ --------
++++++++++++ ++++++++				 hole_basek<<10,
++++++++++++ ++++++++				 (hole_basek + hole_sizek)<<10);
++++++++++++ ++++++++		state->reg = range_to_mtrr(state->reg, hole_basek,
++++++++++++ ++++++++				 hole_sizek, MTRR_TYPE_UNCACHABLE);
                     	}
                     
                     	return second_sizek;
@@@@@@@@@@@@@@@@@@@@@@ -1216,15 -1216,15 -1216,14 -1216,15 -1216,15 -1216,15 -1216,15 -1216,15 -1216,15 -1216,15 -1216,15 -1216,15 -1263,48 -1216,15 -1216,15 -1216,15 -1216,15 -1216,15 -1216,15 -1216,15 -1216,15 +1263,47 @@@@@@@@@@@@@@@@@@@@@@ static int __init mtrr_cleanup(unsigne
                     		num_var_ranges - num[MTRR_NUM_TYPES])
                     		return 0;
                     
++++++++++++ ++++++++	/* print original var MTRRs at first, for debugging: */
++++++++++++ ++++++++	printk(KERN_DEBUG "original variable MTRRs\n");
++++++++++++ ++++++++	for (i = 0; i < num_var_ranges; i++) {
++++++++++++ ++++++++		char start_factor = 'K', size_factor = 'K';
++++++++++++ ++++++++		unsigned long start_base, size_base;
++++++++++++ ++++++++
++++++++++++ ++++++++		size_base = range_state[i].size_pfn << (PAGE_SHIFT - 10);
++++++++++++ ++++++++		if (!size_base)
++++++++++++ ++++++++			continue;
++++++++++++ ++++++++
++++++++++++ ++++++++		size_base = to_size_factor(size_base, &size_factor),
++++++++++++ ++++++++		start_base = range_state[i].base_pfn << (PAGE_SHIFT - 10);
++++++++++++ ++++++++		start_base = to_size_factor(start_base, &start_factor),
++++++++++++ ++++++++		type = range_state[i].type;
++++++++++++ ++++++++
++++++++++++ ++++++++		printk(KERN_DEBUG "reg %d, base: %ld%cB, range: %ld%cB, type %s\n",
++++++++++++ ++++++++			i, start_base, start_factor,
++++++++++++ ++++++++			size_base, size_factor,
++++++++++++ ++++++++			(type == MTRR_TYPE_UNCACHABLE) ? "UC" :
++++++++++++ ++++++++			    ((type == MTRR_TYPE_WRPROT) ? "WP" :
++++++++++++ ++++++++			     ((type == MTRR_TYPE_WRBACK) ? "WB" : "Other"))
++++++++++++ ++++++++			);
++++++++++++ ++++++++	}
++++++++++++ ++++++++
                     	memset(range, 0, sizeof(range));
                     	extra_remove_size = 0;
-- ------------------	if (mtrr_tom2) {
-- ------------------		extra_remove_base = 1 << (32 - PAGE_SHIFT);
++ ++++++++++++++++++	extra_remove_base = 1 << (32 - PAGE_SHIFT);
++ ++++++++++++++++++	if (mtrr_tom2)
                     		extra_remove_size =
                     			(mtrr_tom2 >> PAGE_SHIFT) - extra_remove_base;
-- ------------------	}
                     	nr_range = x86_get_mtrr_mem_range(range, 0, extra_remove_base,
                     					  extra_remove_size);
++++++++++++ ++++++++	/*
++++++++++++ ++++++++	 * [0, 1M) should always be coverred by var mtrr with WB
++++++++++++ ++++++++	 * and fixed mtrrs should take effective before var mtrr for it
++++++++++++ ++++++++	 */
++++++++++++ ++++++++	nr_range = add_range_with_merge(range, nr_range, 0,
++++++++++++ ++++++++					(1ULL<<(20 - PAGE_SHIFT)) - 1);
++++++++++++ ++++++++	/* sort the ranges */
++++++++++++ ++++++++	sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL);
++++++++++++ ++++++++
                     	range_sums = sum_ranges(range, nr_range);
                     	printk(KERN_INFO "total RAM coverred: %ldM\n",
                     	       range_sums >> (20 - PAGE_SHIFT));
diff --cc arch/x86/kernel/process_32.c
index c8609dea443f,53bc653ed5ca,3b7a1ddcc0bc,53bc653ed5ca,3b7a1ddcc0bc,62a4790e425d,3b7a1ddcc0bc,3b7a1ddcc0bc,31f40b24bf5d,53bc653ed5ca,3b7a1ddcc0bc,3b7a1ddcc0bc,31f40b24bf5d,3b7a1ddcc0bc,3b7a1ddcc0bc,53bc653ed5ca,3b7a1ddcc0bc,4b3cfdf54216,3b7a1ddcc0bc,31f40b24bf5d,3b7a1ddcc0bc..205188db9626
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@@@@@@@@@@@@@@@@@@@@@ -55,9 -55,6 -55,6 -55,6 -55,6 -56,6 -55,6 -55,6 -55,7 -55,6 -55,6 -55,6 -55,7 -55,6 -55,6 -55,6 -55,6 -55,6 -55,6 -55,7 -55,6 +56,9 @@@@@@@@@@@@@@@@@@@@@@
                     #include <asm/tlbflush.h>
                     #include <asm/cpu.h>
                     #include <asm/kdebug.h>
 +++++++ +++ ++++++ +#include <asm/idle.h>
 ++++++++++++++++++++#include <asm/syscalls.h>
 ++++++++++++++++++++#include <asm/smp.h>
                     
                     asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
                     
diff --cc arch/x86/kernel/process_64.c
index 79e3e173ab40,3fb62a7d9a16,e04134a80c22,3fb62a7d9a16,71553b664e2a,71553b664e2a,71553b664e2a,71553b664e2a,e12e0e4dd256,3fb62a7d9a16,71553b664e2a,71553b664e2a,e12e0e4dd256,71553b664e2a,71553b664e2a,3fb62a7d9a16,71553b664e2a,e12e0e4dd256,71553b664e2a,e12e0e4dd256,71553b664e2a..2a8ccb9238b4
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@@@@@@@@@@@@@@@@@@@@@ -94,8 -93,7 -93,6 -93,7 -93,6 -93,6 -93,6 -93,6 -93,8 -93,7 -93,6 -93,6 -93,8 -93,6 -93,6 -93,7 -93,6 -93,8 -93,6 -93,8 -93,6 +94,8 @@@@@@@@@@@@@@@@@@@@@@ DECLARE_PER_CPU(int, cpu_state)
                     static inline void play_dead(void)
                     {
                     	idle_task_exit();
 - -     -     -     	wbinvd();
 +++++++ +++ ++++ + +	c1e_remove_cpu(raw_smp_processor_id());
 +++++++ +++ ++++ + +
                     	mb();
                     	/* Ack it */
                     	__get_cpu_var(cpu_state) = CPU_DEAD;
diff --cc arch/x86/kernel/setup.c
index 9838f2539dfc,68b48e3fbcbd,362d4e7f2d38,2f31cddd27b7,9838f2539dfc,9838f2539dfc,362d4e7f2d38,a4656adab53b,9838f2539dfc,68b48e3fbcbd,362d4e7f2d38,362d4e7f2d38,9838f2539dfc,9838f2539dfc,a4656adab53b,b520dae02bf4,362d4e7f2d38,9838f2539dfc,362d4e7f2d38,9838f2539dfc,a4656adab53b..141efab52400
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@@@@@@@@@@@@@@@@@@@@@ -670,18 -678,6 -670,14 -694,6 -670,18 -670,18 -670,14 -678,6 -670,18 -678,6 -670,14 -670,14 -670,18 -670,18 -678,6 -670,6 -670,14 -670,18 -670,14 -670,18 -678,6 +686,18 @@@@@@@@@@@@@@@@@@@@@@ void __init setup_arch(char **cmdline_p
                     
                     	parse_early_param();
                     
 +++  ++ +++  +++ + +#ifdef CONFIG_X86_64
 +++  ++ +++  +++ + +	check_efer();
 +++  ++ +++  +++ + +#endif
 +++  ++ +++  +++ + +
 + +   + +    ++    +#if defined(CONFIG_VMI) && defined(CONFIG_X86_32)
 + +   + +    ++    +	/*
 + +   + +    ++    +	 * Must be before kernel pagetables are setup
 + +   + +    ++    +	 * or fixmap area is touched.
 + +   + +    ++    +	 */
 + +   + +    ++    +	vmi_init();
 + +   + +    ++    +#endif
 + +   + +    ++    +
                     	/* after early param, so could get panic from serial */
                     	reserve_early_setup_data();
                     
diff --cc arch/x86/kernel/signal_64.c
index 4d32487805ef,b45ef8ddd651,162da796a323,b45ef8ddd651,ca316b5b742c,ca316b5b742c,ca316b5b742c,ca316b5b742c,ca316b5b742c,b45ef8ddd651,ca316b5b742c,ca316b5b742c,ca316b5b742c,ca316b5b742c,ca316b5b742c,b45ef8ddd651,ca316b5b742c,ca316b5b742c,ca316b5b742c,ca316b5b742c,ca316b5b742c..694aa888bb19
--- a/arch/x86/kernel/signal_64.c
+++ b/arch/x86/kernel/signal_64.c
@@@@@@@@@@@@@@@@@@@@@@ -357,9 -345,38 -351,38 -345,38 -354,38 -354,38 -354,38 -354,38 -354,38 -345,38 -354,38 -354,38 -354,38 -354,38 -354,38 -345,38 -354,38 -354,38 -354,38 -354,38 -354,38 +354,9 @@@@@@@@@@@@@@@@@@@@@@ give_sigsegv
                     	return -EFAULT;
                     }
                     
 --------------------/*
 -------------------- * Return -1L or the syscall number that @regs is executing.
 -------------------- */
 --------------------static long current_syscall(struct pt_regs *regs)
 --------------------{
 --------------------	/*
 --------------------	 * We always sign-extend a -1 value being set here,
 --------------------	 * so this is always either -1L or a syscall number.
 --------------------	 */
 --------------------	return regs->orig_ax;
 --------------------}
 --------------------
 --------------------/*
 -------------------- * Return a value that is -EFOO if the system call in @regs->orig_ax
 -------------------- * returned an error.  This only works for @regs from @current.
 -------------------- */
 --------------------static long current_syscall_ret(struct pt_regs *regs)
 --------------------{
 --------------------#ifdef CONFIG_IA32_EMULATION
 --------------------	if (test_thread_flag(TIF_IA32))
 --------------------		/*
 --------------------		 * Sign-extend the value so (int)-EFOO becomes (long)-EFOO
 --------------------		 * and will match correctly in comparisons.
 --------------------		 */
 --------------------		return (int) regs->ax;
 --------------------#endif
 --------------------	return regs->ax;
 --------------------}
 --------------------
                     /*
                      * OK, we're invoking a handler
-- ------------------ */	
++ ++++++++++++++++++ */
                     
                     static int
                     handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
@@@@@@@@@@@@@@@@@@@@@@ -427,16 -444,15 -450,15 -444,15 -453,15 -453,15 -453,15 -453,15 -453,15 -444,15 -453,15 -453,15 -453,15 -453,15 -453,15 -444,15 -453,15 -453,15 -453,15 -453,15 -453,15 +424,16 @@@@@@@@@@@@@@@@@@@@@@
                     		 * handler too.
                     		 */
                     		regs->flags &= ~X86_EFLAGS_TF;
 --------------------		if (test_thread_flag(TIF_SINGLESTEP))
 --------------------			ptrace_notify(SIGTRAP);
                     
                     		spin_lock_irq(&current->sighand->siglock);
-- ------------------		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
++ ++++++++++++++++++		sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
                     		if (!(ka->sa.sa_flags & SA_NODEFER))
-- ------------------			sigaddset(&current->blocked,sig);
++ ++++++++++++++++++			sigaddset(&current->blocked, sig);
                     		recalc_sigpending();
                     		spin_unlock_irq(&current->sighand->siglock);
 ++++++++++++++++++++
 ++++++++++++++++++++		tracehook_signal_handler(sig, info, ka, regs,
 ++++++++++++++++++++					 test_thread_flag(TIF_SINGLESTEP));
                     	}
                     
                     	return ret;
diff --cc arch/x86/kernel/sys_x86_64.c
index c9288c883e20,3b360ef33817,56eb8f916e9f,3b360ef33817,3b360ef33817,3b360ef33817,3b360ef33817,3b360ef33817,3b360ef33817,3b360ef33817,3b360ef33817,3b360ef33817,3b360ef33817,3b360ef33817,3b360ef33817,3b360ef33817,3b360ef33817,3b360ef33817,3b360ef33817,3b360ef33817,3b360ef33817..6bc211accf08
--- a/arch/x86/kernel/sys_x86_64.c
+++ b/arch/x86/kernel/sys_x86_64.c
@@@@@@@@@@@@@@@@@@@@@@ -13,16 -13,15 -13,16 -13,15 -13,15 -13,15 -13,15 -13,15 -13,15 -13,15 -13,15 -13,15 -13,15 -13,15 -13,15 -13,15 -13,15 -13,15 -13,15 -13,15 -13,15 +13,17 @@@@@@@@@@@@@@@@@@@@@@
                     #include <linux/utsname.h>
                     #include <linux/personality.h>
                     #include <linux/random.h>
++ ++++++++++++++++++#include <linux/uaccess.h>
                     
-- ------------------#include <asm/uaccess.h>
                     #include <asm/ia32.h>
 ++++++++++++++++++++#include <asm/syscalls.h>
                     
-- ------------------asmlinkage long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
-- ------------------	unsigned long fd, unsigned long off)
++ ++++++++++++++++++asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
++ ++++++++++++++++++		unsigned long prot, unsigned long flags,
++ ++++++++++++++++++		unsigned long fd, unsigned long off)
                     {
                     	long error;
-- ------------------	struct file * file;
++ ++++++++++++++++++	struct file *file;
                     
                     	error = -EINVAL;
                     	if (off & ~PAGE_MASK)
diff --cc arch/x86/kernel/tsc.c
index 8f98e9de1b82,7603c0553909,8f98e9de1b82,7603c0553909,8f98e9de1b82,8f98e9de1b82,8f98e9de1b82,46af71676738,8f98e9de1b82,7603c0553909,8e786b0d665a,8f98e9de1b82,8f98e9de1b82,8f98e9de1b82,46af71676738,7603c0553909,46af71676738,8f98e9de1b82,4847a9280505,8f98e9de1b82,46af71676738..161bb850fc47
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@@@@@@@@@@@@@@@@@@@@@ -104,7 -104,7 -104,7 -104,7 -104,7 -104,7 -104,7 -104,7 -104,7 -104,7 -104,7 -104,7 -104,7 -104,7 -104,7 -104,7 -104,7 -104,7 -104,7 -104,7 -104,7 +104,7 @@@@@@@@@@@@@@@@@@@@@@ __setup("notsc", notsc_setup)
                     /*
                      * Read TSC and the reference counters. Take care of SMI disturbance
                      */
- - ----- ----- -- --static u64 tsc_read_refs(u64 *pm, u64 *hpet)
 - -     -     -     static u64 __init tsc_read_refs(u64 *pm, u64 *hpet)
++++++++++++++++++ ++static u64 tsc_read_refs(u64 *p, int hpet)
                     {
                     	u64 t1, t2;
                     	int i;
@@@@@@@@@@@@@@@@@@@@@@ -122,216 -122,80 -122,216 -122,80 -122,216 -122,216 -122,216 -122,80 -122,216 -122,80 -122,80 -122,216 -122,216 -122,216 -122,80 -122,80 -122,80 -122,216 -122,391 -122,216 -122,80 +122,390 @@@@@@@@@@@@@@@@@@@@@@
                     	return ULLONG_MAX;
                     }
                     
 - -   - --   ---   -/**
 - -   - --   ---   - * native_calibrate_tsc - calibrate the tsc on boot
++++++++++++++++++ ++/*
++++++++++++++++++ ++ * Calculate the TSC frequency from HPET reference
+ + +++ +  +++   + +  */
 - -   - --   ---   -unsigned long native_calibrate_tsc(void)
++++++++++++++++++ ++static unsigned long calc_hpet_ref(u64 deltatsc, u64 hpet1, u64 hpet2)
+ + +++ +  +++   + + {
 - -   - --   ---   -	unsigned long flags;
 - -   - --   ---   -	u64 tsc1, tsc2, tr1, tr2, delta, pm1, pm2, hpet1, hpet2;
 - -   - --   ---   -	int hpet = is_hpet_enabled();
 - -   - --   ---   -	unsigned int tsc_khz_val = 0;
++++++++++++++++++ ++	u64 tmp;
+ + +++ +  +++   + + 
 - -   - --   ---   -	local_irq_save(flags);
++++++++++++++++++ ++	if (hpet2 < hpet1)
++++++++++++++++++ ++		hpet2 += 0x100000000ULL;
++++++++++++++++++ ++	hpet2 -= hpet1;
++++++++++++++++++ ++	tmp = ((u64)hpet2 * hpet_readl(HPET_PERIOD));
++++++++++++++++++ ++	do_div(tmp, 1000000);
++++++++++++++++++ ++	do_div(deltatsc, tmp);
++++++++++++++++++ ++
++++++++++++++++++ ++	return (unsigned long) deltatsc;
++++++++++++++++++ ++}
++++++++++++++++++ ++
++++++++++++++++++ ++/*
++++++++++++++++++ ++ * Calculate the TSC frequency from PMTimer reference
++++++++++++++++++ ++ */
++++++++++++++++++ ++static unsigned long calc_pmtimer_ref(u64 deltatsc, u64 pm1, u64 pm2)
++++++++++++++++++ ++{
++++++++++++++++++ ++	u64 tmp;
+ + +++ + ++++   + + 
 - -   - -    ---   -	tsc1 = tsc_read_refs(&pm1, hpet ? &hpet1 : NULL);
++++++++++++++++++ ++	if (!pm1 && !pm2)
++++++++++++++++++ ++		return ULONG_MAX;
++++++++++++++++++ ++
++++++++++++++++++ ++	if (pm2 < pm1)
++++++++++++++++++ ++		pm2 += (u64)ACPI_PM_OVRRUN;
++++++++++++++++++ ++	pm2 -= pm1;
++++++++++++++++++ ++	tmp = pm2 * 1000000000LL;
++++++++++++++++++ ++	do_div(tmp, PMTMR_TICKS_PER_SEC);
++++++++++++++++++ ++	do_div(deltatsc, tmp);
++++++++++++++++++ ++
++++++++++++++++++ ++	return (unsigned long) deltatsc;
++++++++++++++++++ ++}
++++++++++++++++++ ++
++++++++++++++++++ ++#define CAL_MS		10
++++++++++++++++++ ++#define CAL_LATCH	(CLOCK_TICK_RATE / (1000 / CAL_MS))
++++++++++++++++++ ++#define CAL_PIT_LOOPS	1000
++++++++++++++++++ ++
++++++++++++++++++ ++#define CAL2_MS		50
++++++++++++++++++ ++#define CAL2_LATCH	(CLOCK_TICK_RATE / (1000 / CAL2_MS))
++++++++++++++++++ ++#define CAL2_PIT_LOOPS	5000
++++++++++++++++++ ++
++++++++++++++++++ ++
 + +   + ++   +++   +/*
 + +   + ++   +++   + * Try to calibrate the TSC against the Programmable
 + +   + ++   +++   + * Interrupt Timer and return the frequency of the TSC
 + +   + ++   +++   + * in kHz.
 + +   + ++   +++   + *
 + +   + ++   +++   + * Return ULONG_MAX on failure to calibrate.
 + +   + ++   +++   + */
- - --- -  ---   - - static unsigned long pit_calibrate_tsc(void)
++++++++++++++++++ ++static unsigned long pit_calibrate_tsc(u32 latch, unsigned long ms, int loopmin)
 + +   + ++   +++   +{
 + +   + ++   +++   +	u64 tsc, t1, t2, delta;
 + +   + ++   +++   +	unsigned long tscmin, tscmax;
 + +   + ++   +++   +	int pitcnt;
          +          
 + +   + ++   +++   +	/* Set the Gate high, disable speaker */
          +          	outb((inb(0x61) & ~0x02) | 0x01, 0x61);
          +          
 + +   + ++   +++   +	/*
 + +   + ++   +++   +	 * Setup CTC channel 2* for mode 0, (interrupt on terminal
 + +   + ++   +++   +	 * count mode), binary count. Set the latch register to 50ms
 + +   + ++   +++   +	 * (LSB then MSB) to begin countdown.
 + +   + ++   +++   +	 */
          +          	outb(0xb0, 0x43);
---------- ------- --	outb((CLOCK_TICK_RATE / (1000 / 50)) & 0xff, 0x42);
---------- ------- --	outb((CLOCK_TICK_RATE / (1000 / 50)) >> 8, 0x42);
 - -   - -    ---   -	tr1 = get_cycles();
 - -   - -    ---   -	while ((inb(0x61) & 0x20) == 0);
 - -   - -    ---   -	tr2 = get_cycles();
++++++++++++++++++ ++	outb(latch & 0xff, 0x42);
++++++++++++++++++ ++	outb(latch >> 8, 0x42);
          +          
 - -   - -    ---   -	tsc2 = tsc_read_refs(&pm2, hpet ? &hpet2 : NULL);
 + +   + ++   +++   +	tsc = t1 = t2 = get_cycles();
 + +   + ++   +++   +
 + +   + ++   +++   +	pitcnt = 0;
 + +   + ++   +++   +	tscmax = 0;
 + +   + ++   +++   +	tscmin = ULONG_MAX;
 + +   + ++   +++   +	while ((inb(0x61) & 0x20) == 0) {
 + +   + ++   +++   +		t2 = get_cycles();
 + +   + ++   +++   +		delta = t2 - tsc;
 + +   + ++   +++   +		tsc = t2;
 + +   + ++   +++   +		if ((unsigned long) delta < tscmin)
 + +   + ++   +++   +			tscmin = (unsigned int) delta;
 + +   + ++   +++   +		if ((unsigned long) delta > tscmax)
 + +   + ++   +++   +			tscmax = (unsigned int) delta;
 + +   + ++   +++   +		pitcnt++;
 + +   + ++   +++   +	}
 + +   + ++   +++   +
 + +   + ++   +++   +	/*
 + +   + ++   +++   +	 * Sanity checks:
 + +   + ++   +++   +	 *
- - --- -  ---   - - 	 * If we were not able to read the PIT more than 5000
++++++++++++++++++ ++	 * If we were not able to read the PIT more than loopmin
 + +   + ++   +++   +	 * times, then we have been hit by a massive SMI
 + +   + ++   +++   +	 *
 + +   + ++   +++   +	 * If the maximum is 10 times larger than the minimum,
 + +   + ++   +++   +	 * then we got hit by an SMI as well.
 + +   + ++   +++   +	 */
- - --- -  ---   - - 	if (pitcnt < 5000 || tscmax > 10 * tscmin)
++++++++++++++++++ ++	if (pitcnt < loopmin || tscmax > 10 * tscmin)
 + +   + ++   +++   +		return ULONG_MAX;
 + +   + ++   +++   +
 + +   + ++   +++   +	/* Calculate the PIT value */
 + +   + ++   +++   +	delta = t2 - t1;
- - --- -  ---   - - 	do_div(delta, 50);
++++++++++++++++++ ++	do_div(delta, ms);
 + +   + ++   +++   +	return delta;
 + +   + ++   +++   +}
          +          
++++++++++++++++++ ++/*
++++++++++++++++++ ++ * This reads the current MSB of the PIT counter, and
++++++++++++++++++ ++ * checks if we are running on sufficiently fast and
++++++++++++++++++ ++ * non-virtualized hardware.
++++++++++++++++++ ++ *
++++++++++++++++++ ++ * Our expectations are:
++++++++++++++++++ ++ *
++++++++++++++++++ ++ *  - the PIT is running at roughly 1.19MHz
++++++++++++++++++ ++ *
++++++++++++++++++ ++ *  - each IO is going to take about 1us on real hardware,
++++++++++++++++++ ++ *    but we allow it to be much faster (by a factor of 10) or
++++++++++++++++++ ++ *    _slightly_ slower (ie we allow up to a 2us read+counter
++++++++++++++++++ ++ *    update - anything else implies a unacceptably slow CPU
++++++++++++++++++ ++ *    or PIT for the fast calibration to work.
++++++++++++++++++ ++ *
++++++++++++++++++ ++ *  - with 256 PIT ticks to read the value, we have 214us to
++++++++++++++++++ ++ *    see the same MSB (and overhead like doing a single TSC
++++++++++++++++++ ++ *    read per MSB value etc).
++++++++++++++++++ ++ *
++++++++++++++++++ ++ *  - We're doing 2 reads per loop (LSB, MSB), and we expect
++++++++++++++++++ ++ *    them each to take about a microsecond on real hardware.
++++++++++++++++++ ++ *    So we expect a count value of around 100. But we'll be
++++++++++++++++++ ++ *    generous, and accept anything over 50.
++++++++++++++++++ ++ *
++++++++++++++++++ ++ *  - if the PIT is stuck, and we see *many* more reads, we
++++++++++++++++++ ++ *    return early (and the next caller of pit_expect_msb()
++++++++++++++++++ ++ *    then consider it a failure when they don't see the
++++++++++++++++++ ++ *    next expected value).
++++++++++++++++++ ++ *
++++++++++++++++++ ++ * These expectations mean that we know that we have seen the
++++++++++++++++++ ++ * transition from one expected value to another with a fairly
++++++++++++++++++ ++ * high accuracy, and we didn't miss any events. We can thus
++++++++++++++++++ ++ * use the TSC value at the transitions to calculate a pretty
++++++++++++++++++ ++ * good value for the TSC frequencty.
++++++++++++++++++ ++ */
++++++++++++++++++ ++static inline int pit_expect_msb(unsigned char val)
++++++++++++++++++ ++{
++++++++++++++++++ ++	int count = 0;
++++++++++ +++++++ ++
          -          	tsc1 = tsc_read_refs(&pm1, hpet ? &hpet1 : NULL);
++++++++++++++++++ ++	for (count = 0; count < 50000; count++) {
++++++++++++++++++ ++		/* Ignore LSB */
++++++++++++++++++ ++		inb(0x42);
++++++++++++++++++ ++		if (inb(0x42) != val)
++++++++++++++++++ ++			break;
++++++++++++++++++ ++	}
++++++++++++++++++ ++	return count > 50;
++++++++++++++++++ ++}
++++++++++++++++++ ++
++++++++++++++++++ ++/*
++++++++++++++++++ ++ * How many MSB values do we want to see? We aim for a
++++++++++++++++++ ++ * 15ms calibration, which assuming a 2us counter read
++++++++++++++++++ ++ * error should give us roughly 150 ppm precision for
++++++++++++++++++ ++ * the calibration.
++++++++++++++++++ ++ */
++++++++++++++++++ ++#define QUICK_PIT_MS 15
++++++++++++++++++ ++#define QUICK_PIT_ITERATIONS (QUICK_PIT_MS * PIT_TICK_RATE / 1000 / 256)
++++++++++ +++++++ ++
++++++++++++++++++ ++static unsigned long quick_pit_calibrate(void)
++++++++++++++++++ ++{
++++++++++++++++++ ++	/* Set the Gate high, disable speaker */
++++++++++ +++++++ ++	outb((inb(0x61) & ~0x02) | 0x01, 0x61);
++++++++++ +++++++ ++
++++++++++++++++++ ++	/*
++++++++++++++++++ ++	 * Counter 2, mode 0 (one-shot), binary count
++++++++++++++++++ ++	 *
++++++++++++++++++ ++	 * NOTE! Mode 2 decrements by two (and then the
++++++++++++++++++ ++	 * output is flipped each time, giving the same
++++++++++++++++++ ++	 * final output frequency as a decrement-by-one),
++++++++++++++++++ ++	 * so mode 0 is much better when looking at the
++++++++++++++++++ ++	 * individual counts.
++++++++++++++++++ ++	 */
++++++++++ +++++++ ++	outb(0xb0, 0x43);
          -          	outb((CLOCK_TICK_RATE / (1000 / 50)) & 0xff, 0x42);
          -          	outb((CLOCK_TICK_RATE / (1000 / 50)) >> 8, 0x42);
          -          	tr1 = get_cycles();
          -          	while ((inb(0x61) & 0x20) == 0);
          -          	tr2 = get_cycles();
++++++++++ +++++++ ++
          -          	tsc2 = tsc_read_refs(&pm2, hpet ? &hpet2 : NULL);
++++++++++++++++++ ++	/* Start at 0xffff */
++++++++++++++++++ ++	outb(0xff, 0x42);
++++++++++++++++++ ++	outb(0xff, 0x42);
++++++++++++++++++ ++
++++++++++++++++++ ++	if (pit_expect_msb(0xff)) {
++++++++++++++++++ ++		int i;
++++++++++++++++++ ++		u64 t1, t2, delta;
++++++++++++++++++ ++		unsigned char expect = 0xfe;
++++++++++++++++++ ++
++++++++++++++++++ ++		t1 = get_cycles();
++++++++++++++++++ ++		for (i = 0; i < QUICK_PIT_ITERATIONS; i++, expect--) {
++++++++++++++++++ ++			if (!pit_expect_msb(expect))
++++++++++++++++++ ++				goto failed;
++++++++++++++++++ ++		}
++++++++++++++++++ ++		t2 = get_cycles();
++++++++++++++++++ ++
++++++++++++++++++ ++		/*
++++++++++++++++++ ++		 * Make sure we can rely on the second TSC timestamp:
++++++++++++++++++ ++		 */
++++++++++++++++++ ++		if (!pit_expect_msb(expect))
++++++++++++++++++ ++			goto failed;
++++++++++++++++++ ++
++++++++++++++++++ ++		/*
++++++++++++++++++ ++		 * Ok, if we get here, then we've seen the
++++++++++++++++++ ++		 * MSB of the PIT decrement QUICK_PIT_ITERATIONS
++++++++++++++++++ ++		 * times, and each MSB had many hits, so we never
++++++++++++++++++ ++		 * had any sudden jumps.
++++++++++++++++++ ++		 *
++++++++++++++++++ ++		 * As a result, we can depend on there not being
++++++++++++++++++ ++		 * any odd delays anywhere, and the TSC reads are
++++++++++++++++++ ++		 * reliable.
++++++++++++++++++ ++		 *
++++++++++++++++++ ++		 * kHz = ticks / time-in-seconds / 1000;
++++++++++++++++++ ++		 * kHz = (t2 - t1) / (QPI * 256 / PIT_TICK_RATE) / 1000
++++++++++++++++++ ++		 * kHz = ((t2 - t1) * PIT_TICK_RATE) / (QPI * 256 * 1000)
++++++++++++++++++ ++		 */
++++++++++++++++++ ++		delta = (t2 - t1)*PIT_TICK_RATE;
++++++++++++++++++ ++		do_div(delta, QUICK_PIT_ITERATIONS*256*1000);
++++++++++++++++++ ++		printk("Fast TSC calibration using PIT\n");
++++++++++++++++++ ++		return delta;
++++++++++++++++++ ++	}
++++++++++++++++++ ++failed:
++++++++++++++++++ ++	return 0;
++++++++++++++++++ ++}
 + +   + +    +++   +
 + +   + ++   +++   +/**
 + +   + ++   +++   + * native_calibrate_tsc - calibrate the tsc on boot
 + +   + ++   +++   + */
 + +   + ++   +++   +unsigned long native_calibrate_tsc(void)
 + +   + ++   +++   +{
- - --- -  ---   - - 	u64 tsc1, tsc2, delta, pm1, pm2, hpet1, hpet2;
++++++++++++++++++ ++	u64 tsc1, tsc2, delta, ref1, ref2;
 + +   + ++   +++   +	unsigned long tsc_pit_min = ULONG_MAX, tsc_ref_min = ULONG_MAX;
- - --- -  ---   - - 	unsigned long flags;
- - --- -  ---   - - 	int hpet = is_hpet_enabled(), i;
++++++++++++++++++ ++	unsigned long flags, latch, ms, fast_calibrate;
++++++++++++++++++ ++	int hpet = is_hpet_enabled(), i, loopmin;
++++++++++++++++++ ++
++++++++++++++++++ ++	local_irq_save(flags);
++++++++++++++++++ ++	fast_calibrate = quick_pit_calibrate();
+ + +++ +  +++   + + 	local_irq_restore(flags);
++++++++++++++++++ ++	if (fast_calibrate)
++++++++++++++++++ ++		return fast_calibrate;
                     
                     	/*
 - -   - --   ---   -	 * Preset the result with the raw and inaccurate PIT
 - -   - --   ---   -	 * calibration value
 + +   + ++   +++   +	 * Run 5 calibration loops to get the lowest frequency value
 + +   + ++   +++   +	 * (the best estimate). We use two different calibration modes
 + +   + ++   +++   +	 * here:
 + +   + ++   +++   +	 *
 + +   + ++   +++   +	 * 1) PIT loop. We set the PIT Channel 2 to oneshot mode and
 + +   + ++   +++   +	 * load a timeout of 50ms. We read the time right after we
 + +   + ++   +++   +	 * started the timer and wait until the PIT count down reaches
 + +   + ++   +++   +	 * zero. In each wait loop iteration we read the TSC and check
 + +   + ++   +++   +	 * the delta to the previous read. We keep track of the min
 + +   + ++   +++   +	 * and max values of that delta. The delta is mostly defined
 + +   + ++   +++   +	 * by the IO time of the PIT access, so we can detect when a
 + +   + ++   +++   +	 * SMI/SMM disturbance happend between the two reads. If the
 + +   + ++   +++   +	 * maximum time is significantly larger than the minimum time,
 + +   + ++   +++   +	 * then we discard the result and have another try.
 + +   + ++   +++   +	 *
 + +   + ++   +++   +	 * 2) Reference counter. If available we use the HPET or the
 + +   + ++   +++   +	 * PMTIMER as a reference to check the sanity of that value.
 + +   + ++   +++   +	 * We use separate TSC readouts and check inside of the
 + +   + ++   +++   +	 * reference read for a SMI/SMM disturbance. We dicard
 + +   + ++   +++   +	 * disturbed values here as well. We do that around the PIT
 + +   + ++   +++   +	 * calibration delay loop as we have to wait for a certain
 + +   + ++   +++   +	 * amount of time anyway.
                     	 */
- - --- -  ---   - - 	for (i = 0; i < 5; i++) {
 - -   - --   ---   -	delta = (tr2 - tr1);
 - -   - --   ---   -	do_div(delta, 50);
 - -   - --   ---   -	tsc_khz_val = delta;
 - -   - --   ---   -
 - -   - --   ---   -	/* hpet or pmtimer available ? */
 - -   - --   ---   -	if (!hpet && !pm1 && !pm2) {
 - -   - --   ---   -		printk(KERN_INFO "TSC calibrated against PIT\n");
 - -   - --   ---   -		goto out;
++++++++++++++++++ ++
++++++++++++++++++ ++	/* Preset PIT loop values */
++++++++++++++++++ ++	latch = CAL_LATCH;
++++++++++++++++++ ++	ms = CAL_MS;
++++++++++++++++++ ++	loopmin = CAL_PIT_LOOPS;
++++++++++++++++++ ++
++++++++++++++++++ ++	for (i = 0; i < 3; i++) {
 + +   + ++   +++   +		unsigned long tsc_pit_khz;
 + +   + ++   +++   +
 + +   + ++   +++   +		/*
 + +   + ++   +++   +		 * Read the start value and the reference count of
 + +   + ++   +++   +		 * hpet/pmtimer when available. Then do the PIT
 + +   + ++   +++   +		 * calibration, which will take at least 50ms, and
 + +   + ++   +++   +		 * read the end value.
 + +   + ++   +++   +		 */
 + +   + ++   +++   +		local_irq_save(flags);
- - --- -  ---   - - 		tsc1 = tsc_read_refs(&pm1, hpet ? &hpet1 : NULL);
- - --- -  ---   - - 		tsc_pit_khz = pit_calibrate_tsc();
- - --- -  ---   - - 		tsc2 = tsc_read_refs(&pm2, hpet ? &hpet2 : NULL);
++++++++++++++++++ ++		tsc1 = tsc_read_refs(&ref1, hpet);
++++++++++++++++++ ++		tsc_pit_khz = pit_calibrate_tsc(latch, ms, loopmin);
++++++++++++++++++ ++		tsc2 = tsc_read_refs(&ref2, hpet);
 + +   + ++   +++   +		local_irq_restore(flags);
 + +   + ++   +++   +
 + +   + ++   +++   +		/* Pick the lowest PIT TSC calibration so far */
 + +   + ++   +++   +		tsc_pit_min = min(tsc_pit_min, tsc_pit_khz);
 + +   + ++   +++   +
 + +   + ++   +++   +		/* hpet or pmtimer available ? */
- - --- -  ---   - - 		if (!hpet && !pm1 && !pm2)
++++++++++++++++++ ++		if (!hpet && !ref1 && !ref2)
 + +   + ++   +++   +			continue;
 + +   + ++   +++   +
 + +   + ++   +++   +		/* Check, whether the sampling was disturbed by an SMI */
 + +   + ++   +++   +		if (tsc1 == ULLONG_MAX || tsc2 == ULLONG_MAX)
 + +   + ++   +++   +			continue;
 + +   + ++   +++   +
 + +   + ++   +++   +		tsc2 = (tsc2 - tsc1) * 1000000LL;
++++++++++++++++++ ++		if (hpet)
++++++++++++++++++ ++			tsc2 = calc_hpet_ref(tsc2, ref1, ref2);
++++++++++++++++++ ++		else
++++++++++++++++++ ++			tsc2 = calc_pmtimer_ref(tsc2, ref1, ref2);
 + +   + ++   +++   +
- - --- -  ---   - - 		if (hpet) {
- - --- -  ---   - - 			if (hpet2 < hpet1)
- - --- -  ---   - - 				hpet2 += 0x100000000ULL;
- - --- -  ---   - - 			hpet2 -= hpet1;
- - --- -  ---   - - 			tsc1 = ((u64)hpet2 * hpet_readl(HPET_PERIOD));
- - --- -  ---   - - 			do_div(tsc1, 1000000);
- - --- -  ---   - - 		} else {
- - --- -  ---   - - 			if (pm2 < pm1)
- - --- -  ---   - - 				pm2 += (u64)ACPI_PM_OVRRUN;
- - --- -  ---   - - 			pm2 -= pm1;
- - --- -  ---   - - 			tsc1 = pm2 * 1000000000LL;
- - --- -  ---   - - 			do_div(tsc1, PMTMR_TICKS_PER_SEC);
++++++++++++++++++ ++		tsc_ref_min = min(tsc_ref_min, (unsigned long) tsc2);
++++++++++++++++++ ++
++++++++++++++++++ ++		/* Check the reference deviation */
++++++++++++++++++ ++		delta = ((u64) tsc_pit_min) * 100;
++++++++++++++++++ ++		do_div(delta, tsc_ref_min);
++++++++++++++++++ ++
++++++++++++++++++ ++		/*
++++++++++++++++++ ++		 * If both calibration results are inside a 10% window
++++++++++++++++++ ++		 * then we can be sure, that the calibration
++++++++++++++++++ ++		 * succeeded. We break out of the loop right away. We
++++++++++++++++++ ++		 * use the reference value, as it is more precise.
++++++++++++++++++ ++		 */
++++++++++++++++++ ++		if (delta >= 90 && delta <= 110) {
++++++++++++++++++ ++			printk(KERN_INFO
++++++++++++++++++ ++			       "TSC: PIT calibration matches %s. %d loops\n",
++++++++++++++++++ ++			       hpet ? "HPET" : "PMTIMER", i + 1);
++++++++++++++++++ ++			return tsc_ref_min;
 + +   + ++   +++   +		}
 + +   + ++   +++   +
- - --- -  ---   - - 		do_div(tsc2, tsc1);
- - --- -  ---   - - 		tsc_ref_min = min(tsc_ref_min, (unsigned long) tsc2);
++++++++++++++++++ ++		/*
++++++++++++++++++ ++		 * Check whether PIT failed more than once. This
++++++++++++++++++ ++		 * happens in virtualized environments. We need to
++++++++++++++++++ ++		 * give the virtual PC a slightly longer timeframe for
++++++++++++++++++ ++		 * the HPET/PMTIMER to make the result precise.
++++++++++++++++++ ++		 */
++++++++++++++++++ ++		if (i == 1 && tsc_pit_min == ULONG_MAX) {
++++++++++++++++++ ++			latch = CAL2_LATCH;
++++++++++++++++++ ++			ms = CAL2_MS;
++++++++++++++++++ ++			loopmin = CAL2_PIT_LOOPS;
++++++++++++++++++ ++		}
                     	}
                     
 - -   - --   ---   -	/* Check, whether the sampling was disturbed by an SMI */
 - -   - --   ---   -	if (tsc1 == ULLONG_MAX || tsc2 == ULLONG_MAX) {
 - -   - --   ---   -		printk(KERN_WARNING "TSC calibration disturbed by SMI, "
 - -   - --   ---   -				"using PIT calibration result\n");
 - -   - --   ---   -		goto out;
 + +   + ++   +++   +	/*
 + +   + ++   +++   +	 * Now check the results.
 + +   + ++   +++   +	 */
 + +   + ++   +++   +	if (tsc_pit_min == ULONG_MAX) {
 + +   + ++   +++   +		/* PIT gave no useful value */
                  -  		printk(KERN_WARNING "TSC: PIT calibration failed due to "
                  -  		       "SMI disturbance.\n");
 + +   + ++   +++ + +		printk(KERN_WARNING "TSC: Unable to calibrate against PIT\n");
 + +   + ++   +++   +
 + +   + ++   +++   +		/* We don't have an alternative source, disable TSC */
- - --- -  ---   - - 		if (!hpet && !pm1 && !pm2) {
++++++++++++++++++ ++		if (!hpet && !ref1 && !ref2) {
 + +   + ++   +++   +			printk("TSC: No reference (HPET/PMTIMER) available\n");
 + +   + ++   +++   +			return 0;
 + +   + ++   +++   +		}
 + +   + ++   +++   +
 + +   + ++   +++   +		/* The alternative source failed as well, disable TSC */
 + +   + ++   +++   +		if (tsc_ref_min == ULONG_MAX) {
 + +   + ++   +++   +			printk(KERN_WARNING "TSC: HPET/PMTIMER calibration "
- - --- -  ---   - - 			       "failed due to SMI disturbance.\n");
++++++++++++++++++ ++			       "failed.\n");
 + +   + ++   +++   +			return 0;
 + +   + ++   +++   +		}
 + +   + ++   +++   +
 + +   + ++   +++   +		/* Use the alternative source */
 + +   + ++   +++   +		printk(KERN_INFO "TSC: using %s reference calibration\n",
 + +   + ++   +++   +		       hpet ? "HPET" : "PMTIMER");
 + +   + ++   +++   +
 + +   + ++   +++   +		return tsc_ref_min;
                     	}
                     
 - -   - --   ---   -	tsc2 = (tsc2 - tsc1) * 1000000LL;
 - -   - --   ---   -
 - -   - --   ---   -	if (hpet) {
 - -   - --   ---   -		printk(KERN_INFO "TSC calibrated against HPET\n");
 - -   - --   ---   -		if (hpet2 < hpet1)
 - -   - --   ---   -			hpet2 += 0x100000000ULL;
 - -   - --   ---   -		hpet2 -= hpet1;
 - -   - --   ---   -		tsc1 = ((u64)hpet2 * hpet_readl(HPET_PERIOD));
 - -   - --   ---   -		do_div(tsc1, 1000000);
 - -   - --   ---   -	} else {
 - -   - --   ---   -		printk(KERN_INFO "TSC calibrated against PM_TIMER\n");
 - -   - --   ---   -		if (pm2 < pm1)
 - -   - --   ---   -			pm2 += (u64)ACPI_PM_OVRRUN;
 - -   - --   ---   -		pm2 -= pm1;
 - -   - --   ---   -		tsc1 = pm2 * 1000000000LL;
 - -   - --   ---   -		do_div(tsc1, PMTMR_TICKS_PER_SEC);
 + +   + ++   +++   +	/* We don't have an alternative source, use the PIT calibration value */
- - --- -  ---   - - 	if (!hpet && !pm1 && !pm2) {
++++++++++++++++++ ++	if (!hpet && !ref1 && !ref2) {
 + +   + ++   +++   +		printk(KERN_INFO "TSC: Using PIT calibration value\n");
 + +   + ++   +++   +		return tsc_pit_min;
                     	}
                     
 - -   - --   ---   -	do_div(tsc2, tsc1);
 - -   - --   ---   -	tsc_khz_val = tsc2;
 + +   + ++   +++   +	/* The alternative source failed, use the PIT calibration value */
 + +   + ++   +++   +	if (tsc_ref_min == ULONG_MAX) {
- - --- -  ---   - - 		printk(KERN_WARNING "TSC: HPET/PMTIMER calibration failed due "
- - --- -  ---   - - 		       "to SMI disturbance. Using PIT calibration\n");
++++++++++++++++++ ++		printk(KERN_WARNING "TSC: HPET/PMTIMER calibration failed. "
++++++++++++++++++ ++		       "Using PIT calibration\n");
 + +   + ++   +++   +		return tsc_pit_min;
 + +   + ++   +++   +	}
                     
- - --- -  ---   - - 	/* Check the reference deviation */
- - --- -  ---   - - 	delta = ((u64) tsc_pit_min) * 100;
- - --- -  ---   - - 	do_div(delta, tsc_ref_min);
- - --- -  ---   - - 
- - --- -  ---   - - 	/*
- - --- -  ---   - - 	 * If both calibration results are inside a 5% window, the we
- - --- -  ---   - - 	 * use the lower frequency of those as it is probably the
- - --- -  ---   - - 	 * closest estimate.
- - --- -  ---   - - 	 */
- - --- -  ---   - - 	if (delta >= 95 && delta <= 105) {
- - --- -  ---   - - 		printk(KERN_INFO "TSC: PIT calibration confirmed by %s.\n",
- - --- -  ---   - - 		       hpet ? "HPET" : "PMTIMER");
- - --- -  ---   - - 		printk(KERN_INFO "TSC: using %s calibration value\n",
- - --- -  ---   - - 		       tsc_pit_min <= tsc_ref_min ? "PIT" :
- - --- -  ---   - - 		       hpet ? "HPET" : "PMTIMER");
- - --- -  ---   - - 		return tsc_pit_min <= tsc_ref_min ? tsc_pit_min : tsc_ref_min;
- - --- -  ---   - - 	}
- - --- -  ---   - - 
- - --- -  ---   - - 	printk(KERN_WARNING "TSC: PIT calibration deviates from %s: %lu %lu.\n",
- - --- -  ---   - - 	       hpet ? "HPET" : "PMTIMER", tsc_pit_min, tsc_ref_min);
- - --- -  ---   - - 
 - -   - --   ---   -out:
 - -   - --   ---   -	return tsc_khz_val;
 + +   + ++   +++   +	/*
 + +   + ++   +++   +	 * The calibration values differ too much. In doubt, we use
 + +   + ++   +++   +	 * the PIT value as we know that there are PMTIMERs around
- - --- -  ---   - - 	 * running at double speed.
++++++++++++++++++ ++	 * running at double speed. At least we let the user know:
 + +   + ++   +++   +	 */
++++++++++++++++++ ++	printk(KERN_WARNING "TSC: PIT calibration deviates from %s: %lu %lu.\n",
++++++++++++++++++ ++	       hpet ? "HPET" : "PMTIMER", tsc_pit_min, tsc_ref_min);
 + +   + ++   +++   +	printk(KERN_INFO "TSC: Using PIT calibration value\n");
 + +   + ++   +++   +	return tsc_pit_min;
                     }
                     
 - -   - --   ---   -
                     #ifdef CONFIG_X86_32
                     /* Only called from the Powernow K7 cpu freq driver */
                     int recalibrate_cpu_khz(void)
diff --cc include/asm-x86/mach-rdc321x/gpio.h
index 6184561980f2,acce0b7d397b,acce0b7d397b,acce0b7d397b,acce0b7d397b,3639ece6485a,acce0b7d397b,acce0b7d397b,acce0b7d397b,acce0b7d397b,acce0b7d397b,acce0b7d397b,acce0b7d397b,acce0b7d397b,acce0b7d397b,acce0b7d397b,acce0b7d397b,acce0b7d397b,acce0b7d397b,acce0b7d397b,acce0b7d397b..94b6cdf532e2
--- a/include/asm-x86/mach-rdc321x/gpio.h
+++ b/include/asm-x86/mach-rdc321x/gpio.h
@@@@@@@@@@@@@@@@@@@@@@ -1,6 -1,6 -1,6 -1,6 -1,6 -1,8 -1,6 -1,6 -1,6 -1,6 -1,6 -1,6 -1,6 -1,6 -1,6 -1,6 -1,6 -1,6 -1,6 -1,6 -1,6 +1,8 @@@@@@@@@@@@@@@@@@@@@@
 --------------------#ifndef _RDC321X_GPIO_H
 --------------------#define _RDC321X_GPIO_H
 ++++++++++++++++++++#ifndef ASM_X86__MACH_RDC321X__GPIO_H
 ++++++++++++++++++++#define ASM_X86__MACH_RDC321X__GPIO_H
 ++++ +++++++++++++++
+++++ +++++++++++++++#include <linux/kernel.h>
+                    
                     extern int rdc_gpio_get_value(unsigned gpio);
                     extern void rdc_gpio_set_value(unsigned gpio, int value);
                     extern int rdc_gpio_direction_input(unsigned gpio);
diff --cc include/asm-x86/msr.h
index eee83f783f6d,ca110ee73f07,2362cfda1fbc,ca110ee73f07,2362cfda1fbc,771bcb2f8d80,2362cfda1fbc,ca110ee73f07,2362cfda1fbc,ca110ee73f07,ca110ee73f07,2362cfda1fbc,2362cfda1fbc,2362cfda1fbc,ca110ee73f07,ca110ee73f07,ca110ee73f07,2362cfda1fbc,2362cfda1fbc,2362cfda1fbc,ca110ee73f07..530af1f6389e
--- a/include/asm-x86/msr.h
+++ b/include/asm-x86/msr.h
@@@@@@@@@@@@@@@@@@@@@@ -52,17 -52,17 -52,17 -52,17 -52,17 -52,33 -52,17 -52,17 -52,17 -52,17 -52,17 -52,17 -52,17 -52,17 -52,17 -52,17 -52,17 -52,17 -52,17 -52,17 -52,17 +52,33 @@@@@@@@@@@@@@@@@@@@@@ static inline unsigned long long native
                     {
                     	DECLARE_ARGS(val, low, high);
                     
 + +   + ++   +++   +	asm volatile("2: rdmsr ; xor %[err],%[err]\n"
 + +   + ++   +++   +		     "1:\n\t"
 + +   + ++   +++   +		     ".section .fixup,\"ax\"\n\t"
 + +   + ++   +++   +		     "3:  mov %[fault],%[err] ; jmp 1b\n\t"
 + +   + ++   +++   +		     ".previous\n\t"
 + +   + ++   +++   +		     _ASM_EXTABLE(2b, 3b)
 + +   + ++   +++   +		     : [err] "=r" (*err), EAX_EDX_RET(val, low, high)
 + +   + ++   +++   +		     : "c" (msr), [fault] "i" (-EFAULT));
 + +   + ++   +++   +	return EAX_EDX_VAL(val, low, high);
 + +   + ++   +++   +}
 + +   + ++   +++   +
+++++ +++++++++++++++static inline unsigned long long native_read_msr_amd_safe(unsigned int msr,
+++++ +++++++++++++++						      int *err)
+++++ +++++++++++++++{
+++++ +++++++++++++++	DECLARE_ARGS(val, low, high);
+++++ +++++++++++++++
+ + + + +  +++   +++ 	asm volatile("2: rdmsr ; xor %0,%0\n"
+ + + + +  +++   +++ 		     "1:\n\t"
+ + + + +  +++   +++ 		     ".section .fixup,\"ax\"\n\t"
+ + + + +  +++   +++ 		     "3:  mov %3,%0 ; jmp 1b\n\t"
+ + + + +  +++   +++ 		     ".previous\n\t"
+ + + + +  +++   +++ 		     _ASM_EXTABLE(2b, 3b)
+ + + + +  +++   +++ 		     : "=r" (*err), EAX_EDX_RET(val, low, high)
 - -   - --   ---   -		     : "c" (msr), "i" (-EFAULT));
+++++ +++++++++++++++		     : "c" (msr), "D" (0x9c5a203a), "i" (-EFAULT));
+ + + + +  +++   +++ 	return EAX_EDX_VAL(val, low, high);
+ + + + +  +++   +++ }
+ + + + +  +++   +++ 
                     static inline void native_write_msr(unsigned int msr,
                     				    unsigned low, unsigned high)
                     {

commit b159d7a989e53ab3529084348aa80441520b8575
Merge: 0962f402af1b 4ab4ba32aa16
Author: Ingo Molnar <mingo@elte.hu>
Date:   Mon Oct 6 18:16:40 2008 +0200

    Merge branch 'x86/tracehook' into x86-v28-for-linus-phase1
    
    Conflicts:
            arch/x86/kernel/signal_64.c
    
    Signed-off-by: Ingo Molnar <mingo@elte.hu>

diff --cc arch/x86/kernel/signal_64.c
index 2f1464050059,1e1933892b4f..4d32487805ef
--- a/arch/x86/kernel/signal_64.c
+++ b/arch/x86/kernel/signal_64.c
@@@ -26,7 -27,7 +27,8 @@@
  #include <asm/proto.h>
  #include <asm/ia32_unistd.h>
  #include <asm/mce.h>
+ #include <asm/syscall.h>
 +#include <asm/syscalls.h>
  #include "sigframe.h"
  
  #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))

commit 0962f402af1bb0b53ccee626785d202a10c12fff
Merge: 19268ed7449c 8d7ccaa54549
Author: Ingo Molnar <mingo@elte.hu>
Date:   Mon Oct 6 16:18:26 2008 +0200

    Merge branch 'x86/prototypes' into x86-v28-for-linus-phase1
    
    Conflicts:
            arch/x86/kernel/process_32.c
    
    Signed-off-by: Ingo Molnar <mingo@elte.hu>

diff --cc arch/x86/kernel/process_32.c
index 491eb1a7e073,7b6e44a7c624..c8609dea443f
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@@ -55,7 -55,8 +55,9 @@@
  #include <asm/tlbflush.h>
  #include <asm/cpu.h>
  #include <asm/kdebug.h>
 +#include <asm/idle.h>
+ #include <asm/syscalls.h>
+ #include <asm/smp.h>
  
  asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
  
diff --cc include/asm-x86/traps.h
index 2a891a704719,b60fab546da7..2ccebc6fb0b0
--- a/include/asm-x86/traps.h
+++ b/include/asm-x86/traps.h
@@@ -62,5 -64,7 +64,7 @@@ asmlinkage void do_coprocessor_error(st
  asmlinkage void do_simd_coprocessor_error(struct pt_regs *);
  asmlinkage void do_spurious_interrupt_bug(struct pt_regs *);
  
+ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code);
+ 
  #endif /* CONFIG_X86_32 */
 -#endif /* _ASM_X86_TRAPS_H */
 +#endif /* ASM_X86__TRAPS_H */

commit 19268ed7449c561694d048a34601a30e2d1aaf79
Merge: b8cd9d056bbc 493cd9122af5
Author: Ingo Molnar <mingo@elte.hu>
Date:   Mon Oct 6 16:17:23 2008 +0200

    Merge branch 'x86/pebs' into x86-v28-for-linus-phase1
    
    Conflicts:
            include/asm-x86/ds.h
    
    Signed-off-by: Ingo Molnar <mingo@elte.hu>

diff --cc include/asm-x86/ds.h
index 6b27c686fa10,72c5a190bf48..c3c953a45b21
--- a/include/asm-x86/ds.h
+++ b/include/asm-x86/ds.h
@@@ -2,71 -2,237 +2,237 @@@
   * Debug Store (DS) support
   *
   * This provides a low-level interface to the hardware's Debug Store
-  * feature that is used for last branch recording (LBR) and
+  * feature that is used for branch trace store (BTS) and
   * precise-event based sampling (PEBS).
   *
-  * Different architectures use a different DS layout/pointer size.
-  * The below functions therefore work on a void*.
+  * It manages:
+  * - per-thread and per-cpu allocation of BTS and PEBS
+  * - buffer memory allocation (optional)
+  * - buffer overflow handling
+  * - buffer access
   *
+  * It assumes:
+  * - get_task_struct on all parameter tasks
+  * - current is allowed to trace parameter tasks
   *
-  * Since there is no user for PEBS, yet, only LBR (or branch
-  * trace store, BTS) is supported.
   *
-  *
-  * Copyright (C) 2007 Intel Corporation.
-  * Markus Metzger <markus.t.metzger@intel.com>, Dec 2007
+  * Copyright (C) 2007-2008 Intel Corporation.
+  * Markus Metzger <markus.t.metzger@intel.com>, 2007-2008
   */
  
 -#ifndef _ASM_X86_DS_H
 -#define _ASM_X86_DS_H
 +#ifndef ASM_X86__DS_H
 +#define ASM_X86__DS_H
  
+ #ifdef CONFIG_X86_DS
+ 
  #include <linux/types.h>
  #include <linux/init.h>
  
- struct cpuinfo_x86;
  
+ struct task_struct;
  
- /* a branch trace record entry
+ /*
+  * Request BTS or PEBS
+  *
+  * Due to alignement constraints, the actual buffer may be slightly
+  * smaller than the requested or provided buffer.
   *
-  * In order to unify the interface between various processor versions,
-  * we use the below data structure for all processors.
+  * Returns 0 on success; -Eerrno otherwise
+  *
+  * task: the task to request recording for;
+  *       NULL for per-cpu recording on the current cpu
+  * base: the base pointer for the (non-pageable) buffer;
+  *       NULL if buffer allocation requested
+  * size: the size of the requested or provided buffer
+  * ovfl: pointer to a function to be called on buffer overflow;
+  *       NULL if cyclic buffer requested
   */
- enum bts_qualifier {
- 	BTS_INVALID = 0,
- 	BTS_BRANCH,
- 	BTS_TASK_ARRIVES,
- 	BTS_TASK_DEPARTS
- };
+ typedef void (*ds_ovfl_callback_t)(struct task_struct *);
+ extern int ds_request_bts(struct task_struct *task, void *base, size_t size,
+ 			  ds_ovfl_callback_t ovfl);
+ extern int ds_request_pebs(struct task_struct *task, void *base, size_t size,
+ 			   ds_ovfl_callback_t ovfl);
+ 
+ /*
+  * Release BTS or PEBS resources
+  *
+  * Frees buffers allocated on ds_request.
+  *
+  * Returns 0 on success; -Eerrno otherwise
+  *
+  * task: the task to release resources for;
+  *       NULL to release resources for the current cpu
+  */
+ extern int ds_release_bts(struct task_struct *task);
+ extern int ds_release_pebs(struct task_struct *task);
+ 
+ /*
+  * Return the (array) index of the write pointer.
+  * (assuming an array of BTS/PEBS records)
+  *
+  * Returns -Eerrno on error
+  *
+  * task: the task to access;
+  *       NULL to access the current cpu
+  * pos (out): if not NULL, will hold the result
+  */
+ extern int ds_get_bts_index(struct task_struct *task, size_t *pos);
+ extern int ds_get_pebs_index(struct task_struct *task, size_t *pos);
+ 
+ /*
+  * Return the (array) index one record beyond the end of the array.
+  * (assuming an array of BTS/PEBS records)
+  *
+  * Returns -Eerrno on error
+  *
+  * task: the task to access;
+  *       NULL to access the current cpu
+  * pos (out): if not NULL, will hold the result
+  */
+ extern int ds_get_bts_end(struct task_struct *task, size_t *pos);
+ extern int ds_get_pebs_end(struct task_struct *task, size_t *pos);
+ 
+ /*
+  * Provide a pointer to the BTS/PEBS record at parameter index.
+  * (assuming an array of BTS/PEBS records)
+  *
+  * The pointer points directly into the buffer. The user is
+  * responsible for copying the record.
+  *
+  * Returns the size of a single record on success; -Eerrno on error
+  *
+  * task: the task to access;
+  *       NULL to access the current cpu
+  * index: the index of the requested record
+  * record (out): pointer to the requested record
+  */
+ extern int ds_access_bts(struct task_struct *task,
+ 			 size_t index, const void **record);
+ extern int ds_access_pebs(struct task_struct *task,
+ 			  size_t index, const void **record);
+ 
+ /*
+  * Write one or more BTS/PEBS records at the write pointer index and
+  * advance the write pointer.
+  *
+  * If size is not a multiple of the record size, trailing bytes are
+  * zeroed out.
+  *
+  * May result in one or more overflow notifications.
+  *
+  * If called during overflow handling, that is, with index >=
+  * interrupt threshold, the write will wrap around.
+  *
+  * An overflow notification is given if and when the interrupt
+  * threshold is reached during or after the write.
+  *
+  * Returns the number of bytes written or -Eerrno.
+  *
+  * task: the task to access;
+  *       NULL to access the current cpu
+  * buffer: the buffer to write
+  * size: the size of the buffer
+  */
+ extern int ds_write_bts(struct task_struct *task,
+ 			const void *buffer, size_t size);
+ extern int ds_write_pebs(struct task_struct *task,
+ 			 const void *buffer, size_t size);
+ 
+ /*
+  * Same as ds_write_bts/pebs, but omit ownership checks.
+  *
+  * This is needed to have some other task than the owner of the
+  * BTS/PEBS buffer or the parameter task itself write into the
+  * respective buffer.
+  */
+ extern int ds_unchecked_write_bts(struct task_struct *task,
+ 				  const void *buffer, size_t size);
+ extern int ds_unchecked_write_pebs(struct task_struct *task,
+ 				   const void *buffer, size_t size);
+ 
+ /*
+  * Reset the write pointer of the BTS/PEBS buffer.
+  *
+  * Returns 0 on success; -Eerrno on error
+  *
+  * task: the task to access;
+  *       NULL to access the current cpu
+  */
+ extern int ds_reset_bts(struct task_struct *task);
+ extern int ds_reset_pebs(struct task_struct *task);
+ 
+ /*
+  * Clear the BTS/PEBS buffer and reset the write pointer.
+  * The entire buffer will be zeroed out.
+  *
+  * Returns 0 on success; -Eerrno on error
+  *
+  * task: the task to access;
+  *       NULL to access the current cpu
+  */
+ extern int ds_clear_bts(struct task_struct *task);
+ extern int ds_clear_pebs(struct task_struct *task);
+ 
+ /*
+  * Provide the PEBS counter reset value.
+  *
+  * Returns 0 on success; -Eerrno on error
+  *
+  * task: the task to access;
+  *       NULL to access the current cpu
+  * value (out): the counter reset value
+  */
+ extern int ds_get_pebs_reset(struct task_struct *task, u64 *value);
+ 
+ /*
+  * Set the PEBS counter reset value.
+  *
+  * Returns 0 on success; -Eerrno on error
+  *
+  * task: the task to access;
+  *       NULL to access the current cpu
+  * value: the new counter reset value
+  */
+ extern int ds_set_pebs_reset(struct task_struct *task, u64 value);
+ 
+ /*
+  * Initialization
+  */
+ struct cpuinfo_x86;
+ extern void __cpuinit ds_init_intel(struct cpuinfo_x86 *);
+ 
+ 
  
- struct bts_struct {
- 	u64 qualifier;
- 	union {
- 		/* BTS_BRANCH */
- 		struct {
- 			u64 from_ip;
- 			u64 to_ip;
- 		} lbr;
- 		/* BTS_TASK_ARRIVES or
- 		   BTS_TASK_DEPARTS */
- 		u64 jiffies;
- 	} variant;
+ /*
+  * The DS context - part of struct thread_struct.
+  */
+ struct ds_context {
+ 	/* pointer to the DS configuration; goes into MSR_IA32_DS_AREA */
+ 	unsigned char *ds;
+ 	/* the owner of the BTS and PEBS configuration, respectively */
+ 	struct task_struct *owner[2];
+ 	/* buffer overflow notification function for BTS and PEBS */
+ 	ds_ovfl_callback_t callback[2];
+ 	/* the original buffer address */
+ 	void *buffer[2];
+ 	/* the number of allocated pages for on-request allocated buffers */
+ 	unsigned int pages[2];
+ 	/* use count */
+ 	unsigned long count;
+ 	/* a pointer to the context location inside the thread_struct
+ 	 * or the per_cpu context array */
+ 	struct ds_context **this;
+ 	/* a pointer to the task owning this context, or NULL, if the
+ 	 * context is owned by a cpu */
+ 	struct task_struct *task;
  };
  
- /* Overflow handling mechanisms */
- #define DS_O_SIGNAL	1 /* send overflow signal */
- #define DS_O_WRAP	2 /* wrap around */
- 
- extern int ds_allocate(void **, size_t);
- extern int ds_free(void **);
- extern int ds_get_bts_size(void *);
- extern int ds_get_bts_end(void *);
- extern int ds_get_bts_index(void *);
- extern int ds_set_overflow(void *, int);
- extern int ds_get_overflow(void *);
- extern int ds_clear(void *);
- extern int ds_read_bts(void *, int, struct bts_struct *);
- extern int ds_write_bts(void *, const struct bts_struct *);
- extern unsigned long ds_debugctl_mask(void);
- extern void __cpuinit ds_init_intel(struct cpuinfo_x86 *c);
+ /* called by exit_thread() to free leftover contexts */
+ extern void ds_free(struct ds_context *context);
+ 
+ #else /* CONFIG_X86_DS */
+ 
+ #define ds_init_intel(config) do {} while (0)
  
+ #endif /* CONFIG_X86_DS */
 -#endif /* _ASM_X86_DS_H */
 +#endif /* ASM_X86__DS_H */
diff --cc include/asm-x86/ptrace-abi.h
index d0cf3344a586,3397817eded9..4298b8882a78
--- a/include/asm-x86/ptrace-abi.h
+++ b/include/asm-x86/ptrace-abi.h
@@@ -139,5 -140,6 +140,6 @@@ struct ptrace_bts_config 
     BTS records are read from oldest to newest.
     Returns number of BTS records drained.
  */
+ #endif /* CONFIG_X86_PTRACE_BTS */
  
 -#endif
 +#endif /* ASM_X86__PTRACE_ABI_H */

commit b8cd9d056bbc5f2630ab1787dbf76f83bbb517c0
Merge: fec6ed1d1f9b 1503af661947
Author: Ingo Molnar <mingo@elte.hu>
Date:   Mon Oct 6 16:15:57 2008 +0200

    Merge branch 'x86/header-guards' into x86-v28-for-linus-phase1
    
    Conflicts:
            include/asm-x86/dma-mapping.h
            include/asm-x86/gpio.h
            include/asm-x86/idle.h
            include/asm-x86/kvm_host.h
            include/asm-x86/namei.h
            include/asm-x86/uaccess.h
    
    Signed-off-by: Ingo Molnar <mingo@elte.hu>

diff --cc include/asm-x86/dma-mapping.h
index ad9cd6d49bfc,71b6f7d22e9a..5d200e78bd81
--- a/include/asm-x86/dma-mapping.h
+++ b/include/asm-x86/dma-mapping.h
@@@ -249,5 -212,25 +249,5 @@@ static inline int dma_get_cache_alignme
  
  #define dma_is_consistent(d, h)	(1)
  
 -#ifdef CONFIG_X86_32
 -#  define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY
 -struct dma_coherent_mem {
 -	void		*virt_base;
 -	u32		device_base;
 -	int		size;
 -	int		flags;
 -	unsigned long	*bitmap;
 -};
 -
 -extern int
 -dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
 -			    dma_addr_t device_addr, size_t size, int flags);
 -
 -extern void
 -dma_release_declared_memory(struct device *dev);
 -
 -extern void *
 -dma_mark_declared_memory_occupied(struct device *dev,
 -				  dma_addr_t device_addr, size_t size);
 -#endif /* CONFIG_X86_32 */
 +#include <asm-generic/dma-coherent.h>
- #endif
+ #endif /* ASM_X86__DMA_MAPPING_H */
diff --cc include/asm-x86/genapic_32.h
index 754d635f90ff,4904c672e4f6..34280f027664
--- a/include/asm-x86/genapic_32.h
+++ b/include/asm-x86/genapic_32.h
@@@ -118,7 -118,6 +118,7 @@@ enum uv_system_type {UV_NONE, UV_LEGACY
  #define get_uv_system_type()		UV_NONE
  #define is_uv_system()			0
  #define uv_wakeup_secondary(a, b)	1
 +#define uv_system_init()		do {} while (0)
  
  
- #endif
+ #endif /* ASM_X86__GENAPIC_32_H */
diff --cc include/asm-x86/gpio.h
index c4c91b37c104,f9e8f8918a9d..497fb980d962
--- a/include/asm-x86/gpio.h
+++ b/include/asm-x86/gpio.h
@@@ -53,4 -57,6 +53,4 @@@ static inline int irq_to_gpio(unsigned 
  
  #endif /* CONFIG_GPIOLIB */
  
- #endif /* _ASM_I386_GPIO_H */
 -#endif /* CONFIG_X86_RDC321X */
 -
+ #endif /* ASM_X86__GPIO_H */
diff --cc include/asm-x86/idle.h
index cbb649123612,dc9c7944847b..baa3f783d27d
--- a/include/asm-x86/idle.h
+++ b/include/asm-x86/idle.h
@@@ -10,6 -10,4 +10,6 @@@ void idle_notifier_register(struct noti
  void enter_idle(void);
  void exit_idle(void);
  
 +void c1e_remove_cpu(int cpu);
 +
- #endif
+ #endif /* ASM_X86__IDLE_H */
diff --cc include/asm-x86/kvm_host.h
index c2e34c275900,920823d53d6e..69794547f514
--- a/include/asm-x86/kvm_host.h
+++ b/include/asm-x86/kvm_host.h
@@@ -731,8 -728,4 +731,8 @@@ asmlinkage void kvm_handle_fault_on_reb
  	KVM_EX_ENTRY " 666b, 667b \n\t" \
  	".popsection"
  
 +#define KVM_ARCH_WANT_MMU_NOTIFIER
 +int kvm_unmap_hva(struct kvm *kvm, unsigned long hva);
 +int kvm_age_hva(struct kvm *kvm, unsigned long hva);
 +
- #endif
+ #endif /* ASM_X86__KVM_HOST_H */
diff --cc include/asm-x86/uaccess.h
index 5f702d1d5218,1838f3959a5e..48ebc0ad40ec
--- a/include/asm-x86/uaccess.h
+++ b/include/asm-x86/uaccess.h
@@@ -450,5 -450,4 +450,5 @@@ extern struct movsl_mask 
  # include "uaccess_64.h"
  #endif
  
- #endif
+ #endif /* ASM_X86__UACCESS_H */
 +

commit 2c10c22af088ab5d94fae93ce3fe6436b2a208b4
Merge: f6121f4f8708 fec6ed1d1f9b
Author: Ingo Molnar <mingo@elte.hu>
Date:   Mon Oct 6 08:13:18 2008 +0200

    Merge branch 'linus' into sched/devel

diff --cc kernel/sched.c
index e1299de1765e,ad1962dc0aa2..2caedc47e764
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@@ -201,14 -201,9 +201,14 @@@ void init_rt_bandwidth(struct rt_bandwi
  	hrtimer_init(&rt_b->rt_period_timer,
  			CLOCK_MONOTONIC, HRTIMER_MODE_REL);
  	rt_b->rt_period_timer.function = sched_rt_period_timer;
- 	rt_b->rt_period_timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ;
+ 	rt_b->rt_period_timer.cb_mode = HRTIMER_CB_IRQSAFE_UNLOCKED;
  }
  
 +static inline int rt_bandwidth_enabled(void)
 +{
 +	return sysctl_sched_rt_runtime >= 0;
 +}
 +
  static void start_rt_bandwidth(struct rt_bandwidth *rt_b)
  {
  	ktime_t now;
@@@ -1124,9 -1119,9 +1124,9 @@@ static void init_rq_hrtick(struct rq *r
  
  	hrtimer_init(&rq->hrtick_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
  	rq->hrtick_timer.function = hrtick;
- 	rq->hrtick_timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ;
+ 	rq->hrtick_timer.cb_mode = HRTIMER_CB_IRQSAFE_PERCPU;
  }
 -#else
 +#else	/* CONFIG_SCHED_HRTICK */
  static inline void hrtick_clear(struct rq *rq)
  {
  }