diff options
author | Dmitry Torokhov <dtor_core@ameritech.net> | 2006-04-29 07:11:23 +0200 |
---|---|---|
committer | Dmitry Torokhov <dtor_core@ameritech.net> | 2006-04-29 07:11:23 +0200 |
commit | 7b7e394185014e0f3bd8989cac937003f20ef9ce (patch) | |
tree | 3beda5f979bba0aa9822534e239cf1b45f3be69c /arch/x86_64/kernel/process.c | |
parent | Input: move input_device_id to mod_devicetable.h (diff) | |
parent | [PATCH] slab: fix crash on __drain_alien_cahce() during CPU Hotplug (diff) | |
download | linux-7b7e394185014e0f3bd8989cac937003f20ef9ce.tar.xz linux-7b7e394185014e0f3bd8989cac937003f20ef9ce.zip |
Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'arch/x86_64/kernel/process.c')
-rw-r--r-- | arch/x86_64/kernel/process.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index 70dd8e5c6889..fb903e65e079 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c @@ -575,8 +575,10 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) prev->userrsp = read_pda(oldrsp); write_pda(oldrsp, next->userrsp); write_pda(pcurrent, next_p); + /* This must be here to ensure both math_state_restore() and - kernel_fpu_begin() work consistently. */ + kernel_fpu_begin() work consistently. + And the AMD workaround requires it to be after DS reload. */ unlazy_fpu(prev_p); write_pda(kernelstack, task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET); @@ -781,10 +783,16 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) } case ARCH_GET_GS: { unsigned long base; + unsigned gsindex; if (task->thread.gsindex == GS_TLS_SEL) base = read_32bit_tls(task, GS_TLS); - else if (doit) - rdmsrl(MSR_KERNEL_GS_BASE, base); + else if (doit) { + asm("movl %%gs,%0" : "=r" (gsindex)); + if (gsindex) + rdmsrl(MSR_KERNEL_GS_BASE, base); + else + base = task->thread.gs; + } else base = task->thread.gs; ret = put_user(base, (unsigned long __user *)addr); |