[PATCH v4] riscv: Use Zalrsc extension to implement atomic functions
Aleksa Paunovic
aleksa.paunovic at htecgroup.com
Mon Aug 10 08:20:22 PDT 2026
Hi Jesse,
On 7/28/26 00:37, Jesse Taube wrote:
> On Mon, Jul 27, 2026 at 5:03 PM Jesse Taube <jtaubepe at redhat.com> wrote:
>> On Thu, Jul 23, 2026 at 11:53 AM Aleksa Paunovic via B4 Relay
>> <devnull+aleksa.paunovic.htecgroup.com at kernel.org> wrote:
>>> From: Chao-ying Fu <cfu at mips.com>
>>>
>>> MIPS P8700 does not natively support Zaamo instructions.
>>> They are emulated with Zalrsc extension instructions instead [1].
>>> Since the emulation is implemented through M-mode traps in the SBI
>>> layer, it is best to avoid using these instructions wherever possible on
>>> the P8700.
>>>
>>> Implement kernel atomic operations using LR/SC sequences only.
>>> This is achieved by using the errata mechanism, with minimal
>>> interference on other cores.
>>>
>>> Signed-off-by: Chao-ying Fu <cfu at mips.com>
>>> Signed-off-by: Aleksandar Rikalo <arikalo at gmail.com>
>>> Co-developed-by: Aleksa Paunovic <aleksa.paunovic at htecgroup.com>
>>> Signed-off-by: Aleksa Paunovic <aleksa.paunovic at htecgroup.com>
> Tested-by: Jesse Taube <jtaubepe at redhat.com>
Thank you for taking the time to test the patch!
>
>>> [1] https://mips.com/wp-content/uploads/2026/03/MIPS_P8700_P8700-F_Programmers_Reference_Guide_Rev1.86_2-17-2026.pdf
>>>
>>> ---
>>> The patch was tested on QEMU configured to emulate an eight-hart MIPS P8700 CPU.
>> Can you share the tests. I made my own tests a while back here:
>> https://github.com/Mr-Bossman/zalrsc-buildroot/tree/master
>> Though they don't seem to boot without the zaamo extension
> I found out that the devicetree needs to have the amo extention to work.
> Somewhere there is a patch to split support into Zalrsc and Zaamo, but
> here is one on my tree
> https://github.com/Mr-Bossman/linux/commit/2bde8c4382a55cb82e769b0c8d9d8bf1b9c9164d
That's correct. We still pass 'a' to the riscv,isa-extensions list in our private dts.
I think [1] both addresses this issue and overlaps with this patch.
If it's not a major issue though, we are content with leaving things as they are.
The tests I ran were generic kselftests (and kernel modules). Compiled with GCC 15.1.0.
>> Thanks,
>> Jesse Taube
>>
>>> Testing done since v3: futex kselftests and perf futex tests. These tests caught the issues described below.
>>> The same tests were executed on the Boston board with a single-hart P8700 core.
>>>
>>> Since the main issue was with an incorrectly written erratum, it shouldn't affect Vladimir's version [1].
>>> However, since chips supporting only one part of the A extension are rare, we believe it might be
>>> better to address this using the alternative mechanism, instead of demanding that the wider community
>>> relax the A extension requirement.
>>>
>>> Changes in v4:
>>> - The amo part of the ALT_TEST_AND_OP_BIT_ORD erratum erroneously hardcoded zero as the destination register.
>>> This is fixed in v4.
>>> - futex.h was missing the ANDN case.
>>> - Link to v3: https://lore.kernel.org/r/20250901-p8700-zalrsc-v3-1-ec64fabbe093@htecgroup.com
>>>
>>> Changes in v3:
>>> - Use alternatives to replace AMO instructions with LR/SC
>>> - Rebase on Alexandre Ghiti's "for-next" branch.
>>> - Link to v2: https://lore.kernel.org/linux-riscv/20241225082412.36727-1-arikalo@gmail.com/
>>>
>>> Links:
>>> [1] https://lore.kernel.org/linux-riscv/20260120-lrsc-only-v2-0-a522e640d27d@mobileye.com/
>>>
>>> Signed-off-by: Aleksa Paunovic <aleksa.paunovic at htecgroup.com>
>>> ---
>>> arch/riscv/Kconfig.errata | 11 ++
>>> arch/riscv/errata/mips/errata.c | 13 +-
>>> arch/riscv/include/asm/atomic.h | 29 ++--
>>> arch/riscv/include/asm/bitops.h | 28 ++--
>>> arch/riscv/include/asm/cmpxchg.h | 9 +-
>>> arch/riscv/include/asm/errata_list.h | 215 +++++++++++++++++++++++++++
>>> arch/riscv/include/asm/errata_list_vendors.h | 3 +-
>>> arch/riscv/include/asm/futex.h | 40 ++---
>>> arch/riscv/kernel/entry.S | 10 +-
>>> 9 files changed, 290 insertions(+), 68 deletions(-)
>>>
>>> diff --git a/arch/riscv/Kconfig.errata b/arch/riscv/Kconfig.errata
>>> index 3c945d086c7d0266b685f9506d58b0662af071c4..cd5bd5e8eb395418c3ad103dbd836c775b7fd901 100644
>>> --- a/arch/riscv/Kconfig.errata
>>> +++ b/arch/riscv/Kconfig.errata
>>> @@ -44,6 +44,17 @@ config ERRATA_MIPS_P8700_PAUSE_OPCODE
>>>
>>> If you are not using the P8700 processor, say n.
>>>
>>> +config ERRATA_MIPS_P8700_AMO_ZALRSC
>>> + bool "Replace AMO instructions with LR/SC on MIPS P8700"
>>> + depends on ERRATA_MIPS && 64BIT
>>> + default n
>>> + help
>>> + The MIPS P8700 does not implement the full A extension,
>>> + implementing only Zalrsc. Enabling this will replace
>>> + all AMO instructions with LR/SC instructions on the P8700.
>>> +
>>> + If you are not using the P8700 processor, say n.
>>> +
>>> config ERRATA_SIFIVE
>>> bool "SiFive errata"
>>> depends on RISCV_ALTERNATIVE
>>> diff --git a/arch/riscv/errata/mips/errata.c b/arch/riscv/errata/mips/errata.c
>>> index e984a8152208c34690f89d8101571b097485c360..08c5efd58bf242d3831957f91f6338ef49f61238 100644
>>> --- a/arch/riscv/errata/mips/errata.c
>>> +++ b/arch/riscv/errata/mips/errata.c
>>> @@ -23,13 +23,22 @@ static inline bool errata_probe_pause(void)
>>> return true;
>>> }
>>>
>>> -static u32 mips_errata_probe(void)
>>> +static inline bool errata_probe_zalrsc(unsigned long archid)
>>> +{
>>> + return archid == 0x8000000000000201;
>>> +}
>>> +
>>> +static u32 mips_errata_probe(unsigned long archid)
>>> {
>>> u32 cpu_req_errata = 0;
>>>
>>> if (errata_probe_pause())
>>> cpu_req_errata |= BIT(ERRATA_MIPS_P8700_PAUSE_OPCODE);
>>>
>>> + if (errata_probe_zalrsc(archid))
>>> + cpu_req_errata |= BIT(ERRATA_MIPS_P8700_ZALRSC);
>>> +
>>> +
>>> return cpu_req_errata;
>>> }
>>>
>>> @@ -38,7 +47,7 @@ void mips_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
>>> unsigned int stage)
>>> {
> We should be patching this in at RISCV_ALTERNATIVES_EARLY_BOOT
> This gives as few instructions as possible that aren't patched. Please
> do something
> similar to how thead does it.
> https://elixir.bootlin.com/linux/v7.2-rc4/source/arch/riscv/errata/thead/errata.c#L222
Thank you for the suggestion! I just sent out a patch to address this.
Best regards,
Aleksa
Links:
[1] https://lore.kernel.org/linux-riscv/20260120-lrsc-only-v2-1-a522e640d27d@mobileye.com/
More information about the linux-riscv
mailing list