|
@@ -36,6 +36,7 @@
|
|
|
#include <linux/personality.h>
|
|
|
#include <linux/tick.h>
|
|
|
#include <linux/percpu.h>
|
|
|
+#include <linux/prctl.h>
|
|
|
|
|
|
#include <asm/uaccess.h>
|
|
|
#include <asm/pgtable.h>
|
|
@@ -523,11 +524,11 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(start_thread);
|
|
|
|
|
|
-#ifdef CONFIG_SECCOMP
|
|
|
static void hard_disable_TSC(void)
|
|
|
{
|
|
|
write_cr4(read_cr4() | X86_CR4_TSD);
|
|
|
}
|
|
|
+
|
|
|
void disable_TSC(void)
|
|
|
{
|
|
|
preempt_disable();
|
|
@@ -539,11 +540,47 @@ void disable_TSC(void)
|
|
|
hard_disable_TSC();
|
|
|
preempt_enable();
|
|
|
}
|
|
|
+
|
|
|
static void hard_enable_TSC(void)
|
|
|
{
|
|
|
write_cr4(read_cr4() & ~X86_CR4_TSD);
|
|
|
}
|
|
|
-#endif /* CONFIG_SECCOMP */
|
|
|
+
|
|
|
+void enable_TSC(void)
|
|
|
+{
|
|
|
+ preempt_disable();
|
|
|
+ if (test_and_clear_thread_flag(TIF_NOTSC))
|
|
|
+ /*
|
|
|
+ * Must flip the CPU state synchronously with
|
|
|
+ * TIF_NOTSC in the current running context.
|
|
|
+ */
|
|
|
+ hard_enable_TSC();
|
|
|
+ preempt_enable();
|
|
|
+}
|
|
|
+
|
|
|
+int get_tsc_mode(unsigned long adr)
|
|
|
+{
|
|
|
+ unsigned int val;
|
|
|
+
|
|
|
+ if (test_thread_flag(TIF_NOTSC))
|
|
|
+ val = PR_TSC_SIGSEGV;
|
|
|
+ else
|
|
|
+ val = PR_TSC_ENABLE;
|
|
|
+
|
|
|
+ return put_user(val, (unsigned int __user *)adr);
|
|
|
+}
|
|
|
+
|
|
|
+int set_tsc_mode(unsigned int val)
|
|
|
+{
|
|
|
+ if (val == PR_TSC_SIGSEGV)
|
|
|
+ disable_TSC();
|
|
|
+ else if (val == PR_TSC_ENABLE)
|
|
|
+ enable_TSC();
|
|
|
+ else
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
|
|
|
static noinline void
|
|
|
__switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
|
|
@@ -577,7 +614,6 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
|
|
|
set_debugreg(next->debugreg7, 7);
|
|
|
}
|
|
|
|
|
|
-#ifdef CONFIG_SECCOMP
|
|
|
if (test_tsk_thread_flag(prev_p, TIF_NOTSC) ^
|
|
|
test_tsk_thread_flag(next_p, TIF_NOTSC)) {
|
|
|
/* prev and next are different */
|
|
@@ -586,7 +622,6 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
|
|
|
else
|
|
|
hard_enable_TSC();
|
|
|
}
|
|
|
-#endif
|
|
|
|
|
|
#ifdef X86_BTS
|
|
|
if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS))
|