From: "Roger Pau Monné" <roger.pau@citrix.com>
To: Jan Beulich <jbeulich@suse.com>
Cc: Alejandro Vallejo <alejandro.vallejo@cloud.com>,
xen-devel@lists.xenproject.org,
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: Wed, 24 Jul 2024 10:28:14 +0200 [thread overview]
Message-ID: <ZqC7Hn8R6Mkyqtpl@macbook> (raw)
In-Reply-To: <7a5da6ce-0ef0-4666-a5c4-44383469f67e@suse.com>
On Wed, Jul 24, 2024 at 08:39:05AM +0200, Jan Beulich wrote:
> On 23.07.2024 18:24, Alejandro Vallejo wrote:
> > On Tue Jul 23, 2024 at 5:09 PM BST, Roger Pau Monné wrote:
> >> 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:
> >>>> --- 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)?
> >
> > Bah, yes. I wrote it as a COMPILE_ASSERT().
> >
> >>
> >>> 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?
> >
> > I explained myself poorly. If the current BUILD_BUG_ON() stays as-is that's
> > right, but...
> >
> >>
> >> 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.
> >
> > ... I thought the point of the patch was to cover the full union with the
> > array, and not just a subset. My proposed alternative merely tries to ensure
> > the argument is always a submultiple in size of a long so the array is always a
> > perfect match.
I would be fine with the adjusted BUILD_BUG_ON(), but if we change the
instance for clang we should also update the BUILD_BUG_ON() used on
the gcc counterpart so they both match. That might be undesirable
however since gcc doesn't exhibit any of those bugs, and hence
shouldn't have such constraints.
> Question is whether there's an issue with odd sized values in Clang. I
> wouldn't want to exclude such (admittedly somewhat exotic) uses "just
> in case". My understanding here is that the issue the patch addresses
> is not merely the treatment of the union by Clang, but the combination
> thereof with it violating the psABI when it comes to passing bool
> around.
So there are at least two issues, one is the lack of truncation of
register value done by the callee, which is a psABI violation. The
other is clang not resetting the high bits of the register when the
altcall is inside a loop construct. In the godbolt example provided
the high bits of %rdi are not cleared between loops. This last issue
would also be 'fixed' if clang implemented the psABI properly and
truncated the register at the callee.
I've given a try in godbolt, and odd structure sizes seem to be
affected:
https://godbolt.org/z/778YsoWsn
We have no usages of such structures in Xen so far.
The only way I've found to cope with this is to use something like:
#define ALT_CALL_ARG(arg, n) \
union { \
typeof(arg) e[(sizeof(long) + sizeof(arg) - 1) / sizeof(arg)]; \
unsigned long r; \
} a ## n ## __ = { \
.e[0] = ({ BUILD_BUG_ON(sizeof(arg) > sizeof(void *)); (arg); })\
}; \
register unsigned long a ## n ## _ asm ( ALT_CALL_arg ## n ) = \
a ## n ## __.r
An oversized array that ensures all the space of the long is covered
by the array, but then we need an extra variable, as we would
otherwise require modifying ALT_CALL{0..6}_OUT to use aX_.r instead of
aX_.
Thanks, Roger.
next prev parent reply other threads:[~2024-07-24 8:28 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é
2024-07-23 16:24 ` Alejandro Vallejo
2024-07-24 6:39 ` Jan Beulich
2024-07-24 8:28 ` Roger Pau Monné [this message]
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=ZqC7Hn8R6Mkyqtpl@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.