MIPS: Loongson64: Test register availability before use
authorJiaxun Yang <jiaxun.yang@flygoat.com>
Fri, 14 Jun 2024 15:40:14 +0000 (16:40 +0100)
committerThomas Bogendoerfer <tsbogend@alpha.franken.de>
Fri, 21 Jun 2024 08:22:10 +0000 (10:22 +0200)
Some global register address variable may be missing on
specific CPU type, test them before use them.

Cc: stable@vger.kernel.org
Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
arch/mips/loongson64/smp.c

index 5a990cdef91a6fb44d4b89688022441a85a4303f..66d049cdcf1459e0833d8bcf88ea589a59873b16 100644 (file)
@@ -466,12 +466,25 @@ static void loongson3_smp_finish(void)
 static void __init loongson3_smp_setup(void)
 {
        int i = 0, num = 0; /* i: physical id, num: logical id */
+       int max_cpus = 0;
 
        init_cpu_possible(cpu_none_mask);
 
+       for (i = 0; i < ARRAY_SIZE(smp_group); i++) {
+               if (!smp_group[i])
+                       break;
+               max_cpus += loongson_sysconf.cores_per_node;
+       }
+
+       if (max_cpus < loongson_sysconf.nr_cpus) {
+               pr_err("SMP Groups are less than the number of CPUs\n");
+               loongson_sysconf.nr_cpus = max_cpus ? max_cpus : 1;
+       }
+
        /* For unified kernel, NR_CPUS is the maximum possible value,
         * loongson_sysconf.nr_cpus is the really present value
         */
+       i = 0;
        while (i < loongson_sysconf.nr_cpus) {
                if (loongson_sysconf.reserved_cpus_mask & (1<<i)) {
                        /* Reserved physical CPU cores */
@@ -492,14 +505,14 @@ static void __init loongson3_smp_setup(void)
                __cpu_logical_map[num] = -1;
                num++;
        }
-
        csr_ipi_probe();
        ipi_set0_regs_init();
        ipi_clear0_regs_init();
        ipi_status0_regs_init();
        ipi_en0_regs_init();
        ipi_mailbox_buf_init();
-       ipi_write_enable(0);
+       if (smp_group[0])
+               ipi_write_enable(0);
 
        cpu_set_core(&cpu_data[0],
                     cpu_logical_map(0) % loongson_sysconf.cores_per_package);
@@ -818,6 +831,9 @@ static int loongson3_disable_clock(unsigned int cpu)
        uint64_t core_id = cpu_core(&cpu_data[cpu]);
        uint64_t package_id = cpu_data[cpu].package;
 
+       if (!loongson_chipcfg[package_id] || !loongson_freqctrl[package_id])
+               return 0;
+
        if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) {
                LOONGSON_CHIPCFG(package_id) &= ~(1 << (12 + core_id));
        } else {
@@ -832,6 +848,9 @@ static int loongson3_enable_clock(unsigned int cpu)
        uint64_t core_id = cpu_core(&cpu_data[cpu]);
        uint64_t package_id = cpu_data[cpu].package;
 
+       if (!loongson_chipcfg[package_id] || !loongson_freqctrl[package_id])
+               return 0;
+
        if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) {
                LOONGSON_CHIPCFG(package_id) |= 1 << (12 + core_id);
        } else {