All of lore.kernel.org
 help / color / mirror / Atom feed
From: Aurelien Jarno <aurelien@aurel32.net>
To: spacemit@lists.linux.dev
Cc: linux-riscv@lists.infradead.org,
	Andy Chiu <tchiu@tenstorrent.com>,
	Karl Mehltretter <kmehltretter@gmail.com>
Subject: Re: Random corruption on SpacemiT K1 (and K3) with RVV
Date: Wed, 9 Sep 2026 18:45:14 +0200	[thread overview]
Message-ID: <aqGNGp8PInSV4vty@aurel32.net> (raw)
In-Reply-To: <ap-SIQ9DLt-CfAx6@aurel32.net>

[Added Andy and Karl in Cc: as they have been involved in the vectored 
user copy code and fighting similar issues]

Hi,

Some more progress on that topic.

On 2026-09-08 06:42, Aurelien Jarno wrote:
> Dear all,
> 
> I have done some small progress on that issue. Help is still wanted and 
> would be appreciated.
> 
> On 2026-08-30 22:52, Aurelien Jarno wrote:
> > Dear all,
> > 
> > For the last weeks, I have been tracking a random memory corruption and
> > relatively rare on SpacemiT K1 (Banana Pi F3 and Milk-V Jupiter). It 
> > started upgrading to glibc 2.43, which does memset() through vector 
> > instructions.  It is reproducible using the Debian 7.1.7-1~bpo13+1 
> > kernel, but I have also been able to reproduce it with a vanilla 7.2.2 
> > kernel, using a similar configuration to the Debian kernel. The board 
> > uses OpenSBI 1.9 and the vendor U-Boot.
> 
> I have been able to rule out OpenSBI from the issue, I have checked 
> there is not trap top OpenSBI when the problem happens.
> 
> > Typically it manifests itself with the following kind of error, when 
> > running g++ from GCC 16 as part of building software (e.g. OpenJDK, 
> > Blender, Dolfin, Qt6):   
> > 
> > Assembler messages:
> > {standard input}:284588: Error: unknown pseudo-op: `.uleb1'
> > {standard input}:284588: Error: unrecognized opcode `ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿvl874'
> > 
> > The broken chars are 0xff and it seems there are always 240 (but with 
> > poor statistics). Sometimes it instead causes a GCC ICE instead.
> 
> I have identified that the 0xff comes from the poisoning done for v0 in
> __riscv_v_vstate_discard(), which should only happen for a syscall. 
> Indeed changing the value to different ones propagates to the above 
> error message.
> 
> Furthermore I have found that changing CONFIG_RISCV_ISA_V_PREEMPTIVE 
> doesn't change anything, and that changing RISCV_ISA_V_UCOPY_THRESHOLD 
> changes the number of broken bytes.

The values from __riscv_v_vstate_discard() end-up there because they are 
the last values written to the vector registers. I have added some 
poisoning in __asm_vector_usercopy_sum_enabled before the loop, and 
those values appear instead. Using different values per vector register, 
I have found that the corruption comes from a partial load of the vle8.v 
instruction, while the result of the poisoning and the partial load are
then both written by the vse8.v:

 loop:
        vsetvli iVL, iNum, e8, ELEM_LMUL_SETTING, ta, ma
        fixup vle8.v vData, (pSrc), 10f
        sub iNum, iNum, iVL
        add pSrc, pSrc, iVL
        fixup vse8.v vData, (pDst), 11f
        add pDst, pDst, iVL
        bnez iNum, loop

One hypothesis could be that for some reason, an exception (page table 
fault, irq, ...), the vle8.v instruction is interrupted, and only 
partially loads the vector register from memory. This stops at a 16-byte 
boundary (at least on the K1), and the remaining part of the v0-v7 
register is left with the previous value (with the original kernel that 
is the poisoning done in __riscv_v_vstate_discard). In theory when the 
instruction is interrupted, vstart is set to a non-zero value (for 
instance 16), and it should get re-executed after the exception. In 
practice, in some very rare cases, it doesn't happen and the next 
executed instruction is the following sub.

That said with exceptions and vector context switches, the explanation 
is likely way more complex. [1] gives a possible different scenario, 
involving an interrupt or a fault between the vsetvli and vle8.v/vse8.v 
instructions. However it doesn't fix the issue, neither patch [2]
(in that case tested with CONFIG_RISCV_ISA_V_PREEMPTIVE=y).


> Disabling the vectored user code entirely with the following patch seems
> to prevent the issue (or make it sufficiently rare that I have not 
> encountered it):

A much better way to do that is setting RISCV_ISA_V_UCOPY_THRESHOLD=-1.  

I also tried the same kernel on a K3, and it appears to improve 
stability, getting rid of issues that I attributed to thermal issues.  
(due to the absence of fan driver, I run the fan as a fixed speed 
~4000rpm). The symptoms are however quite different, it's GCC crashes 
with "The bug is not reproducible, so it is likely a hardware or OS 
problem.".

Regards
Aurelien

[1] https://lore.kernel.org/20260806193241.10552-1-kmehltretter@gmail.com/
[2] https://lore.kernel.org/all/20260810172255.1532787-2-tchiu@tenstorrent.com/

-- 
Aurelien Jarno                          GPG: 4096R/1DDD8C9B
aurelien@aurel32.net                     http://aurel32.net

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

WARNING: multiple messages have this Message-ID (diff)
From: Aurelien Jarno <aurelien@aurel32.net>
To: spacemit@lists.linux.dev
Cc: linux-riscv@lists.infradead.org,
	Andy Chiu <tchiu@tenstorrent.com>,
	Karl Mehltretter <kmehltretter@gmail.com>
