* [PATCH v3 0/2] arch/riscv: Add bitrev.h file to support rev8 and brev8
@ 2026-04-17 9:31 Jinjie Ruan
2026-04-17 9:31 ` [PATCH v3 1/2] bitops: Define generic __bitrev8/16/32 for reuse Jinjie Ruan
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Jinjie Ruan @ 2026-04-17 9:31 UTC (permalink / raw)
To: pjw, palmer, aou, alex, yury.norov, linux, arnd, akpm, ruanjinjie,
linux-riscv, linux-kernel, linux-arch, david.laight.linux, nathan
Add bitrev.h file to support rev8 and brev8 for riscv.
Tested functionally on riscv64 QEMU with:
"-M virt,acpi=on,zbkb=true,zbb=true"
Changes in v3:
- Fix the build issue by remving the CONFIG_HAVE_ARCH_BITREVERSE macro
for byte_rev_table.
- Update the riscv implementation as David suggested.
- Add Reviwed-by.
Changes in v2:
- Define generic __bitrev8/16/32 for reuse in riscv.
Jinjie Ruan (2):
bitops: Define generic __bitrev8/16/32 for reuse
arch/riscv: Add bitrev.h file to support rev8 and brev8
arch/riscv/Kconfig | 1 +
arch/riscv/include/asm/bitrev.h | 55 +++++++++++++++++++++++++++
include/asm-generic/bitops/__bitrev.h | 22 +++++++++++
include/linux/bitrev.h | 20 ++--------
lib/bitrev.c | 3 --
5 files changed, 82 insertions(+), 19 deletions(-)
create mode 100644 arch/riscv/include/asm/bitrev.h
create mode 100644 include/asm-generic/bitops/__bitrev.h
--
2.34.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v3 1/2] bitops: Define generic __bitrev8/16/32 for reuse
2026-04-17 9:31 [PATCH v3 0/2] arch/riscv: Add bitrev.h file to support rev8 and brev8 Jinjie Ruan
@ 2026-04-17 9:31 ` Jinjie Ruan
2026-04-17 9:31 ` [PATCH v3 2/2] arch/riscv: Add bitrev.h file to support rev8 and brev8 Jinjie Ruan
2026-04-17 16:09 ` [PATCH v3 0/2] " Yury Norov
2 siblings, 0 replies; 6+ messages in thread
From: Jinjie Ruan @ 2026-04-17 9:31 UTC (permalink / raw)
To: pjw, palmer, aou, alex, yury.norov, linux, arnd, akpm, ruanjinjie,
linux-riscv, linux-kernel, linux-arch, david.laight.linux, nathan
Define generic __bitrev8/16/32 using the implementation
in <linux/bitrev.h>, so they can be reused in <asm/bitrev.h>,
such as RISCV.
Reviewed-by: Yury Norov <ynorov@nvidia.com>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
include/asm-generic/bitops/__bitrev.h | 22 ++++++++++++++++++++++
include/linux/bitrev.h | 20 ++++----------------
lib/bitrev.c | 3 ---
3 files changed, 26 insertions(+), 19 deletions(-)
create mode 100644 include/asm-generic/bitops/__bitrev.h
diff --git a/include/asm-generic/bitops/__bitrev.h b/include/asm-generic/bitops/__bitrev.h
new file mode 100644
index 000000000000..1b8c0f464d26
--- /dev/null
+++ b/include/asm-generic/bitops/__bitrev.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_GENERIC_BITOPS___BITREV_H_
+#define _ASM_GENERIC_BITOPS___BITREV_H_
+
+#include <asm/types.h>
+
+extern u8 const byte_rev_table[256];
+static __always_inline __attribute_const__ u8 generic___bitrev8(u8 byte)
+{
+ return byte_rev_table[byte];
+}
+
+static __always_inline __attribute_const__ u16 generic___bitrev16(u16 x)
+{
+ return (generic___bitrev8(x & 0xff) << 8) | generic___bitrev8(x >> 8);
+}
+
+static __always_inline __attribute_const__ u32 generic___bitrev32(u32 x)
+{
+ return (generic___bitrev16(x & 0xffff) << 16) | generic___bitrev16(x >> 16);
+}
+#endif /* _ASM_GENERIC_BITOPS___BITREV_H_ */
diff --git a/include/linux/bitrev.h b/include/linux/bitrev.h
index d35b8ec1c485..11620a70e776 100644
--- a/include/linux/bitrev.h
+++ b/include/linux/bitrev.h
@@ -12,22 +12,10 @@
#define __bitrev8 __arch_bitrev8
#else
-extern u8 const byte_rev_table[256];
-static inline u8 __bitrev8(u8 byte)
-{
- return byte_rev_table[byte];
-}
-
-static inline u16 __bitrev16(u16 x)
-{
- return (__bitrev8(x & 0xff) << 8) | __bitrev8(x >> 8);
-}
-
-static inline u32 __bitrev32(u32 x)
-{
- return (__bitrev16(x & 0xffff) << 16) | __bitrev16(x >> 16);
-}
-
+#include <asm-generic/bitops/__bitrev.h>
+#define __bitrev32 generic___bitrev32
+#define __bitrev16 generic___bitrev16
+#define __bitrev8 generic___bitrev8
#endif /* CONFIG_HAVE_ARCH_BITREVERSE */
#define __bitrev8x4(x) (__bitrev32(swab32(x)))
diff --git a/lib/bitrev.c b/lib/bitrev.c
index 81b56e0a7f32..05088231f31f 100644
--- a/lib/bitrev.c
+++ b/lib/bitrev.c
@@ -1,5 +1,4 @@
// SPDX-License-Identifier: GPL-2.0-only
-#ifndef CONFIG_HAVE_ARCH_BITREVERSE
#include <linux/types.h>
#include <linux/module.h>
#include <linux/bitrev.h>
@@ -43,5 +42,3 @@ const u8 byte_rev_table[256] = {
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
};
EXPORT_SYMBOL_GPL(byte_rev_table);
-
-#endif /* CONFIG_HAVE_ARCH_BITREVERSE */
--
2.34.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v3 2/2] arch/riscv: Add bitrev.h file to support rev8 and brev8
2026-04-17 9:31 [PATCH v3 0/2] arch/riscv: Add bitrev.h file to support rev8 and brev8 Jinjie Ruan
2026-04-17 9:31 ` [PATCH v3 1/2] bitops: Define generic __bitrev8/16/32 for reuse Jinjie Ruan
@ 2026-04-17 9:31 ` Jinjie Ruan
2026-04-17 13:17 ` David Laight
2026-04-17 16:09 ` [PATCH v3 0/2] " Yury Norov
2 siblings, 1 reply; 6+ messages in thread
From: Jinjie Ruan @ 2026-04-17 9:31 UTC (permalink / raw)
To: pjw, palmer, aou, alex, yury.norov, linux, arnd, akpm, ruanjinjie,
linux-riscv, linux-kernel, linux-arch, david.laight.linux, nathan
The RISC-V Bit-manipulation Extension for Cryptography (Zbkb) provides
the 'brev8' instruction, which reverses the bits within each byte.
Combined with the 'rev8' instruction (from Zbb or Zbkb), which reverses
the byte order of a register, we can efficiently implement 16-bit,
32-bit, and (on RV64) 64-bit bit reversal.
This is significantly faster than the default software table-lookup
implementation in lib/bitrev.c, as it replaces memory accesses and
multiple arithmetic operations with just two or three hardware
instructions.
Select HAVE_ARCH_BITREVERSE and provide <asm/bitrev.h> to utilize
these instructions when the Zbkb extension is available at runtime
via the alternatives mechanism.
Link: https://docs.riscv.org/reference/isa/unpriv/b-st-ext.html
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/riscv/Kconfig | 1 +
arch/riscv/include/asm/bitrev.h | 55 +++++++++++++++++++++++++++++++++
2 files changed, 56 insertions(+)
create mode 100644 arch/riscv/include/asm/bitrev.h
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 90c531e6abf5..05f2b2166a83 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -128,6 +128,7 @@ config RISCV
select HAS_IOPORT if MMU
select HAVE_ALIGNED_STRUCT_PAGE
select HAVE_ARCH_AUDITSYSCALL
+ select HAVE_ARCH_BITREVERSE if RISCV_ISA_ZBKB
select HAVE_ARCH_HUGE_VMALLOC if HAVE_ARCH_HUGE_VMAP
select HAVE_ARCH_HUGE_VMAP if MMU && 64BIT
select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
diff --git a/arch/riscv/include/asm/bitrev.h b/arch/riscv/include/asm/bitrev.h
new file mode 100644
index 000000000000..eef263cc6655
--- /dev/null
+++ b/arch/riscv/include/asm/bitrev.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_BITREV_H
+#define __ASM_BITREV_H
+
+#include <linux/types.h>
+#include <asm/cpufeature-macros.h>
+#include <asm/hwcap.h>
+#include <asm-generic/bitops/__bitrev.h>
+
+static __always_inline __attribute_const__ u32 __arch_bitrev32(u32 x)
+{
+ unsigned long result = (unsigned long)x;
+
+ if (!riscv_has_extension_likely(RISCV_ISA_EXT_ZBKB))
+ return generic___bitrev32(x);
+
+ asm volatile(
+ ".option push\n"
+ ".option arch,+zbkb\n"
+ "rev8 %0, %0\n"
+ "brev8 %0, %0\n"
+ ".option pop"
+ : "+r" (result)
+ );
+
+#if __riscv_xlen == 64
+ return (u32)(result >> 32);
+#else
+ return (u32)result;
+#endif
+}
+
+static __always_inline __attribute_const__ u16 __arch_bitrev16(u16 x)
+{
+ return __arch_bitrev32((u32)x) >> 16;
+}
+
+static __always_inline __attribute_const__ u8 __arch_bitrev8(u8 x)
+{
+ unsigned long result = (unsigned long)x;
+
+ if (!riscv_has_extension_likely(RISCV_ISA_EXT_ZBKB))
+ return generic___bitrev8(x);
+
+ asm volatile(
+ ".option push\n"
+ ".option arch,+zbkb\n"
+ "brev8 %0, %0\n"
+ ".option pop"
+ : "+r" (result)
+ );
+
+ return (u8)result;
+}
+#endif
--
2.34.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v3 2/2] arch/riscv: Add bitrev.h file to support rev8 and brev8
2026-04-17 9:31 ` [PATCH v3 2/2] arch/riscv: Add bitrev.h file to support rev8 and brev8 Jinjie Ruan
@ 2026-04-17 13:17 ` David Laight
0 siblings, 0 replies; 6+ messages in thread
From: David Laight @ 2026-04-17 13:17 UTC (permalink / raw)
To: Jinjie Ruan
Cc: pjw, palmer, aou, alex, yury.norov, linux, arnd, akpm,
linux-riscv, linux-kernel, linux-arch, nathan
On Fri, 17 Apr 2026 17:31:02 +0800
Jinjie Ruan <ruanjinjie@huawei.com> wrote:
> The RISC-V Bit-manipulation Extension for Cryptography (Zbkb) provides
> the 'brev8' instruction, which reverses the bits within each byte.
> Combined with the 'rev8' instruction (from Zbb or Zbkb), which reverses
> the byte order of a register, we can efficiently implement 16-bit,
> 32-bit, and (on RV64) 64-bit bit reversal.
>
> This is significantly faster than the default software table-lookup
> implementation in lib/bitrev.c, as it replaces memory accesses and
> multiple arithmetic operations with just two or three hardware
> instructions.
>
> Select HAVE_ARCH_BITREVERSE and provide <asm/bitrev.h> to utilize
> these instructions when the Zbkb extension is available at runtime
> via the alternatives mechanism.
>
> Link: https://docs.riscv.org/reference/isa/unpriv/b-st-ext.html
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
> ---
> arch/riscv/Kconfig | 1 +
> arch/riscv/include/asm/bitrev.h | 55 +++++++++++++++++++++++++++++++++
> 2 files changed, 56 insertions(+)
> create mode 100644 arch/riscv/include/asm/bitrev.h
>
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index 90c531e6abf5..05f2b2166a83 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -128,6 +128,7 @@ config RISCV
> select HAS_IOPORT if MMU
> select HAVE_ALIGNED_STRUCT_PAGE
> select HAVE_ARCH_AUDITSYSCALL
> + select HAVE_ARCH_BITREVERSE if RISCV_ISA_ZBKB
> select HAVE_ARCH_HUGE_VMALLOC if HAVE_ARCH_HUGE_VMAP
> select HAVE_ARCH_HUGE_VMAP if MMU && 64BIT
> select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
> diff --git a/arch/riscv/include/asm/bitrev.h b/arch/riscv/include/asm/bitrev.h
> new file mode 100644
> index 000000000000..eef263cc6655
> --- /dev/null
> +++ b/arch/riscv/include/asm/bitrev.h
> @@ -0,0 +1,55 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef __ASM_BITREV_H
> +#define __ASM_BITREV_H
> +
> +#include <linux/types.h>
> +#include <asm/cpufeature-macros.h>
> +#include <asm/hwcap.h>
> +#include <asm-generic/bitops/__bitrev.h>
> +
> +static __always_inline __attribute_const__ u32 __arch_bitrev32(u32 x)
> +{
> + unsigned long result = (unsigned long)x;
Just:
unsigned long result;
> +
> + if (!riscv_has_extension_likely(RISCV_ISA_EXT_ZBKB))
> + return generic___bitrev32(x);
> +
> + asm volatile(
> + ".option push\n"
> + ".option arch,+zbkb\n"
> + "rev8 %0, %0\n"
Replace the source with %1
> + "brev8 %0, %0\n"
> + ".option pop"
> + : "+r" (result)
then:
: "=r" (result) : "r" ((long)x)
it is likely to save a register-register move
> + );
> +
> +#if __riscv_xlen == 64
> + return (u32)(result >> 32);
> +#else
> + return (u32)result;
> +#endif
There is no need to either cast, and the kernel style doesn't need them.
(Filling code with casts that match the implicit conversions just makes
it harder to find/check the ones that are absolutely necessary and actually
change the behaviour.)
You could just do:
return result >> (__riscv_xlen - 32);
> +}
> +
> +static __always_inline __attribute_const__ u16 __arch_bitrev16(u16 x)
> +{
> + return __arch_bitrev32((u32)x) >> 16;
Kill the cast.
> +}
> +
> +static __always_inline __attribute_const__ u8 __arch_bitrev8(u8 x)
> +{
> + unsigned long result = (unsigned long)x;
> +
> + if (!riscv_has_extension_likely(RISCV_ISA_EXT_ZBKB))
> + return generic___bitrev8(x);
> +
> + asm volatile(
> + ".option push\n"
> + ".option arch,+zbkb\n"
> + "brev8 %0, %0\n"
> + ".option pop"
> + : "+r" (result)
Use "=r" (result) : "r" ((long)x) again
> + );
> +
> + return (u8)result;
Kill another cast.
> +}
> +#endif
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 0/2] arch/riscv: Add bitrev.h file to support rev8 and brev8
2026-04-17 9:31 [PATCH v3 0/2] arch/riscv: Add bitrev.h file to support rev8 and brev8 Jinjie Ruan
2026-04-17 9:31 ` [PATCH v3 1/2] bitops: Define generic __bitrev8/16/32 for reuse Jinjie Ruan
2026-04-17 9:31 ` [PATCH v3 2/2] arch/riscv: Add bitrev.h file to support rev8 and brev8 Jinjie Ruan
@ 2026-04-17 16:09 ` Yury Norov
2026-04-17 18:42 ` David Laight
2 siblings, 1 reply; 6+ messages in thread
From: Yury Norov @ 2026-04-17 16:09 UTC (permalink / raw)
To: Jinjie Ruan
Cc: pjw, palmer, aou, alex, yury.norov, linux, arnd, akpm,
linux-riscv, linux-kernel, linux-arch, david.laight.linux, nathan
On Fri, Apr 17, 2026 at 05:31:00PM +0800, Jinjie Ruan wrote:
> Add bitrev.h file to support rev8 and brev8 for riscv.
>
> Tested functionally on riscv64 QEMU with:
> "-M virt,acpi=on,zbkb=true,zbb=true"
>
> Changes in v3:
> - Fix the build issue by remving the CONFIG_HAVE_ARCH_BITREVERSE macro
> for byte_rev_table.
No arch needs byte_rev_table, except risc-v under a very certain
configuration. Please find a better approach that wouldn't bloat
random victims' .data section.
> - Update the riscv implementation as David suggested.
> - Add Reviwed-by.
>
> Changes in v2:
> - Define generic __bitrev8/16/32 for reuse in riscv.
>
> Jinjie Ruan (2):
> bitops: Define generic __bitrev8/16/32 for reuse
> arch/riscv: Add bitrev.h file to support rev8 and brev8
>
> arch/riscv/Kconfig | 1 +
> arch/riscv/include/asm/bitrev.h | 55 +++++++++++++++++++++++++++
> include/asm-generic/bitops/__bitrev.h | 22 +++++++++++
> include/linux/bitrev.h | 20 ++--------
> lib/bitrev.c | 3 --
> 5 files changed, 82 insertions(+), 19 deletions(-)
> create mode 100644 arch/riscv/include/asm/bitrev.h
> create mode 100644 include/asm-generic/bitops/__bitrev.h
>
> --
> 2.34.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 0/2] arch/riscv: Add bitrev.h file to support rev8 and brev8
2026-04-17 16:09 ` [PATCH v3 0/2] " Yury Norov
@ 2026-04-17 18:42 ` David Laight
0 siblings, 0 replies; 6+ messages in thread
From: David Laight @ 2026-04-17 18:42 UTC (permalink / raw)
To: Yury Norov
Cc: Jinjie Ruan, pjw, palmer, aou, alex, yury.norov, linux, arnd,
akpm, linux-riscv, linux-kernel, linux-arch, nathan
On Fri, 17 Apr 2026 12:09:03 -0400
Yury Norov <ynorov@nvidia.com> wrote:
> On Fri, Apr 17, 2026 at 05:31:00PM +0800, Jinjie Ruan wrote:
> > Add bitrev.h file to support rev8 and brev8 for riscv.
> >
> > Tested functionally on riscv64 QEMU with:
> > "-M virt,acpi=on,zbkb=true,zbb=true"
> >
> > Changes in v3:
> > - Fix the build issue by remving the CONFIG_HAVE_ARCH_BITREVERSE macro
> > for byte_rev_table.
>
> No arch needs byte_rev_table, except risc-v under a very certain
> configuration. Please find a better approach that wouldn't bloat
> random victims' .data section.
Eh?
x86 doesn't have a bit-reverse instruction.
The only arch that 'select HAVE_ARCH_BITREVERSE' are arm64, arm32 (some cpu),
loongarch and mips (for CPU_MIPSR6).
I think you mean that no arch that sets CONFIG_HAVE_ARCH_BITREVERSE needs it
except riscv.
Could you globally have:
select NEED_BYTE_REV_TABLE if !HAVE_ARCH_BITREVERSE
and then riscv could also select it?
(And isn't there a method of including files in the build based on
kconfig options rather than unconditionally compiling it and getting cpp
to throw the contents away?)
David
>
> > - Update the riscv implementation as David suggested.
> > - Add Reviwed-by.
> >
> > Changes in v2:
> > - Define generic __bitrev8/16/32 for reuse in riscv.
> >
> > Jinjie Ruan (2):
> > bitops: Define generic __bitrev8/16/32 for reuse
> > arch/riscv: Add bitrev.h file to support rev8 and brev8
> >
> > arch/riscv/Kconfig | 1 +
> > arch/riscv/include/asm/bitrev.h | 55 +++++++++++++++++++++++++++
> > include/asm-generic/bitops/__bitrev.h | 22 +++++++++++
> > include/linux/bitrev.h | 20 ++--------
> > lib/bitrev.c | 3 --
> > 5 files changed, 82 insertions(+), 19 deletions(-)
> > create mode 100644 arch/riscv/include/asm/bitrev.h
> > create mode 100644 include/asm-generic/bitops/__bitrev.h
> >
> > --
> > 2.34.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-04-17 18:43 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-17 9:31 [PATCH v3 0/2] arch/riscv: Add bitrev.h file to support rev8 and brev8 Jinjie Ruan
2026-04-17 9:31 ` [PATCH v3 1/2] bitops: Define generic __bitrev8/16/32 for reuse Jinjie Ruan
2026-04-17 9:31 ` [PATCH v3 2/2] arch/riscv: Add bitrev.h file to support rev8 and brev8 Jinjie Ruan
2026-04-17 13:17 ` David Laight
2026-04-17 16:09 ` [PATCH v3 0/2] " Yury Norov
2026-04-17 18:42 ` David Laight
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox