Merge tag 'mips-fixes_6.18_1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux

Pull MIPS fixes from Thomas Bogendoerfer:

- Fix CPU type in DT for econet

- Fix for Malta PCI MMIO breakage for SOC-it

- Fix TLB shutdown caused by iniital uniquification

- Fix random seg faults due to missed vdso storage requirement

* tag 'mips-fixes_6.18_1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux:
MIPS: kernel: Fix random segmentation faults
MIPS: mm: Prevent a TLB shutdown on initial uniquification
mips: dts: econet: fix EN751221 core type
MIPS: Malta: Fix !EVA SOC-it PCI MMIO

Changed files
+79 -47
arch
mips
boot
dts
econet
kernel
mm
mti-malta
+1 -1
arch/mips/boot/dts/econet/en751221.dtsi
··· 18 18 19 19 cpu@0 { 20 20 device_type = "cpu"; 21 - compatible = "mips,mips24KEc"; 21 + compatible = "mips,mips34Kc"; 22 22 reg = <0>; 23 23 }; 24 24 };
+1 -1
arch/mips/kernel/process.c
··· 692 692 /* Space for the VDSO, data page & GIC user page */ 693 693 if (current->thread.abi) { 694 694 top -= PAGE_ALIGN(current->thread.abi->vdso->size); 695 - top -= PAGE_SIZE; 695 + top -= VDSO_NR_PAGES * PAGE_SIZE; 696 696 top -= mips_gic_present() ? PAGE_SIZE : 0; 697 697 698 698 /* Space to randomize the VDSO base */
+64 -38
arch/mips/mm/tlb-r4k.c
··· 15 15 #include <linux/mm.h> 16 16 #include <linux/hugetlb.h> 17 17 #include <linux/export.h> 18 + #include <linux/sort.h> 18 19 19 20 #include <asm/cpu.h> 20 21 #include <asm/cpu-type.h> ··· 509 508 510 509 __setup("ntlb=", set_ntlb); 511 510 512 - /* Initialise all TLB entries with unique values */ 511 + 512 + /* Comparison function for EntryHi VPN fields. */ 513 + static int r4k_vpn_cmp(const void *a, const void *b) 514 + { 515 + long v = *(unsigned long *)a - *(unsigned long *)b; 516 + int s = sizeof(long) > sizeof(int) ? sizeof(long) * 8 - 1: 0; 517 + return s ? (v != 0) | v >> s : v; 518 + } 519 + 520 + /* 521 + * Initialise all TLB entries with unique values that do not clash with 522 + * what we have been handed over and what we'll be using ourselves. 523 + */ 513 524 static void r4k_tlb_uniquify(void) 514 525 { 515 - int entry = num_wired_entries(); 526 + unsigned long tlb_vpns[1 << MIPS_CONF1_TLBS_SIZE]; 527 + int tlbsize = current_cpu_data.tlbsize; 528 + int start = num_wired_entries(); 529 + unsigned long vpn_mask; 530 + int cnt, ent, idx, i; 531 + 532 + vpn_mask = GENMASK(cpu_vmbits - 1, 13); 533 + vpn_mask |= IS_ENABLED(CONFIG_64BIT) ? 3ULL << 62 : 1 << 31; 516 534 517 535 htw_stop(); 536 + 537 + for (i = start, cnt = 0; i < tlbsize; i++, cnt++) { 538 + unsigned long vpn; 539 + 540 + write_c0_index(i); 541 + mtc0_tlbr_hazard(); 542 + tlb_read(); 543 + tlb_read_hazard(); 544 + vpn = read_c0_entryhi(); 545 + vpn &= vpn_mask & PAGE_MASK; 546 + tlb_vpns[cnt] = vpn; 547 + 548 + /* Prevent any large pages from overlapping regular ones. */ 549 + write_c0_pagemask(read_c0_pagemask() & PM_DEFAULT_MASK); 550 + mtc0_tlbw_hazard(); 551 + tlb_write_indexed(); 552 + tlbw_use_hazard(); 553 + } 554 + 555 + sort(tlb_vpns, cnt, sizeof(tlb_vpns[0]), r4k_vpn_cmp, NULL); 556 + 557 + write_c0_pagemask(PM_DEFAULT_MASK); 518 558 write_c0_entrylo0(0); 519 559 write_c0_entrylo1(0); 520 560 521 - while (entry < current_cpu_data.tlbsize) { 522 - unsigned long asid_mask = cpu_asid_mask(&current_cpu_data); 523 - unsigned long asid = 0; 524 - int idx; 561 + idx = 0; 562 + ent = tlbsize; 563 + for (i = start; i < tlbsize; i++) 564 + while (1) { 565 + unsigned long entryhi, vpn; 525 566 526 - /* Skip wired MMID to make ginvt_mmid work */ 527 - if (cpu_has_mmid) 528 - asid = MMID_KERNEL_WIRED + 1; 567 + entryhi = UNIQUE_ENTRYHI(ent); 568 + vpn = entryhi & vpn_mask & PAGE_MASK; 529 569 530 - /* Check for match before using UNIQUE_ENTRYHI */ 531 - do { 532 - if (cpu_has_mmid) { 533 - write_c0_memorymapid(asid); 534 - write_c0_entryhi(UNIQUE_ENTRYHI(entry)); 535 - } else { 536 - write_c0_entryhi(UNIQUE_ENTRYHI(entry) | asid); 537 - } 538 - mtc0_tlbw_hazard(); 539 - tlb_probe(); 540 - tlb_probe_hazard(); 541 - idx = read_c0_index(); 542 - /* No match or match is on current entry */ 543 - if (idx < 0 || idx == entry) 570 + if (idx >= cnt || vpn < tlb_vpns[idx]) { 571 + write_c0_entryhi(entryhi); 572 + write_c0_index(i); 573 + mtc0_tlbw_hazard(); 574 + tlb_write_indexed(); 575 + ent++; 544 576 break; 545 - /* 546 - * If we hit a match, we need to try again with 547 - * a different ASID. 548 - */ 549 - asid++; 550 - } while (asid < asid_mask); 551 - 552 - if (idx >= 0 && idx != entry) 553 - panic("Unable to uniquify TLB entry %d", idx); 554 - 555 - write_c0_index(entry); 556 - mtc0_tlbw_hazard(); 557 - tlb_write_indexed(); 558 - entry++; 559 - } 577 + } else if (vpn == tlb_vpns[idx]) { 578 + ent++; 579 + } else { 580 + idx++; 581 + } 582 + } 560 583 561 584 tlbw_use_hazard(); 562 585 htw_start(); ··· 627 602 628 603 /* From this point on the ARC firmware is dead. */ 629 604 r4k_tlb_uniquify(); 605 + local_flush_tlb_all(); 630 606 631 607 /* Did I tell you that ARC SUCKS? */ 632 608 }
+13 -7
arch/mips/mti-malta/malta-init.c
··· 241 241 #endif 242 242 243 243 /* 244 - * Setup the Malta max (2GB) memory for PCI DMA in host bridge 245 - * in transparent addressing mode. 244 + * Set up memory mapping in host bridge for PCI DMA masters, 245 + * in transparent addressing mode. For EVA use the Malta 246 + * maximum of 2 GiB memory in the alias space at 0x80000000 247 + * as per PHYS_OFFSET. Otherwise use 256 MiB of memory in 248 + * the regular space, avoiding mapping the PCI MMIO window 249 + * for DMA as it seems to confuse the system controller's 250 + * logic, causing PCI MMIO to stop working. 246 251 */ 247 - mask = PHYS_OFFSET | PCI_BASE_ADDRESS_MEM_PREFETCH; 248 - MSC_WRITE(MSC01_PCI_BAR0, mask); 249 - MSC_WRITE(MSC01_PCI_HEAD4, mask); 252 + mask = PHYS_OFFSET ? PHYS_OFFSET : 0xf0000000; 253 + MSC_WRITE(MSC01_PCI_BAR0, 254 + mask | PCI_BASE_ADDRESS_MEM_PREFETCH); 255 + MSC_WRITE(MSC01_PCI_HEAD4, 256 + PHYS_OFFSET | PCI_BASE_ADDRESS_MEM_PREFETCH); 250 257 251 - mask &= MSC01_PCI_BAR0_SIZE_MSK; 252 258 MSC_WRITE(MSC01_PCI_P2SCMSKL, mask); 253 - MSC_WRITE(MSC01_PCI_P2SCMAPL, mask); 259 + MSC_WRITE(MSC01_PCI_P2SCMAPL, PHYS_OFFSET); 254 260 255 261 /* Don't handle target retries indefinitely. */ 256 262 if ((data & MSC01_PCI_CFG_MAXRTRY_MSK) ==