From 0f5cc249ff73552d3bd864e62f85841dafaa107d Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Sat, 2 Dec 2023 14:14:19 +0300 Subject: mips: Fix incorrect max_low_pfn adjustment max_low_pfn variable is incorrectly adjusted if the kernel is built with high memory support and the later is detected in a running system, so the memory which actually can be directly mapped is getting into the highmem zone. See the ZONE_NORMAL range on my MIPS32r5 system: > Zone ranges: > DMA [mem 0x0000000000000000-0x0000000000ffffff] > Normal [mem 0x0000000001000000-0x0000000007ffffff] > HighMem [mem 0x0000000008000000-0x000000020fffffff] while the zones are supposed to look as follows: > Zone ranges: > DMA [mem 0x0000000000000000-0x0000000000ffffff] > Normal [mem 0x0000000001000000-0x000000001fffffff] > HighMem [mem 0x0000000020000000-0x000000020fffffff] Even though the physical memory within the range [0x08000000;0x20000000] belongs to MMIO on our system, we don't really want it to be considered as high memory since on MIPS32 that range still can be directly mapped. Note there might be other problems caused by the max_low_pfn variable misconfiguration. For instance high_memory variable is initialize with virtual address corresponding to the max_low_pfn PFN, and by design it must define the upper bound on direct map memory, then end of the normal zone. That in its turn potentially may cause problems in accessing the memory by means of the /dev/mem and /dev/kmem devices. Let's fix the discovered misconfiguration then. It turns out the commit a94e4f24ec83 ("MIPS: init: Drop boot_mem_map") didn't introduce the max_low_pfn adjustment quite correct. If the kernel is built with high memory support and the system is equipped with high memory, the max_low_pfn variable will need to be initialized with PFN of the most upper directly reachable memory address so the zone normal would be correctly setup. On MIPS that PFN corresponds to PFN_DOWN(HIGHMEM_START). If the system is built with no high memory support and one is detected in the running system, we'll just need to adjust the max_pfn variable to discard the found high memory from the system and leave the max_low_pfn as is, since the later will be less than PFN_DOWN(HIGHMEM_START) anyway by design of the for_each_memblock() loop performed a bit early in the bootmem_init() method. Fixes: a94e4f24ec83 ("MIPS: init: Drop boot_mem_map") Signed-off-by: Serge Semin Signed-off-by: Thomas Bogendoerfer --- arch/mips/kernel/setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 2d2ca024bd47..0461ab49e8f1 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -321,11 +321,11 @@ static void __init bootmem_init(void) panic("Incorrect memory mapping !!!"); if (max_pfn > PFN_DOWN(HIGHMEM_START)) { + max_low_pfn = PFN_DOWN(HIGHMEM_START); #ifdef CONFIG_HIGHMEM - highstart_pfn = PFN_DOWN(HIGHMEM_START); + highstart_pfn = max_low_pfn; highend_pfn = max_pfn; #else - max_low_pfn = PFN_DOWN(HIGHMEM_START); max_pfn = max_low_pfn; #endif } -- cgit v1.2.3 From efe8ee1a8b9a89835dcbbec8cebc9d5a27428914 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Sat, 2 Dec 2023 14:14:23 +0300 Subject: mips: Set dump-stack arch description In the framework of the MIPS architecture the mips_set_machine_name() method is defined to set the machine name. The name currently is only used in the /proc/cpuinfo file content generation. Let's have it utilized to mach-personalize the dump-stack data too in a way it's done on ARM, ARM64, RISC-V, etc. Signed-off-by: Serge Semin Signed-off-by: Thomas Bogendoerfer --- arch/mips/kernel/prom.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c index f88ce78e13e3..6062e6fa589a 100644 --- a/arch/mips/kernel/prom.c +++ b/arch/mips/kernel/prom.c @@ -28,6 +28,8 @@ __init void mips_set_machine_name(const char *name) strscpy(mips_machine_name, name, sizeof(mips_machine_name)); pr_info("MIPS: machine is %s\n", mips_get_machine_name()); + + dump_stack_set_arch_desc(name); } char *mips_get_machine_name(void) -- cgit v1.2.3 From 682fb5be353117b7321f1dfb65b7bb98cbfe59ab Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Thu, 21 Dec 2023 13:54:03 +0100 Subject: MIPS: Allow vectored interrupt handler to reside everywhere for 64bit Setting up vector interrupts worked only with handlers, which resided in CKSEG0 space. This limits the kernel placement for 64bit platforms. By patching in the offset into vi_handlers[] instead of the full handler address, the vectored exception handler can load the address by itself and jump to it. Signed-off-by: Thomas Bogendoerfer Reviewed-by: Jiaxun Yang --- arch/mips/kernel/genex.S | 8 ++++---- arch/mips/kernel/traps.c | 9 +++------ 2 files changed, 7 insertions(+), 10 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index b6de8e88c1bd..a572ce36a24f 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S @@ -272,18 +272,17 @@ NESTED(except_vec_vi, 0, sp) .set push .set noreorder PTR_LA v1, except_vec_vi_handler -FEXPORT(except_vec_vi_lui) - lui v0, 0 /* Patched */ jr v1 FEXPORT(except_vec_vi_ori) - ori v0, 0 /* Patched */ + ori v0, zero, 0 /* Offset in vi_handlers[] */ .set pop END(except_vec_vi) EXPORT(except_vec_vi_end) /* * Common Vectored Interrupt code - * Complete the register saves and invoke the handler which is passed in $v0 + * Complete the register saves and invoke the handler, $v0 holds + * offset into vi_handlers[] */ NESTED(except_vec_vi_handler, 0, sp) SAVE_TEMP @@ -331,6 +330,7 @@ NESTED(except_vec_vi_handler, 0, sp) /* Save task's sp on IRQ stack so that unwinding can follow it */ LONG_S s1, 0(sp) 2: + PTR_L v0, vi_handlers(v0) jalr v0 /* Restore sp */ diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 246c6a6b0261..d90b18908692 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -2091,16 +2091,14 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) * If no shadow set is selected then use the default handler * that does normal register saving and standard interrupt exit */ - extern const u8 except_vec_vi[], except_vec_vi_lui[]; + extern const u8 except_vec_vi[]; extern const u8 except_vec_vi_ori[], except_vec_vi_end[]; extern const u8 rollback_except_vec_vi[]; const u8 *vec_start = using_rollback_handler() ? rollback_except_vec_vi : except_vec_vi; #if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_BIG_ENDIAN) - const int lui_offset = except_vec_vi_lui - vec_start + 2; const int ori_offset = except_vec_vi_ori - vec_start + 2; #else - const int lui_offset = except_vec_vi_lui - vec_start; const int ori_offset = except_vec_vi_ori - vec_start; #endif const int handler_len = except_vec_vi_end - vec_start; @@ -2119,10 +2117,9 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) #else handler_len); #endif - h = (u16 *)(b + lui_offset); - *h = (handler >> 16) & 0xffff; + /* insert offset into vi_handlers[] */ h = (u16 *)(b + ori_offset); - *h = (handler & 0xffff); + *h = n * sizeof(handler); local_flush_icache_range((unsigned long)b, (unsigned long)(b+handler_len)); } -- cgit v1.2.3 From 8e1803900ef1b61ed33e6963d9e6a95028b41110 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Thu, 21 Dec 2023 13:54:04 +0100 Subject: MIPS: Remove unused shadow GPR support from vector irq setup Using shadow GPRs for vectored interrupts has never been used, time to remove it. Signed-off-by: Thomas Bogendoerfer --- arch/mips/kernel/traps.c | 88 +++++++++++++++--------------------------------- 1 file changed, 27 insertions(+), 61 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index d90b18908692..c1b2b18b0505 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -2055,105 +2055,71 @@ static void do_default_vi(void) panic("Caught unexpected vectored interrupt."); } -static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) +void *set_vi_handler(int n, vi_handler_t addr) { + extern const u8 except_vec_vi[]; + extern const u8 except_vec_vi_ori[], except_vec_vi_end[]; + extern const u8 rollback_except_vec_vi[]; unsigned long handler; unsigned long old_handler = vi_handlers[n]; int srssets = current_cpu_data.srsets; u16 *h; unsigned char *b; + const u8 *vec_start; + int ori_offset; + int handler_len; BUG_ON(!cpu_has_veic && !cpu_has_vint); if (addr == NULL) { handler = (unsigned long) do_default_vi; - srs = 0; } else handler = (unsigned long) addr; vi_handlers[n] = handler; b = (unsigned char *)(ebase + 0x200 + n*VECTORSPACING); - if (srs >= srssets) - panic("Shadow register set %d not supported", srs); - if (cpu_has_veic) { if (board_bind_eic_interrupt) - board_bind_eic_interrupt(n, srs); + board_bind_eic_interrupt(n, 0); } else if (cpu_has_vint) { /* SRSMap is only defined if shadow sets are implemented */ if (srssets > 1) - change_c0_srsmap(0xf << n*4, srs << n*4); + change_c0_srsmap(0xf << n*4, 0 << n*4); } - if (srs == 0) { - /* - * If no shadow set is selected then use the default handler - * that does normal register saving and standard interrupt exit - */ - extern const u8 except_vec_vi[]; - extern const u8 except_vec_vi_ori[], except_vec_vi_end[]; - extern const u8 rollback_except_vec_vi[]; - const u8 *vec_start = using_rollback_handler() ? - rollback_except_vec_vi : except_vec_vi; + vec_start = using_rollback_handler() ? rollback_except_vec_vi : + except_vec_vi; #if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_BIG_ENDIAN) - const int ori_offset = except_vec_vi_ori - vec_start + 2; + ori_offset = except_vec_vi_ori - vec_start + 2; #else - const int ori_offset = except_vec_vi_ori - vec_start; + ori_offset = except_vec_vi_ori - vec_start; #endif - const int handler_len = except_vec_vi_end - vec_start; - - if (handler_len > VECTORSPACING) { - /* - * Sigh... panicing won't help as the console - * is probably not configured :( - */ - panic("VECTORSPACING too small"); - } + handler_len = except_vec_vi_end - vec_start; - set_handler(((unsigned long)b - ebase), vec_start, -#ifdef CONFIG_CPU_MICROMIPS - (handler_len - 1)); -#else - handler_len); -#endif - /* insert offset into vi_handlers[] */ - h = (u16 *)(b + ori_offset); - *h = n * sizeof(handler); - local_flush_icache_range((unsigned long)b, - (unsigned long)(b+handler_len)); - } - else { + if (handler_len > VECTORSPACING) { /* - * In other cases jump directly to the interrupt handler. It - * is the handler's responsibility to save registers if required - * (eg hi/lo) and return from the exception using "eret". + * Sigh... panicing won't help as the console + * is probably not configured :( */ - u32 insn; + panic("VECTORSPACING too small"); + } - h = (u16 *)b; - /* j handler */ + set_handler(((unsigned long)b - ebase), vec_start, #ifdef CONFIG_CPU_MICROMIPS - insn = 0xd4000000 | (((u32)handler & 0x07ffffff) >> 1); + (handler_len - 1)); #else - insn = 0x08000000 | (((u32)handler & 0x0fffffff) >> 2); + handler_len); #endif - h[0] = (insn >> 16) & 0xffff; - h[1] = insn & 0xffff; - h[2] = 0; - h[3] = 0; - local_flush_icache_range((unsigned long)b, - (unsigned long)(b+8)); - } + /* insert offset into vi_handlers[] */ + h = (u16 *)(b + ori_offset); + *h = n * sizeof(handler); + local_flush_icache_range((unsigned long)b, + (unsigned long)(b+handler_len)); return (void *)old_handler; } -void *set_vi_handler(int n, vi_handler_t addr) -{ - return set_vi_srs_handler(n, addr, 0); -} - extern void tlb_init(void); /* -- cgit v1.2.3 From 2f9060b1db4aa2c21c248e34476d8936a2b69cf6 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 3 Jan 2024 17:16:03 -0600 Subject: MIPS: Fix typos Fix typos, most reported by "codespell arch/mips". Only touches comments, no code changes. Signed-off-by: Bjorn Helgaas Cc: linux-mips@vger.kernel.org Reviewed-by: Randy Dunlap Signed-off-by: Thomas Bogendoerfer --- arch/mips/kernel/cpu-probe.c | 2 +- arch/mips/kernel/kprobes.c | 2 +- arch/mips/kernel/relocate.c | 2 +- arch/mips/kernel/relocate_kernel.S | 2 +- arch/mips/kernel/setup.c | 2 +- arch/mips/kernel/signal.c | 2 +- arch/mips/kernel/traps.c | 2 +- arch/mips/kernel/vpe.c | 4 ++-- 8 files changed, 9 insertions(+), 9 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index b406d8bfb15a..2f4fafdc5fcc 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -1139,7 +1139,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) * This processor doesn't have an MMU, so it's not * "real easy" to run Linux on it. It is left purely * for documentation. Commented out because it shares - * it's c0_prid id number with the TX3900. + * its c0_prid id number with the TX3900. */ c->cputype = CPU_R4650; __cpu_name[cpu] = "R4650"; diff --git a/arch/mips/kernel/kprobes.c b/arch/mips/kernel/kprobes.c index 316b27d0d2fb..dc39f5b3fb83 100644 --- a/arch/mips/kernel/kprobes.c +++ b/arch/mips/kernel/kprobes.c @@ -55,7 +55,7 @@ NOKPROBE_SYMBOL(insn_has_delayslot); * one; putting breakpoint on top of atomic ll/sc pair is bad idea; * so we need to prevent it and refuse kprobes insertion for such * instructions; cannot do much about breakpoint in the middle of - * ll/sc pair; it is upto user to avoid those places + * ll/sc pair; it is up to user to avoid those places */ static int insn_has_ll_or_sc(union mips_instruction insn) { diff --git a/arch/mips/kernel/relocate.c b/arch/mips/kernel/relocate.c index 58fc8d089402..7eeeaf1ff95d 100644 --- a/arch/mips/kernel/relocate.c +++ b/arch/mips/kernel/relocate.c @@ -380,7 +380,7 @@ void *__init relocate_kernel(void) } #endif /* CONFIG_USE_OF */ - /* Copy the kernel to it's new location */ + /* Copy the kernel to its new location */ memcpy(loc_new, &_text, kernel_length); /* Perform relocations on the new kernel */ diff --git a/arch/mips/kernel/relocate_kernel.S b/arch/mips/kernel/relocate_kernel.S index 8f0a7263a9d6..de894a0211d7 100644 --- a/arch/mips/kernel/relocate_kernel.S +++ b/arch/mips/kernel/relocate_kernel.S @@ -70,7 +70,7 @@ copy_word: done: #ifdef CONFIG_SMP /* kexec_flag reset is signal to other CPUs what kernel - was moved to it's location. Note - we need relocated address + was moved to its location. Note - we need relocated address of kexec_flag. */ bal 1f diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 0461ab49e8f1..844307a86b15 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -146,7 +146,7 @@ static unsigned long __init init_initrd(void) /* * Board specific code or command line parser should have * already set up initrd_start and initrd_end. In these cases - * perfom sanity checks and use them if all looks good. + * perform sanity checks and use them if all looks good. */ if (!initrd_start || initrd_end <= initrd_start) goto disable; diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 479999b7f2de..a8e20fdc7afd 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c @@ -569,7 +569,7 @@ void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, return (void __user __force *)(-1UL); /* - * FPU emulator may have it's own trampoline active just + * FPU emulator may have its own trampoline active just * above the user stack, 16-bytes before the next lowest * 16 byte boundary. Try to avoid trashing it. */ diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index c1b2b18b0505..0e3f2f2fa732 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -2381,7 +2381,7 @@ void __init trap_init(void) set_except_vector(i, handle_reserved); /* - * Copy the EJTAG debug exception vector handler code to it's final + * Copy the EJTAG debug exception vector handler code to its final * destination. */ if (cpu_has_ejtag && board_ejtag_handler_setup) diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index e9a0cfd02ae2..737d0d4fdcd3 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c @@ -6,9 +6,9 @@ * Copyright (C) 2004, 2005 MIPS Technologies, Inc. All rights reserved. * Copyright (C) 2013 Imagination Technologies Ltd. * - * VPE spport module for loading a MIPS SP program into VPE1. The SP + * VPE support module for loading a MIPS SP program into VPE1. The SP * environment is rather simple since there are no TLBs. It needs - * to be relocatable (or partiall linked). Initialize your stack in + * to be relocatable (or partially linked). Initialize your stack in * the startup-code. The loader looks for the symbol __start and sets * up the execution to resume from there. To load and run, simply do * a cat SP 'binary' to the /dev/vpe1 device. -- cgit v1.2.3