objtool,x86: Fix uaccess PUSHF/POPF validation
Commitab234a260b
("x86/pv: Rework arch_local_irq_restore() to not use popf") replaced "push %reg; popf" with something like: "test $0x200, %reg; jz 1f; sti; 1:", which breaks the pushf/popf symmetry that commitea24213d80
("objtool: Add UACCESS validation") relies on. The result is: drivers/gpu/drm/amd/amdgpu/si.o: warning: objtool: si_common_hw_init()+0xf36: PUSHF stack exhausted Meanwhile, commitc9c324dc22
("objtool: Support stack layout changes in alternatives") makes that we can actually use stack-ops in alternatives, which means we can revert1ff865e343
("x86,smap: Fix smap_{save,restore}() alternatives"). That in turn means we can limit the PUSHF/POPF handling ofea24213d80
to those instructions that are in alternatives. Fixes:ab234a260b
("x86/pv: Rework arch_local_irq_restore() to not use popf") Reported-by: Borislav Petkov <bp@alien8.de> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Josh Poimboeuf <jpoimboe@redhat.com> Link: https://lkml.kernel.org/r/YEY4rIbQYa5fnnEp@hirez.programming.kicks-ass.net
This commit is contained in:
Родитель
a38fd87484
Коммит
ba08abca66
|
@ -58,9 +58,8 @@ static __always_inline unsigned long smap_save(void)
|
|||
unsigned long flags;
|
||||
|
||||
asm volatile ("# smap_save\n\t"
|
||||
ALTERNATIVE("jmp 1f", "", X86_FEATURE_SMAP)
|
||||
"pushf; pop %0; " __ASM_CLAC "\n\t"
|
||||
"1:"
|
||||
ALTERNATIVE("", "pushf; pop %0; " __ASM_CLAC "\n\t",
|
||||
X86_FEATURE_SMAP)
|
||||
: "=rm" (flags) : : "memory", "cc");
|
||||
|
||||
return flags;
|
||||
|
@ -69,9 +68,8 @@ static __always_inline unsigned long smap_save(void)
|
|||
static __always_inline void smap_restore(unsigned long flags)
|
||||
{
|
||||
asm volatile ("# smap_restore\n\t"
|
||||
ALTERNATIVE("jmp 1f", "", X86_FEATURE_SMAP)
|
||||
"push %0; popf\n\t"
|
||||
"1:"
|
||||
ALTERNATIVE("", "push %0; popf\n\t",
|
||||
X86_FEATURE_SMAP)
|
||||
: : "g" (flags) : "memory", "cc");
|
||||
}
|
||||
|
||||
|
|
|
@ -2442,6 +2442,9 @@ static int handle_insn_ops(struct instruction *insn, struct insn_state *state)
|
|||
if (update_cfi_state(insn, &state->cfi, op))
|
||||
return 1;
|
||||
|
||||
if (!insn->alt_group)
|
||||
continue;
|
||||
|
||||
if (op->dest.type == OP_DEST_PUSHF) {
|
||||
if (!state->uaccess_stack) {
|
||||
state->uaccess_stack = 1;
|
||||
|
|
Загрузка…
Ссылка в новой задаче