]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
MIPS: Always record SEGBITS in cpu_data.vmbits
authorMaciej W. Rozycki <macro@orcam.me.uk>
Fri, 10 Apr 2026 00:52:57 +0000 (01:52 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 18 Apr 2026 08:35:56 +0000 (10:35 +0200)
commit 8374c2cb83b95b3c92f129fd56527225c20a058c upstream.

With a 32-bit kernel running on 64-bit MIPS hardware the hardcoded value
of `cpu_vmbits' only records the size of compatibility useg and does not
reflect the size of native xuseg or the complete range of values allowed
in the VPN2 field of TLB entries.

An upcoming change will need the actual VPN2 value range permitted even
in 32-bit kernel configurations, so always include the `vmbits' member
in `struct cpuinfo_mips' and probe for SEGBITS when running on 64-bit
hardware and resorting to the currently hardcoded value of 31 on 32-bit
processors.  No functional change for users of `cpu_vmbits'.

Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
arch/mips/include/asm/cpu-features.h
arch/mips/include/asm/cpu-info.h
arch/mips/include/asm/mipsregs.h
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/cpu-r3k-probe.c

index e0a4da4cfd8bc0e128c4b46e8200a483e02a7300..53ea41be373517ce55686560164840fc53b379f4 100644 (file)
 # endif
 # ifndef cpu_vmbits
 # define cpu_vmbits cpu_data[0].vmbits
-# define __NEED_VMBITS_PROBE
 # endif
 #endif
 
index a600670d00e970f4c9f02ce68ad71cde8b9255a8..1aee44124f11878c5cbfe2423d964edec10ad464 100644 (file)
@@ -80,9 +80,7 @@ struct cpuinfo_mips {
        int                     srsets; /* Shadow register sets */
        int                     package;/* physical package number */
        unsigned int            globalnumber;
-#ifdef CONFIG_64BIT
        int                     vmbits; /* Virtual memory size in bits */
-#endif
        void                    *data;  /* Additional data */
        unsigned int            watch_reg_count;   /* Number that exist */
        unsigned int            watch_reg_use_cnt; /* Usable by ptrace */
index c60e72917a2813c8307a1545d3d6674b5a7fc502..581aa8876a74cddc85847ee0a36c9a7cfdd7fd61 100644 (file)
@@ -1714,6 +1714,8 @@ do {                                                                      \
 
 #define read_c0_entryhi()      __read_ulong_c0_register($10, 0)
 #define write_c0_entryhi(val)  __write_ulong_c0_register($10, 0, val)
+#define read_c0_entryhi_64()   __read_64bit_c0_register($10, 0)
+#define write_c0_entryhi_64(val) __write_64bit_c0_register($10, 0, val)
 
 #define read_c0_guestctl1()    __read_32bit_c0_register($10, 4)
 #define write_c0_guestctl1(val)        __write_32bit_c0_register($10, 4, val)
index fdf00c228b67f60c60167a6878641d8012343076..09d95482957a47d78d68f47cc5247f8bb1aa45ea 100644 (file)
@@ -208,11 +208,14 @@ static inline void set_elf_base_platform(const char *plat)
 
 static inline void cpu_probe_vmbits(struct cpuinfo_mips *c)
 {
-#ifdef __NEED_VMBITS_PROBE
-       write_c0_entryhi(0x3fffffffffffe000ULL);
-       back_to_back_c0_hazard();
-       c->vmbits = fls64(read_c0_entryhi() & 0x3fffffffffffe000ULL);
-#endif
+       int vmbits = 31;
+
+       if (cpu_has_64bits) {
+               write_c0_entryhi_64(0x3fffffffffffe000ULL);
+               back_to_back_c0_hazard();
+               vmbits = fls64(read_c0_entryhi_64() & 0x3fffffffffffe000ULL);
+       }
+       c->vmbits = vmbits;
 }
 
 static void set_isa(struct cpuinfo_mips *c, unsigned int isa)
index be93469c0e0eca4fc59ae9f2594740d1d660d067..2adf95225aa7ee604110b588c109e90d676ad18c 100644 (file)
@@ -138,6 +138,8 @@ void cpu_probe(void)
        else
                cpu_set_nofpu_opts(c);
 
+       c->vmbits = 31;
+
        reserve_exception_space(0, 0x400);
 }