From: "Chang S. Bae" <chang.seok.bae@intel.com>
To: Thomas Gleixner <tglx@linutronix.de>,
Andy Lutomirski <luto@kernel.org>,
"H . Peter Anvin" <hpa@zytor.com>, Ingo Molnar <mingo@kernel.org>
Cc: Andi Kleen <ak@linux.intel.com>,
Dave Hansen <dave.hansen@linux.intel.com>,
Markus T Metzger <markus.t.metzger@intel.com>,
Ravi Shankar <ravi.v.shankar@intel.com>,
"Chang S . Bae" <chang.seok.bae@intel.com>,
LKML <linux-kernel@vger.kernel.org>
Subject: [RESEND PATCH V5 3/8] x86/fsgsbase/64: Make ptrace use FS/GS base helpers
Date: Thu, 23 Aug 2018 09:44:33 -0700 [thread overview]
Message-ID: <1535042678-31366-4-git-send-email-chang.seok.bae@intel.com> (raw)
In-Reply-To: <1535042678-31366-1-git-send-email-chang.seok.bae@intel.com>
The FS/GS base helper functions are used on ptrace APIs
(PTRACE_ARCH_PRCTL, PTRACE_SETREG, PTRACE_GETREG, etc).
The FS/GS-update mechanism is now a bit organized.
Based-on-code-from: Andy Lutomirski <luto@kernel.org>
Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
---
arch/x86/include/asm/fsgsbase.h | 2 --
arch/x86/kernel/process_64.c | 48 +++++++++--------------------------------
arch/x86/kernel/ptrace.c | 25 +++++++--------------
3 files changed, 18 insertions(+), 57 deletions(-)
diff --git a/arch/x86/include/asm/fsgsbase.h b/arch/x86/include/asm/fsgsbase.h
index 9dce8c0..f00a8a6 100644
--- a/arch/x86/include/asm/fsgsbase.h
+++ b/arch/x86/include/asm/fsgsbase.h
@@ -8,8 +8,6 @@
#include <asm/msr-index.h>
-unsigned long task_seg_base(struct task_struct *task, unsigned short selector);
-
/*
* Read/write a task's fsbase or gsbase. This returns the value that
* the FS/GS base would have (if the task were to be resumed). These
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index ec76796..bf0bd5c 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -279,7 +279,8 @@ static __always_inline void load_seg_legacy(unsigned short prev_index,
}
}
-unsigned long task_seg_base(struct task_struct *task, unsigned short selector)
+static unsigned long task_seg_base(struct task_struct *task,
+ unsigned short selector)
{
unsigned short idx = selector >> 3;
unsigned long base;
@@ -741,54 +742,25 @@ static long prctl_map_vdso(const struct vdso_image *image, unsigned long addr)
long do_arch_prctl_64(struct task_struct *task, int option, unsigned long arg2)
{
int ret = 0;
- int doit = task == current;
- int cpu;
switch (option) {
- case ARCH_SET_GS:
- if (arg2 >= TASK_SIZE_MAX)
- return -EPERM;
- cpu = get_cpu();
- task->thread.gsindex = 0;
- task->thread.gsbase = arg2;
- if (doit) {
- load_gs_index(0);
- ret = wrmsrl_safe(MSR_KERNEL_GS_BASE, arg2);
- }
- put_cpu();
+ case ARCH_SET_GS: {
+ ret = write_task_gsbase(task, arg2);
break;
- case ARCH_SET_FS:
- /* Not strictly needed for fs, but do it for symmetry
- with gs */
- if (arg2 >= TASK_SIZE_MAX)
- return -EPERM;
- cpu = get_cpu();
- task->thread.fsindex = 0;
- task->thread.fsbase = arg2;
- if (doit) {
- /* set the selector to 0 to not confuse __switch_to */
- loadsegment(fs, 0);
- ret = wrmsrl_safe(MSR_FS_BASE, arg2);
- }
- put_cpu();
+ }
+ case ARCH_SET_FS: {
+ ret = write_task_fsbase(task, arg2);
break;
+ }
case ARCH_GET_FS: {
- unsigned long base;
+ unsigned long base = read_task_fsbase(task);
- if (doit)
- rdmsrl(MSR_FS_BASE, base);
- else
- base = task->thread.fsbase;
ret = put_user(base, (unsigned long __user *)arg2);
break;
}
case ARCH_GET_GS: {
- unsigned long base;
+ unsigned long base = read_task_gsbase(task);
- if (doit)
- rdmsrl(MSR_KERNEL_GS_BASE, base);
- else
- base = task->thread.gsbase;
ret = put_user(base, (unsigned long __user *)arg2);
break;
}
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 7be53f9..d41d605 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -397,12 +397,11 @@ static int putreg(struct task_struct *child,
if (value >= TASK_SIZE_MAX)
return -EIO;
/*
- * When changing the segment base, use do_arch_prctl_64
- * to set either thread.fs or thread.fsindex and the
- * corresponding GDT slot.
+ * When changing the FS base, use the same
+ * mechanism as for do_arch_prctl_64.
*/
if (child->thread.fsbase != value)
- return do_arch_prctl_64(child, ARCH_SET_FS, value);
+ return write_task_fsbase(child, value);
return 0;
case offsetof(struct user_regs_struct,gs_base):
/*
@@ -411,7 +410,7 @@ static int putreg(struct task_struct *child,
if (value >= TASK_SIZE_MAX)
return -EIO;
if (child->thread.gsbase != value)
- return do_arch_prctl_64(child, ARCH_SET_GS, value);
+ return write_task_gsbase(child, value);
return 0;
#endif
}
@@ -435,18 +434,10 @@ static unsigned long getreg(struct task_struct *task, unsigned long offset)
return get_flags(task);
#ifdef CONFIG_X86_64
- case offsetof(struct user_regs_struct, fs_base): {
- if (task->thread.fsindex == 0)
- return task->thread.fsbase;
- else
- return task_seg_base(task, task->thread.fsindex);
- }
- case offsetof(struct user_regs_struct, gs_base): {
- if (task->thread.gsindex == 0)
- return task->thread.gsbase;
- else
- return task_seg_base(task, task->thread.gsindex);
- }
+ case offsetof(struct user_regs_struct, fs_base):
+ return read_task_fsbase(task);
+ case offsetof(struct user_regs_struct, gs_base):
+ return read_task_gsbase(task);
#endif
}
--
2.7.4
next prev parent reply other threads:[~2018-08-23 16:46 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-08-23 16:44 [RESEND PATCH V5 0/8] x86: infrastructure to enable FSGSBASE Chang S. Bae
2018-08-23 16:44 ` [RESEND PATCH V5 1/8] x86/arch_prctl/64: Make ptrace read FS/GS base accurately Chang S. Bae
2018-08-23 16:44 ` [RESEND PATCH V5 2/8] x86/fsgsbase/64: Introduce FS/GS base helper functions Chang S. Bae
2018-08-23 16:44 ` Chang S. Bae [this message]
2018-08-23 16:44 ` [RESEND PATCH V5 4/8] x86/fsgsbase/64: Use FS/GS base helpers in core dump Chang S. Bae
2018-08-23 16:44 ` [RESEND PATCH V5 5/8] x86/fsgsbase/64: Factor out load FS/GS segments from __switch_to Chang S. Bae
2018-08-23 16:44 ` [RESEND PATCH V5 6/8] x86/segments/64: Rename PER_CPU segment to CPU_NUMBER Chang S. Bae
2018-08-23 16:44 ` [RESEND PATCH V5 7/8] x86/vdso: Introduce helper functions for CPU and node number Chang S. Bae
2018-08-23 16:44 ` [RESEND PATCH V5 8/8] x86/vdso: Move out the CPU initialization Chang S. Bae
2018-09-14 9:27 ` [RESEND PATCH V5 0/8] x86: infrastructure to enable FSGSBASE Ingo Molnar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1535042678-31366-4-git-send-email-chang.seok.bae@intel.com \
--to=chang.seok.bae@intel.com \
--cc=ak@linux.intel.com \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@kernel.org \
--cc=markus.t.metzger@intel.com \
--cc=mingo@kernel.org \
--cc=ravi.v.shankar@intel.com \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®