* [PATCH] arch/riscv: Add bitrev.h file to support rev8 and brev8
@ 2026-03-11 7:13 Jinjie Ruan
2026-04-02 6:41 ` Jinjie Ruan
2026-04-10 11:36 ` cp0613
0 siblings, 2 replies; 6+ messages in thread
From: Jinjie Ruan @ 2026-03-11 7:13 UTC (permalink / raw)
To: pjw, palmer, aou, alex, akpm, ruanjinjie, linux-riscv,
linux-kernel
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.
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/riscv/Kconfig | 1 +
arch/riscv/include/asm/bitrev.h | 46 +++++++++++++++++++++++++++++++++
lib/bitrev.c | 3 ---
3 files changed, 47 insertions(+), 3 deletions(-)
create mode 100644 arch/riscv/include/asm/bitrev.h
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 90c531e6abf5..e7a04b96c0c8 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
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..b1977600638a
--- /dev/null
+++ b/arch/riscv/include/asm/bitrev.h
@@ -0,0 +1,46 @@
+/* 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>
+
+extern u8 const byte_rev_table[256];
+static __always_inline __attribute_const__ u32 __arch_bitrev32(u32 x)
+{
+ if (IS_ENABLED(CONFIG_RISCV_ISA_ZBKB) &&
+ riscv_has_extension_likely(RISCV_ISA_EXT_ZBKB)) {
+ unsigned long result = 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);
+
+ return (u32)result;
+ }
+
+ return (u32)byte_rev_table[x & 0xff] << 24 |
+ (u32)byte_rev_table[(x >> 8) & 0xff] << 16 |
+ (u32)byte_rev_table[(x >> 16) & 0xff] << 8 |
+ (u32)byte_rev_table[x >> 24];
+}
+
+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)
+{
+ return __arch_bitrev32((u32)x) >> 24;
+}
+#endif
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
* Re: [PATCH] arch/riscv: Add bitrev.h file to support rev8 and brev8
2026-03-11 7:13 [PATCH] arch/riscv: Add bitrev.h file to support rev8 and brev8 Jinjie Ruan
@ 2026-04-02 6:41 ` Jinjie Ruan
2026-04-10 11:36 ` cp0613
1 sibling, 0 replies; 6+ messages in thread
From: Jinjie Ruan @ 2026-04-02 6:41 UTC (permalink / raw)
To: pjw, palmer, aou, alex, akpm, linux-riscv, linux-kernel
On 2026/3/11 15:13, Jinjie Ruan 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.
Gentle ping.
>
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
> ---
> arch/riscv/Kconfig | 1 +
> arch/riscv/include/asm/bitrev.h | 46 +++++++++++++++++++++++++++++++++
> lib/bitrev.c | 3 ---
> 3 files changed, 47 insertions(+), 3 deletions(-)
> create mode 100644 arch/riscv/include/asm/bitrev.h
>
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index 90c531e6abf5..e7a04b96c0c8 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
> 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..b1977600638a
> --- /dev/null
> +++ b/arch/riscv/include/asm/bitrev.h
> @@ -0,0 +1,46 @@
> +/* 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>
> +
> +extern u8 const byte_rev_table[256];
> +static __always_inline __attribute_const__ u32 __arch_bitrev32(u32 x)
> +{
> + if (IS_ENABLED(CONFIG_RISCV_ISA_ZBKB) &&
> + riscv_has_extension_likely(RISCV_ISA_EXT_ZBKB)) {
> + unsigned long result = 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);
> +
> + return (u32)result;
> + }
> +
> + return (u32)byte_rev_table[x & 0xff] << 24 |
> + (u32)byte_rev_table[(x >> 8) & 0xff] << 16 |
> + (u32)byte_rev_table[(x >> 16) & 0xff] << 8 |
> + (u32)byte_rev_table[x >> 24];
> +}
> +
> +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)
> +{
> + return __arch_bitrev32((u32)x) >> 24;
> +}
> +#endif
> 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 */
_______________________________________________
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] arch/riscv: Add bitrev.h file to support rev8 and brev8
2026-03-11 7:13 [PATCH] arch/riscv: Add bitrev.h file to support rev8 and brev8 Jinjie Ruan
2026-04-02 6:41 ` Jinjie Ruan
@ 2026-04-10 11:36 ` cp0613
2026-04-11 2:48 ` Jinjie Ruan
1 sibling, 1 reply; 6+ messages in thread
From: cp0613 @ 2026-04-10 11:36 UTC (permalink / raw)
To: ruanjinjie; +Cc: akpm, alex, aou, linux-kernel, linux-riscv, palmer, pjw
On Wed, 11 Mar 2026 15:13:44 +0800, ruanjinjie@huawei.com wrote:
> +#include <linux/types.h>
> +#include <asm/cpufeature-macros.h>
> +#include <asm/hwcap.h>
> +
> +extern u8 const byte_rev_table[256];
> +static __always_inline __attribute_const__ u32 __arch_bitrev32(u32 x)
> +{
> + if (IS_ENABLED(CONFIG_RISCV_ISA_ZBKB) &&
> + riscv_has_extension_likely(RISCV_ISA_EXT_ZBKB)) {
> + unsigned long result = 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);
> +
> + return (u32)result;
> + }
> +
> + return (u32)byte_rev_table[x & 0xff] << 24 |
> + (u32)byte_rev_table[(x >> 8) & 0xff] << 16 |
> + (u32)byte_rev_table[(x >> 16) & 0xff] << 8 |
> + (u32)byte_rev_table[x >> 24];
> +}
Hi Jinjie,
Thanks for your patch. I have two suggestions.
1. When ZBKB is not supported, is it simpler to directly use the generic
implementation __bitrev32 in <linux/bitrev.h>.
2. Could you please provide a benchmark test case to illustrate the
performance comparison with and without this extension (refer to
test_bitops.c) and also provide the results by bloat-o-meter.
Thanks,
Pei
_______________________________________________
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] arch/riscv: Add bitrev.h file to support rev8 and brev8
2026-04-10 11:36 ` cp0613
@ 2026-04-11 2:48 ` Jinjie Ruan
2026-04-13 12:28 ` cp0613
0 siblings, 1 reply; 6+ messages in thread
From: Jinjie Ruan @ 2026-04-11 2:48 UTC (permalink / raw)
To: cp0613; +Cc: akpm, alex, aou, linux-kernel, linux-riscv, palmer, pjw
On 2026/4/10 19:36, cp0613@linux.alibaba.com wrote:
> On Wed, 11 Mar 2026 15:13:44 +0800, ruanjinjie@huawei.com wrote:
>
>> +#include <linux/types.h>
>> +#include <asm/cpufeature-macros.h>
>> +#include <asm/hwcap.h>
>> +
>> +extern u8 const byte_rev_table[256];
>> +static __always_inline __attribute_const__ u32 __arch_bitrev32(u32 x)
>> +{
>> + if (IS_ENABLED(CONFIG_RISCV_ISA_ZBKB) &&
>> + riscv_has_extension_likely(RISCV_ISA_EXT_ZBKB)) {
>> + unsigned long result = 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);
>> +
>> + return (u32)result;
>> + }
>> +
>> + return (u32)byte_rev_table[x & 0xff] << 24 |
>> + (u32)byte_rev_table[(x >> 8) & 0xff] << 16 |
>> + (u32)byte_rev_table[(x >> 16) & 0xff] << 8 |
>> + (u32)byte_rev_table[x >> 24];
>> +}
>
> Hi Jinjie,
>
> Thanks for your patch. I have two suggestions.
> 1. When ZBKB is not supported, is it simpler to directly use the generic
> implementation __bitrev32 in <linux/bitrev.h>.
Actually, you can't simply use the default implementation from
linux/bitrev.h. It includes asm/bitrev.h (the architecture-specific
implementation), which would lead to compilation issues. Furthermore,
when ZBKB is not supported, current implementation is identical to the
default one.
> 2. Could you please provide a benchmark test case to illustrate the
> performance comparison with and without this extension (refer to
> test_bitops.c) and also provide the results by bloat-o-meter.
I don't have access to RISC-V hardware at the moment, so I've only
performed basic functional testing on QEMU, which completed without
issues,could you please help run some benchmarks to verify the performance?
Thanks,
Jinjie
>
> Thanks,
> Pei
_______________________________________________
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] arch/riscv: Add bitrev.h file to support rev8 and brev8
2026-04-11 2:48 ` Jinjie Ruan
@ 2026-04-13 12:28 ` cp0613
2026-04-15 7:39 ` Jinjie Ruan
0 siblings, 1 reply; 6+ messages in thread
From: cp0613 @ 2026-04-13 12:28 UTC (permalink / raw)
To: ruanjinjie; +Cc: akpm, alex, aou, linux-kernel, linux-riscv, palmer, pjw
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=y, Size: 2271 bytes --]
On Sat, 11 Apr 2026 10:48:17 +0800, ruanjinjie@huawei.com wrote:
> >> +#include <linux/types.h>
> >> +#include <asm/cpufeature-macros.h>
> >> +#include <asm/hwcap.h>
> >> +
> >> +extern u8 const byte_rev_table[256];
> >> +static __always_inline __attribute_const__ u32 __arch_bitrev32(u32 x)
> >> +{
> >> + if (IS_ENABLED(CONFIG_RISCV_ISA_ZBKB) &&
> >> + riscv_has_extension_likely(RISCV_ISA_EXT_ZBKB)) {
> >> + unsigned long result = 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);
> >> +
> >> + return (u32)result;
> >> + }
> >> +
> >> + return (u32)byte_rev_table[x & 0xff] << 24 |
> >> + (u32)byte_rev_table[(x >> 8) & 0xff] << 16 |
> >> + (u32)byte_rev_table[(x >> 16) & 0xff] << 8 |
> >> + (u32)byte_rev_table[x >> 24];
> >> +}
> >
> > Hi Jinjie,
> >
> > Thanks for your patch. I have two suggestions.
> > 1. When ZBKB is not supported, is it simpler to directly use the generic
> > implementation __bitrev32 in <linux/bitrev.h>.
>
> Actually, you can't simply use the default implementation from
> linux/bitrev.h. It includes asm/bitrev.h (the architecture-specific
> implementation), which would lead to compilation issues. Furthermore,
> when ZBKB is not supported, current implementation is identical to the
> default one.
Understood. So, have you considered renaming the function to `generic_xxx`,
like `generic___ffs` in bitops?
> > 2. Could you please provide a benchmark test case to illustrate the
> > performance comparison with and without this extension (refer to
> > test_bitops.c) and also provide the results by bloat-o-meter.
>
> I don't have access to RISC-V hardware at the moment, so I've only
> performed basic functional testing on QEMU, which completed without
> issues,could you please help run some benchmarks to verify the performance?
I don't currently have the hardware that supports the corresponding extension,
but I can test it using an FPGA environment when I have the opportunity (it
will take some time).
> Thanks,
> Jinjie
>
> >
> > Thanks,
> > Pei
Thanks,
Pei
[-- Attachment #2: Type: text/plain, Size: 161 bytes --]
_______________________________________________
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] arch/riscv: Add bitrev.h file to support rev8 and brev8
2026-04-13 12:28 ` cp0613
@ 2026-04-15 7:39 ` Jinjie Ruan
0 siblings, 0 replies; 6+ messages in thread
From: Jinjie Ruan @ 2026-04-15 7:39 UTC (permalink / raw)
To: cp0613; +Cc: akpm, alex, aou, linux-kernel, linux-riscv, palmer, pjw
On 4/13/2026 8:28 PM, cp0613@linux.alibaba.com wrote:
> On Sat, 11 Apr 2026 10:48:17 +0800, ruanjinjie@huawei.com wrote:
>
>>>> +#include <linux/types.h>
>>>> +#include <asm/cpufeature-macros.h>
>>>> +#include <asm/hwcap.h>
>>>> +
>>>> +extern u8 const byte_rev_table[256];
>>>> +static __always_inline __attribute_const__ u32 __arch_bitrev32(u32 x)
>>>> +{
>>>> + if (IS_ENABLED(CONFIG_RISCV_ISA_ZBKB) &&
>>>> + riscv_has_extension_likely(RISCV_ISA_EXT_ZBKB)) {
>>>> + unsigned long result = 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);
>>>> +
>>>> + return (u32)result;
>>>> + }
>>>> +
>>>> + return (u32)byte_rev_table[x & 0xff] << 24 |
>>>> + (u32)byte_rev_table[(x >> 8) & 0xff] << 16 |
>>>> + (u32)byte_rev_table[(x >> 16) & 0xff] << 8 |
>>>> + (u32)byte_rev_table[x >> 24];
>>>> +}
>>>
>>> Hi Jinjie,
>>>
>>> Thanks for your patch. I have two suggestions.
>>> 1. When ZBKB is not supported, is it simpler to directly use the generic
>>> implementation __bitrev32 in <linux/bitrev.h>.
>>
>> Actually, you can't simply use the default implementation from
>> linux/bitrev.h. It includes asm/bitrev.h (the architecture-specific
>> implementation), which would lead to compilation issues. Furthermore,
>> when ZBKB is not supported, current implementation is identical to the
>> default one.
>
> Understood. So, have you considered renaming the function to `generic_xxx`,
> like `generic___ffs` in bitops?
You are right! I'll try doing it this way.
>
>>> 2. Could you please provide a benchmark test case to illustrate the
>>> performance comparison with and without this extension (refer to
>>> test_bitops.c) and also provide the results by bloat-o-meter.
>>
>> I don't have access to RISC-V hardware at the moment, so I've only
>> performed basic functional testing on QEMU, which completed without
>> issues,could you please help run some benchmarks to verify the performance?
>
> I don't currently have the hardware that supports the corresponding extension,
> but I can test it using an FPGA environment when I have the opportunity (it
> will take some time).
Thank you very much!
>
>> Thanks,
>> Jinjie
>>
>>>
>>> Thanks,
>>> Pei
>
> Thanks,
> Pei
_______________________________________________
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-15 7:39 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-11 7:13 [PATCH] arch/riscv: Add bitrev.h file to support rev8 and brev8 Jinjie Ruan
2026-04-02 6:41 ` Jinjie Ruan
2026-04-10 11:36 ` cp0613
2026-04-11 2:48 ` Jinjie Ruan
2026-04-13 12:28 ` cp0613
2026-04-15 7:39 ` Jinjie Ruan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox