aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel/process.c')
-rw-r--r--arch/i386/kernel/process.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 5f8cfa6b7940..ba243a4cc119 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -617,6 +617,33 @@ handle_io_bitmap(struct thread_struct *next, struct tss_struct *tss)
617} 617}
618 618
619/* 619/*
620 * This function selects if the context switch from prev to next
621 * has to tweak the TSC disable bit in the cr4.
622 */
623static inline void disable_tsc(struct task_struct *prev_p,
624 struct task_struct *next_p)
625{
626 struct thread_info *prev, *next;
627
628 /*
629 * gcc should eliminate the ->thread_info dereference if
630 * has_secure_computing returns 0 at compile time (SECCOMP=n).
631 */
632 prev = prev_p->thread_info;
633 next = next_p->thread_info;
634
635 if (has_secure_computing(prev) || has_secure_computing(next)) {
636 /* slow path here */
637 if (has_secure_computing(prev) &&
638 !has_secure_computing(next)) {
639 write_cr4(read_cr4() & ~X86_CR4_TSD);
640 } else if (!has_secure_computing(prev) &&
641 has_secure_computing(next))
642 write_cr4(read_cr4() | X86_CR4_TSD);
643 }
644}
645
646/*
620 * switch_to(x,yn) should switch tasks from x to y. 647 * switch_to(x,yn) should switch tasks from x to y.
621 * 648 *
622 * We fsave/fwait so that an exception goes off at the right time 649 * We fsave/fwait so that an exception goes off at the right time
@@ -695,6 +722,8 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas
695 if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) 722 if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr))
696 handle_io_bitmap(next, tss); 723 handle_io_bitmap(next, tss);
697 724
725 disable_tsc(prev_p, next_p);
726
698 return prev_p; 727 return prev_p;
699} 728}
700 729