arch/mips/mm/tlb-r4k.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
Latest MIPS cores could have much more than 64 TLB entries, therefore
allocate array for unification instead of placing a too small array
on stack.
Fixes: 9f048fa48740 ("MIPS: mm: Prevent a TLB shutdown on initial uniquification")
Tested-by: Gregory CLEMENT <gregory.clement@bootlin.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---
arch/mips/mm/tlb-r4k.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index 3facf7cc6c7d..5f96a19ecb67 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -524,15 +524,19 @@ static int r4k_vpn_cmp(const void *a, const void *b)
*/
static void r4k_tlb_uniquify(void)
{
- unsigned long tlb_vpns[1 << MIPS_CONF1_TLBS_SIZE];
int tlbsize = current_cpu_data.tlbsize;
int start = num_wired_entries();
+ unsigned long *tlb_vpns;
unsigned long vpn_mask;
int cnt, ent, idx, i;
vpn_mask = GENMASK(cpu_vmbits - 1, 13);
vpn_mask |= IS_ENABLED(CONFIG_64BIT) ? 3ULL << 62 : 1 << 31;
+ tlb_vpns = kmalloc_array(tlbsize, sizeof(unsigned long), GFP_KERNEL);
+ if (WARN_ON(!tlb_vpns))
+ return; /* Pray local_flush_tlb_all() is good enough. */
+
htw_stop();
for (i = start, cnt = 0; i < tlbsize; i++, cnt++) {
@@ -585,6 +589,7 @@ static void r4k_tlb_uniquify(void)
tlbw_use_hazard();
htw_start();
flush_micro_tlb();
+ kfree(tlb_vpns);
}
/*
--
2.43.0
On Tue, 25 Nov 2025, Thomas Bogendoerfer wrote:
> Latest MIPS cores could have much more than 64 TLB entries, therefore
> allocate array for unification instead of placing a too small array
> on stack.
Hmm, I get:
------------[ cut here ]------------
WARNING: CPU: 0 PID: 0 at arch/mips/mm/tlb-r4k.c:540 tlb_init+0x2a0/0x4bc
Modules linked in:
CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 6.18.0-rc1-dirty #60 NONE
Hardware name: mti,malta
Stack : 00000000 00000004 00000000 0000001d 809d1d2c 00000000 00000100 80944048
809d91bc 80944048 80a16a73 00000000 80b634a4 00000001 809d1ce0 809f7bc8
00000000 00000000 80944048 0000001f 00000001 809d1c14 00000000 653a206d
00000000 80b656d4 80b6570b 00000000 00000000 00000000 80944048 00000000
00000000 0000021c 80a40000 00000000 00000000 00000020 00000000 800472a4
...
Call Trace:
[<80112bd8>] show_stack+0x28/0xf0
[<8010a69c>] dump_stack_lvl+0x48/0x7c
[<8012fedc>] __warn+0x9c/0x118
[<801015e8>] warn_slowpath_fmt+0x58/0xa4
[<8012ba84>] tlb_init+0x2a0/0x4bc
[<80114738>] per_cpu_trap_init+0x17c/0x27c
[<80a1d0f8>] trap_init+0xf0/0x794
[<80a19ae4>] start_kernel+0x3c4/0x598
---[ end trace 0000000000000000 ]---
exactly here:
> + tlb_vpns = kmalloc_array(tlbsize, sizeof(unsigned long), GFP_KERNEL);
> + if (WARN_ON(!tlb_vpns))
> + return; /* Pray local_flush_tlb_all() is good enough. */
I'll try to find out more, but right now this doesn't appear to work.
Maciej
On Wed, Nov 26, 2025 at 06:52:07PM +0000, Maciej W. Rozycki wrote: > On Tue, 25 Nov 2025, Thomas Bogendoerfer wrote: > > > Latest MIPS cores could have much more than 64 TLB entries, therefore > > allocate array for unification instead of placing a too small array > > on stack. > > Hmm, I get: > > ------------[ cut here ]------------ > WARNING: CPU: 0 PID: 0 at arch/mips/mm/tlb-r4k.c:540 tlb_init+0x2a0/0x4bc > Modules linked in: > CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 6.18.0-rc1-dirty #60 NONE > Hardware name: mti,malta > Stack : 00000000 00000004 00000000 0000001d 809d1d2c 00000000 00000100 80944048 > 809d91bc 80944048 80a16a73 00000000 80b634a4 00000001 809d1ce0 809f7bc8 > 00000000 00000000 80944048 0000001f 00000001 809d1c14 00000000 653a206d > 00000000 80b656d4 80b6570b 00000000 00000000 00000000 80944048 00000000 > 00000000 0000021c 80a40000 00000000 00000000 00000020 00000000 800472a4 > ... > Call Trace: > [<80112bd8>] show_stack+0x28/0xf0 > [<8010a69c>] dump_stack_lvl+0x48/0x7c > [<8012fedc>] __warn+0x9c/0x118 > [<801015e8>] warn_slowpath_fmt+0x58/0xa4 > [<8012ba84>] tlb_init+0x2a0/0x4bc > [<80114738>] per_cpu_trap_init+0x17c/0x27c > [<80a1d0f8>] trap_init+0xf0/0x794 > [<80a19ae4>] start_kernel+0x3c4/0x598 > > ---[ end trace 0000000000000000 ]--- > > exactly here: > > > + tlb_vpns = kmalloc_array(tlbsize, sizeof(unsigned long), GFP_KERNEL); > > + if (WARN_ON(!tlb_vpns)) > > + return; /* Pray local_flush_tlb_all() is good enough. */ > > I'll try to find out more, but right now this doesn't appear to work. kmalloc() doesn't work at that point :-( It only fixed the problem, because we skip unification... d'oh Thomas. -- Crap can work. Given enough thrust pigs will fly, but it's not necessarily a good idea. [ RFC1925, 2.3 ]
On Wed, 26 Nov 2025, Thomas Bogendoerfer wrote: > > > Latest MIPS cores could have much more than 64 TLB entries, therefore > > > allocate array for unification instead of placing a too small array > > > on stack. > > > > Hmm, I get: > > > > ------------[ cut here ]------------ > > WARNING: CPU: 0 PID: 0 at arch/mips/mm/tlb-r4k.c:540 tlb_init+0x2a0/0x4bc > > Modules linked in: > > CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 6.18.0-rc1-dirty #60 NONE > > Hardware name: mti,malta > > Stack : 00000000 00000004 00000000 0000001d 809d1d2c 00000000 00000100 80944048 > > 809d91bc 80944048 80a16a73 00000000 80b634a4 00000001 809d1ce0 809f7bc8 > > 00000000 00000000 80944048 0000001f 00000001 809d1c14 00000000 653a206d > > 00000000 80b656d4 80b6570b 00000000 00000000 00000000 80944048 00000000 > > 00000000 0000021c 80a40000 00000000 00000000 00000020 00000000 800472a4 > > ... > > Call Trace: > > [<80112bd8>] show_stack+0x28/0xf0 > > [<8010a69c>] dump_stack_lvl+0x48/0x7c > > [<8012fedc>] __warn+0x9c/0x118 > > [<801015e8>] warn_slowpath_fmt+0x58/0xa4 > > [<8012ba84>] tlb_init+0x2a0/0x4bc > > [<80114738>] per_cpu_trap_init+0x17c/0x27c > > [<80a1d0f8>] trap_init+0xf0/0x794 > > [<80a19ae4>] start_kernel+0x3c4/0x598 > > > > ---[ end trace 0000000000000000 ]--- > > > > exactly here: > > > > > + tlb_vpns = kmalloc_array(tlbsize, sizeof(unsigned long), GFP_KERNEL); > > > + if (WARN_ON(!tlb_vpns)) > > > + return; /* Pray local_flush_tlb_all() is good enough. */ > > > > I'll try to find out more, but right now this doesn't appear to work. > > kmalloc() doesn't work at that point :-( It only fixed the problem, because > we skip unification... d'oh Correct, I have a fix in the works. Maciej
© 2016 - 2025 Red Hat, Inc.