Commit 5f185caa authored by Dmitry Safonov's avatar Dmitry Safonov Committed by Andrei Vagin

compel/x86: Add workaround on ptrace() bug on Skylake

On Skylake processors and kernel older than v4.14
    ptrace(PTRACE_GETREGSET, pid, NT_X86_XSTATE, iov)
may return not full xstate, ommiting FP part (that is XFEATURE_MASK_FP).
There is a patch which describes this bug:
  https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1318800.html
Anyway, it's fixed in v4.14 kernel by (what we believe with Andrey) this:
  https://patchwork.kernel.org/patch/9567939/

As we still support kernels from v3.10 and newer, we need to have a
workaround for this kernel bug on Skylake CPUs.

Big thanks to Shlomi for the reports, the effort and for providing an
Amazon VM to test this. I wish more bug reporters were like you.
Reported-by: 's avatarShlomi Matichin <shlomi@binaris.com>
Provided-test-env: Shlomi Matichin <shlomi@binaris.com>
Investigated-with: Andrei Vagin <avagin@virtuozzo.com>
Signed-off-by: 's avatarDmitry Safonov <dima@arista.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent 0e609f8c
...@@ -251,7 +251,7 @@ static int get_task_fpregs(pid_t pid, user_fpregs_struct_t *xsave) ...@@ -251,7 +251,7 @@ static int get_task_fpregs(pid_t pid, user_fpregs_struct_t *xsave)
} }
int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save, int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save,
void *arg, __maybe_unused unsigned long flags) void *arg, unsigned long flags)
{ {
user_fpregs_struct_t xsave = { }, *xs = NULL; user_fpregs_struct_t xsave = { }, *xs = NULL;
int ret = -1; int ret = -1;
...@@ -286,14 +286,24 @@ int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save, ...@@ -286,14 +286,24 @@ int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save,
pr_info("Dumping GP/FPU registers for %d\n", pid); pr_info("Dumping GP/FPU registers for %d\n", pid);
if (compel_cpu_has_feature(X86_FEATURE_OSXSAVE)) { if (!compel_cpu_has_feature(X86_FEATURE_OSXSAVE)) {
if (get_task_xsave(pid, &xsave)) ret = get_task_fpregs(pid, &xsave);
goto err; } else if (unlikely(flags & INFECT_X86_PTRACE_MXCSR_BUG)) {
/*
* get_task_fpregs() will fill FP state,
* get_task_xsave() will overwrite rightly sse/mmx/etc
*/
pr_warn("Skylake xsave fpu bug workaround used\n");
ret = get_task_fpregs(pid, &xsave);
if (!ret)
ret = get_task_xsave(pid, &xsave);
} else { } else {
if (get_task_fpregs(pid, &xsave)) ret = get_task_xsave(pid, &xsave);
goto err;
} }
if (ret)
goto err;
xs = &xsave; xs = &xsave;
out: out:
ret = save(arg, regs, xs); ret = save(arg, regs, xs);
......
...@@ -127,6 +127,8 @@ extern struct infect_ctx *compel_infect_ctx(struct parasite_ctl *); ...@@ -127,6 +127,8 @@ extern struct infect_ctx *compel_infect_ctx(struct parasite_ctl *);
#define INFECT_FAIL_CONNECT 0x2 /* make parasite connect() fail */ #define INFECT_FAIL_CONNECT 0x2 /* make parasite connect() fail */
#define INFECT_NO_BREAKPOINTS 0x4 /* no breakpoints in pie tracking */ #define INFECT_NO_BREAKPOINTS 0x4 /* no breakpoints in pie tracking */
#define INFECT_COMPATIBLE 0x8 /* can run parasite inside compat tasks */ #define INFECT_COMPATIBLE 0x8 /* can run parasite inside compat tasks */
/* Workaround for ptrace bug on Skylake CPUs with kernels older than v4.14 */
#define INFECT_X86_PTRACE_MXCSR_BUG 0x10
/* /*
* There are several ways to describe a blob to compel * There are several ways to describe a blob to compel
......
...@@ -511,6 +511,8 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item, ...@@ -511,6 +511,8 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
ictx->flags |= INFECT_NO_BREAKPOINTS; ictx->flags |= INFECT_NO_BREAKPOINTS;
if (kdat.compat_cr) if (kdat.compat_cr)
ictx->flags |= INFECT_COMPATIBLE; ictx->flags |= INFECT_COMPATIBLE;
if (kdat.x86_has_ptrace_fpu_xsave_bug)
ictx->flags |= INFECT_X86_PTRACE_MXCSR_BUG;
ictx->log_fd = log_get_fd(); ictx->log_fd = log_get_fd();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment