Re: [RFC PATCH v5 1/2] selftests/x86: sysret_rip: Handle syscall in a FRED system

H. Peter Anvin
2023-01-25T08:47:02Z

On 1/24/23 19:49, Ammar Faizi wrote:
> +
> + /*
> + * Test that:
> + *
> + * - "syscall" in a FRED system doesn't clobber %rcx and %r11.
> + * - "syscall" in a non-FRED system sets %rcx=%rip and %r11=%rflags.
> + */
> + ret = check_regs_result(r11, rcx, rbx);
> + assert(ret != REGS_ERROR);
> +
> + /*
> + * Test that we don't get a mix of REGS_SAVED and REGS_SYSRET.
> + * It needs at least calling do_syscall() twice to assert.
> + */
> + if (regs_ok_state == REGS_UNDEFINED) {
> + /*
> + * First time calling do_syscall().
> + */
> + regs_ok_state = ret;
> + } else {
> + assert(regs_ok_state == ret);
> + }
> +

[...]

> + ret = check_regs_result(ctx->uc_mcontext.gregs[REG_R11],
> + ctx->uc_mcontext.gregs[REG_RCX],
> + ctx->uc_mcontext.gregs[REG_RBX]);
> +
> + assert(ret != REGS_ERROR);
> +

This instance, too, needs to be checked against regs_ok_result. It would
make most sense to move that handling, and the assert() into
check_regs_result() or into a separate function around it.

> /* Set IP and CX to match so that SYSRET can happen. */
> ctx->uc_mcontext.gregs[REG_RIP] = rip;
> ctx->uc_mcontext.gregs[REG_RCX] = rip;

It would be interesting to have the syscall handler try both with and
without this (so it would end up doing both IRET and SYSCALL on legacy.)
Perhaps SIGUSR1 versus SIGUSR2...

-hpa