Skip to content

Commit d13f3ac

Browse files
committed
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
2 parents 0629dcf + 14b46ba commit d13f3ac

File tree

4 files changed

+78
-46
lines changed

4 files changed

+78
-46
lines changed

arch/mips/boot/dts/econet/en751221.dtsi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
cpu@0 {
2020
device_type = "cpu";
21-
compatible = "mips,mips24KEc";
21+
compatible = "mips,mips34Kc";
2222
reg = <0>;
2323
};
2424
};

arch/mips/kernel/process.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,7 @@ unsigned long mips_stack_top(void)
692692
/* Space for the VDSO, data page & GIC user page */
693693
if (current->thread.abi) {
694694
top -= PAGE_ALIGN(current->thread.abi->vdso->size);
695-
top -= PAGE_SIZE;
695+
top -= VDSO_NR_PAGES * PAGE_SIZE;
696696
top -= mips_gic_present() ? PAGE_SIZE : 0;
697697

698698
/* Space to randomize the VDSO base */

arch/mips/mm/tlb-r4k.c

Lines changed: 63 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <linux/mm.h>
1616
#include <linux/hugetlb.h>
1717
#include <linux/export.h>
18+
#include <linux/sort.h>
1819

1920
#include <asm/cpu.h>
2021
#include <asm/cpu-type.h>
@@ -508,54 +509,78 @@ static int __init set_ntlb(char *str)
508509

509510
__setup("ntlb=", set_ntlb);
510511

511-
/* Initialise all TLB entries with unique values */
512+
513+
/* Comparison function for EntryHi VPN fields. */
514+
static int r4k_vpn_cmp(const void *a, const void *b)
515+
{
516+
long v = *(unsigned long *)a - *(unsigned long *)b;
517+
int s = sizeof(long) > sizeof(int) ? sizeof(long) * 8 - 1: 0;
518+
return s ? (v != 0) | v >> s : v;
519+
}
520+
521+
/*
522+
* Initialise all TLB entries with unique values that do not clash with
523+
* what we have been handed over and what we'll be using ourselves.
524+
*/
512525
static void r4k_tlb_uniquify(void)
513526
{
514-
int entry = num_wired_entries();
527+
unsigned long tlb_vpns[1 << MIPS_CONF1_TLBS_SIZE];
528+
int tlbsize = current_cpu_data.tlbsize;
529+
int start = num_wired_entries();
530+
unsigned long vpn_mask;
531+
int cnt, ent, idx, i;
532+
533+
vpn_mask = GENMASK(cpu_vmbits - 1, 13);
534+
vpn_mask |= IS_ENABLED(CONFIG_64BIT) ? 3ULL << 62 : 1 << 31;
515535

516536
htw_stop();
537+
538+
for (i = start, cnt = 0; i < tlbsize; i++, cnt++) {
539+
unsigned long vpn;
540+
541+
write_c0_index(i);
542+
mtc0_tlbr_hazard();
543+
tlb_read();
544+
tlb_read_hazard();
545+
vpn = read_c0_entryhi();
546+
vpn &= vpn_mask & PAGE_MASK;
547+
tlb_vpns[cnt] = vpn;
548+
549+
/* Prevent any large pages from overlapping regular ones. */
550+
write_c0_pagemask(read_c0_pagemask() & PM_DEFAULT_MASK);
551+
mtc0_tlbw_hazard();
552+
tlb_write_indexed();
553+
tlbw_use_hazard();
554+
}
555+
556+
sort(tlb_vpns, cnt, sizeof(tlb_vpns[0]), r4k_vpn_cmp, NULL);
557+
558+
write_c0_pagemask(PM_DEFAULT_MASK);
517559
write_c0_entrylo0(0);
518560
write_c0_entrylo1(0);
519561

520-
while (entry < current_cpu_data.tlbsize) {
521-
unsigned long asid_mask = cpu_asid_mask(&current_cpu_data);
522-
unsigned long asid = 0;
523-
int idx;
562+
idx = 0;
563+
ent = tlbsize;
564+
for (i = start; i < tlbsize; i++)
565+
while (1) {
566+
unsigned long entryhi, vpn;
524567

525-
/* Skip wired MMID to make ginvt_mmid work */
526-
if (cpu_has_mmid)
527-
asid = MMID_KERNEL_WIRED + 1;
568+
entryhi = UNIQUE_ENTRYHI(ent);
569+
vpn = entryhi & vpn_mask & PAGE_MASK;
528570

529-
/* Check for match before using UNIQUE_ENTRYHI */
530-
do {
531-
if (cpu_has_mmid) {
532-
write_c0_memorymapid(asid);
533-
write_c0_entryhi(UNIQUE_ENTRYHI(entry));
571+
if (idx >= cnt || vpn < tlb_vpns[idx]) {
572+
write_c0_entryhi(entryhi);
573+
write_c0_index(i);
574+
mtc0_tlbw_hazard();
575+
tlb_write_indexed();
576+
ent++;
577+
break;
578+
} else if (vpn == tlb_vpns[idx]) {
579+
ent++;
534580
} else {
535-
write_c0_entryhi(UNIQUE_ENTRYHI(entry) | asid);
581+
idx++;
536582
}
537-
mtc0_tlbw_hazard();
538-
tlb_probe();
539-
tlb_probe_hazard();
540-
idx = read_c0_index();
541-
/* No match or match is on current entry */
542-
if (idx < 0 || idx == entry)
543-
break;
544-
/*
545-
* If we hit a match, we need to try again with
546-
* a different ASID.
547-
*/
548-
asid++;
549-
} while (asid < asid_mask);
550-
551-
if (idx >= 0 && idx != entry)
552-
panic("Unable to uniquify TLB entry %d", idx);
553-
554-
write_c0_index(entry);
555-
mtc0_tlbw_hazard();
556-
tlb_write_indexed();
557-
entry++;
558-
}
583+
}
559584

560585
tlbw_use_hazard();
561586
htw_start();
@@ -602,6 +627,7 @@ static void r4k_tlb_configure(void)
602627

603628
/* From this point on the ARC firmware is dead. */
604629
r4k_tlb_uniquify();
630+
local_flush_tlb_all();
605631

606632
/* Did I tell you that ARC SUCKS? */
607633
}

arch/mips/mti-malta/malta-init.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -241,16 +241,22 @@ void __init prom_init(void)
241241
#endif
242242

243243
/*
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.
246251
*/
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);
250257

251-
mask &= MSC01_PCI_BAR0_SIZE_MSK;
252258
MSC_WRITE(MSC01_PCI_P2SCMSKL, mask);
253-
MSC_WRITE(MSC01_PCI_P2SCMAPL, mask);
259+
MSC_WRITE(MSC01_PCI_P2SCMAPL, PHYS_OFFSET);
254260

255261
/* Don't handle target retries indefinitely. */
256262
if ((data & MSC01_PCI_CFG_MAXRTRY_MSK) ==

0 commit comments

Comments
 (0)