diff options
| -rw-r--r-- | arch/x86_64/kernel/process.c | 10 | 
1 files changed, 8 insertions, 2 deletions
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index 70dd8e5c6889..1c44b53cb15b 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c  | |||
| @@ -781,10 +781,16 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) | |||
| 781 | } | 781 | } | 
| 782 | case ARCH_GET_GS: { | 782 | case ARCH_GET_GS: { | 
| 783 | unsigned long base; | 783 | unsigned long base; | 
| 784 | unsigned gsindex; | ||
| 784 | if (task->thread.gsindex == GS_TLS_SEL) | 785 | if (task->thread.gsindex == GS_TLS_SEL) | 
| 785 | base = read_32bit_tls(task, GS_TLS); | 786 | base = read_32bit_tls(task, GS_TLS); | 
| 786 | else if (doit) | 787 | else if (doit) { | 
| 787 | rdmsrl(MSR_KERNEL_GS_BASE, base); | 788 | asm("movl %%gs,%0" : "=r" (gsindex)); | 
| 789 | if (gsindex) | ||
| 790 | rdmsrl(MSR_KERNEL_GS_BASE, base); | ||
| 791 | else | ||
| 792 | base = task->thread.gs; | ||
| 793 | } | ||
| 788 | else | 794 | else | 
| 789 | base = task->thread.gs; | 795 | base = task->thread.gs; | 
| 790 | ret = put_user(base, (unsigned long __user *)addr); | 796 | ret = put_user(base, (unsigned long __user *)addr); | 
