|
@@ -616,6 +616,33 @@ handle_io_bitmap(struct thread_struct *next, struct tss_struct *tss)
|
|
|
tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * This function selects if the context switch from prev to next
|
|
|
+ * has to tweak the TSC disable bit in the cr4.
|
|
|
+ */
|
|
|
+static inline void disable_tsc(struct task_struct *prev_p,
|
|
|
+ struct task_struct *next_p)
|
|
|
+{
|
|
|
+ struct thread_info *prev, *next;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * gcc should eliminate the ->thread_info dereference if
|
|
|
+ * has_secure_computing returns 0 at compile time (SECCOMP=n).
|
|
|
+ */
|
|
|
+ prev = prev_p->thread_info;
|
|
|
+ next = next_p->thread_info;
|
|
|
+
|
|
|
+ if (has_secure_computing(prev) || has_secure_computing(next)) {
|
|
|
+ /* slow path here */
|
|
|
+ if (has_secure_computing(prev) &&
|
|
|
+ !has_secure_computing(next)) {
|
|
|
+ write_cr4(read_cr4() & ~X86_CR4_TSD);
|
|
|
+ } else if (!has_secure_computing(prev) &&
|
|
|
+ has_secure_computing(next))
|
|
|
+ write_cr4(read_cr4() | X86_CR4_TSD);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* switch_to(x,yn) should switch tasks from x to y.
|
|
|
*
|
|
@@ -695,6 +722,8 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas
|
|
|
if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr))
|
|
|
handle_io_bitmap(next, tss);
|
|
|
|
|
|
+ disable_tsc(prev_p, next_p);
|
|
|
+
|
|
|
return prev_p;
|
|
|
}
|
|
|
|