]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
LoongArch: Allow specify SIMD width via kernel parameters
authorHuacai Chen <chenhuacai@loongson.cn>
Thu, 2 Oct 2025 14:39:07 +0000 (22:39 +0800)
committerHuacai Chen <chenhuacai@loongson.cn>
Thu, 2 Oct 2025 14:39:07 +0000 (22:39 +0800)
For power saving or debugging purpose, we usually want to limit the SIMD
(LSX/LASX) usage on a rich feature platform. So allow specify SIMD width
via kernel parameters "simd=".

Allowed values of "simd=" are any integers, and recommended values are:
0: Disable all SIMD features;
128: Enable at most 128bit SIMD features;
256: Enable at most 256bit SIMD features;
-1(default): Enable as many as possible SIMD features automatically.

Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
arch/loongarch/kernel/cpu-probe.c

index fedaa67cde410e2e0ae55da904e64b4f7dd91398..cbfce2872d7165fc17a2c4b7e46fa6d8a37453e8 100644 (file)
@@ -52,6 +52,48 @@ static inline void cpu_set_fpu_fcsr_mask(struct cpuinfo_loongarch *c)
        c->fpu_mask = ~(fcsr0 ^ fcsr1) & ~mask;
 }
 
+/* simd = -1/0/128/256 */
+static unsigned int simd = -1U;
+
+static int __init cpu_setup_simd(char *str)
+{
+       get_option(&str, &simd);
+       pr_info("Set SIMD width = %u\n", simd);
+
+       return 0;
+}
+
+early_param("simd", cpu_setup_simd);
+
+static int __init cpu_final_simd(void)
+{
+       struct cpuinfo_loongarch *c = &cpu_data[0];
+
+       if (simd < 128) {
+               c->options &= ~LOONGARCH_CPU_LSX;
+               elf_hwcap &= ~HWCAP_LOONGARCH_LSX;
+       }
+
+       if (simd < 256) {
+               c->options &= ~LOONGARCH_CPU_LASX;
+               elf_hwcap &= ~HWCAP_LOONGARCH_LASX;
+       }
+
+       simd = 0;
+
+       if (c->options & LOONGARCH_CPU_LSX)
+               simd = 128;
+
+       if (c->options & LOONGARCH_CPU_LASX)
+               simd = 256;
+
+       pr_info("Final SIMD width = %u\n", simd);
+
+       return 0;
+}
+
+arch_initcall(cpu_final_simd);
+
 static inline void set_elf_platform(int cpu, const char *plat)
 {
        if (cpu == 0)
@@ -134,13 +176,13 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c)
                elf_hwcap |= HWCAP_LOONGARCH_FPU;
        }
 #ifdef CONFIG_CPU_HAS_LSX
-       if (config & CPUCFG2_LSX) {
+       if ((config & CPUCFG2_LSX) && (simd >= 128)) {
                c->options |= LOONGARCH_CPU_LSX;
                elf_hwcap |= HWCAP_LOONGARCH_LSX;
        }
 #endif
 #ifdef CONFIG_CPU_HAS_LASX
-       if (config & CPUCFG2_LASX) {
+       if ((config & CPUCFG2_LASX) && (simd >= 256)) {
                c->options |= LOONGARCH_CPU_LASX;
                elf_hwcap |= HWCAP_LOONGARCH_LASX;
        }