From: "Roger Pau Monné" <roger.pau@citrix.com>
To: Alejandro Vallejo <alejandro.vallejo@cloud.com>
Cc: xen-devel@lists.xenproject.org, Jan Beulich <jbeulich@suse.com>,
Andrew Cooper <andrew.cooper3@citrix.com>,
Oleksii Kurochko <oleksii.kurochko@gmail.com>
Subject: Re: [PATCH for-4.19] x86/altcall: fix clang code-gen when using altcall in loop constructs
Date: Tue, 23 Jul 2024 18:09:31 +0200 [thread overview]
Message-ID: <Zp_VuwxqH3Mii8_W@macbook> (raw)
In-Reply-To: <D2X13ED477J8.25JRFH9VEW33O@cloud.com>
On Tue, Jul 23, 2024 at 04:37:12PM +0100, Alejandro Vallejo wrote:
> On Tue Jul 23, 2024 at 10:31 AM BST, Roger Pau Monne wrote:
> > Yet another clang code generation issue when using altcalls.
> >
> > The issue this time is with using loop constructs around alternative_{,v}call
> > instances using parameter types smaller than the register size.
> >
> > Given the following example code:
> >
> > static void bar(bool b)
> > {
> > unsigned int i;
> >
> > for ( i = 0; i < 10; i++ )
> > {
> > int ret_;
> > register union {
> > bool e;
> > unsigned long r;
> > } di asm("rdi") = { .e = b };
> > register unsigned long si asm("rsi");
> > register unsigned long dx asm("rdx");
> > register unsigned long cx asm("rcx");
> > register unsigned long r8 asm("r8");
> > register unsigned long r9 asm("r9");
> > register unsigned long r10 asm("r10");
> > register unsigned long r11 asm("r11");
> >
> > asm volatile ( "call %c[addr]"
> > : "+r" (di), "=r" (si), "=r" (dx),
> > "=r" (cx), "=r" (r8), "=r" (r9),
> > "=r" (r10), "=r" (r11), "=a" (ret_)
> > : [addr] "i" (&(func)), "g" (func)
> > : "memory" );
> > }
> > }
> >
> > See: https://godbolt.org/z/qvxMGd84q
> >
> > Clang will generate machine code that only resets the low 8 bits of %rdi
> > between loop calls, leaving the rest of the register possibly containing
> > garbage from the use of %rdi inside the called function. Note also that clang
> > doesn't truncate the input parameters at the callee, thus breaking the psABI.
> >
> > Fix this by turning the `e` element in the anonymous union into an array that
> > consumes the same space as an unsigned long, as this forces clang to reset the
> > whole %rdi register instead of just the low 8 bits.
> >
> > Fixes: 2ce562b2a413 ('x86/altcall: use a union as register type for function parameters on clang')
> > Suggested-by: Jan Beulich <jbeulich@suse.com>
> > Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> > ---
> > Adding Oleksii as to whether this could be considered for 4.19: it's strictly
> > limited to clang builds, plus will need to be backported anyway.
> > ---
> > xen/arch/x86/include/asm/alternative.h | 4 ++--
> > 1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/xen/arch/x86/include/asm/alternative.h b/xen/arch/x86/include/asm/alternative.h
> > index 0d3697f1de49..e63b45927643 100644
> > --- a/xen/arch/x86/include/asm/alternative.h
> > +++ b/xen/arch/x86/include/asm/alternative.h
> > @@ -185,10 +185,10 @@ extern void alternative_branches(void);
> > */
> > #define ALT_CALL_ARG(arg, n) \
> > register union { \
> > - typeof(arg) e; \
> > + typeof(arg) e[sizeof(long) / sizeof(arg)]; \
> > unsigned long r; \
> > } a ## n ## _ asm ( ALT_CALL_arg ## n ) = { \
> > - .e = ({ BUILD_BUG_ON(sizeof(arg) > sizeof(void *)); (arg); }) \
> > + .e[0] = ({ BUILD_BUG_ON(sizeof(arg) > sizeof(void *)); (arg); })\
> > }
> > #else
> > #define ALT_CALL_ARG(arg, n) \
>
> Don't we want BUILD_BUG_ON(sizeof(long) % sizeof(arg) == 0) instead?
I think you meant BUILD_BUG_ON(sizeof(long) % sizeof(arg) != 0)?
> Otherwise
> odd sizes will cause the wrong union size to prevail, and while I can't see
> today how those might come to happen there's Murphy's law.
The overall union size would still be fine, because it has the
unsigned long element, it's just that the array won't cover all the
space assigned to the long member?
IOW if sizeof(arg) == 7, then we would define an array with only 1
element, which won't make the size of the union change, but won't
cover the same space that's used by the long member.
However it's not possible for sizeof(arg) > 8 due to the existing
BUILD_BUG_ON(), so the union can never be bigger than a long.
Thanks, Roger.
next prev parent reply other threads:[~2024-07-23 16:10 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-07-23 9:31 [PATCH for-4.19] x86/altcall: fix clang code-gen when using altcall in loop constructs Roger Pau Monne
2024-07-23 9:56 ` oleksii.kurochko
2024-07-23 10:07 ` Jan Beulich
2024-07-23 15:37 ` Alejandro Vallejo
2024-07-23 16:09 ` Roger Pau Monné [this message]
2024-07-23 16:24 ` Alejandro Vallejo
2024-07-24 6:39 ` Jan Beulich
2024-07-24 8:28 ` Roger Pau Monné
2024-07-24 8:41 ` Jan Beulich
2024-07-24 9:13 ` Roger Pau Monné
2024-07-24 9:16 ` Jan Beulich
2024-07-24 9:23 ` Roger Pau Monné
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Zp_VuwxqH3Mii8_W@macbook \
--to=roger.pau@citrix.com \
--cc=alejandro.vallejo@cloud.com \
--cc=andrew.cooper3@citrix.com \
--cc=jbeulich@suse.com \
--cc=oleksii.kurochko@gmail.com \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.