Subject: Re: Random corruption on SpacemiT K1 (and K3) with RVV
Date: Wed, 9 Sep 2026 18:45:14 +0200	[thread overview]
Message-ID: <aqGNGp8PInSV4vty@aurel32.net> (raw)
In-Reply-To: <ap-SIQ9DLt-CfAx6@aurel32.net>

[Added Andy and Karl in Cc: as they have been involved in the vectored 
user copy code and fighting similar issues]

Hi,

Some more progress on that topic.

On 2026-09-08 06:42, Aurelien Jarno wrote:
> Dear all,
> 
> I have done some small progress on that issue. Help is still wanted and 
> would be appreciated.
> 
> On 2026-08-30 22:52, Aurelien Jarno wrote:
> > Dear all,
> > 
> > For the last weeks, I have been tracking a random memory corruption and
> > relatively rare on SpacemiT K1 (Banana Pi F3 and Milk-V Jupiter). It 
> > started upgrading to glibc 2.43, which does memset() through vector 
> > instructions.  It is reproducible using the Debian 7.1.7-1~bpo13+1 
> > kernel, but I have also been able to reproduce it with a vanilla 7.2.2 
> > kernel, using a similar configuration to the Debian kernel. The board 
> > uses OpenSBI 1.9 and the vendor U-Boot.
> 
> I have been able to rule out OpenSBI from the issue, I have checked 
> there is not trap top OpenSBI when the problem happens.
> 
> > Typically it manifests itself with the following kind of error, when 
> > running g++ from GCC 16 as part of building software (e.g. OpenJDK, 
> > Blender, Dolfin, Qt6):   
> > 
> > Assembler messages:
> > {standard input}:284588: Error: unknown pseudo-op: `.uleb1'
> > {standard input}:284588: Error: unrecognized opcode `ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿvl874'
> > 
> > The broken chars are 0xff and it seems there are always 240 (but with 
> > poor statistics). Sometimes it instead causes a GCC ICE instead.
> 
> I have identified that the 0xff comes from the poisoning done for v0 in
> __riscv_v_vstate_discard(), which should only happen for a syscall. 
> Indeed changing the value to different ones propagates to the above 
> error message.
> 
> Furthermore I have found that changing CONFIG_RISCV_ISA_V_PREEMPTIVE 
> doesn't change anything, and that changing RISCV_ISA_V_UCOPY_THRESHOLD 
> changes the number of broken bytes.

The values from __riscv_v_vstate_discard() end-up there because they are 
the last values written to the vector registers. I have added some 
poisoning in __asm_vector_usercopy_sum_enabled before the loop, and 
those values appear instead. Using different values per vector register, 
I have found that the corruption comes from a partial load of the vle8.v 
instruction, while the result of the poisoning and the partial load are
then both written by the vse8.v:

 loop:
        vsetvli iVL, iNum, e8, ELEM_LMUL_SETTING, ta, ma
        fixup vle8.v vData, (pSrc), 10f
        sub iNum, iNum, iVL
        add pSrc, pSrc, iVL
        fixup vse8.v vData, (pDst), 11f
        add pDst, pDst, iVL
        bnez iNum, loop

One hypothesis could be that for some reason, an exception (page table 
fault, irq, ...), the vle8.v instruction is interrupted, and only 
partially loads the vector register from memory. This stops at a 16-byte 
boundary (at least on the K1), and the remaining part of the v0-v7 
register is left with the previous value (with the original kernel that 
is the poisoning done in __riscv_v_vstate_discard). In theory when the 
instruction is interrupted, vstart is set to a non-zero value (for 
instance 16), and it should get re-executed after the exception. In 
practice, in some very rare cases, it doesn't happen and the next 
executed instruction is the following sub.

That said with exceptions and vector context switches, the explanation 
is likely way more complex. [1] gives a possible different scenario, 
involving an interrupt or a fault between the vsetvli and vle8.v/vse8.v 
instructions. However it doesn't fix the issue, neither patch [2]
(in that case tested with CONFIG_RISCV_ISA_V_PREEMPTIVE=y).


> Disabling the vectored user code entirely with the following patch seems
> to prevent the issue (or make it sufficiently rare that I have not 
> encountered it):

A much better way to do that is setting RISCV_ISA_V_UCOPY_THRESHOLD=-1.  

I also tried the same kernel on a K3, and it appears to improve 
stability, getting rid of issues that I attributed to thermal issues.  
(due to the absence of fan driver, I run the fan as a fixed speed 
~4000rpm). The symptoms are however quite different, it's GCC crashes 
with "The bug is not reproducible, so it is likely a hardware or OS 
problem.".

Regards
Aurelien

[1] https://lore.kernel.org/20260806193241.10552-1-kmehltretter@gmail.com/
[2] https://lore.kernel.org/all/20260810172255.1532787-2-tchiu@tenstorrent.com/

-- 
Aurelien Jarno                          GPG: 4096R/1DDD8C9B
aurelien@aurel32.net                     http://aurel32.net

  reply	other threads:[~2026-09-09 16:45 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-30 20:52 Random corruption on SpacemiT K1 with RVV and THP Aurelien Jarno
2026-08-30 20:52 ` Aurelien Jarno
2026-09-08  4:42 ` Random corruption on SpacemiT K1 with RVV Aurelien Jarno
2026-09-08  4:42   ` Aurelien Jarno
2026-09-09 16:45   ` Aurelien Jarno [this message]
2026-09-09 16:45     ` Random corruption on SpacemiT K1 (and K3) " Aurelien Jarno

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=aqGNGp8PInSV4vty@aurel32.net \
    --to=aurelien@aurel32.net \
    --cc=kmehltretter@gmail.com \
    --cc=linux-riscv@lists.infradead.org \
    --cc=spacemit@lists.linux.dev \
    --cc=tchiu@tenstorrent.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.