On Tue, Apr 28, 2020 at 3:21 PM Peter Zijlstra <pet...@infradead.org> wrote: > > As reported by objtool: > > lib/ubsan.o: warning: objtool: .altinstr_replacement+0x0: alternative > modifies stack > lib/ubsan.o: warning: objtool: .altinstr_replacement+0x7: alternative > modifies stack > > the smap_{save,restore}() alternatives violate (the newly enforced) > rule on stack invariance. That is, due to there only being a single > ORC table it must be valid to any alternative. These alternatives > violate this with the direct result that unwinds will not be correct > in between these calls. > > [ In specific, since we force SMAP on for objtool, running on !SMAP > hardware will observe a different stack-layout and the ORC unwinder > will stumble. ] > > So rewrite the functions to unconditionally save/restore the flags, > which gives an invariant stack layout irrespective of the SMAP state. > > Signed-off-by: Peter Zijlstra (Intel) <pet...@infradead.org> > --- > arch/x86/include/asm/smap.h | 11 +++++++---- > 1 file changed, 7 insertions(+), 4 deletions(-) > > --- a/arch/x86/include/asm/smap.h > +++ b/arch/x86/include/asm/smap.h > @@ -57,16 +57,19 @@ static __always_inline unsigned long sma > { > unsigned long flags; > > - asm volatile (ALTERNATIVE("", "pushf; pop %0; " __ASM_CLAC, > - X86_FEATURE_SMAP) > - : "=rm" (flags) : : "memory", "cc"); > + asm volatile ("# smap_save\n\t" > + "pushf; pop %0" > + : "=rm" (flags) : : "memory"); > + > + clac(); > > return flags; > } > > static __always_inline void smap_restore(unsigned long flags) > { > - asm volatile (ALTERNATIVE("", "push %0; popf", X86_FEATURE_SMAP) > + asm volatile ("# smap_restore\n\t" > + "push %0; popf" > : : "g" (flags) : "memory", "cc"); > }
POPF is an expensive instruction that should be avoided if possible. A better solution would be to have the alternative jump over the push/pop when SMAP is disabled. -- Brian Gerst