diff options
author | Waldemar Brodkorb <wbx@openadk.org> | 2015-10-27 21:55:12 +0100 |
---|---|---|
committer | Waldemar Brodkorb <wbx@openadk.org> | 2015-10-27 21:55:12 +0100 |
commit | 4ca0a2ecda8f72cf4e44b0c5169eb61999220f7a (patch) | |
tree | 66e79392ae8aa487f4c3ba336d290e4e35b85054 /target | |
parent | dd02d07d943f8fc2e31c9aa86e838556dcd24567 (diff) |
drop rt support for 3.14.x/3.18.x kernels
Diffstat (limited to 'target')
-rw-r--r-- | target/linux/config/Config.in.kernel | 7 | ||||
-rw-r--r-- | target/linux/patches/3.18.22/realtime.patch | 36846 |
2 files changed, 2 insertions, 36851 deletions
diff --git a/target/linux/config/Config.in.kernel b/target/linux/config/Config.in.kernel index 6516c133c..b53df07bf 100644 --- a/target/linux/config/Config.in.kernel +++ b/target/linux/config/Config.in.kernel @@ -294,13 +294,10 @@ endchoice config ADK_KERNEL_HIGH_RES_TIMERS bool "Enable high resolution timers" - help config ADK_KERNEL_PREEMPT_RT_FULL - bool "Enable Realtime support (external kernel patch)" - depends on ADK_TARGET_KERNEL_VERSION_3_18 \ - || ADK_TARGET_KERNEL_VERSION_3_14 \ - || ADK_TARGET_KERNEL_VERSION_4_1 + bool "Enable Full Realtime support (external kernel patch)" + depends on ADK_TARGET_KERNEL_VERSION_4_1 help https://www.kernel.org/pub/linux/kernel/projects/rt/ diff --git a/target/linux/patches/3.18.22/realtime.patch b/target/linux/patches/3.18.22/realtime.patch deleted file mode 100644 index 28b9b271c..000000000 --- a/target/linux/patches/3.18.22/realtime.patch +++ /dev/null @@ -1,36846 +0,0 @@ -diff -Nur linux-3.18.14.orig/arch/alpha/mm/fault.c linux-3.18.14-rt/arch/alpha/mm/fault.c ---- linux-3.18.14.orig/arch/alpha/mm/fault.c 2015-05-20 10:04:50.000000000 -0500 -+++ linux-3.18.14-rt/arch/alpha/mm/fault.c 2015-05-31 15:32:45.517635394 -0500 -@@ -107,7 +107,7 @@ - - /* If we're in an interrupt context, or have no user context, - we must not take the fault. */ -- if (!mm || in_atomic()) -+ if (!mm || pagefault_disabled()) - goto no_context; - - #ifdef CONFIG_ALPHA_LARGE_VMALLOC -diff -Nur linux-3.18.14.orig/arch/arm/include/asm/cmpxchg.h linux-3.18.14-rt/arch/arm/include/asm/cmpxchg.h ---- linux-3.18.14.orig/arch/arm/include/asm/cmpxchg.h 2015-05-20 10:04:50.000000000 -0500 -+++ linux-3.18.14-rt/arch/arm/include/asm/cmpxchg.h 2015-05-31 15:32:45.557635393 -0500 -@@ -129,6 +129,8 @@ - - #else /* min ARCH >= ARMv6 */ - -+#define __HAVE_ARCH_CMPXCHG 1 -+ - extern void __bad_cmpxchg(volatile void *ptr, int size); - - /* -diff -Nur linux-3.18.14.orig/arch/arm/include/asm/futex.h linux-3.18.14-rt/arch/arm/include/asm/futex.h ---- linux-3.18.14.orig/arch/arm/include/asm/futex.h 2015-05-20 10:04:50.000000000 -0500 -+++ linux-3.18.14-rt/arch/arm/include/asm/futex.h 2015-05-31 15:32:45.561635393 -0500 -@@ -93,6 +93,8 @@ - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; - -+ preempt_disable_rt(); -+ - __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n" - "1: " TUSER(ldr) " %1, [%4]\n" - " teq %1, %2\n" -@@ -104,6 +106,8 @@ - : "cc", "memory"); - - *uval = val; -+ -+ preempt_enable_rt(); - return ret; - } - -diff -Nur linux-3.18.14.orig/arch/arm/include/asm/switch_to.h linux-3.18.14-rt/arch/arm/include/asm/switch_to.h ---- linux-3.18.14.orig/arch/arm/include/asm/switch_to.h 2015-05-20 10:04:50.000000000 -0500 -+++ linux-3.18.14-rt/arch/arm/include/asm/switch_to.h 2015-05-31 15:32:45.565635393 -0500 -@@ -3,6 +3,13 @@ - - #include <linux/thread_info.h> - -+#if defined CONFIG_PREEMPT_RT_FULL && defined CONFIG_HIGHMEM -+void switch_kmaps(struct task_struct *prev_p, struct task_struct *next_p); -+#else -+static inline void -+switch_kmaps(struct task_struct *prev_p, struct task_struct *next_p) { } -+#endif -+ - /* - * For v7 SMP cores running a preemptible kernel we may be pre-empted - * during a TLB maintenance operation, so execute an inner-shareable dsb -@@ -22,6 +29,7 @@ - - #define switch_to(prev,next,last) \ - do { \ -+ switch_kmaps(prev, next); \ - last = __switch_to(prev,task_thread_info(prev), task_thread_info(next)); \ - } while (0) - -diff -Nur linux-3.18.14.orig/arch/arm/include/asm/thread_info.h linux-3.18.14-rt/arch/arm/include/asm/thread_info.h ---- linux-3.18.14.orig/arch/arm/include/asm/thread_info.h 2015-05-20 10:04:50.000000000 -0500 -+++ linux-3.18.14-rt/arch/arm/include/asm/thread_info.h 2015-05-31 15:32:45.585635393 -0500 -@@ -51,6 +51,7 @@ - struct thread_info { - unsigned long flags; /* low level flags */ - int preempt_count; /* 0 => preemptable, <0 => bug */ -+ int preempt_lazy_count; /* 0 => preemptable, <0 => bug */ - mm_segment_t addr_limit; /* address limit */ - struct task_struct *task; /* main task structure */ - struct exec_domain *exec_domain; /* execution domain */ -@@ -149,6 +150,7 @@ - #define TIF_SIGPENDING 0 - #define TIF_NEED_RESCHED 1 - #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ -+#define TIF_NEED_RESCHED_LAZY 3 - #define TIF_UPROBE 7 - #define TIF_SYSCALL_TRACE 8 - #define TIF_SYSCALL_AUDIT 9 -@@ -162,6 +164,7 @@ - #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) - #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) - #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) -+#define _TIF_NEED_RESCHED_LAZY (1 << TIF_NEED_RESCHED_LAZY) - #define _TIF_UPROBE (1 << TIF_UPROBE) - #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) - #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) -diff -Nur linux-3.18.14.orig/arch/arm/Kconfig linux-3.18.14-rt/arch/arm/Kconfig ---- linux-3.18.14.orig/arch/arm/Kconfig 2015-05-20 10:04:50.000000000 -0500 -+++ linux-3.18.14-rt/arch/arm/Kconfig 2015-05-31 15:32:45.529635394 -0500 -@@ -62,6 +62,7 @@ - select HAVE_PERF_EVENTS - select HAVE_PERF_REGS - select HAVE_PERF_USER_STACK_DUMP -+ select HAVE_PREEMPT_LAZY - select HAVE_RCU_TABLE_FREE if (SMP && ARM_LPAE) - select HAVE_REGS_AND_STACK_ACCESS_API - select HAVE_SYSCALL_TRACEPOINTS -diff -Nur linux-3.18.14.orig/arch/arm/kernel/asm-offsets.c linux-3.18.14-rt/arch/arm/kernel/asm-offsets.c ---- linux-3.18.14.orig/arch/arm/kernel/asm-offsets.c 2015-05-20 10:04:50.000000000 -0500 -+++ linux-3.18.14-rt/arch/arm/kernel/asm-offsets.c 2015-05-31 15:32:45.605635393 -0500 -@@ -64,6 +64,7 @@ - BLANK(); - DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); - DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); -+ DEFINE(TI_PREEMPT_LAZY, offsetof(struct thread_info, preempt_lazy_count)); - DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit)); - DEFINE(TI_TASK, offsetof(struct thread_info, task)); - DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain)); -diff -Nur linux-3.18.14.orig/arch/arm/kernel/entry-armv.S linux-3.18.14-rt/arch/arm/kernel/entry-armv.S ---- linux-3.18.14.orig/arch/arm/kernel/entry-armv.S 2015-05-20 10:04:50.000000000 -0500 -+++ linux-3.18.14-rt/arch/arm/kernel/entry-armv.S 2015-05-31 15:32:45.613635393 -0500 -@@ -207,11 +207,18 @@ - #ifdef CONFIG_PREEMPT - get_thread_info tsk - ldr r8, [tsk, #TI_PREEMPT] @ get preempt count -- ldr r0, [tsk, #TI_FLAGS] @ get flags - teq r8, #0 @ if preempt count != 0 -+ bne 1f @ return from exeption -+ ldr r0, [tsk, #TI_FLAGS] @ get flags -+ tst r0, #_TIF_NEED_RESCHED @ if NEED_RESCHED is set -+ blne svc_preempt @ preempt! -+ -+ ldr r8, [tsk, #TI_PREEMPT_LAZY] @ get preempt lazy count -+ teq r8, #0 @ if preempt lazy count != 0 - movne r0, #0 @ force flags to 0 -- tst r0, #_TIF_NEED_RESCHED -+ tst r0, #_TIF_NEED_RESCHED_LAZY - blne svc_preempt -+1: - #endif - - svc_exit r5, irq = 1 @ return from exception -@@ -226,6 +233,8 @@ - 1: bl preempt_schedule_irq @ irq en/disable is done inside - ldr r0, [tsk, #TI_FLAGS] @ get new tasks TI_FLAGS - tst r0, #_TIF_NEED_RESCHED -+ bne 1b -+ tst r0, #_TIF_NEED_RESCHED_LAZY - reteq r8 @ go again - b 1b - #endif -diff -Nur linux-3.18.14.orig/arch/arm/kernel/process.c linux-3.18.14-rt/arch/arm/kernel/process.c ---- linux-3.18.14.orig/arch/arm/kernel/process.c 2015-05-20 10:04:50.000000000 -0500 -+++ linux-3.18.14-rt/arch/arm/kernel/process.c 2015-05-31 15:32:45.617635393 -0500 -@@ -437,6 +437,30 @@ - } - - #ifdef CONFIG_MMU -+/* -+ * CONFIG_SPLIT_PTLOCK_CPUS results in a page->ptl lock. If the lock is not -+ * initialized by pgtable_page_ctor() then a coredump of the vector page will -+ * fail. -+ */ -+static int __init vectors_user_mapping_init_page(void) -+{ -+ struct page *page; -+ unsigned long addr = 0xffff0000; -+ pgd_t *pgd; -+ pud_t *pud; -+ pmd_t *pmd; -+ -+ pgd = pgd_offset_k(addr); -+ pud = pud_offset(pgd, addr); -+ pmd = pmd_offset(pud, addr); -+ page = pmd_page(*(pmd)); -+ -+ pgtable_page_ctor(page); -+ -+ return 0; -+} -+late_initcall(vectors_user_mapping_init_page); -+ - #ifdef CONFIG_KUSER_HELPERS - /* - * The vectors page is always readable from user space for the -diff -Nur linux-3.18.14.orig/arch/arm/kernel/process.c.orig linux-3.18.14-rt/arch/arm/kernel/process.c.orig ---- linux-3.18.14.orig/arch/arm/kernel/process.c.orig 1969-12-31 18:00:00.000000000 -0600 -+++ linux-3.18.14-rt/arch/arm/kernel/process.c.orig 2015-05-20 10:04:50.000000000 -0500 -@@ -0,0 +1,560 @@ -+/* -+ * linux/arch/arm/kernel/process.c -+ * -+ * Copyright (C) 1996-2000 Russell King - Converted to ARM. -+ * Original Copyright (C) 1995 Linus Torvalds -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#include <stdarg.h> -+ -+#include <linux/export.h> -+#include <linux/sched.h> -+#include <linux/kernel.h> -+#include <linux/mm.h> -+#include <linux/stddef.h> -+#include <linux/unistd.h> -+#include <linux/user.h> -+#include <linux/delay.h> -+#include <linux/reboot.h> -+#include <linux/interrupt.h> -+#include <linux/kallsyms.h> -+#include <linux/init.h> -+#include <linux/cpu.h> -+#include <linux/elfcore.h> -+#include <linux/pm.h> -+#include <linux/tick.h> -+#include <linux/utsname.h> -+#include <linux/uaccess.h> -+#include <linux/random.h> -+#include <linux/hw_breakpoint.h> -+#include <linux/leds.h> -+#include <linux/reboot.h> -+ -+#include <asm/cacheflush.h> -+#include <asm/idmap.h> -+#include <asm/processor.h> -+#include <asm/thread_notify.h> -+#include <asm/stacktrace.h> -+#include <asm/system_misc.h> -+#include <asm/mach/time.h> -+#include <asm/tls.h> -+#include "reboot.h" -+ -+#ifdef CONFIG_CC_STACKPROTECTOR -+#include <linux/stackprotector.h> -+unsigned long __stack_chk_guard __read_mostly; -+EXPORT_SYMBOL(__stack_chk_guard); -+#endif -+ -+static const char *processor_modes[] __maybe_unused = { -+ "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" , -+ "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26", -+ "USER_32", "FIQ_32" , "IRQ_32" , "SVC_32" , "UK4_32" , "UK5_32" , "UK6_32" , "ABT_32" , -+ "UK8_32" , "UK9_32" , "UK10_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32" -+}; -+ -+static const char *isa_modes[] __maybe_unused = { -+ "ARM" , "Thumb" , "Jazelle", "ThumbEE" -+}; -+ -+extern void call_with_stack(void (*fn)(void *), void *arg, void *sp); -+typedef void (*phys_reset_t)(unsigned long); -+ -+/* -+ * A temporary stack to use for CPU reset. This is static so that we -+ * don't clobber it with the identity mapping. When running with this -+ * stack, any references to the current task *will not work* so you -+ * should really do as little as possible before jumping to your reset -+ * code. -+ */ -+static u64 soft_restart_stack[16]; -+ -+static void __soft_restart(void *addr) -+{ -+ phys_reset_t phys_reset; -+ -+ /* Take out a flat memory mapping. */ -+ setup_mm_for_reboot(); -+ -+ /* Clean and invalidate caches */ -+ flush_cache_all(); -+ -+ /* Turn off caching */ -+ cpu_proc_fin(); -+ -+ /* Push out any further dirty data, and ensure cache is empty */ -+ flush_cache_all(); -+ -+ /* Switch to the identity mapping. */ -+ phys_reset = (phys_reset_t)(unsigned long)virt_to_phys(cpu_reset); -+ phys_reset((unsigned long)addr); -+ -+ /* Should never get here. */ -+ BUG(); -+} -+ -+void _soft_restart(unsigned long addr, bool disable_l2) -+{ -+ u64 *stack = soft_restart_stack + ARRAY_SIZE(soft_restart_stack); -+ -+ /* Disable interrupts first */ -+ raw_local_irq_disable(); -+ local_fiq_disable(); -+ -+ /* Disable the L2 if we're the last man standing. */ -+ if (disable_l2) -+ outer_disable(); -+ -+ /* Change to the new stack and continue with the reset. */ -+ call_with_stack(__soft_restart, (void *)addr, (void *)stack); -+ -+ /* Should never get here. */ -+ BUG(); -+} -+ -+void soft_restart(unsigned long addr) -+{ -+ _soft_restart(addr, num_online_cpus() == 1); -+} -+ -+/* -+ * Function pointers to optional machine specific functions -+ */ -+void (*pm_power_off)(void); -+EXPORT_SYMBOL(pm_power_off); -+ -+void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd); -+ -+/* -+ * This is our default idle handler. -+ */ -+ -+void (*arm_pm_idle)(void); -+ -+/* -+ * Called from the core idle loop. -+ */ -+ -+void arch_cpu_idle(void) -+{ -+ if (arm_pm_idle) -+ arm_pm_idle(); -+ else -+ cpu_do_idle(); -+ local_irq_enable(); -+} -+ -+void arch_cpu_idle_prepare(void) -+{ -+ local_fiq_enable(); -+} -+ -+void arch_cpu_idle_enter(void) -+{ -+ ledtrig_cpu(CPU_LED_IDLE_START); -+#ifdef CONFIG_PL310_ERRATA_769419 -+ wmb(); -+#endif -+} -+ -+void arch_cpu_idle_exit(void) -+{ -+ ledtrig_cpu(CPU_LED_IDLE_END); -+} -+ -+#ifdef CONFIG_HOTPLUG_CPU -+void arch_cpu_idle_dead(void) -+{ -+ cpu_die(); -+} -+#endif -+ -+/* -+ * Called by kexec, immediately prior to machine_kexec(). -+ * -+ * This must completely disable all secondary CPUs; simply causing those CPUs -+ * to execute e.g. a RAM-based pin loop is not sufficient. This allows the -+ * kexec'd kernel to use any and all RAM as it sees fit, without having to -+ * avoid any code or data used by any SW CPU pin loop. The CPU hotplug -+ * functionality embodied in disable_nonboot_cpus() to achieve this. -+ */ -+void machine_shutdown(void) -+{ -+ disable_nonboot_cpus(); -+} -+ -+/* -+ * Halting simply requires that the secondary CPUs stop performing any -+ * activity (executing tasks, handling interrupts). smp_send_stop() -+ * achieves this. -+ */ -+void machine_halt(void) -+{ -+ local_irq_disable(); -+ smp_send_stop(); -+ -+ local_irq_disable(); -+ while (1); -+} -+ -+/* -+ * Power-off simply requires that the secondary CPUs stop performing any -+ * activity (executing tasks, handling interrupts). smp_send_stop() -+ * achieves this. When the system power is turned off, it will take all CPUs -+ * with it. -+ */ -+void machine_power_off(void) -+{ -+ local_irq_disable(); -+ smp_send_stop(); -+ -+ if (pm_power_off) -+ pm_power_off(); -+} -+ -+/* -+ * Restart requires that the secondary CPUs stop performing any activity -+ * while the primary CPU resets the system. Systems with a single CPU can -+ * use soft_restart() as their machine descriptor's .restart hook, since that -+ * will cause the only available CPU to reset. Systems with multiple CPUs must -+ * provide a HW restart implementation, to ensure that all CPUs reset at once. -+ * This is required so that any code running after reset on the primary CPU -+ * doesn't have to co-ordinate with other CPUs to ensure they aren't still -+ * executing pre-reset code, and using RAM that the primary CPU's code wishes -+ * to use. Implementing such co-ordination would be essentially impossible. -+ */ -+void machine_restart(char *cmd) -+{ -+ local_irq_disable(); -+ smp_send_stop(); -+ -+ if (arm_pm_restart) -+ arm_pm_restart(reboot_mode, cmd); -+ else -+ do_kernel_restart(cmd); -+ -+ /* Give a grace period for failure to restart of 1s */ -+ mdelay(1000); -+ -+ /* Whoops - the platform was unable to reboot. Tell the user! */ -+ printk("Reboot failed -- System halted\n"); -+ local_irq_disable(); -+ while (1); -+} -+ -+void __show_regs(struct pt_regs *regs) -+{ -+ unsigned long flags; -+ char buf[64]; -+ -+ show_regs_print_info(KERN_DEFAULT); -+ -+ print_symbol("PC is at %s\n", instruction_pointer(regs)); -+ print_symbol("LR is at %s\n", regs->ARM_lr); -+ printk("pc : [<%08lx>] lr : [<%08lx>] psr: %08lx\n" -+ "sp : %08lx ip : %08lx fp : %08lx\n", -+ regs->ARM_pc, regs->ARM_lr, regs->ARM_cpsr, -+ regs->ARM_sp, regs->ARM_ip, regs->ARM_fp); -+ printk("r10: %08lx r9 : %08lx r8 : %08lx\n", -+ regs->ARM_r10, regs->ARM_r9, -+ regs->ARM_r8); -+ printk("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n", -+ regs->ARM_r7, regs->ARM_r6, -+ regs->ARM_r5, regs->ARM_r4); -+ printk("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n", -+ regs->ARM_r3, regs->ARM_r2, -+ regs->ARM_r1, regs->ARM_r0); -+ -+ flags = regs->ARM_cpsr; -+ buf[0] = flags & PSR_N_BIT ? 'N' : 'n'; -+ buf[1] = flags & PSR_Z_BIT ? 'Z' : 'z'; -+ buf[2] = flags & PSR_C_BIT ? 'C' : 'c'; -+ buf[3] = flags & PSR_V_BIT ? 'V' : 'v'; -+ buf[4] = '\0'; -+ -+#ifndef CONFIG_CPU_V7M -+ printk("Flags: %s IRQs o%s FIQs o%s Mode %s ISA %s Segment %s\n", -+ buf, interrupts_enabled(regs) ? "n" : "ff", -+ fast_interrupts_enabled(regs) ? "n" : "ff", -+ processor_modes[processor_mode(regs)], -+ isa_modes[isa_mode(regs)], -+ get_fs() == get_ds() ? "kernel" : "user"); -+#else -+ printk("xPSR: %08lx\n", regs->ARM_cpsr); -+#endif -+ -+#ifdef CONFIG_CPU_CP15 -+ { -+ unsigned int ctrl; -+ -+ buf[0] = '\0'; -+#ifdef CONFIG_CPU_CP15_MMU -+ { -+ unsigned int transbase, dac; -+ asm("mrc p15, 0, %0, c2, c0\n\t" -+ "mrc p15, 0, %1, c3, c0\n" -+ : "=r" (transbase), "=r" (dac)); -+ snprintf(buf, sizeof(buf), " Table: %08x DAC: %08x", -+ transbase, dac); -+ } -+#endif -+ asm("mrc p15, 0, %0, c1, c0\n" : "=r" (ctrl)); -+ -+ printk("Control: %08x%s\n", ctrl, buf); -+ } -+#endif -+} -+ -+void show_regs(struct pt_regs * regs) -+{ -+ __show_regs(regs); -+ dump_stack(); -+} -+ -+ATOMIC_NOTIFIER_HEAD(thread_notify_head); -+ -+EXPORT_SYMBOL_GPL(thread_notify_head); -+ -+/* -+ * Free current thread data structures etc.. -+ */ -+void exit_thread(void) -+{ -+ thread_notify(THREAD_NOTIFY_EXIT, current_thread_info()); -+} -+ -+void flush_thread(void) -+{ -+ struct thread_info *thread = current_thread_info(); -+ struct task_struct *tsk = current; -+ -+ flush_ptrace_hw_breakpoint(tsk); -+ -+ memset(thread->used_cp, 0, sizeof(thread->used_cp)); -+ memset(&tsk->thread.debug, 0, sizeof(struct debug_info)); -+ memset(&thread->fpstate, 0, sizeof(union fp_state)); -+ -+ flush_tls(); -+ -+ thread_notify(THREAD_NOTIFY_FLUSH, thread); -+} -+ -+void release_thread(struct task_struct *dead_task) -+{ -+} -+ -+asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); -+ -+int -+copy_thread(unsigned long clone_flags, unsigned long stack_start, -+ unsigned long stk_sz, struct task_struct *p) -+{ -+ struct thread_info *thread = task_thread_info(p); -+ struct pt_regs *childregs = task_pt_regs(p); -+ -+ memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save)); -+ -+ if (likely(!(p->flags & PF_KTHREAD))) { -+ *childregs = *current_pt_regs(); -+ childregs->ARM_r0 = 0; -+ if (stack_start) -+ childregs->ARM_sp = stack_start; -+ } else { -+ memset(childregs, 0, sizeof(struct pt_regs)); -+ thread->cpu_context.r4 = stk_sz; -+ thread->cpu_context.r5 = stack_start; -+ childregs->ARM_cpsr = SVC_MODE; -+ } -+ thread->cpu_context.pc = (unsigned long)ret_from_fork; -+ thread->cpu_context.sp = (unsigned long)childregs; -+ -+ clear_ptrace_hw_breakpoint(p); -+ -+ if (clone_flags & CLONE_SETTLS) -+ thread->tp_value[0] = childregs->ARM_r3; -+ thread->tp_value[1] = get_tpuser(); -+ -+ thread_notify(THREAD_NOTIFY_COPY, thread); -+ -+ return 0; -+} -+ -+/* -+ * Fill in the task's elfregs structure for a core dump. -+ */ -+int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs) -+{ -+ elf_core_copy_regs(elfregs, task_pt_regs(t)); -+ return 1; -+} -+ -+/* -+ * fill in the fpe structure for a core dump... -+ */ -+int dump_fpu (struct pt_regs *regs, struct user_fp *fp) -+{ -+ struct thread_info *thread = current_thread_info(); -+ int used_math = thread->used_cp[1] | thread->used_cp[2]; -+ -+ if (used_math) -+ memcpy(fp, &thread->fpstate.soft, sizeof (*fp)); -+ -+ return used_math != 0; -+} -+EXPORT_SYMBOL(dump_fpu); -+ -+unsigned long get_wchan(struct task_struct *p) -+{ -+ struct stackframe frame; -+ unsigned long stack_page; -+ int count = 0; -+ if (!p || p == current || p->state == TASK_RUNNING) -+ return 0; -+ -+ frame.fp = thread_saved_fp(p); -+ frame.sp = thread_saved_sp(p); -+ frame.lr = 0; /* recovered from the stack */ -+ frame.pc = thread_saved_pc(p); -+ stack_page = (unsigned long)task_stack_page(p); -+ do { -+ if (frame.sp < stack_page || -+ frame.sp >= stack_page + THREAD_SIZE || -+ unwind_frame(&frame) < 0) -+ return 0; -+ if (!in_sched_functions(frame.pc)) -+ return frame.pc; -+ } while (count ++ < 16); -+ return 0; -+} -+ -+unsigned long arch_randomize_brk(struct mm_struct *mm) -+{ -+ unsigned long range_end = mm->brk + 0x02000000; -+ return randomize_range(mm->brk, range_end, 0) ? : mm->brk; -+} -+ -+#ifdef CONFIG_MMU -+#ifdef CONFIG_KUSER_HELPERS -+/* -+ * The vectors page is always readable from user space for the -+ * atomic helpers. Insert it into the gate_vma so that it is visible -+ * through ptrace and /proc/<pid>/mem. -+ */ -+static struct vm_area_struct gate_vma = { -+ .vm_start = 0xffff0000, -+ .vm_end = 0xffff0000 + PAGE_SIZE, -+ .vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC, -+}; -+ -+static int __init gate_vma_init(void) -+{ -+ gate_vma.vm_page_prot = PAGE_READONLY_EXEC; -+ return 0; -+} -+arch_initcall(gate_vma_init); -+ -+struct vm_area_struct *get_gate_vma(struct mm_struct *mm) -+{ -+ return &gate_vma; -+} -+ -+int in_gate_area(struct mm_struct *mm, unsigned long addr) -+{ -+ return (addr >= gate_vma.vm_start) && (addr < gate_vma.vm_end); -+} -+ -+int in_gate_area_no_mm(unsigned long addr) -+{ -+ return in_gate_area(NULL, addr); -+} -+#define is_gate_vma(vma) ((vma) == &gate_vma) -+#else -+#define is_gate_vma(vma) 0 -+#endif -+ -+const char *arch_vma_name(struct vm_area_struct *vma) -+{ -+ return is_gate_vma(vma) ? "[vectors]" : NULL; -+} -+ -+/* If possible, provide a placement hint at a random offset from the -+ * stack for the signal page. -+ */ -+static unsigned long sigpage_addr(const struct mm_struct *mm, -+ unsigned int npages) -+{ -+ unsigned long offset; -+ unsigned long first; -+ unsigned long last; -+ unsigned long addr; -+ unsigned int slots; -+ -+ first = PAGE_ALIGN(mm->start_stack); -+ -+ last = TASK_SIZE - (npages << PAGE_SHIFT); -+ -+ /* No room after stack? */ -+ if (first > last) -+ return 0; -+ -+ /* Just enough room? */ -+ if (first == last) -+ return first; -+ -+ slots = ((last - first) >> PAGE_SHIFT) + 1; -+ -+ offset = get_random_int() % slots; -+ -+ addr = first + (offset << PAGE_SHIFT); -+ -+ return addr; -+} -+ -+static struct page *signal_page; -+extern struct page *get_signal_page(void); -+ -+static const struct vm_special_mapping sigpage_mapping = { -+ .name = "[sigpage]", -+ .pages = &signal_page, -+}; -+ -+int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) -+{ -+ struct mm_struct *mm = current->mm; -+ struct vm_area_struct *vma; -+ unsigned long addr; -+ unsigned long hint; -+ int ret = 0; -+ -+ if (!signal_page) -+ signal_page = get_signal_page(); -+ if (!signal_page) -+ return -ENOMEM; -+ -+ down_write(&mm->mmap_sem); -+ hint = sigpage_addr(mm, 1); -+ addr = get_unmapped_area(NULL, hint, PAGE_SIZE, 0, 0); -+ if (IS_ERR_VALUE(addr)) { -+ ret = addr; -+ goto up_fail; -+ } -+ -+ vma = _install_special_mapping(mm, addr, PAGE_SIZE, -+ VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC, -+ &sigpage_mapping); -+ -+ if (IS_ERR(vma)) { -+ ret = PTR_ERR(vma); -+ goto up_fail; -+ } -+ -+ mm->context.sigpage = addr; -+ -+ up_fail: -+ up_write(&mm->mmap_sem); -+ return ret; -+} -+#endif -diff -Nur linux-3.18.14.orig/arch/arm/kernel/signal.c linux-3.18.14-rt/arch/arm/kernel/signal.c ---- linux-3.18.14.orig/arch/arm/kernel/signal.c 2015-05-20 10:04:50.000000000 -0500 -+++ linux-3.18.14-rt/arch/arm/kernel/signal.c 2015-05-31 15:32:45.617635393 -0500 -@@ -574,7 +574,8 @@ - do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall) - { - do { -- if (likely(thread_flags & _TIF_NEED_RESCHED)) { -+ if (likely(thread_flags & (_TIF_NEED_RESCHED | -+ _TIF_NEED_RESCHED_LAZY))) { - schedule(); - } else { - if (unlikely(!user_mode(regs))) -diff -Nur linux-3.18.14.orig/arch/arm/kernel/unwind.c linux-3.18.14-rt/arch/arm/kernel/unwind.c ---- linux-3.18.14.orig/arch/arm/kernel/unwind.c 2015-05-20 10:04:50.000000000 -0500 -+++ linux-3.18.14-rt/arch/arm/kernel/unwind.c 2015-05-31 15:32:45.653635392 -0500 -@@ -93,7 +93,7 @@ - static const struct unwind_idx *__origin_unwind_idx; - extern const struct unwind_idx __stop_unwind_idx[]; - --static DEFINE_SPINLOCK(unwind_lock); -+static DEFINE_RAW_SPINLOCK(unwind_lock); - static LIST_HEAD(unwind_tables); - - /* Convert a prel31 symbol to an absolute address */ -@@ -201,7 +201,7 @@ - /* module unwind tables */ - struct unwind_table *table; - -- spin_lock_irqsave(&unwind_lock, flags); -+ raw_spin_lock_irqsave(&unwind_lock, flags); - list_for_each_entry(table, &unwind_tables, list) { - if (addr >= table->begin_addr && - addr < table->end_addr) { -@@ -213,7 +213,7 @@ - break; - } - } -- spin_unlock_irqrestore(&unwind_lock, flags); -+ raw_spin_unlock_irqrestore(&unwind_lock, flags); - } - - pr_debug("%s: idx = %p\n", __func__, idx); -@@ -530,9 +530,9 @@ - tab->begin_addr = text_addr; - tab->end_addr = text_addr + text_size; - -- spin_lock_irqsave(&unwind_lock, flags); -+ raw_spin_lock_irqsave(&unwind_lock, flags); - list_add_tail(&tab->list, &unwind_tables); -- spin_unlock_irqrestore(&unwind_lock, flags); -+ raw_spin_unlock_irqrestore(&unwind_lock, flags); - - return tab; - } -@@ -544,9 +544,9 @@ - if (!tab) - return; - -- spin_lock_irqsave(&unwind_lock, flags); -+ raw_spin_lock_irqsave(&unwind_lock, flags); - list_del(&tab->list); -- spin_unlock_irqrestore(&unwind_lock, flags); -+ raw_spin_unlock_irqrestore(&unwind_lock, flags); - - kfree(tab); - } -diff -Nur linux-3.18.14.orig/arch/arm/kvm/arm.c linux-3.18.14-rt/arch/arm/kvm/arm.c ---- linux-3.18.14.orig/arch/arm/kvm/arm.c 2015-05-20 10:04:50.000000000 -0500 -+++ linux-3.18.14-rt/arch/arm/kvm/arm.c 2015-05-31 15:32:45.669635392 -0500 -@@ -455,9 +455,9 @@ - - static void vcpu_pause(struct kvm_vcpu *vcpu) - { -- wait_queue_head_t *wq = kvm_arch_vcpu_wq(vcpu); -+ struct swait_head *wq = kvm_arch_vcpu_wq(vcpu); - -- wait_event_interruptible(*wq, !vcpu->arch.pause); -+ swait_event_interruptible(*wq, !vcpu->arch.pause); - } - - static int kvm_vcpu_initialized(struct kvm_vcpu *vcpu) -diff -Nur linux-3.18.14.orig/arch/arm/kvm/arm.c.orig linux-3.18.14-rt/arch/arm/kvm/arm.c.orig ---- linux-3.18.14.orig/arch/arm/kvm/arm.c.orig 1969-12-31 18:00:00.000000000 -0600 -+++ linux-3.18.14-rt/arch/arm/kvm/arm.c.orig 2015-05-20 10:04:50.000000000 -0500 -@@ -0,0 +1,1060 @@ -+/* -+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University -+ * Author: Christoffer Dall <c.dall@virtualopensystems.com> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#include <linux/cpu.h> -+#include <linux/cpu_pm.h> -+#include <linux/errno.h> -+#include <linux/err.h> -+#include <linux/kvm_host.h> -+#include <linux/module.h> -+#include <linux/vmalloc.h> -+#include <linux/fs.h> -+#include <linux/mman.h> -+#include <linux/sched.h> -+#include <linux/kvm.h> -+#include <trace/events/kvm.h> -+ -+#define CREATE_TRACE_POINTS -+#include "trace.h" -+ -+#include <asm/uaccess.h> -+#include <asm/ptrace.h> -+#include <asm/mman.h> -+#include <asm/tlbflush.h> -+#include <asm/cacheflush.h> -+#include <asm/virt.h> -+#include <asm/kvm_arm.h> -+#include <asm/kvm_asm.h> -+#include <asm/kvm_mmu.h> -+#include <asm/kvm_emulate.h> -+#include <asm/kvm_coproc.h> -+#include <asm/kvm_psci.h> -+ -+#ifdef REQUIRES_VIRT -+__asm__(".arch_extension virt"); -+#endif -+ -+static DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_page); -+static kvm_cpu_context_t __percpu *kvm_host_cpu_state; -+static unsigned long hyp_default_vectors; -+ -+/* Per-CPU variable containing the currently running vcpu. */ -+static DEFINE_PER_CPU(struct kvm_vcpu *, kvm_arm_running_vcpu); -+ -+/* The VMID used in the VTTBR */ -+static atomic64_t kvm_vmid_gen = ATOMIC64_INIT(1); -+static u8 kvm_next_vmid; -+static DEFINE_SPINLOCK(kvm_vmid_lock); -+ -+static bool vgic_present; -+ -+static void kvm_arm_set_running_vcpu(struct kvm_vcpu *vcpu) -+{ -+ BUG_ON(preemptible()); -+ __this_cpu_write(kvm_arm_running_vcpu, vcpu); -+} -+ -+/** -+ * kvm_arm_get_running_vcpu - get the vcpu running on the current CPU. -+ * Must be called from non-preemptible context -+ */ -+struct kvm_vcpu *kvm_arm_get_running_vcpu(void) -+{ -+ BUG_ON(preemptible()); -+ return __this_cpu_read(kvm_arm_running_vcpu); -+} -+ -+/** -+ * kvm_arm_get_running_vcpus - get the per-CPU array of currently running vcpus. -+ */ -+struct kvm_vcpu * __percpu *kvm_get_running_vcpus(void) -+{ -+ return &kvm_arm_running_vcpu; -+} -+ -+int kvm_arch_hardware_enable(void) -+{ -+ return 0; -+} -+ -+int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu) -+{ -+ return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE; -+} -+ -+int kvm_arch_hardware_setup(void) -+{ -+ return 0; -+} -+ -+void kvm_arch_check_processor_compat(void *rtn) -+{ -+ *(int *)rtn = 0; -+} -+ -+ -+/** -+ * kvm_arch_init_vm - initializes a VM data structure -+ * @kvm: pointer to the KVM struct -+ */ -+int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) -+{ -+ int ret = 0; -+ -+ if (type) -+ return -EINVAL; -+ -+ ret = kvm_alloc_stage2_pgd(kvm); -+ if (ret) -+ goto out_fail_alloc; -+ -+ ret = create_hyp_mappings(kvm, kvm + 1); -+ if (ret) -+ goto out_free_stage2_pgd; -+ -+ kvm_timer_init(kvm); -+ -+ /* Mark the initial VMID generation invalid */ -+ kvm->arch.vmid_gen = 0; -+ -+ return ret; -+out_free_stage2_pgd: -+ kvm_free_stage2_pgd(kvm); -+out_fail_alloc: -+ return ret; -+} -+ -+int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf) -+{ -+ return VM_FAULT_SIGBUS; -+} -+ -+ -+/** -+ * kvm_arch_destroy_vm - destroy the VM data structure -+ * @kvm: pointer to the KVM struct -+ */ -+void kvm_arch_destroy_vm(struct kvm *kvm) -+{ -+ int i; -+ -+ kvm_free_stage2_pgd(kvm); -+ -+ for (i = 0; i < KVM_MAX_VCPUS; ++i) { -+ if (kvm->vcpus[i]) { -+ kvm_arch_vcpu_free(kvm->vcpus[i]); -+ kvm->vcpus[i] = NULL; -+ } -+ } -+ -+ kvm_vgic_destroy(kvm); -+} -+ -+int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) -+{ -+ int r; -+ switch (ext) { -+ case KVM_CAP_IRQCHIP: -+ r = vgic_present; -+ break; -+ case KVM_CAP_DEVICE_CTRL: -+ case KVM_CAP_USER_MEMORY: -+ case KVM_CAP_SYNC_MMU: -+ case KVM_CAP_DESTROY_MEMORY_REGION_WORKS: -+ case KVM_CAP_ONE_REG: -+ case KVM_CAP_ARM_PSCI: -+ case KVM_CAP_ARM_PSCI_0_2: -+ case KVM_CAP_READONLY_MEM: -+ r = 1; -+ break; -+ case KVM_CAP_COALESCED_MMIO: -+ r = KVM_COALESCED_MMIO_PAGE_OFFSET; -+ break; -+ case KVM_CAP_ARM_SET_DEVICE_ADDR: -+ r = 1; -+ break; -+ case KVM_CAP_NR_VCPUS: -+ r = num_online_cpus(); -+ break; -+ case KVM_CAP_MAX_VCPUS: -+ r = KVM_MAX_VCPUS; -+ break; -+ default: -+ r = kvm_arch_dev_ioctl_check_extension(ext); -+ break; -+ } -+ return r; -+} -+ -+long kvm_arch_dev_ioctl(struct file *filp, -+ unsigned int ioctl, unsigned long arg) -+{ -+ return -EINVAL; -+} -+ -+ -+struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id) -+{ -+ int err; -+ struct kvm_vcpu *vcpu; -+ -+ if (irqchip_in_kernel(kvm) && vgic_initialized(kvm)) { -+ err = -EBUSY; -+ goto out; -+ } -+ -+ vcpu = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL); -+ if (!vcpu) { -+ err = -ENOMEM; -+ goto out; -+ } -+ -+ err = kvm_vcpu_init(vcpu, kvm, id); -+ if (err) -+ goto free_vcpu; -+ -+ err = create_hyp_mappings(vcpu, vcpu + 1); -+ if (err) -+ goto vcpu_uninit; -+ -+ return vcpu; -+vcpu_uninit: -+ kvm_vcpu_uninit(vcpu); -+free_vcpu: -+ kmem_cache_free(kvm_vcpu_cache, vcpu); -+out: -+ return ERR_PTR(err); -+} -+ -+int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) -+{ -+ return 0; -+} -+ -+void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu) -+{ -+ kvm_mmu_free_memory_caches(vcpu); -+ kvm_timer_vcpu_terminate(vcpu); -+ kvm_vgic_vcpu_destroy(vcpu); -+ kmem_cache_free(kvm_vcpu_cache, vcpu); -+} -+ -+void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) -+{ -+ kvm_arch_vcpu_free(vcpu); -+} -+ -+int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) -+{ -+ return 0; -+} -+ -+int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) -+{ -+ /* Force users to call KVM_ARM_VCPU_INIT */ -+ vcpu->arch.target = -1; -+ -+ /* Set up the timer */ -+ kvm_timer_vcpu_init(vcpu); -+ -+ r |