From: David Laight <david.laight.linux@gmail.com>
To: Yury Norov <ynorov@nvidia.com>
Cc: Nathan Chancellor <nathan@kernel.org>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Thomas Gleixner <tglx@linutronix.de>,
Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@kernel.org>,
Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
Arnd Bergmann <arnd@arndb.de>,
linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org,
Yury Norov <yury.norov@gmail.com>,
Lucas De Marchi <lucas.demarchi@intel.com>,
Jani Nikula <jani.nikula@intel.com>,
Vincent Mailhol <mailhol.vincent@wanadoo.fr>,
Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
Kees Cook <keescook@chromium.org>,
Andrew Morton <akpm@linux-foundation.org>
Subject: Re: [PATCH next 10/14] bits: Fix assmebler expansions of GENMASK_Uxx() and BIT_Uxx()
Date: Sun, 8 Feb 2026 22:27:24 +0000 [thread overview]
Message-ID: <20260208222724.6e2dd07e@pumpkin> (raw)
In-Reply-To: <aYj-LdTWwvGLJP4O@yury>
On Sun, 8 Feb 2026 16:20:45 -0500
Yury Norov <ynorov@nvidia.com> wrote:
> On Sun, Feb 08, 2026 at 11:42:14AM +0000, David Laight wrote:
> > On Sat, 7 Feb 2026 22:31:34 -0500
> > Yury Norov <ynorov@nvidia.com> wrote:
> >
> > > On Wed, Jan 21, 2026 at 02:57:27PM +0000, david.laight.linux@gmail.com wrote:
> > > > From: David Laight <david.laight.linux@gmail.com>
> > > >
> > > > The assembler only supports one type of signed integers, so expressions
> > > > using BITS_PER_LONG (etc) cannot be guaranteed to be correct.
> > > >
> > > > Use ((2 << (h)) - (1 << (l))) for all assembler GENMASK() expansions and
> > > > add definitions of BIT_Uxx() as (1 << (nr)).
> > > >
> > > > Note that 64bit results are (probably) only correct for 64bit builds
> > > > and 128bits results will never be valid.
> > >
> > > And this important note will sink in git history.
> >
> > At least it isn't only in the email archives.
> > I can put it in a comment.
> >
> > > > Signed-off-by: David Laight <david.laight.linux@gmail.com>
> > >
> > > This has been discussed in details when those GENMASK_Uxx() were
> > > introduced. Assembler doesn't support C types, and can't provide any
> > > guarantees. It may only confuse readers when they see something like
> > > GENMASK_U8() in the assembler code, and there's nothing on behalf of
> > > that declaration to enforce the limitation.
> >
> > It won't be in asm code, the asm code will be expanding a constant
> > from a C header file.
>
> It can be included and preprocessed well in any .S file:
>
> #define GENMASK_TYPE(t, h,l) ((2 << (h)) - (1 << (l)))
> #define GENMASK(h, l) GENMASK_TYPE(unsigned long, (h), (l))
>
> .section .rodata
> fmt:
> .string "GENMASK(63,60) = 0x%016llx\n"
>
> .text
> .globl main
> .type main, @function
>
> main:
> push %rbp
> mov %rsp, %rbp
>
> lea fmt(%rip), %rdi
> mov $GENMASK(63,60), %rsi
> xor %rax, %rax
> call printf@PLT
>
> mov $0, %eax
> pop %rbp
> ret
>
> In C this doesn't work at all as it throws overflow. It doesn't even
> work in asm volatile section.
Indeed - that I'm not trying to use that expression in C.
Although it will work for non-constants.
For constants you'd have to use ((1 << hi) - 1) * 2) + 1.
While I'm pretty sure the compiler will convert it to the former, both
generate worse code in some corner cases.
The issue at the moment is that you get these definitions from uapi/linux/bits.h
#define __GENMASK(h, l) (((~_UL(0)) << (l)) & (~_UL(0) >> (__BITS_PER_LONG - 1 - (h))))
#define __GENMASK_ULL(h, l) (((~_ULL(0)) << (l)) & (~_ULL(0) >> (__BITS_PER_LONG_LONG - 1 - (h))))
For .S files both _UL() and _ULL() are null, so these are:
#define __GENMASK(h, l) (((~0) << (l)) & (~0 >> (__BITS_PER_LONG - 1 - (h))))
#define __GENMASK_ULL(h, l) (((~0) << (l)) & (~0 >> (__BITS_PER_LONG_LONG - 1 - (h))))
Which makes them identical except for the two constants.
On 32bit builds the two constants are different which means that while __GENMASK(5, 2)
and __GENMASK_ULL(5,2) should have the same value they may not (depending exactly
how the assembler evaluates constant expressions).
Assuming that either __BITS_PER_LONG or __BITS_PER_LONG_LONG has anything to do
with the number of bits in the assembler's expression evaluator doesn't seem
right at all.
David
>
> > > That's why we didn't add fake C types support in the assembler. Unless
> > > we find a way to enforce C types capacity in assembler(s), let's keep
> > > those macros C-only.
> >
> > But GENMASK_ULL() was already there and would generate invalid values
> > (for small values) on 32bit.
>
> You continuously repeat that GENMASK_ULL() generates wrong values, but
> never submitted a fix.
>
> Anyways, if you think GENMASK_ULL() is not needed in assembler, it's
> even harder to advocate fixed-type flavors.
>
> > The only reason for defining these for assembler is so that .h files
> > that use the definitions can be used in .S files.
> > As soon as any of the BIT_Unn() get used the asm code is likely to
> > try to expand them.
>
> The only reason for fixed-type GENMASK() and BIT() is strict
> parameters checking. This is not possible in assembler.
>
> Thanks,
> Yury
next prev parent reply other threads:[~2026-02-08 22:27 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-21 14:57 [PATCH next 00/14] bits: De-bloat expansion of GENMASK() david.laight.linux
2026-01-21 14:57 ` [PATCH next 01/14] overflow: Reduce expansion of __type_max() david.laight.linux
2026-01-21 20:59 ` Kees Cook
2026-02-02 16:45 ` Yury Norov
2026-01-21 14:57 ` [PATCH next 02/14] kbuild: Add W=c for additional compile time checks david.laight.linux
2026-02-02 18:33 ` Yury Norov
2026-02-02 20:07 ` David Laight
2026-02-03 4:47 ` Nathan Chancellor
2026-02-03 11:14 ` David Laight
2026-02-03 19:41 ` Yury Norov
2026-01-21 14:57 ` [PATCH next 03/14] media: videobuf2-core: Use static_assert() for sanity check david.laight.linux
2026-01-21 14:57 ` [PATCH next 04/14] media: atomisp: " david.laight.linux
2026-01-21 14:57 ` [PATCH next 05/14] ixgbevf: Use C test for PAGE_SIZE > IXGBE_MAX_DATA_PER_TXD david.laight.linux
2026-01-23 15:44 ` Simon Horman
2026-01-21 14:57 ` [PATCH next 06/14] asm-generic: include linux/bits.h not vdso/bits.h david.laight.linux
2026-01-21 14:57 ` [PATCH next 07/14] x86/tlb: " david.laight.linux
2026-01-21 14:57 ` [PATCH next 08/14] bits: simplify GENMASK_TYPE() david.laight.linux
2026-02-08 2:36 ` Yury Norov
2026-02-09 9:42 ` David Laight
2026-01-21 14:57 ` [PATCH next 09/14] bits: Change BIT_U8/16() and GENMASK_U8/16() to have unsigned values david.laight.linux
2026-01-21 14:57 ` [PATCH next 10/14] bits: Fix assmebler expansions of GENMASK_Uxx() and BIT_Uxx() david.laight.linux
2026-02-08 3:31 ` Yury Norov
2026-02-08 11:42 ` David Laight
2026-02-08 21:20 ` Yury Norov
2026-02-08 22:27 ` David Laight [this message]
2026-01-21 14:57 ` [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT() david.laight.linux
2026-01-21 18:43 ` Vincent Mailhol
2026-01-21 19:14 ` David Laight
2026-01-22 1:11 ` kernel test robot
2026-01-22 10:25 ` David Laight
2026-01-22 20:10 ` David Laight
2026-01-22 4:41 ` kernel test robot
2026-01-22 10:33 ` David Laight
2026-01-22 14:26 ` Andy Shevchenko
2026-01-22 14:55 ` David Laight
2026-01-23 1:25 ` Philip Li
2026-01-23 8:01 ` Vincent Mailhol
2026-01-23 8:11 ` Andy Shevchenko
2026-01-23 8:20 ` Al Viro
2026-01-23 8:24 ` Andy Shevchenko
2026-01-23 8:32 ` Vincent Mailhol
2026-01-23 8:46 ` Andy Shevchenko
2026-01-23 1:24 ` Philip Li
2026-01-21 14:57 ` [PATCH next 12/14] bits: move the defitions of BIT() and BIT_ULL() back to linux/bits.h david.laight.linux
2026-01-21 15:17 ` Thomas Weißschuh
2026-01-21 19:24 ` David Laight
2026-01-22 7:39 ` Thomas Weißschuh
2026-01-22 0:50 ` kernel test robot
2026-01-22 1:23 ` kernel test robot
2026-01-22 10:30 ` David Laight
2026-02-07 22:40 ` Thomas Gleixner
2026-02-08 4:23 ` Yury Norov
2026-01-21 14:57 ` [PATCH next 13/14] test_bits: Change all the tests to be compile-time tests david.laight.linux
2026-02-08 4:37 ` Yury Norov
2026-02-08 11:32 ` David Laight
2026-01-21 14:57 ` [PATCH next 14/14] test_bits: include some invalid input tests for GENMASK_INPUT_CHECK() david.laight.linux
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=20260208222724.6e2dd07e@pumpkin \
--to=david.laight.linux@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=andriy.shevchenko@linux.intel.com \
--cc=arnd@arndb.de \
--cc=gregkh@linuxfoundation.org \
--cc=jani.nikula@intel.com \
--cc=keescook@chromium.org \
--cc=linux-arch@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lucas.demarchi@intel.com \
--cc=mailhol.vincent@wanadoo.fr \
--cc=mathieu.desnoyers@efficios.com \
--cc=mingo@kernel.org \
--cc=nathan@kernel.org \
--cc=peterz@infradead.org \
--cc=tglx@linutronix.de \
--cc=ynorov@nvidia.com \
--cc=yury.norov@gmail.com \
/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