From c502d480f94231b4c8068ac90bbd7ab86612356e Mon Sep 17 00:00:00 2001 From: Alexander Mikhalitsyn Date: Tue, 10 May 2022 13:37:09 +0200 Subject: [PATCH] x86/compel/fault-inject: fixup mxcsr for PTRACE_SETFPREGS Error from: ./test/zdtm.py run -t zdtm/static/fpu00 --fault 134 -f h --norst (00.003111) Dumping GP/FPU registers for 56 (00.003121) Error (compel/arch/x86/src/lib/infect.c:310): Corrupting fpuregs for 56, seed 1651766595 (00.003125) Error (compel/arch/x86/src/lib/infect.c:314): Can't set FPU registers for 56: Invalid argument (00.003129) Error (compel/src/lib/infect.c:688): Can't obtain regs for thread 56 (00.003174) Error (criu/cr-dump.c:1564): Can't infect (pid: 56) with parasite See also: 145e9e0d8c6 ("x86/fpu: Fail ptrace() requests that try to set invalid MXCSR values") https://github.com/torvalds/linux/commit/145e9e0d8c6fada4a40f9fc65b34658077874d9c We decided to move from mxcsr cleaning up scheme and use mxcsr mask (0x0000ffbf) as kernel does. Thanks to Dmitry Safonov for pointing out. Tested-on: Intel(R) Xeon(R) CPU E3-1246 v3 @ 3.50GHz Reported-by: Mr. Jenkins Suggested-by: Dmitry Safonov Signed-off-by: Alexander Mikhalitsyn --- compel/arch/x86/src/lib/infect.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/compel/arch/x86/src/lib/infect.c b/compel/arch/x86/src/lib/infect.c index 98e2512e7..c0e7a544a 100644 --- a/compel/arch/x86/src/lib/infect.c +++ b/compel/arch/x86/src/lib/infect.c @@ -245,6 +245,19 @@ static int get_task_fpregs(pid_t pid, user_fpregs_struct_t *xsave) return 0; } +static inline void fixup_mxcsr(struct xsave_struct *xsave) +{ + /* + * Right now xsave->i387.mxcsr filled with the random garbage, + * let's make it valid by applying mask which allows all + * features, except the denormals-are-zero feature bit. + * + * See also fpu__init_system_mxcsr function: + * https://github.com/torvalds/linux/blob/8cb1ae19/arch/x86/kernel/fpu/init.c#L117 + */ + xsave->i387.mxcsr &= 0x0000ffbf; +} + /* See arch/x86/kernel/fpu/xstate.c */ static void validate_random_xstate(struct xsave_struct *xsave) { @@ -272,17 +285,6 @@ static void validate_random_xstate(struct xsave_struct *xsave) /* No reserved bits may be set */ memset(&hdr->reserved, 0, sizeof(hdr->reserved)); - - /* - * While using PTRACE_SETREGSET the kernel checks that - * "Reserved bits in MXCSR must be zero." - * if (mxcsr[0] & ~mxcsr_feature_mask) - * return -EINVAL; - * - * As the mxcsr_feature_mask depends on the CPU the easiest solution for - * this error injection test is to set mxcsr just to zero. - */ - xsave->i387.mxcsr = 0; } /* @@ -309,6 +311,8 @@ static int corrupt_extregs(pid_t pid) */ pr_err("Corrupting %s for %d, seed %u\n", use_xsave ? "xsave" : "fpuregs", pid, init_seed); + fixup_mxcsr(&ext_regs); + if (!use_xsave) { if (ptrace(PTRACE_SETFPREGS, pid, NULL, &ext_regs)) { pr_perror("Can't set FPU registers for %d", pid);