Re: [PATCH] selftests/x86: Fix sysret_rip assertion failure on FRED systems
From: H. Peter Anvin
Date: Tue Mar 24 2026 - 11:13:45 EST
On March 24, 2026 4:08:56 AM PDT, David Laight <david.laight.linux@xxxxxxxxx> wrote:
>On Fri, 20 Mar 2026 14:33:01 +0800
>Yi Lai <yi1.lai@xxxxxxxxx> wrote:
>
>> The existing 'sysret_rip' selftest asserts that 'regs->r11 ==
>> regs->flags'. This check relies on the behavior of the SYSCALL
>> instruction on legacy x86_64, which saves 'RFLAGS' into 'R11'.
>>
>> However, on systems with FRED (Flexible Return and Event Delivery)
>> enabled, instead of using registers, all state is saved onto the stack.
>> Consequently, 'R11' retains its userspace value, causing the assertion
>> to fail.
>>
>> Fix this by detecting FRED support via CPUID (Leaf 0x7, Subleaf 0x1, EAX
>> bit 17) and skipping the register assertion if FRED is present.
>
>For the selftest can't you just allow for R11 being unchanged?
>That would be much simpler.
>It isn't as though the test is doing much more than checking that
>R11 is corrupted by being overwritten by EFLAGS.
>
> David
>
>>
>> Signed-off-by: Yi Lai <yi1.lai@xxxxxxxxx>
>> ---
>> tools/testing/selftests/x86/sysret_rip.c | 16 +++++++++++++---
>> 1 file changed, 13 insertions(+), 3 deletions(-)
>>
>> diff --git a/tools/testing/selftests/x86/sysret_rip.c b/tools/testing/selftests/x86/sysret_rip.c
>> index 2e423a335e1c..0228d6174d5b 100644
>> --- a/tools/testing/selftests/x86/sysret_rip.c
>> +++ b/tools/testing/selftests/x86/sysret_rip.c
>> @@ -21,6 +21,7 @@
>> #include <sys/user.h>
>> #include <sys/mman.h>
>> #include <assert.h>
>> +#include <cpuid.h>
>>
>> #include "helpers.h"
>>
>> @@ -64,9 +65,18 @@ static void sigusr1(int sig, siginfo_t *info, void *ctx_void)
>> ctx->uc_mcontext.gregs[REG_RIP] = rip;
>> ctx->uc_mcontext.gregs[REG_RCX] = rip;
>>
>> - /* R11 and EFLAGS should already match. */
>> - assert(ctx->uc_mcontext.gregs[REG_EFL] ==
>> - ctx->uc_mcontext.gregs[REG_R11]);
>> + /*
>> + * SYSCALL works differently on FRED, it does not save RIP and RFLAGS
>> + * to RCX and R11.
>> + */
>> + unsigned int eax, ebx, ecx, edx;
>> +
>> + __cpuid_count(0x7, 0x1, eax, ebx, ecx, edx);
>> + if (!(eax & (1 << 17))) {
>> + /* R11 and EFLAGS should already match. */
>> + assert(ctx->uc_mcontext.gregs[REG_EFL] ==
>> + ctx->uc_mcontext.gregs[REG_R11]);
>> + }
>>
>> sethandler(SIGSEGV, sigsegv_for_sigreturn_test, SA_RESETHAND);
>> }
>
I thought we already made it do that a while ago...