Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86: allow "=rm" in native_save_fl()

This is a partial revert of f1f029c7bfbf4ee1918b90a431ab823bed812504.

"=rm" is allowed in this context, because "pop" is explicitly defined
to adjust the stack pointer *before* it evaluates its effective
address, if it has one. Thus, we do end up writing to the correct
address even if we use an on-stack memory argument.

The original reporter for f1f029c7bfbf4ee1918b90a431ab823bed812504 was
apparently using a broken x86 simulator.

[ Impact: performance ]

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Cc: Gabe Black <spamforgabe@umich.edu>

+4 -5
+4 -5
arch/x86/include/asm/irqflags.h
··· 13 13 unsigned long flags; 14 14 15 15 /* 16 - * Note: this needs to be "=r" not "=rm", because we have the 17 - * stack offset from what gcc expects at the time the "pop" is 18 - * executed, and so a memory reference with respect to the stack 19 - * would end up using the wrong address. 16 + * "=rm" is safe here, because "pop" adjusts the stack before 17 + * it evaluates its effective address -- this is part of the 18 + * documented behavior of the "pop" instruction. 20 19 */ 21 20 asm volatile("# __raw_save_flags\n\t" 22 21 "pushf ; pop %0" 23 - : "=r" (flags) 22 + : "=rm" (flags) 24 23 : /* no input */ 25 24 : "memory"); 26 25