From: Andrea Arcangeli <andrea@cpushare.com>

I believe at least for seccomp it's worth to turn off the tsc, not just for
HT but for the L2 cache too.  So it's up to you, either you turn it off
completely (which isn't very nice IMHO) or I recommend to apply this below
patch.

This has been tested successfully on x86-64 against current cogito
repository (i686 compiles so I didn't bother testing ;).  People selling
the cpu through cpushare may appreciate this bit for a peace of mind. 

There's no way to get any timing info anymore with this applied
(gettimeofday is forbidden of course).  The seccomp environment is
completely deterministic so it can't be allowed to get timing info, it has
to be deterministic so in the future I can enable a computing mode that
does a parallel computing for each task with server side transparent
checkpointing and verification that the output is the same from all the 2/3
seller computers for each task, without the buyer even noticing (for now
the verification is left to the buyer client side and there's no
checkpointing, since that would require more kernel changes to track the
dirty bits but it'll be easy to extend once the basic mode is finished).

Signed-off-by: Andrea Arcangeli <andrea@cpushare.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 arch/i386/kernel/process.c   |   21 +++++++++++++++++++++
 arch/x86_64/kernel/process.c |   21 +++++++++++++++++++++
 include/linux/seccomp.h      |    6 ++++++
 3 files changed, 48 insertions(+)

diff -puN arch/i386/kernel/process.c~seccomp-disable-tsc-for-seccomp-enabled-tasks arch/i386/kernel/process.c
--- 25/arch/i386/kernel/process.c~seccomp-disable-tsc-for-seccomp-enabled-tasks	2005-05-25 00:53:08.000000000 -0700
+++ 25-akpm/arch/i386/kernel/process.c	2005-05-25 00:53:08.000000000 -0700
@@ -616,6 +616,25 @@ handle_io_bitmap(struct thread_struct *n
 }
 
 /*
+ * This function selects if the context switch from prev to next
+ * has to tweak the TSC disable bit in the cr4.
+ */
+static void disable_tsc(struct thread_info *prev,
+			struct thread_info *next)
+{
+	if (unlikely(has_secure_computing(prev) ||
+		     has_secure_computing(next))) {
+		/* slow path here */
+		if (has_secure_computing(prev) &&
+		    !has_secure_computing(next)) {
+			clear_in_cr4(X86_CR4_TSD);
+		} else if (!has_secure_computing(prev) &&
+			   has_secure_computing(next))
+			set_in_cr4(X86_CR4_TSD);
+	}
+}
+
+/*
  *	switch_to(x,yn) should switch tasks from x to y.
  *
  * We fsave/fwait so that an exception goes off at the right time
@@ -694,6 +713,8 @@ struct task_struct fastcall * __switch_t
 	if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr))
 		handle_io_bitmap(next, tss);
 
+	disable_tsc(prev_p->thread_info, next_p->thread_info);
+
 	return prev_p;
 }
 
diff -puN arch/x86_64/kernel/process.c~seccomp-disable-tsc-for-seccomp-enabled-tasks arch/x86_64/kernel/process.c
--- 25/arch/x86_64/kernel/process.c~seccomp-disable-tsc-for-seccomp-enabled-tasks	2005-05-25 00:53:08.000000000 -0700
+++ 25-akpm/arch/x86_64/kernel/process.c	2005-05-25 00:53:08.000000000 -0700
@@ -439,6 +439,25 @@ out:
 }
 
 /*
+ * This function selects if the context switch from prev to next
+ * has to tweak the TSC disable bit in the cr4.
+ */
+static void disable_tsc(struct thread_info *prev,
+			struct thread_info *next)
+{
+	if (unlikely(has_secure_computing(prev) ||
+		     has_secure_computing(next))) {
+		/* slow path here */
+		if (has_secure_computing(prev) &&
+		    !has_secure_computing(next)) {
+			clear_in_cr4(X86_CR4_TSD);
+		} else if (!has_secure_computing(prev) &&
+			   has_secure_computing(next))
+			set_in_cr4(X86_CR4_TSD);
+	}
+}
+
+/*
  * This special macro can be used to load a debugging register
  */
 #define loaddebug(thread,r) set_debug(thread->debugreg ## r, r)
@@ -556,6 +575,8 @@ struct task_struct *__switch_to(struct t
 		}
 	}
 
+	disable_tsc(prev_p->thread_info, next_p->thread_info);
+
 	return prev_p;
 }
 
diff -puN include/linux/seccomp.h~seccomp-disable-tsc-for-seccomp-enabled-tasks include/linux/seccomp.h
--- 25/include/linux/seccomp.h~seccomp-disable-tsc-for-seccomp-enabled-tasks	2005-05-25 00:53:08.000000000 -0700
+++ 25-akpm/include/linux/seccomp.h	2005-05-25 00:53:08.000000000 -0700
@@ -19,6 +19,11 @@ static inline void secure_computing(int 
 		__secure_computing(this_syscall);
 }
 
+static inline int has_secure_computing(struct thread_info *ti)
+{
+	return unlikely(test_ti_thread_flag(ti, TIF_SECCOMP));
+}
+
 #else /* CONFIG_SECCOMP */
 
 #if (__GNUC__ > 2)
@@ -28,6 +33,7 @@ static inline void secure_computing(int 
 #endif
 
 #define secure_computing(x) do { } while (0)
+#define has_secure_computing(x) 0
 
 #endif /* CONFIG_SECCOMP */
 
_