From: Ingo Molnar <mingo@elte.hu>
Date: Mon, 6 Oct 2008 16:17:07 +0000 (+0200)
Subject: Merge branches 'x86/alternatives', 'x86/cleanups', 'x86/commandline', 'x86/crashdump... 
X-Git-Tag: firefly_0821_release~17842^2
X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=e496e3d645c93206faf61ff6005995ebd08cc39c;p=firefly-linux-kernel-4.4.55.git

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
---

e496e3d645c93206faf61ff6005995ebd08cc39c
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)
                     {