mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-24 19:45:06 +08:00
cced0b24bb
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 <luto@kernel.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lkml.kernel.org/r/982ce58ae8dea2f1e57093ee894760e35267e751.1593191971.git.luto@kernel.org
42 lines
705 B
C
42 lines
705 B
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
#ifndef __SELFTESTS_X86_HELPERS_H
|
|
#define __SELFTESTS_X86_HELPERS_H
|
|
|
|
#include <asm/processor-flags.h>
|
|
|
|
static inline unsigned long get_eflags(void)
|
|
{
|
|
unsigned long eflags;
|
|
|
|
asm volatile (
|
|
#ifdef __x86_64__
|
|
"subq $128, %%rsp\n\t"
|
|
"pushfq\n\t"
|
|
"popq %0\n\t"
|
|
"addq $128, %%rsp"
|
|
#else
|
|
"pushfl\n\t"
|
|
"popl %0"
|
|
#endif
|
|
: "=r" (eflags) :: "memory");
|
|
|
|
return eflags;
|
|
}
|
|
|
|
static inline void set_eflags(unsigned long eflags)
|
|
{
|
|
asm volatile (
|
|
#ifdef __x86_64__
|
|
"subq $128, %%rsp\n\t"
|
|
"pushq %0\n\t"
|
|
"popfq\n\t"
|
|
"addq $128, %%rsp"
|
|
#else
|
|
"pushl %0\n\t"
|
|
"popfl"
|
|
#endif
|
|
:: "r" (eflags) : "flags", "memory");
|
|
}
|
|
|
|
#endif /* __SELFTESTS_X86_HELPERS_H */
|