Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

MIPS: mm: kmalloc tlb_vpn array to avoid stack overflow

Owing to Config4.MMUSizeExt and VTLB/FTLB MMU features later MIPSr2+
cores can have more than 64 TLB entries. Therefore allocate an array
for uniquification instead of placing too an small array on the stack.

Fixes: 35ad7e181541 ("MIPS: mm: tlb-r4k: Uniquify TLB entries on init")
Co-developed-by: Maciej W. Rozycki <macro@orcam.me.uk>
Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
Cc: stable@vger.kernel.org # v6.17+: 9f048fa48740: MIPS: mm: Prevent a TLB shutdown on initial uniquification
Cc: stable@vger.kernel.org # v6.17+
Tested-by: Gregory CLEMENT <gregory.clement@bootlin.com>
Tested-by: Klara Modin <klarasmodin@gmail.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>

+16 -2
+16 -2
arch/mips/mm/tlb-r4k.c
··· 12 12 #include <linux/init.h> 13 13 #include <linux/sched.h> 14 14 #include <linux/smp.h> 15 + #include <linux/memblock.h> 15 16 #include <linux/mm.h> 16 17 #include <linux/hugetlb.h> 17 18 #include <linux/export.h> ··· 523 522 * Initialise all TLB entries with unique values that do not clash with 524 523 * what we have been handed over and what we'll be using ourselves. 525 524 */ 526 - static void r4k_tlb_uniquify(void) 525 + static void __ref r4k_tlb_uniquify(void) 527 526 { 528 - unsigned long tlb_vpns[1 << MIPS_CONF1_TLBS_SIZE]; 529 527 int tlbsize = current_cpu_data.tlbsize; 528 + bool use_slab = slab_is_available(); 530 529 int start = num_wired_entries(); 530 + phys_addr_t tlb_vpn_size; 531 + unsigned long *tlb_vpns; 531 532 unsigned long vpn_mask; 532 533 int cnt, ent, idx, i; 533 534 534 535 vpn_mask = GENMASK(cpu_vmbits - 1, 13); 535 536 vpn_mask |= IS_ENABLED(CONFIG_64BIT) ? 3ULL << 62 : 1 << 31; 537 + 538 + tlb_vpn_size = tlbsize * sizeof(*tlb_vpns); 539 + tlb_vpns = (use_slab ? 540 + kmalloc(tlb_vpn_size, GFP_KERNEL) : 541 + memblock_alloc_raw(tlb_vpn_size, sizeof(*tlb_vpns))); 542 + if (WARN_ON(!tlb_vpns)) 543 + return; /* Pray local_flush_tlb_all() is good enough. */ 536 544 537 545 htw_stop(); 538 546 ··· 595 585 tlbw_use_hazard(); 596 586 htw_start(); 597 587 flush_micro_tlb(); 588 + if (use_slab) 589 + kfree(tlb_vpns); 590 + else 591 + memblock_free(tlb_vpns, tlb_vpn_size); 598 592 } 599 593 600 594 /*