public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] LoongArch: detect and disable sc.q if erratic
@ 2026-04-09 12:19 Xi Ruoyao
  2026-04-27  2:17 ` Ping: " Xi Ruoyao
  2026-04-28 18:47 ` Yao Zi
  0 siblings, 2 replies; 6+ messages in thread
From: Xi Ruoyao @ 2026-04-09 12:19 UTC (permalink / raw)
  To: Huacai Chen, WANG Xuerui
  Cc: Thomas Weißschuh, loongarch, Zixing Liu, Mingcong Bai,
	Xi Ruoyao, Arnd Bergmann, Jiaxun Yang, George Guo, linux-kernel

We've observed that, on some Loongson 2K3000/3B6000M systems with earlier
firmware revisions, the sc.q instruction may write incorrect data into
the upper half of the written 128-bit datum.

It seems upgrading the firmware (for example, the 202602 release from
Loongson [1]) will resolve the issue. But since not all systems may be
running the most up-to-date firmware, based on firmware update avail-
ability and the environment in which they are running in.

To help with system compatibility and ensure correct behavior, check if
sc.q behaves erratically and disable if so.

Link: https://github.com/loongson/Firmware/pull/156 [1]
Signed-off-by: Xi Ruoyao <xry111@xry111.site>
---
 arch/loongarch/kernel/cpu-probe.c | 39 ++++++++++++++++++++++++++++++-
 1 file changed, 38 insertions(+), 1 deletion(-)

diff --git a/arch/loongarch/kernel/cpu-probe.c b/arch/loongarch/kernel/cpu-probe.c
index 657bbae6c1c7..5fcf2672172f 100644
--- a/arch/loongarch/kernel/cpu-probe.c
+++ b/arch/loongarch/kernel/cpu-probe.c
@@ -132,6 +132,43 @@ static void set_isa(struct cpuinfo_loongarch *c, unsigned int isa)
 	}
 }
 
+/*
+ * Some LoongArch has broken sc.q which incorrectly handles the upper word
+ * when the lower word is zero. Newer firmware versions (such as the 202602
+ * release from Loongson) seem to contain a workaround for this issue.
+ *
+ * Disable sc.q if erratic to ensure reliability and compatibility.
+ */
+static bool sc_q_is_sane(void)
+{
+	struct {
+		long word[2];
+	} __aligned(16) mem;
+	register long tmp asm("t0");
+	register long one asm("t1") = 1;
+	register long *ptr asm("t2") = &mem.word[0];
+
+	/*
+	 * The sc.q instruction is hard coded with .word so the HWCAP bit
+	 * exported to the userspace won't depend on the assembler version
+	 * used to build the kernel.
+	 */
+	asm (
+		"1:ll.d\t$r0, %[ptr], 0\n\t"
+		"move\t%[tmp], $r0\n\t"
+		".word\t0x385735cc\n\t" /* sc.q %[tmp], %[one], %[ptr]*/
+		"beqz\t%[tmp], 1b"
+		: [tmp] "=&r" (tmp), "=m" (mem)
+		: [ptr] "r" (ptr), [one] "r" (one));
+
+	if (mem.word[1] != 1) {
+		pr_warn_once("Warning: sc.q is erratic on this platform, disabling for both kernel and HWCAP. Please try a firmware update.");
+		return false;
+	}
+
+	return true;
+}
+
 static void cpu_probe_common(struct cpuinfo_loongarch *c)
 {
 	unsigned int config;
@@ -177,7 +214,7 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c)
 		c->options |= LOONGARCH_CPU_LAM;
 		elf_hwcap |= HWCAP_LOONGARCH_LAM;
 	}
