Re: [RFC 6/8] x86_64/bug: Implement __WARN_printf()

From: Josh Poimboeuf
Date: Mon Jun 02 2025 - 16:04:54 EST


On Mon, Jun 02, 2025 at 08:09:22PM +0200, Peter Zijlstra wrote:
> On Mon, Jun 02, 2025 at 09:38:09AM -0700, Linus Torvalds wrote:
> > On Mon, 2 Jun 2025 at 08:50, Peter Zijlstra <peterz@xxxxxxxxxxxxx> wrote:
> > >
> > > Yes, it absolutely builds with clang. The inline asm isn't something we
> > > don't already do elsewhere :-) *cough* extable *cough*
> >
> > Eww. I hadn't looked at that (or repressed it if I did). *Shudder*.
> >
> > But looking around, I don't think any of the normal code I ever look
> > at actually *generate* that disgusting thing.
> >
> > I had to search for it, and looked at the absolute horror it generates
> > in the futex code, and honestly, if I ever have to look at that
> > garbage, I would throw up.
> >
> > And WARN_ONCE() is in stuff I *do* look at.
> >
> > So no. I'm NAK'ing it just because it makes the asm look entirely unreadable.
> >
> > And no, I'm not ok with only using 'objdump' and friends to look at
> > assembly generation. I want to be able to do
> >
> > make xyz.s
> >
> > and look at code generation without throwing up.
> >
> > The fact that we have this disgusting thing elsewhere in places that
> > I've not looked at does *not* excuse adding it to other places.
>
> Right. So the problem is using asm macros in inline-asm. We've tried
> adding those macros to a global asm, but IIRC that had trouble.
>
> So yeah, now we do the macro definition and purge right around the
> inline asm and then you get this horror show :-(
>
> Anyway, I'll try and come up with something else.

At least the purge could be skipped if you check a global assembler
variable before defining the macro.

For example here was one of my experiments trying to making alternatives
more readable:

#define DEFINE_ALT_MACRO \
".ifndef alt; " \
".set alt, 1; " \
__stringify(ALTERNATIVE_MACRO) "; " \
".endif\n\n\t" \

#define __ALTERNATIVE(oldinstr, newinstr, ft_flags, ft_flags_str) \
"\n# <ALTERNATIVE>\n" \
DEFINE_ALT_MACRO \
"alternative \"" oldinstr "\", \"" \
newinstr "\", \"" \
__stringify(ft_flags) "\" /* " ft_flags_str " */" \
"\n# </ALTERNATIVE>\n"

which produced code like:

# <ALTERNATIVE>
.ifndef alt; .set alt, 1; .macro __alt_replace orig, orig_end, newinstr, ft_flags, args:vararg; .skip -(((.Lnew_end_\@ - .Lnew_\@) - (\orig_end - \orig)) > 0) * ((.Lnew_end_\@ - .Lnew_\@) - (\orig_end - \orig)), 0x90; .Lskip_end_\@: .pushsection .altinstr_replacement, "ax"; .Lnew_\@: \newinstr; .Lnew_end_\@: .popsection; .pushsection .altinstructions, "a"; .long \orig - .; .long .Lnew_\@ - .; .4byte \ft_flags; .byte .Lskip_end_\@ - \orig; .byte .Lnew_end_\@ - .Lnew_\@; .popsection; .ifnb \args; __alt_replace \orig, \orig_end, \args; .endif; .endm; .macro alternative oldinstr, args:vararg; .Lorig_\@: \oldinstr; .Lorig_end_\@: __alt_replace .Lorig_\@, .Lorig_end_\@, \args; .endm; .endif

alternative "", "stac", "( 9*32+20)" /* X86_FEATURE_SMAP */
# </ALTERNATIVE>

which is much more readable if you ignore the horrendous first line ;-)

--
Josh