From: Marco Elver <elver@google.com>
To: David Laight <David.Laight@aculab.com>
Cc: "peterz@infradead.org" <peterz@infradead.org>,
"mingo@redhat.com" <mingo@redhat.com>,
"tglx@linutronix.de" <tglx@linutronix.de>,
"m.szyprowski@samsung.com" <m.szyprowski@samsung.com>,
"jonathanh@nvidia.com" <jonathanh@nvidia.com>,
"dvyukov@google.com" <dvyukov@google.com>,
"glider@google.com" <glider@google.com>,
"arnd@arndb.de" <arnd@arndb.de>,
"christian@brauner.io" <christian@brauner.io>,
"axboe@kernel.dk" <axboe@kernel.dk>,
"pcc@google.com" <pcc@google.com>,
"oleg@redhat.com" <oleg@redhat.com>,
"kasan-dev@googlegroups.com" <kasan-dev@googlegroups.com>,
"linux-arch@vger.kernel.org" <linux-arch@vger.kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"linux-arm-kernel@lists.infradead.org"
<linux-arm-kernel@lists.infradead.org>
Subject: Re: [PATCH tip 1/2] signal, perf: Fix siginfo_t by avoiding u64 on 32-bit architectures
Date: Thu, 22 Apr 2021 12:17:20 +0200 [thread overview]
Message-ID: <CANpmjNNjkQdziFZDkPy5EnwCF+VyBWKXEwCDgNpxHGZd+BLQag@mail.gmail.com> (raw)
In-Reply-To: <d480a4f56d544fb98eb1cdd62f44ae91@AcuMS.aculab.com>
On Thu, 22 Apr 2021 at 11:48, David Laight <David.Laight@aculab.com> wrote:
>
> From: Marco Elver
> > Sent: 22 April 2021 07:45
> >
> > On some architectures, like Arm, the alignment of a structure is that of
> > its largest member.
>
> That is true everywhere.
> (Apart from obscure ABI where structure have at least 4 byte alignment!)
For instance, x86 didn't complain, nor did m68k. Both of them have
compile-time checks for the layout (I'm adding those for Arm
elsewhere).
> > This means that there is no portable way to add 64-bit integers to
> > siginfo_t on 32-bit architectures, because siginfo_t does not contain
> > any 64-bit integers on 32-bit architectures.
>
> Uh?
>
> The actual problem is that adding a 64-bit aligned item to the union
> forces the union to be 8 byte aligned and adds a 4 byte pad before it
> (and possibly another one at the end of the structure).
Yes, which means there's no portable way (without starting to add
attributes that are outside the C std) to add 64-bit integers to
siginfo_t without breaking the ABI on 32-bit architectures.
> > In the case of the si_perf field, word size is sufficient since there is
> > no exact requirement on size, given the data it contains is user-defined
> > via perf_event_attr::sig_data. On 32-bit architectures, any excess bits
> > of perf_event_attr::sig_data will therefore be truncated when copying
> > into si_perf.
>
> Is that right on BE architectures?
We effectively do
u64 sig_data = ...;
unsigned long si_perf = sig_data;
Since the user decides what to place into perf_event_attr::sig_data,
whatever ends up in si_perf is fully controllable by the user, who
knows which arch they're on. So I do not think this is a problem.
> > Since this field is intended to disambiguate events (e.g. encoding
> > relevant information if there are more events of the same type), 32 bits
> > should provide enough entropy to do so on 32-bit architectures.
>
> What is the size of the field used to supply the data?
> The size of the returned item really ought to match.
It's u64, but because perf_event_attr wants fixed size fields, this
can't change.
> Much as I hate __packed, you could add __packed to the
> definition of the structure member _perf.
> The compiler will remove the padding before it and will
> assume it has the alignment of the previous item.
>
> So it will never use byte accesses.
Sure __packed works for Arm. But I think there's no precedent using
this on siginfo_t, possibly for good reasons? I simply can't find
evidence that this is portable on *all* architectures and for *all*
possible definitions of siginfo_t, including those that live in things
like glibc.
Can we confirm that __packed is fine to add to siginfo_t on *all*
architectures for *all* possible definitions of siginfo_t? I currently
can't. And given it's outside the scope of the C standard (as of C11
we got _Alignas, but that doesn't help I think), I'd vote to not
venture too far for code that should be portable especially things as
important as siginfo_t, and has definitions *outside* the kernel (I
know we do lots of non-standard things, but others might not).
Thanks,
-- Marco
> David
>
> >
> > For 64-bit architectures, no change is intended.
> >
> > Fixes: fb6cc127e0b6 ("signal: Introduce TRAP_PERF si_code and si_perf to siginfo")
> > Reported-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > Reported-by: Jon Hunter <jonathanh@nvidia.com>
> > Signed-off-by: Marco Elver <elver@google.com>
> > ---
> >
> > Note: I added static_assert()s to verify the siginfo_t layout to
> > arch/arm and arch/arm64, which caught the problem. I'll send them
> > separately to arm&arm64 maintainers respectively.
> > ---
> > include/linux/compat.h | 2 +-
> > include/uapi/asm-generic/siginfo.h | 2 +-
> > tools/testing/selftests/perf_events/sigtrap_threads.c | 2 +-
> > 3 files changed, 3 insertions(+), 3 deletions(-)
> >
> > diff --git a/include/linux/compat.h b/include/linux/compat.h
> > index c8821d966812..f0d2dd35d408 100644
> > --- a/include/linux/compat.h
> > +++ b/include/linux/compat.h
> > @@ -237,7 +237,7 @@ typedef struct compat_siginfo {
> > u32 _pkey;
> > } _addr_pkey;
> > /* used when si_code=TRAP_PERF */
> > - compat_u64 _perf;
> > + compat_ulong_t _perf;
> > };
> > } _sigfault;
> >
> > diff --git a/include/uapi/asm-generic/siginfo.h b/include/uapi/asm-generic/siginfo.h
> > index d0bb9125c853..03d6f6d2c1fe 100644
> > --- a/include/uapi/asm-generic/siginfo.h
> > +++ b/include/uapi/asm-generic/siginfo.h
> > @@ -92,7 +92,7 @@ union __sifields {
> > __u32 _pkey;
> > } _addr_pkey;
> > /* used when si_code=TRAP_PERF */
> > - __u64 _perf;
> > + unsigned long _perf;
> > };
> > } _sigfault;
> >
> > diff --git a/tools/testing/selftests/perf_events/sigtrap_threads.c
> > b/tools/testing/selftests/perf_events/sigtrap_threads.c
> > index 9c0fd442da60..78ddf5e11625 100644
> > --- a/tools/testing/selftests/perf_events/sigtrap_threads.c
> > +++ b/tools/testing/selftests/perf_events/sigtrap_threads.c
> > @@ -44,7 +44,7 @@ static struct {
> > } ctx;
> >
> > /* Unique value to check si_perf is correctly set from perf_event_attr::sig_data. */
> > -#define TEST_SIG_DATA(addr) (~(uint64_t)(addr))
> > +#define TEST_SIG_DATA(addr) (~(unsigned long)(addr))
> >
> > static struct perf_event_attr make_event_attr(bool enabled, volatile void *addr)
> > {
> > --
> > 2.31.1.498.g6c1eba8ee3d-goog
>
> -
> Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
> Registration No: 1397386 (Wales)
next prev parent reply other threads:[~2021-04-22 10:17 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-04-22 6:44 [PATCH tip 1/2] signal, perf: Fix siginfo_t by avoiding u64 on 32-bit architectures Marco Elver
2021-04-22 6:44 ` [PATCH tip 2/2] signal, perf: Add missing TRAP_PERF case in siginfo_layout() Marco Elver
2021-04-22 8:15 ` [PATCH tip 1/2] signal, perf: Fix siginfo_t by avoiding u64 on 32-bit architectures Jon Hunter
2021-04-22 9:48 ` David Laight
2021-04-22 10:17 ` Marco Elver [this message]
2021-04-22 19:22 ` Marco Elver
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=CANpmjNNjkQdziFZDkPy5EnwCF+VyBWKXEwCDgNpxHGZd+BLQag@mail.gmail.com \
--to=elver@google.com \
--cc=David.Laight@aculab.com \
--cc=arnd@arndb.de \
--cc=axboe@kernel.dk \
--cc=christian@brauner.io \
--cc=dvyukov@google.com \
--cc=glider@google.com \
--cc=jonathanh@nvidia.com \
--cc=kasan-dev@googlegroups.com \
--cc=linux-arch@vger.kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=m.szyprowski@samsung.com \
--cc=mingo@redhat.com \
--cc=oleg@redhat.com \
--cc=pcc@google.com \
--cc=peterz@infradead.org \
--cc=tglx@linutronix.de \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).