-	if (config & CPUCFG2_SCQ) {
+	if ((config & CPUCFG2_SCQ) && sc_q_is_sane()) {
 		c->options |= LOONGARCH_CPU_SCQ;
 		elf_hwcap |= HWCAP_LOONGARCH_SCQ;
 	}
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Ping: [PATCH v2] LoongArch: detect and disable sc.q if erratic
  2026-04-09 12:19 [PATCH v2] LoongArch: detect and disable sc.q if erratic Xi Ruoyao
@ 2026-04-27  2:17 ` Xi Ruoyao
  2026-04-27  8:43   ` Huacai Chen
  2026-04-28 18:47 ` Yao Zi
  1 sibling, 1 reply; 6+ messages in thread
From: Xi Ruoyao @ 2026-04-27  2:17 UTC (permalink / raw)
  To: Huacai Chen, WANG Xuerui
  Cc: Thomas Weißschuh, loongarch, Zixing Liu, Mingcong Bai,
	Arnd Bergmann, Jiaxun Yang, George Guo, linux-kernel

Ping.

On Thu, 2026-04-09 at 20:19 +0800, Xi Ruoyao wrote:
> We've observed that, on some Loongson 2K3000/3B6000M systems with earlier
> firmware revisions, the sc.q instruction may write incorrect data into
> the upper half of the written 128-bit datum.
> 
> It seems upgrading the firmware (for example, the 202602 release from
> Loongson [1]) will resolve the issue. But since not all systems may be
> running the most up-to-date firmware, based on firmware update avail-
> ability and the environment in which they are running in.
> 
> To help with system compatibility and ensure correct behavior, check if
> sc.q behaves erratically and disable if so.
> 
> Link: https://github.com/loongson/Firmware/pull/156 [1]
> Signed-off-by: Xi Ruoyao <xry111@xry111.site>
> ---
>  arch/loongarch/kernel/cpu-probe.c | 39 ++++++++++++++++++++++++++++++-
>  1 file changed, 38 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/loongarch/kernel/cpu-probe.c b/arch/loongarch/kernel/cpu-probe.c
> index 657bbae6c1c7..5fcf2672172f 100644
> --- a/arch/loongarch/kernel/cpu-probe.c
> +++ b/arch/loongarch/kernel/cpu-probe.c
> @@ -132,6 +132,43 @@ static void set_isa(struct cpuinfo_loongarch *c, unsigned int isa)
>  	}
>  }
>  
> +/*
> + * Some LoongArch has broken sc.q which incorrectly handles the upper word
> + * when the lower word is zero. Newer firmware versions (such as the 202602
> + * release from Loongson) seem to contain a workaround for this issue.
> + *
> + * Disable sc.q if erratic to ensure reliability and compatibility.
> + */
> +static bool sc_q_is_sane(void)
> +{
> +	struct {
> +		long word[2];
> +	} __aligned(16) mem;
> +	register long tmp asm("t0");
> +	register long one asm("t1") = 1;
> +	register long *ptr asm("t2") = &mem.word[0];
> +
> +	/*
> +	 * The sc.q instruction is hard coded with .word so the HWCAP bit
> +	 * exported to the userspace won't depend on the assembler version
> +	 * used to build the kernel.
> +	 */
> +	asm (
> +		"1:ll.d\t$r0, %[ptr], 0\n\t"
> +		"move\t%[tmp], $r0\n\t"
> +		".word\t0x385735cc\n\t" /* sc.q %[tmp], %[one], %[ptr]*/
> +		"beqz\t%[tmp], 1b"
> +		: [tmp] "=&r" (tmp), "=m" (mem)
> +		: [ptr] "r" (ptr), [one] "r" (one));
> +
> +	if (mem.word[1] != 1) {
> +		pr_warn_once("Warning: sc.q is erratic on this platform, disabling for both kernel and HWCAP. Please try a firmware update.");
> +		return false;
> +	}
> +
> +	return true;
> +}
> +
>  static void cpu_probe_common(struct cpuinfo_loongarch *c)
>  {
>  	unsigned int config;
> @@ -177,7 +214,7 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c)
>  		c->options |= LOONGARCH_CPU_LAM;
>  		elf_hwcap |= HWCAP_LOONGARCH_LAM;
>  	}
> -	if (config & CPUCFG2_SCQ) {
> +	if ((config & CPUCFG2_SCQ) && sc_q_is_sane()) {
>  		c->options |= LOONGARCH_CPU_SCQ;
>  		elf_hwcap |= HWCAP_LOONGARCH_SCQ;
>  	}

-- 
Xi Ruoyao <xry111@xry111.site>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Ping: [PATCH v2] LoongArch: detect and disable sc.q if erratic
  2026-04-27  2:17 ` Ping: " Xi Ruoyao
@ 2026-04-27  8:43   ` Huacai Chen
  2026-04-28 15:49     ` Xi Ruoyao
  0 siblings, 1 reply; 6+ messages in thread
From: Huacai Chen @ 2026-04-27  8:43 UTC (permalink / raw)
  To: Xi Ruoyao
  Cc: WANG Xuerui, Thomas Weißschuh, loongarch, Zixing Liu,
	Mingcong Bai, Arnd Bergmann, Jiaxun Yang, George Guo,
	linux-kernel

Hi, Ruoyao,

On Mon, Apr 27, 2026 at 10:17 AM Xi Ruoyao <xry111@xry111.site> wrote:
>
> Ping.
Can we keep this as an out-of-tree patch? It's a bit ugly and I think
the corrct way is update firmware.

Huacai

>
> On Thu, 2026-04-09 at 20:19 +0800, Xi Ruoyao wrote:
> > We've observed that, on some Loongson 2K3000/3B6000M systems with earlier
> > firmware revisions, the sc.q instruction may write incorrect data into
> > the upper half of the written 128-bit datum.
> >
> > It seems upgrading the firmware (for example, the 202602 release from
> > Loongson [1]) will resolve the issue. But since not all systems may be
> > running the most up-to-date firmware, based on firmware update avail-
> > ability and the environment in which they are running in.
> >
> > To help with system compatibility and ensure correct behavior, check if
> > sc.q behaves erratically and disable if so.
> >
> > Link: https://github.com/loongson/Firmware/pull/156 [1]
> > Signed-off-by: Xi Ruoyao <xry111@xry111.site>
> > ---
> >  arch/loongarch/kernel/cpu-probe.c | 39 ++++++++++++++++++++++++++++++-
> >  1 file changed, 38 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/loongarch/kernel/cpu-probe.c b/arch/loongarch/kernel/cpu-probe.c
> > index 657bbae6c1c7..5fcf2672172f 100644
> > --- a/arch/loongarch/kernel/cpu-probe.c
> > +++ b/arch/loongarch/kernel/cpu-probe.c
> > @@ -132,6 +132,43 @@ static void set_isa(struct cpuinfo_loongarch *c, unsigned int isa)
> >       }
> >  }
> >
> > +/*
> > + * Some LoongArch has broken sc.q which incorrectly handles the upper word
> > + * when the lower word is zero. Newer firmware versions (such as the 202602
> > + * release from Loongson) seem to contain a workaround for this issue.
> > + *
> > + * Disable sc.q if erratic to ensure reliability and compatibility.
> > + */
> > +static bool sc_q_is_sane(void)
> > +{
> > +     struct {
> > +             long word[2];
> > +     } __aligned(16) mem;
> > +     register long tmp asm("t0");
> > +     register long one asm("t1") = 1;
> > +     register long *ptr asm("t2") = &mem.word[0];
> > +
> > +     /*
> > +      * The sc.q instruction is hard coded with .word so the HWCAP bit
> > +      * exported to the userspace won't depend on the assembler version
> > +      * used to build the kernel.
> > +      */
> > +     asm (
> > +             "1:ll.d\t$r0, %[ptr], 0\n\t"
> > +             "move\t%[tmp], $r0\n\t"
> > +             ".word\t0x385735cc\n\t" /* sc.q %[tmp], %[one], %[ptr]*/
> > +             "beqz\t%[tmp], 1b"
> > +             : [tmp] "=&r" (tmp), "=m" (mem)
> > +             : [ptr] "r" (ptr), [one] "r" (one));
> > +
> > +     if (mem.word[1] != 1) {
> > +             pr_warn_once("Warning: sc.q is erratic on this platform, disabling for both kernel and HWCAP. Please try a firmware update.");
> > +             return false;
> > +     }
> > +
> > +     return true;
> > +}
> > +
> >  static void cpu_probe_common(struct cpuinfo_loongarch *c)
> >  {
> >       unsigned int config;
> > @@ -177,7 +214,7 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c)
> >               c->options |= LOONGARCH_CPU_LAM;
> >               elf_hwcap |= HWCAP_LOONGARCH_LAM;
> >       }
> > -     if (config & CPUCFG2_SCQ) {
> > +     if ((config & CPUCFG2_SCQ) && sc_q_is_sane()) {
> >               c->options |= LOONGARCH_CPU_SCQ;
> >               elf_hwcap |= HWCAP_LOONGARCH_SCQ;
> >       }
>
> --
> Xi Ruoyao <xry111@xry111.site>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Ping: [PATCH v2] LoongArch: detect and disable sc.q if erratic
  2026-04-27  8:43   ` Huacai Chen
@ 2026-04-28 15:49     ` Xi Ruoyao
  2026-04-29  2:13       ` Huacai Chen
  0 siblings, 1 reply; 6+ messages in thread
From: Xi Ruoyao @ 2026-04-28 15:49 UTC (permalink / raw)
  To: Huacai Chen
  Cc: WANG Xuerui, Thomas Weißschuh, loongarch, Zixing Liu,
	Mingcong Bai, Arnd Bergmann, Jiaxun Yang, George Guo,
	linux-kernel

On Mon, 2026-04-27 at 16:43 +0800, Huacai Chen wrote:
> Hi, Ruoyao,
> 
> On Mon, Apr 27, 2026 at 10:17 AM Xi Ruoyao <xry111@xry111.site> wrote:
> > 
> > Ping.
> Can we keep this as an out-of-tree patch? It's a bit ugly and I think
> the corrct way is update firmware.

We can try harder urging the vendors to release the firmware update
(there are other firmware bugs those the kernel cannot deal with anyway)
but in many cases the users just complain "hey your distro doesn't boot"
to the distro maintainers.  And some rogue ODM/OEM tend to ignore any
reports relayed by the distro maintainers unless the distro pays some
thousands of dollar.

Thus IMO it's better to make the system at least bootable with a message
(the pr_warn_once line in the patch) to clearly indicate the users that
they need a firmware update, and the vendors may become motivated a
little with more users complaining directly.
> 

-- 
Xi Ruoyao <xry111@xry111.site>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] LoongArch: detect and disable sc.q if erratic
  2026-04-09 12:19 [PATCH v2] LoongArch: detect and disable sc.q if erratic Xi Ruoyao
  2026-04-27  2:17 ` Ping: " Xi Ruoyao
@ 2026-04-28 18:47 ` Yao Zi
  1 sibling, 0 replies; 6+ messages in thread
From: Yao Zi @ 2026-04-28 18:47 UTC (permalink / raw)
  To: Xi Ruoyao, Huacai Chen, WANG Xuerui
  Cc: Thomas Weißschuh, loongarch, Zixing Liu, Mingcong Bai,
	Arnd Bergmann, Jiaxun Yang, George Guo, linux-kernel

On Thu, Apr 09, 2026 at 08:19:34PM +0800, Xi Ruoyao wrote:
> We've observed that, on some Loongson 2K3000/3B6000M systems with earlier
> firmware revisions, the sc.q instruction may write incorrect data into
> the upper half of the written 128-bit datum.
> 
> It seems upgrading the firmware (for example, the 202602 release from
> Loongson [1]) will resolve the issue. But since not all systems may be
> running the most up-to-date firmware, based on firmware update avail-
> ability and the environment in which they are running in.
> 
> To help with system compatibility and ensure correct behavior, check if
> sc.q behaves erratically and disable if so.
> 
> Link: https://github.com/loongson/Firmware/pull/156 [1]
> Signed-off-by: Xi Ruoyao <xry111@xry111.site>
> ---
>  arch/loongarch/kernel/cpu-probe.c | 39 ++++++++++++++++++++++++++++++-
>  1 file changed, 38 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/loongarch/kernel/cpu-probe.c b/arch/loongarch/kernel/cpu-probe.c
> index 657bbae6c1c7..5fcf2672172f 100644
> --- a/arch/loongarch/kernel/cpu-probe.c
> +++ b/arch/loongarch/kernel/cpu-probe.c
> @@ -132,6 +132,43 @@ static void set_isa(struct cpuinfo_loongarch *c, unsigned int isa)
>  	}
>  }
>  
> +/*
> + * Some LoongArch has broken sc.q which incorrectly handles the upper word
> + * when the lower word is zero. Newer firmware versions (such as the 202602
> + * release from Loongson) seem to contain a workaround for this issue.
> + *
> + * Disable sc.q if erratic to ensure reliability and compatibility.
> + */
> +static bool sc_q_is_sane(void)
> +{
> +	struct {
> +		long word[2];
> +	} __aligned(16) mem;

Isn't this equivalent to

	long word[2] __aligned(16);

with which we could eliminate the outer structure?

And should we introduce Kconfig options like ARM64_ERRATUM_* (arm64) or
ERRATA_MIPS_P8700_PAUSE_OPCODE (RISC-V) to conditionally compile these
work arounds? This might not be an emergency, but might be useful when
there are more quirks like this coming in the future.

Otherwise this patch looks good to me,

Reviewed-by: Yao Zi <me@ziyao.cc>

Regards,
Yao Zi

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Ping: [PATCH v2] LoongArch: detect and disable sc.q if erratic
  2026-04-28 15:49     ` Xi Ruoyao
@ 2026-04-29  2:13       ` Huacai Chen
  0 siblings, 0 replies; 6+ messages in thread
From: Huacai Chen @ 2026-04-29  2:13 UTC (permalink / raw)
  To: Xi Ruoyao
  Cc: WANG Xuerui, Thomas Weißschuh, loongarch, Zixing Liu,
	Mingcong Bai, Arnd Bergmann, Jiaxun Yang, George Guo,
	linux-kernel

On Tue, Apr 28, 2026 at 11:49 PM Xi Ruoyao <xry111@xry111.site> wrote:
>
> On Mon, 2026-04-27 at 16:43 +0800, Huacai Chen wrote:
> > Hi, Ruoyao,
> >
> > On Mon, Apr 27, 2026 at 10:17 AM Xi Ruoyao <xry111@xry111.site> wrote:
> > >
> > > Ping.
> > Can we keep this as an out-of-tree patch? It's a bit ugly and I think
> > the corrct way is update firmware.
>
> We can try harder urging the vendors to release the firmware update
> (there are other firmware bugs those the kernel cannot deal with anyway)
> but in many cases the users just complain "hey your distro doesn't boot"
> to the distro maintainers.  And some rogue ODM/OEM tend to ignore any
> reports relayed by the distro maintainers unless the distro pays some
> thousands of dollar.
I know, but distro kernels usually carry out-of-tree patches, this is
not the only one, right?

Huacai

>
> Thus IMO it's better to make the system at least bootable with a message
> (the pr_warn_once line in the patch) to clearly indicate the users that
> they need a firmware update, and the vendors may become motivated a
> little with more users complaining directly.
> >
>
> --
> Xi Ruoyao <xry111@xry111.site>

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-04-29  2:13 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-09 12:19 [PATCH v2] LoongArch: detect and disable sc.q if erratic Xi Ruoyao
2026-04-27  2:17 ` Ping: " Xi Ruoyao
2026-04-27  8:43   ` Huacai Chen
2026-04-28 15:49     ` Xi Ruoyao
2026-04-29  2:13       ` Huacai Chen
2026-04-28 18:47 ` Yao Zi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox