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")
145e9e0d8c

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 <dima@arista.com>
Signed-off-by: Alexander Mikhalitsyn <alexander.mikhalitsyn@virtuozzo.com>
This commit is contained in:
Alexander Mikhalitsyn 2022-05-10 13:37:09 +02:00 committed by Andrei Vagin
parent e30d18f435
commit c502d480f9

View file

@ -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);