Skip to content

Commit cced0b2

Browse files
amlutoKAGA-KOKO
authored andcommitted
selftests/x86: Consolidate and fix get/set_eflags() helpers
There are several copies of get_eflags() and set_eflags() and they all are buggy. Consolidate them and fix them. The fixes are: Add memory clobbers. These are probably unnecessary but they make sure that the compiler doesn't move something past one of these calls when it shouldn't. Respect the redzone on x86_64. There has no failure been observed related to this, but it's definitely a bug. Signed-off-by: Andy Lutomirski <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lkml.kernel.org/r/982ce58ae8dea2f1e57093ee894760e35267e751.1593191971.git.luto@kernel.org
1 parent a61fa27 commit cced0b2

File tree

7 files changed

+51
-90
lines changed

7 files changed

+51
-90
lines changed

tools/testing/selftests/x86/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,10 @@ all_64: $(BINARIES_64)
7070

7171
EXTRA_CLEAN := $(BINARIES_32) $(BINARIES_64)
7272

73-
$(BINARIES_32): $(OUTPUT)/%_32: %.c
73+
$(BINARIES_32): $(OUTPUT)/%_32: %.c helpers.h
7474
$(CC) -m32 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl -lm
7575

76-
$(BINARIES_64): $(OUTPUT)/%_64: %.c
76+
$(BINARIES_64): $(OUTPUT)/%_64: %.c helpers.h
7777
$(CC) -m64 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl
7878

7979
# x86_64 users should be encouraged to install 32-bit libraries

tools/testing/selftests/x86/helpers.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
#ifndef __SELFTESTS_X86_HELPERS_H
3+
#define __SELFTESTS_X86_HELPERS_H
4+
5+
#include <asm/processor-flags.h>
6+
7+
static inline unsigned long get_eflags(void)
8+
{
9+
unsigned long eflags;
10+
11+
asm volatile (
12+
#ifdef __x86_64__
13+
"subq $128, %%rsp\n\t"
14+
"pushfq\n\t"
15+
"popq %0\n\t"
16+
"addq $128, %%rsp"
17+
#else
18+
"pushfl\n\t"
19+
"popl %0"
20+
#endif
21+
: "=r" (eflags) :: "memory");
22+
23+
return eflags;
24+
}
25+
26+
static inline void set_eflags(unsigned long eflags)
27+
{
28+
asm volatile (
29+
#ifdef __x86_64__
30+
"subq $128, %%rsp\n\t"
31+
"pushq %0\n\t"
32+
"popfq\n\t"
33+
"addq $128, %%rsp"
34+
#else
35+
"pushl %0\n\t"
36+
"popfl"
37+
#endif
38+
:: "r" (eflags) : "flags", "memory");
39+
}
40+
41+
#endif /* __SELFTESTS_X86_HELPERS_H */

tools/testing/selftests/x86/single_step_syscall.c

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#include <sys/ptrace.h>
3232
#include <sys/user.h>
3333

