[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