Skip to content

Commit

Permalink
x86/process/64: Use FSGSBASE instructions on thread copy and ptrace
Browse files Browse the repository at this point in the history
When FSGSBASE is enabled, copying threads and reading fsbase and gsbase
using ptrace must read the actual values.

When copying a thread, use save_fsgs() and copy the saved values.  For
ptrace, the bases must be read from memory regardless of the selector if
FSGSBASE is enabled.

[ tglx: Invoke __rdgsbase_inactive() with interrupts disabled ]
[ luto: Massage changelog ]

Suggested-by: Andy Lutomirski <luto@kernel.org>
Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lkml.kernel.org/r/1557309753-24073-9-git-send-email-chang.seok.bae@intel.com
Link: https://lkml.kernel.org/r/20200528201402.1708239-8-sashal@kernel.org
  • Loading branch information
Chang S. Bae authored and Thomas Gleixner committed Jun 18, 2020
1 parent 6739034 commit 005f141
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 6 deletions.
10 changes: 6 additions & 4 deletions arch/x86/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,12 @@ int copy_thread_tls(unsigned long clone_flags, unsigned long sp,
memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));

#ifdef CONFIG_X86_64
savesegment(gs, p->thread.gsindex);
p->thread.gsbase = p->thread.gsindex ? 0 : current->thread.gsbase;
savesegment(fs, p->thread.fsindex);
p->thread.fsbase = p->thread.fsindex ? 0 : current->thread.fsbase;
current_save_fsgs();
p->thread.fsindex = current->thread.fsindex;
p->thread.fsbase = current->thread.fsbase;
p->thread.gsindex = current->thread.gsindex;
p->thread.gsbase = current->thread.gsbase;

savesegment(es, p->thread.es);
savesegment(ds, p->thread.ds);
#else
Expand Down
6 changes: 4 additions & 2 deletions arch/x86/kernel/process_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,8 @@ unsigned long x86_fsbase_read_task(struct task_struct *task)

if (task == current)
fsbase = x86_fsbase_read_cpu();
else if (task->thread.fsindex == 0)
else if (static_cpu_has(X86_FEATURE_FSGSBASE) ||
(task->thread.fsindex == 0))
fsbase = task->thread.fsbase;
else
fsbase = x86_fsgsbase_read_task(task, task->thread.fsindex);
Expand All @@ -440,7 +441,8 @@ unsigned long x86_gsbase_read_task(struct task_struct *task)

if (task == current)
gsbase = x86_gsbase_read_cpu_inactive();
else if (task->thread.gsindex == 0)
else if (static_cpu_has(X86_FEATURE_FSGSBASE) ||
(task->thread.gsindex == 0))
gsbase = task->thread.gsbase;
else
gsbase = x86_fsgsbase_read_task(task, task->thread.gsindex);
Expand Down

0 comments on commit 005f141

Please sign in to comment.