diff options
Diffstat (limited to 'target/linux/generic/patches-4.4')
10 files changed, 305 insertions, 8 deletions
diff --git a/target/linux/generic/patches-4.4/062-01-MIPS-Introduce-irq_stack.patch b/target/linux/generic/patches-4.4/062-01-MIPS-Introduce-irq_stack.patch new file mode 100644 index 0000000000..2a929aa7e1 --- /dev/null +++ b/target/linux/generic/patches-4.4/062-01-MIPS-Introduce-irq_stack.patch @@ -0,0 +1,70 @@ +From: Matt Redfearn <matt.redfearn@imgtec.com> +Date: Mon, 19 Dec 2016 14:20:56 +0000 +Subject: [PATCH] MIPS: Introduce irq_stack + +Allocate a per-cpu irq stack for use within interrupt handlers. + +Also add a utility function on_irq_stack to determine if a given stack +pointer is within the irq stack for that cpu. + +Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com> +--- + +--- a/arch/mips/include/asm/irq.h ++++ b/arch/mips/include/asm/irq.h +@@ -17,6 +17,18 @@ + + #include <irq.h> + ++#define IRQ_STACK_SIZE THREAD_SIZE ++ ++extern void *irq_stack[NR_CPUS]; ++ ++static inline bool on_irq_stack(int cpu, unsigned long sp) ++{ ++ unsigned long low = (unsigned long)irq_stack[cpu]; ++ unsigned long high = low + IRQ_STACK_SIZE; ++ ++ return (low <= sp && sp <= high); ++} ++ + #ifdef CONFIG_I8259 + static inline int irq_canonicalize(int irq) + { +--- a/arch/mips/kernel/asm-offsets.c ++++ b/arch/mips/kernel/asm-offsets.c +@@ -101,6 +101,7 @@ void output_thread_info_defines(void) + OFFSET(TI_REGS, thread_info, regs); + DEFINE(_THREAD_SIZE, THREAD_SIZE); + DEFINE(_THREAD_MASK, THREAD_MASK); ++ DEFINE(_IRQ_STACK_SIZE, IRQ_STACK_SIZE); + BLANK(); + } + +--- a/arch/mips/kernel/irq.c ++++ b/arch/mips/kernel/irq.c +@@ -25,6 +25,8 @@ + #include <linux/atomic.h> + #include <asm/uaccess.h> + ++void *irq_stack[NR_CPUS]; ++ + /* + * 'what should we do if we get a hw irq event on an illegal vector'. + * each architecture has to answer this themselves. +@@ -55,6 +57,15 @@ void __init init_IRQ(void) + irq_set_noprobe(i); + + arch_init_irq(); ++ ++ for_each_possible_cpu(i) { ++ int irq_pages = IRQ_STACK_SIZE / PAGE_SIZE; ++ void *s = (void *)__get_free_pages(GFP_KERNEL, irq_pages); ++ ++ irq_stack[i] = s; ++ pr_debug("CPU%d IRQ stack at 0x%p - 0x%p\n", i, ++ irq_stack[i], irq_stack[i] + IRQ_STACK_SIZE); ++ } + } + + #ifdef CONFIG_DEBUG_STACKOVERFLOW diff --git a/target/linux/generic/patches-4.4/062-02-MIPS-Stack-unwinding-while-on-IRQ-stack.patch b/target/linux/generic/patches-4.4/062-02-MIPS-Stack-unwinding-while-on-IRQ-stack.patch new file mode 100644 index 0000000000..513e904e52 --- /dev/null +++ b/target/linux/generic/patches-4.4/062-02-MIPS-Stack-unwinding-while-on-IRQ-stack.patch @@ -0,0 +1,42 @@ +From: Matt Redfearn <matt.redfearn@imgtec.com> +Date: Mon, 19 Dec 2016 14:20:57 +0000 +Subject: [PATCH] MIPS: Stack unwinding while on IRQ stack + +Within unwind stack, check if the stack pointer being unwound is within +the CPU's irq_stack and if so use that page rather than the task's stack +page. + +Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com> +--- + +--- a/arch/mips/kernel/process.c ++++ b/arch/mips/kernel/process.c +@@ -32,6 +32,7 @@ + #include <asm/cpu.h> + #include <asm/dsp.h> + #include <asm/fpu.h> ++#include <asm/irq.h> + #include <asm/msa.h> + #include <asm/pgtable.h> + #include <asm/mipsregs.h> +@@ -507,7 +508,19 @@ EXPORT_SYMBOL(unwind_stack_by_address); + unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, + unsigned long pc, unsigned long *ra) + { +- unsigned long stack_page = (unsigned long)task_stack_page(task); ++ unsigned long stack_page = 0; ++ int cpu; ++ ++ for_each_possible_cpu(cpu) { ++ if (on_irq_stack(cpu, *sp)) { ++ stack_page = (unsigned long)irq_stack[cpu]; ++ break; ++ } ++ } ++ ++ if (!stack_page) ++ stack_page = (unsigned long)task_stack_page(task); ++ + return unwind_stack_by_address(stack_page, sp, pc, ra); + } + #endif diff --git a/target/linux/generic/patches-4.4/062-03-MIPS-Only-change-28-to-thread_info-if-coming-from-us.patch b/target/linux/generic/patches-4.4/062-03-MIPS-Only-change-28-to-thread_info-if-coming-from-us.patch new file mode 100644 index 0000000000..e13c67be60 --- /dev/null +++ b/target/linux/generic/patches-4.4/062-03-MIPS-Only-change-28-to-thread_info-if-coming-from-us.patch @@ -0,0 +1,48 @@ +From: Matt Redfearn <matt.redfearn@imgtec.com> +Date: Mon, 19 Dec 2016 14:20:58 +0000 +Subject: [PATCH] MIPS: Only change $28 to thread_info if coming from user + mode + +The SAVE_SOME macro is used to save the execution context on all +exceptions. +If an exception occurs while executing user code, the stack is switched +to the kernel's stack for the current task, and register $28 is switched +to point to the current_thread_info, which is at the bottom of the stack +region. +If the exception occurs while executing kernel code, the stack is left, +and this change ensures that register $28 is not updated. This is the +correct behaviour when the kernel can be executing on the separate irq +stack, because the thread_info will not be at the base of it. + +With this change, register $28 is only switched to it's kernel +conventional usage of the currrent thread info pointer at the point at +which execution enters kernel space. Doing it on every exception was +redundant, but OK without an IRQ stack, but will be erroneous once that +is introduced. + +Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com> +Reviewed-by: Maciej W. Rozycki <macro@imgtec.com> +--- + +--- a/arch/mips/include/asm/stackframe.h ++++ b/arch/mips/include/asm/stackframe.h +@@ -216,12 +216,19 @@ + LONG_S $25, PT_R25(sp) + LONG_S $28, PT_R28(sp) + LONG_S $31, PT_R31(sp) ++ ++ /* Set thread_info if we're coming from user mode */ ++ mfc0 k0, CP0_STATUS ++ sll k0, 3 /* extract cu0 bit */ ++ bltz k0, 9f ++ + ori $28, sp, _THREAD_MASK + xori $28, _THREAD_MASK + #ifdef CONFIG_CPU_CAVIUM_OCTEON + .set mips64 + pref 0, 0($28) /* Prefetch the current pointer */ + #endif ++9: + .set pop + .endm + diff --git a/target/linux/generic/patches-4.4/062-04-MIPS-Switch-to-the-irq_stack-in-interrupts.patch b/target/linux/generic/patches-4.4/062-04-MIPS-Switch-to-the-irq_stack-in-interrupts.patch new file mode 100644 index 0000000000..9bd2336974 --- /dev/null +++ b/target/linux/generic/patches-4.4/062-04-MIPS-Switch-to-the-irq_stack-in-interrupts.patch @@ -0,0 +1,116 @@ +From: Matt Redfearn <matt.redfearn@imgtec.com> +Date: Mon, 19 Dec 2016 14:20:59 +0000 +Subject: [PATCH] MIPS: Switch to the irq_stack in interrupts + +When enterring interrupt context via handle_int or except_vec_vi, switch +to the irq_stack of the current CPU if it is not already in use. + +The current stack pointer is masked with the thread size and compared to +the base or the irq stack. If it does not match then the stack pointer +is set to the top of that stack, otherwise this is a nested irq being +handled on the irq stack so the stack pointer should be left as it was. + +The in-use stack pointer is placed in the callee saved register s1. It +will be saved to the stack when plat_irq_dispatch is invoked and can be +restored once control returns here. + +Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com> +--- + +--- a/arch/mips/kernel/genex.S ++++ b/arch/mips/kernel/genex.S +@@ -188,9 +188,44 @@ NESTED(handle_int, PT_SIZE, sp) + + LONG_L s0, TI_REGS($28) + LONG_S sp, TI_REGS($28) +- PTR_LA ra, ret_from_irq +- PTR_LA v0, plat_irq_dispatch +- jr v0 ++ ++ /* ++ * SAVE_ALL ensures we are using a valid kernel stack for the thread. ++ * Check if we are already using the IRQ stack. ++ */ ++ move s1, sp # Preserve the sp ++ ++ /* Get IRQ stack for this CPU */ ++ ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG ++#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) ++ lui k1, %hi(irq_stack) ++#else ++ lui k1, %highest(irq_stack) ++ daddiu k1, %higher(irq_stack) ++ dsll k1, 16 ++ daddiu k1, %hi(irq_stack) ++ dsll k1, 16 ++#endif ++ LONG_SRL k0, SMP_CPUID_PTRSHIFT ++ LONG_ADDU k1, k0 ++ LONG_L t0, %lo(irq_stack)(k1) ++ ++ # Check if already on IRQ stack ++ PTR_LI t1, ~(_THREAD_SIZE-1) ++ and t1, t1, sp ++ beq t0, t1, 2f ++ ++ /* Switch to IRQ stack */ ++ li t1, _IRQ_STACK_SIZE ++ PTR_ADD sp, t0, t1 ++ ++2: ++ jal plat_irq_dispatch ++ ++ /* Restore sp */ ++ move sp, s1 ++ ++ j ret_from_irq + #ifdef CONFIG_CPU_MICROMIPS + nop + #endif +@@ -263,8 +298,44 @@ NESTED(except_vec_vi_handler, 0, sp) + + LONG_L s0, TI_REGS($28) + LONG_S sp, TI_REGS($28) +- PTR_LA ra, ret_from_irq +- jr v0 ++ ++ /* ++ * SAVE_ALL ensures we are using a valid kernel stack for the thread. ++ * Check if we are already using the IRQ stack. ++ */ ++ move s1, sp # Preserve the sp ++ ++ /* Get IRQ stack for this CPU */ ++ ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG ++#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) ++ lui k1, %hi(irq_stack) ++#else ++ lui k1, %highest(irq_stack) ++ daddiu k1, %higher(irq_stack) ++ dsll k1, 16 ++ daddiu k1, %hi(irq_stack) ++ dsll k1, 16 ++#endif ++ LONG_SRL k0, SMP_CPUID_PTRSHIFT ++ LONG_ADDU k1, k0 ++ LONG_L t0, %lo(irq_stack)(k1) ++ ++ # Check if already on IRQ stack ++ PTR_LI t1, ~(_THREAD_SIZE-1) ++ and t1, t1, sp ++ beq t0, t1, 2f ++ ++ /* Switch to IRQ stack */ ++ li t1, _IRQ_STACK_SIZE ++ PTR_ADD sp, t0, t1 ++ ++2: ++ jal plat_irq_dispatch ++ ++ /* Restore sp */ ++ move sp, s1 ++ ++ j ret_from_irq + END(except_vec_vi_handler) + + /* diff --git a/target/linux/generic/patches-4.4/062-05-MIPS-Select-HAVE_IRQ_EXIT_ON_IRQ_STACK.patch b/target/linux/generic/patches-4.4/062-05-MIPS-Select-HAVE_IRQ_EXIT_ON_IRQ_STACK.patch new file mode 100644 index 0000000000..a4942b83af --- /dev/null +++ b/target/linux/generic/patches-4.4/062-05-MIPS-Select-HAVE_IRQ_EXIT_ON_IRQ_STACK.patch @@ -0,0 +1,21 @@ +From: Matt Redfearn <matt.redfearn@imgtec.com> +Date: Mon, 19 Dec 2016 14:21:00 +0000 +Subject: [PATCH] MIPS: Select HAVE_IRQ_EXIT_ON_IRQ_STACK + +Since do_IRQ is now invoked on a separate IRQ stack, we select +HAVE_IRQ_EXIT_ON_IRQ_STACK so that softirq's may be invoked directly +from irq_exit(), rather than requiring do_softirq_own_stack. + +Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com> +--- + +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -9,6 +9,7 @@ config MIPS + select HAVE_CONTEXT_TRACKING + select HAVE_GENERIC_DMA_COHERENT + select HAVE_IDE ++ select HAVE_IRQ_EXIT_ON_IRQ_STACK + select HAVE_OPROFILE + select HAVE_PERF_EVENTS + select PERF_USE_VMALLOC diff --git a/target/linux/generic/patches-4.4/092-MIPS-ZBOOT-copy-appended-dtb-to-the-end-of-the-kerne.patch b/target/linux/generic/patches-4.4/092-MIPS-ZBOOT-copy-appended-dtb-to-the-end-of-the-kerne.patch index 71df42992b..78188dd298 100644 --- a/target/linux/generic/patches-4.4/092-MIPS-ZBOOT-copy-appended-dtb-to-the-end-of-the-kerne.patch +++ b/target/linux/generic/patches-4.4/092-MIPS-ZBOOT-copy-appended-dtb-to-the-end-of-the-kerne.patch @@ -27,7 +27,7 @@ Signed-off-by: Ralf Baechle <ralf@linux-mips.org> --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig -@@ -2752,10 +2752,10 @@ choice +@@ -2753,10 +2753,10 @@ choice the documented boot protocol using a device tree. config MIPS_RAW_APPENDED_DTB @@ -40,7 +40,7 @@ Signed-off-by: Ralf Baechle <ralf@linux-mips.org> (e.g. cat vmlinux.bin <filename>.dtb > vmlinux_w_dtb). This is meant as a backward compatibility convenience for those -@@ -2767,24 +2767,6 @@ choice +@@ -2768,24 +2768,6 @@ choice look like a DTB header after a reboot if no actual DTB is appended to vmlinux.bin. Do not leave this option active in a production kernel if you don't intend to always append a DTB. diff --git a/target/linux/generic/patches-4.4/132-mips_inline_dma_ops.patch b/target/linux/generic/patches-4.4/132-mips_inline_dma_ops.patch index bf7dca6a33..143b0bb3ff 100644 --- a/target/linux/generic/patches-4.4/132-mips_inline_dma_ops.patch +++ b/target/linux/generic/patches-4.4/132-mips_inline_dma_ops.patch @@ -19,7 +19,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig -@@ -1618,6 +1618,7 @@ config CPU_CAVIUM_OCTEON +@@ -1619,6 +1619,7 @@ config CPU_CAVIUM_OCTEON select USB_EHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN select USB_OHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN select MIPS_L1_CACHE_SHIFT_7 @@ -27,7 +27,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> help The Cavium Octeon processor is a highly integrated chip containing many ethernet hardware widgets for networking tasks. The processor -@@ -1913,6 +1914,9 @@ config MIPS_MALTA_PM +@@ -1914,6 +1915,9 @@ config MIPS_MALTA_PM bool default y diff --git a/target/linux/generic/patches-4.4/300-mips_expose_boot_raw.patch b/target/linux/generic/patches-4.4/300-mips_expose_boot_raw.patch index 76c70782a9..0980c26d50 100644 --- a/target/linux/generic/patches-4.4/300-mips_expose_boot_raw.patch +++ b/target/linux/generic/patches-4.4/300-mips_expose_boot_raw.patch @@ -8,7 +8,7 @@ Acked-by: Rob Landley <rob@landley.net> --- --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig -@@ -1032,9 +1032,6 @@ config FW_ARC +@@ -1033,9 +1033,6 @@ config FW_ARC config ARCH_MAY_HAVE_PC_FDC bool @@ -18,7 +18,7 @@ Acked-by: Rob Landley <rob@landley.net> config CEVT_BCM1480 bool -@@ -2792,6 +2789,18 @@ choice +@@ -2793,6 +2790,18 @@ choice bool "Bootloader kernel arguments if available" endchoice diff --git a/target/linux/generic/patches-4.4/301-mips_image_cmdline_hack.patch b/target/linux/generic/patches-4.4/301-mips_image_cmdline_hack.patch index 878f74d69f..625a84c814 100644 --- a/target/linux/generic/patches-4.4/301-mips_image_cmdline_hack.patch +++ b/target/linux/generic/patches-4.4/301-mips_image_cmdline_hack.patch @@ -1,6 +1,6 @@ --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig -@@ -1123,6 +1123,10 @@ config SYNC_R4K +@@ -1124,6 +1124,10 @@ config SYNC_R4K config MIPS_MACHINE def_bool n diff --git a/target/linux/generic/patches-4.4/304-mips_disable_fpu.patch b/target/linux/generic/patches-4.4/304-mips_disable_fpu.patch index aabb4f12b2..a08564dcea 100644 --- a/target/linux/generic/patches-4.4/304-mips_disable_fpu.patch +++ b/target/linux/generic/patches-4.4/304-mips_disable_fpu.patch @@ -26,7 +26,7 @@ v2: incorporated changes suggested by Jonas Gorski --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig -@@ -2724,6 +2724,20 @@ config MIPS_O32_FP64_SUPPORT +@@ -2725,6 +2725,20 @@ config MIPS_O32_FP64_SUPPORT If unsure, say N. |