diff options
| author | Jeff Garzik <jgarzik@pobox.com> | 2005-06-27 22:50:10 -0400 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@pobox.com> | 2005-06-27 22:50:10 -0400 |
| commit | aa8f6dfd355021b4dd8b74b0588fd6fd8f21b79f (patch) | |
| tree | 57ca3e27227695acbd97408eabb0f967726c3b51 /arch/i386/kernel/process.c | |
| parent | f45727d52d1581e9ff4df9d1a12a60789ad2d1eb (diff) | |
| parent | 245ac8738b0b840552d56b842e70e750d65911cc (diff) | |
Merge /spare/repo/netdev-2.6 branch 'ieee80211'
Diffstat (limited to 'arch/i386/kernel/process.c')
| -rw-r--r-- | arch/i386/kernel/process.c | 29 |
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) } /* + * 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. * * 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 if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) handle_io_bitmap(next, tss); + disable_tsc(prev_p, next_p); + return prev_p; } |