34+
#include "helpers.h"
35+
3436
static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
3537
int flags)
3638
{
@@ -67,21 +69,6 @@ static unsigned char altstack_data[SIGSTKSZ];
6769
# define INT80_CLOBBERS
6870
#endif
6971

70-
static unsigned long get_eflags(void)
71-
{
72-
unsigned long eflags;
73-
asm volatile ("pushf" WIDTH "\n\tpop" WIDTH " %0" : "=rm" (eflags));
74-
return eflags;
75-
}
76-
77-
static void set_eflags(unsigned long eflags)
78-
{
79-
asm volatile ("push" WIDTH " %0\n\tpopf" WIDTH
80-
: : "rm" (eflags) : "flags");
81-
}
82-
83-
#define X86_EFLAGS_TF (1UL << 8)
84-
8572
static void sigtrap(int sig, siginfo_t *info, void *ctx_void)
8673
{
8774
ucontext_t *ctx = (ucontext_t*)ctx_void;

tools/testing/selftests/x86/syscall_arg_fault.c

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,11 @@
1515
#include <setjmp.h>
1616
#include <errno.h>
1717

18-
#ifdef __x86_64__
19-
# define WIDTH "q"
20-
#else
21-
# define WIDTH "l"
22-
#endif
18+
#include "helpers.h"
2319

2420
/* Our sigaltstack scratch space. */
2521
static unsigned char altstack_data[SIGSTKSZ];
2622

27-
static unsigned long get_eflags(void)
28-
{
29-
unsigned long eflags;
30-
asm volatile ("pushf" WIDTH "\n\tpop" WIDTH " %0" : "=rm" (eflags));
31-
return eflags;
32-
}
33-
34-
static void set_eflags(unsigned long eflags)
35-
{
36-
asm volatile ("push" WIDTH " %0\n\tpopf" WIDTH
37-
: : "rm" (eflags) : "flags");
38-
}
39-
40-
#define X86_EFLAGS_TF (1UL << 8)
41-
4223
static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
4324
int flags)
4425
{

tools/testing/selftests/x86/syscall_nt.c

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,11 @@
1313
#include <signal.h>
1414
#include <err.h>
1515
#include <sys/syscall.h>
16-
#include <asm/processor-flags.h>
1716

18-
#ifdef __x86_64__
19-
# define WIDTH "q"
20-
#else
21-
# define WIDTH "l"
22-
#endif
17+
#include "helpers.h"
2318

2419
static unsigned int nerrs;
2520

26-
static unsigned long get_eflags(void)
27-
{
28-
unsigned long eflags;
29-
asm volatile ("pushf" WIDTH "\n\tpop" WIDTH " %0" : "=rm" (eflags));
30-
return eflags;
31-
}
32-
33-
static void set_eflags(unsigned long eflags)
34-
{
35-
asm volatile ("push" WIDTH " %0\n\tpopf" WIDTH
36-
: : "rm" (eflags) : "flags");
37-
}
38-
3921
static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
4022
int flags)
4123
{

tools/testing/selftests/x86/test_vsyscall.c

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include <setjmp.h>
2121
#include <sys/uio.h>
2222

23+
#include "helpers.h"
24+
2325
#ifdef __x86_64__
2426
# define VSYS(x) (x)
2527
#else
@@ -493,21 +495,8 @@ static int test_process_vm_readv(void)
493495
}
494496

495497
#ifdef __x86_64__
496-
#define X86_EFLAGS_TF (1UL << 8)
497498
static volatile sig_atomic_t num_vsyscall_traps;
498499

499-
static unsigned long get_eflags(void)
500-
{
501-
unsigned long eflags;
502-
asm volatile ("pushfq\n\tpopq %0" : "=rm" (eflags));
503-
return eflags;
504-
}
505-
506-
static void set_eflags(unsigned long eflags)
507-
{
508-
asm volatile ("pushq %0\n\tpopfq" : : "rm" (eflags) : "flags");
509-
}
510-
511500
static void sigtrap(int sig, siginfo_t *info, void *ctx_void)
512501
{
513502
ucontext_t *ctx = (ucontext_t *)ctx_void;

tools/testing/selftests/x86/unwind_vdso.c

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#include <features.h>
1212
#include <stdio.h>
1313

14+
#include "helpers.h"
15+
1416
#if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16
1517

1618
int main()
@@ -53,27 +55,6 @@ static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
5355
err(1, "sigaction");
5456
}
5557

56-
#ifdef __x86_64__
57-
# define WIDTH "q"
58-
#else
59-
# define WIDTH "l"
60-
#endif
61-
62-
static unsigned long get_eflags(void)
63-
{
64-
unsigned long eflags;
65-
asm volatile ("pushf" WIDTH "\n\tpop" WIDTH " %0" : "=rm" (eflags));
66-
return eflags;
67-
}
68-
69-
static void set_eflags(unsigned long eflags)
70-
{
71-
asm volatile ("push" WIDTH " %0\n\tpopf" WIDTH
72-
: : "rm" (eflags) : "flags");
73-
}
74-
75-
#define X86_EFLAGS_TF (1UL << 8)
76-
7758
static volatile sig_atomic_t nerrs;
7859
static unsigned long sysinfo;
7960
static bool got_sysinfo = false;

0 commit comments

Comments
 (0)