From 25ff0c99fa50b4e13079cf550c2b715eb630d055 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Thu, 5 Mar 2015 13:54:09 +0100 Subject: add realtime linux preempt_rt patch Enable Kernel options for Realtime, HZ and HighRes Timer in menuconfig. --- target/linux/patches/3.18.8/patch-linuxrt | 23744 ++++++++++++++++++++++++++++ 1 file changed, 23744 insertions(+) create mode 100644 target/linux/patches/3.18.8/patch-linuxrt (limited to 'target/linux/patches') diff --git a/target/linux/patches/3.18.8/patch-linuxrt b/target/linux/patches/3.18.8/patch-linuxrt new file mode 100644 index 000000000..444acdc6c --- /dev/null +++ b/target/linux/patches/3.18.8/patch-linuxrt @@ -0,0 +1,23744 @@ +diff -Nur linux-3.18.8.orig/arch/alpha/mm/fault.c linux-3.18.8/arch/alpha/mm/fault.c +--- linux-3.18.8.orig/arch/alpha/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/alpha/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 +@@ -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.8.orig/arch/arm/include/asm/cmpxchg.h linux-3.18.8/arch/arm/include/asm/cmpxchg.h +--- linux-3.18.8.orig/arch/arm/include/asm/cmpxchg.h 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/arm/include/asm/cmpxchg.h 2015-03-03 08:05:17.000000000 +0100 +@@ -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.8.orig/arch/arm/include/asm/futex.h linux-3.18.8/arch/arm/include/asm/futex.h +--- linux-3.18.8.orig/arch/arm/include/asm/futex.h 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/arm/include/asm/futex.h 2015-03-03 08:05:17.000000000 +0100 +@@ -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.8.orig/arch/arm/include/asm/switch_to.h linux-3.18.8/arch/arm/include/asm/switch_to.h +--- linux-3.18.8.orig/arch/arm/include/asm/switch_to.h 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/arm/include/asm/switch_to.h 2015-03-03 08:05:17.000000000 +0100 +@@ -3,6 +3,13 @@ + + #include + ++#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.8.orig/arch/arm/include/asm/thread_info.h linux-3.18.8/arch/arm/include/asm/thread_info.h +--- linux-3.18.8.orig/arch/arm/include/asm/thread_info.h 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/arm/include/asm/thread_info.h 2015-03-03 08:05:17.000000000 +0100 +@@ -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.8.orig/arch/arm/Kconfig linux-3.18.8/arch/arm/Kconfig +--- linux-3.18.8.orig/arch/arm/Kconfig 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/arm/Kconfig 2015-03-03 08:05:17.000000000 +0100 +@@ -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.8.orig/arch/arm/kernel/asm-offsets.c linux-3.18.8/arch/arm/kernel/asm-offsets.c +--- linux-3.18.8.orig/arch/arm/kernel/asm-offsets.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/arm/kernel/asm-offsets.c 2015-03-03 08:05:17.000000000 +0100 +@@ -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.8.orig/arch/arm/kernel/entry-armv.S linux-3.18.8/arch/arm/kernel/entry-armv.S +--- linux-3.18.8.orig/arch/arm/kernel/entry-armv.S 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/arm/kernel/entry-armv.S 2015-03-03 08:05:17.000000000 +0100 +@@ -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.8.orig/arch/arm/kernel/process.c linux-3.18.8/arch/arm/kernel/process.c +--- linux-3.18.8.orig/arch/arm/kernel/process.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/arm/kernel/process.c 2015-03-03 08:05:17.000000000 +0100 +@@ -431,6 +431,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.8.orig/arch/arm/kernel/signal.c linux-3.18.8/arch/arm/kernel/signal.c +--- linux-3.18.8.orig/arch/arm/kernel/signal.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/arm/kernel/signal.c 2015-03-03 08:05:17.000000000 +0100 +@@ -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.8.orig/arch/arm/kernel/smp.c linux-3.18.8/arch/arm/kernel/smp.c +--- linux-3.18.8.orig/arch/arm/kernel/smp.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/arm/kernel/smp.c 2015-03-03 08:05:17.000000000 +0100 +@@ -506,12 +506,14 @@ + } + + #ifdef CONFIG_IRQ_WORK ++#ifndef CONFIG_PREEMPT_RT_FULL + void arch_irq_work_raise(void) + { + if (arch_irq_work_has_interrupt()) + smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK); + } + #endif ++#endif + + #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST + void tick_broadcast(const struct cpumask *mask) +diff -Nur linux-3.18.8.orig/arch/arm/kernel/unwind.c linux-3.18.8/arch/arm/kernel/unwind.c +--- linux-3.18.8.orig/arch/arm/kernel/unwind.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/arm/kernel/unwind.c 2015-03-03 08:05:17.000000000 +0100 +@@ -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.8.orig/arch/arm/mach-at91/at91rm9200_time.c linux-3.18.8/arch/arm/mach-at91/at91rm9200_time.c +--- linux-3.18.8.orig/arch/arm/mach-at91/at91rm9200_time.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/arm/mach-at91/at91rm9200_time.c 2015-03-03 08:05:17.000000000 +0100 +@@ -135,6 +135,7 @@ + break; + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_UNUSED: ++ remove_irq(NR_IRQS_LEGACY + AT91_ID_SYS, &at91rm9200_timer_irq); + case CLOCK_EVT_MODE_RESUME: + irqmask = 0; + break; +diff -Nur linux-3.18.8.orig/arch/arm/mach-exynos/platsmp.c linux-3.18.8/arch/arm/mach-exynos/platsmp.c +--- linux-3.18.8.orig/arch/arm/mach-exynos/platsmp.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/arm/mach-exynos/platsmp.c 2015-03-03 08:05:17.000000000 +0100 +@@ -137,7 +137,7 @@ + return (void __iomem *)(S5P_VA_SCU); + } + +-static DEFINE_SPINLOCK(boot_lock); ++static DEFINE_RAW_SPINLOCK(boot_lock); + + static void exynos_secondary_init(unsigned int cpu) + { +@@ -150,8 +150,8 @@ + /* + * Synchronise with the boot thread. + */ +- spin_lock(&boot_lock); +- spin_unlock(&boot_lock); ++ raw_spin_lock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + } + + static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle) +@@ -165,7 +165,7 @@ + * Set synchronisation state between this boot processor + * and the secondary one + */ +- spin_lock(&boot_lock); ++ raw_spin_lock(&boot_lock); + + /* + * The secondary processor is waiting to be released from +@@ -192,7 +192,7 @@ + + if (timeout == 0) { + printk(KERN_ERR "cpu1 power enable failed"); +- spin_unlock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + return -ETIMEDOUT; + } + } +@@ -242,7 +242,7 @@ + * calibrations, then wait for it to finish + */ + fail: +- spin_unlock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + + return pen_release != -1 ? ret : 0; + } +diff -Nur linux-3.18.8.orig/arch/arm/mach-hisi/platmcpm.c linux-3.18.8/arch/arm/mach-hisi/platmcpm.c +--- linux-3.18.8.orig/arch/arm/mach-hisi/platmcpm.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/arm/mach-hisi/platmcpm.c 2015-03-03 08:05:17.000000000 +0100 +@@ -57,7 +57,7 @@ + + static void __iomem *sysctrl, *fabric; + static int hip04_cpu_table[HIP04_MAX_CLUSTERS][HIP04_MAX_CPUS_PER_CLUSTER]; +-static DEFINE_SPINLOCK(boot_lock); ++static DEFINE_RAW_SPINLOCK(boot_lock); + static u32 fabric_phys_addr; + /* + * [0]: bootwrapper physical address +@@ -104,7 +104,7 @@ + if (cluster >= HIP04_MAX_CLUSTERS || cpu >= HIP04_MAX_CPUS_PER_CLUSTER) + return -EINVAL; + +- spin_lock_irq(&boot_lock); ++ raw_spin_lock_irq(&boot_lock); + + if (hip04_cpu_table[cluster][cpu]) + goto out; +@@ -133,7 +133,7 @@ + udelay(20); + out: + hip04_cpu_table[cluster][cpu]++; +- spin_unlock_irq(&boot_lock); ++ raw_spin_unlock_irq(&boot_lock); + + return 0; + } +@@ -149,7 +149,7 @@ + + __mcpm_cpu_going_down(cpu, cluster); + +- spin_lock(&boot_lock); ++ raw_spin_lock(&boot_lock); + BUG_ON(__mcpm_cluster_state(cluster) != CLUSTER_UP); + hip04_cpu_table[cluster][cpu]--; + if (hip04_cpu_table[cluster][cpu] == 1) { +@@ -162,7 +162,7 @@ + + last_man = hip04_cluster_is_down(cluster); + if (last_man && __mcpm_outbound_enter_critical(cpu, cluster)) { +- spin_unlock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + /* Since it's Cortex A15, disable L2 prefetching. */ + asm volatile( + "mcr p15, 1, %0, c15, c0, 3 \n\t" +@@ -173,7 +173,7 @@ + hip04_set_snoop_filter(cluster, 0); + __mcpm_outbound_leave_critical(cluster, CLUSTER_DOWN); + } else { +- spin_unlock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + v7_exit_coherency_flush(louis); + } + +@@ -192,7 +192,7 @@ + cpu >= HIP04_MAX_CPUS_PER_CLUSTER); + + count = TIMEOUT_MSEC / POLL_MSEC; +- spin_lock_irq(&boot_lock); ++ raw_spin_lock_irq(&boot_lock); + for (tries = 0; tries < count; tries++) { + if (hip04_cpu_table[cluster][cpu]) { + ret = -EBUSY; +@@ -202,10 +202,10 @@ + data = readl_relaxed(sysctrl + SC_CPU_RESET_STATUS(cluster)); + if (data & CORE_WFI_STATUS(cpu)) + break; +- spin_unlock_irq(&boot_lock); ++ raw_spin_unlock_irq(&boot_lock); + /* Wait for clean L2 when the whole cluster is down. */ + msleep(POLL_MSEC); +- spin_lock_irq(&boot_lock); ++ raw_spin_lock_irq(&boot_lock); + } + if (tries >= count) + goto err; +@@ -220,10 +220,10 @@ + } + if (tries >= count) + goto err; +- spin_unlock_irq(&boot_lock); ++ raw_spin_unlock_irq(&boot_lock); + return 0; + err: +- spin_unlock_irq(&boot_lock); ++ raw_spin_unlock_irq(&boot_lock); + return ret; + } + +@@ -235,10 +235,10 @@ + cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); + cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); + +- spin_lock(&boot_lock); ++ raw_spin_lock(&boot_lock); + if (!hip04_cpu_table[cluster][cpu]) + hip04_cpu_table[cluster][cpu] = 1; +- spin_unlock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + } + + static void __naked hip04_mcpm_power_up_setup(unsigned int affinity_level) +diff -Nur linux-3.18.8.orig/arch/arm/mach-omap2/omap-smp.c linux-3.18.8/arch/arm/mach-omap2/omap-smp.c +--- linux-3.18.8.orig/arch/arm/mach-omap2/omap-smp.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/arm/mach-omap2/omap-smp.c 2015-03-03 08:05:17.000000000 +0100 +@@ -43,7 +43,7 @@ + /* SCU base address */ + static void __iomem *scu_base; + +-static DEFINE_SPINLOCK(boot_lock); ++static DEFINE_RAW_SPINLOCK(boot_lock); + + void __iomem *omap4_get_scu_base(void) + { +@@ -74,8 +74,8 @@ + /* + * Synchronise with the boot thread. + */ +- spin_lock(&boot_lock); +- spin_unlock(&boot_lock); ++ raw_spin_lock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + } + + static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle) +@@ -89,7 +89,7 @@ + * Set synchronisation state between this boot processor + * and the secondary one + */ +- spin_lock(&boot_lock); ++ raw_spin_lock(&boot_lock); + + /* + * Update the AuxCoreBoot0 with boot state for secondary core. +@@ -166,7 +166,7 @@ + * Now the secondary core is starting up let it run its + * calibrations, then wait for it to finish + */ +- spin_unlock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + + return 0; + } +diff -Nur linux-3.18.8.orig/arch/arm/mach-prima2/platsmp.c linux-3.18.8/arch/arm/mach-prima2/platsmp.c +--- linux-3.18.8.orig/arch/arm/mach-prima2/platsmp.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/arm/mach-prima2/platsmp.c 2015-03-03 08:05:17.000000000 +0100 +@@ -23,7 +23,7 @@ + static void __iomem *scu_base; + static void __iomem *rsc_base; + +-static DEFINE_SPINLOCK(boot_lock); ++static DEFINE_RAW_SPINLOCK(boot_lock); + + static struct map_desc scu_io_desc __initdata = { + .length = SZ_4K, +@@ -56,8 +56,8 @@ + /* + * Synchronise with the boot thread. + */ +- spin_lock(&boot_lock); +- spin_unlock(&boot_lock); ++ raw_spin_lock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + } + + static struct of_device_id rsc_ids[] = { +@@ -95,7 +95,7 @@ + /* make sure write buffer is drained */ + mb(); + +- spin_lock(&boot_lock); ++ raw_spin_lock(&boot_lock); + + /* + * The secondary processor is waiting to be released from +@@ -127,7 +127,7 @@ + * now the secondary core is starting up let it run its + * calibrations, then wait for it to finish + */ +- spin_unlock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + + return pen_release != -1 ? -ENOSYS : 0; + } +diff -Nur linux-3.18.8.orig/arch/arm/mach-qcom/platsmp.c linux-3.18.8/arch/arm/mach-qcom/platsmp.c +--- linux-3.18.8.orig/arch/arm/mach-qcom/platsmp.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/arm/mach-qcom/platsmp.c 2015-03-03 08:05:17.000000000 +0100 +@@ -46,7 +46,7 @@ + + extern void secondary_startup(void); + +-static DEFINE_SPINLOCK(boot_lock); ++static DEFINE_RAW_SPINLOCK(boot_lock); + + #ifdef CONFIG_HOTPLUG_CPU + static void __ref qcom_cpu_die(unsigned int cpu) +@@ -60,8 +60,8 @@ + /* + * Synchronise with the boot thread. + */ +- spin_lock(&boot_lock); +- spin_unlock(&boot_lock); ++ raw_spin_lock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + } + + static int scss_release_secondary(unsigned int cpu) +@@ -284,7 +284,7 @@ + * set synchronisation state between this boot processor + * and the secondary one + */ +- spin_lock(&boot_lock); ++ raw_spin_lock(&boot_lock); + + /* + * Send the secondary CPU a soft interrupt, thereby causing +@@ -297,7 +297,7 @@ + * now the secondary core is starting up let it run its + * calibrations, then wait for it to finish + */ +- spin_unlock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + + return ret; + } +diff -Nur linux-3.18.8.orig/arch/arm/mach-spear/platsmp.c linux-3.18.8/arch/arm/mach-spear/platsmp.c +--- linux-3.18.8.orig/arch/arm/mach-spear/platsmp.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/arm/mach-spear/platsmp.c 2015-03-03 08:05:17.000000000 +0100 +@@ -32,7 +32,7 @@ + sync_cache_w(&pen_release); + } + +-static DEFINE_SPINLOCK(boot_lock); ++static DEFINE_RAW_SPINLOCK(boot_lock); + + static void __iomem *scu_base = IOMEM(VA_SCU_BASE); + +@@ -47,8 +47,8 @@ + /* + * Synchronise with the boot thread. + */ +- spin_lock(&boot_lock); +- spin_unlock(&boot_lock); ++ raw_spin_lock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + } + + static int spear13xx_boot_secondary(unsigned int cpu, struct task_struct *idle) +@@ -59,7 +59,7 @@ + * set synchronisation state between this boot processor + * and the secondary one + */ +- spin_lock(&boot_lock); ++ raw_spin_lock(&boot_lock); + + /* + * The secondary processor is waiting to be released from +@@ -84,7 +84,7 @@ + * now the secondary core is starting up let it run its + * calibrations, then wait for it to finish + */ +- spin_unlock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + + return pen_release != -1 ? -ENOSYS : 0; + } +diff -Nur linux-3.18.8.orig/arch/arm/mach-sti/platsmp.c linux-3.18.8/arch/arm/mach-sti/platsmp.c +--- linux-3.18.8.orig/arch/arm/mach-sti/platsmp.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/arm/mach-sti/platsmp.c 2015-03-03 08:05:17.000000000 +0100 +@@ -34,7 +34,7 @@ + sync_cache_w(&pen_release); + } + +-static DEFINE_SPINLOCK(boot_lock); ++static DEFINE_RAW_SPINLOCK(boot_lock); + + static void sti_secondary_init(unsigned int cpu) + { +@@ -49,8 +49,8 @@ + /* + * Synchronise with the boot thread. + */ +- spin_lock(&boot_lock); +- spin_unlock(&boot_lock); ++ raw_spin_lock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + } + + static int sti_boot_secondary(unsigned int cpu, struct task_struct *idle) +@@ -61,7 +61,7 @@ + * set synchronisation state between this boot processor + * and the secondary one + */ +- spin_lock(&boot_lock); ++ raw_spin_lock(&boot_lock); + + /* + * The secondary processor is waiting to be released from +@@ -92,7 +92,7 @@ + * now the secondary core is starting up let it run its + * calibrations, then wait for it to finish + */ +- spin_unlock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + + return pen_release != -1 ? -ENOSYS : 0; + } +diff -Nur linux-3.18.8.orig/arch/arm/mach-ux500/platsmp.c linux-3.18.8/arch/arm/mach-ux500/platsmp.c +--- linux-3.18.8.orig/arch/arm/mach-ux500/platsmp.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/arm/mach-ux500/platsmp.c 2015-03-03 08:05:17.000000000 +0100 +@@ -51,7 +51,7 @@ + return NULL; + } + +-static DEFINE_SPINLOCK(boot_lock); ++static DEFINE_RAW_SPINLOCK(boot_lock); + + static void ux500_secondary_init(unsigned int cpu) + { +@@ -64,8 +64,8 @@ + /* + * Synchronise with the boot thread. + */ +- spin_lock(&boot_lock); +- spin_unlock(&boot_lock); ++ raw_spin_lock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + } + + static int ux500_boot_secondary(unsigned int cpu, struct task_struct *idle) +@@ -76,7 +76,7 @@ + * set synchronisation state between this boot processor + * and the secondary one + */ +- spin_lock(&boot_lock); ++ raw_spin_lock(&boot_lock); + + /* + * The secondary processor is waiting to be released from +@@ -97,7 +97,7 @@ + * now the secondary core is starting up let it run its + * calibrations, then wait for it to finish + */ +- spin_unlock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + + return pen_release != -1 ? -ENOSYS : 0; + } +diff -Nur linux-3.18.8.orig/arch/arm/mm/fault.c linux-3.18.8/arch/arm/mm/fault.c +--- linux-3.18.8.orig/arch/arm/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/arm/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 +@@ -277,7 +277,7 @@ + * If we're in an interrupt or have no user + * context, we must not take the fault.. + */ +- if (in_atomic() || !mm) ++ if (!mm || pagefault_disabled()) + goto no_context; + + if (user_mode(regs)) +@@ -431,6 +431,9 @@ + if (addr < TASK_SIZE) + return do_page_fault(addr, fsr, regs); + ++ if (interrupts_enabled(regs)) ++ local_irq_enable(); ++ + if (user_mode(regs)) + goto bad_area; + +@@ -498,6 +501,9 @@ + static int + do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) + { ++ if (interrupts_enabled(regs)) ++ local_irq_enable(); ++ + do_bad_area(addr, fsr, regs); + return 0; + } +diff -Nur linux-3.18.8.orig/arch/arm/mm/highmem.c linux-3.18.8/arch/arm/mm/highmem.c +--- linux-3.18.8.orig/arch/arm/mm/highmem.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/arm/mm/highmem.c 2015-03-03 08:05:17.000000000 +0100 +@@ -53,6 +53,7 @@ + + void *kmap_atomic(struct page *page) + { ++ pte_t pte = mk_pte(page, kmap_prot); + unsigned int idx; + unsigned long vaddr; + void *kmap; +@@ -91,7 +92,10 @@ + * in place, so the contained TLB flush ensures the TLB is updated + * with the new mapping. + */ +- set_fixmap_pte(idx, mk_pte(page, kmap_prot)); ++#ifdef CONFIG_PREEMPT_RT_FULL ++ current->kmap_pte[type] = pte; ++#endif ++ set_fixmap_pte(idx, pte); + + return (void *)vaddr; + } +@@ -108,12 +112,15 @@ + + if (cache_is_vivt()) + __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE); ++#ifdef CONFIG_PREEMPT_RT_FULL ++ current->kmap_pte[type] = __pte(0); ++#endif + #ifdef CONFIG_DEBUG_HIGHMEM + BUG_ON(vaddr != __fix_to_virt(idx)); +- set_fixmap_pte(idx, __pte(0)); + #else + (void) idx; /* to kill a warning */ + #endif ++ set_fixmap_pte(idx, __pte(0)); + kmap_atomic_idx_pop(); + } else if (vaddr >= PKMAP_ADDR(0) && vaddr < PKMAP_ADDR(LAST_PKMAP)) { + /* this address was obtained through kmap_high_get() */ +@@ -125,6 +132,7 @@ + + void *kmap_atomic_pfn(unsigned long pfn) + { ++ pte_t pte = pfn_pte(pfn, kmap_prot); + unsigned long vaddr; + int idx, type; + struct page *page = pfn_to_page(pfn); +@@ -139,7 +147,10 @@ + #ifdef CONFIG_DEBUG_HIGHMEM + BUG_ON(!pte_none(*(fixmap_page_table + idx))); + #endif +- set_fixmap_pte(idx, pfn_pte(pfn, kmap_prot)); ++#ifdef CONFIG_PREEMPT_RT_FULL ++ current->kmap_pte[type] = pte; ++#endif ++ set_fixmap_pte(idx, pte); + + return (void *)vaddr; + } +@@ -153,3 +164,28 @@ + + return pte_page(get_fixmap_pte(vaddr)); + } ++ ++#if defined CONFIG_PREEMPT_RT_FULL ++void switch_kmaps(struct task_struct *prev_p, struct task_struct *next_p) ++{ ++ int i; ++ ++ /* ++ * Clear @prev's kmap_atomic mappings ++ */ ++ for (i = 0; i < prev_p->kmap_idx; i++) { ++ int idx = i + KM_TYPE_NR * smp_processor_id(); ++ ++ set_fixmap_pte(idx, __pte(0)); ++ } ++ /* ++ * Restore @next_p's kmap_atomic mappings ++ */ ++ for (i = 0; i < next_p->kmap_idx; i++) { ++ int idx = i + KM_TYPE_NR * smp_processor_id(); ++ ++ if (!pte_none(next_p->kmap_pte[i])) ++ set_fixmap_pte(idx, next_p->kmap_pte[i]); ++ } ++} ++#endif +diff -Nur linux-3.18.8.orig/arch/arm/plat-versatile/platsmp.c linux-3.18.8/arch/arm/plat-versatile/platsmp.c +--- linux-3.18.8.orig/arch/arm/plat-versatile/platsmp.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/arm/plat-versatile/platsmp.c 2015-03-03 08:05:17.000000000 +0100 +@@ -30,7 +30,7 @@ + sync_cache_w(&pen_release); + } + +-static DEFINE_SPINLOCK(boot_lock); ++static DEFINE_RAW_SPINLOCK(boot_lock); + + void versatile_secondary_init(unsigned int cpu) + { +@@ -43,8 +43,8 @@ + /* + * Synchronise with the boot thread. + */ +- spin_lock(&boot_lock); +- spin_unlock(&boot_lock); ++ raw_spin_lock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + } + + int versatile_boot_secondary(unsigned int cpu, struct task_struct *idle) +@@ -55,7 +55,7 @@ + * Set synchronisation state between this boot processor + * and the secondary one + */ +- spin_lock(&boot_lock); ++ raw_spin_lock(&boot_lock); + + /* + * This is really belt and braces; we hold unintended secondary +@@ -85,7 +85,7 @@ + * now the secondary core is starting up let it run its + * calibrations, then wait for it to finish + */ +- spin_unlock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + + return pen_release != -1 ? -ENOSYS : 0; + } +diff -Nur linux-3.18.8.orig/arch/arm64/kernel/smp.c linux-3.18.8/arch/arm64/kernel/smp.c +--- linux-3.18.8.orig/arch/arm64/kernel/smp.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/arm64/kernel/smp.c 2015-03-03 08:05:17.000000000 +0100 +@@ -529,12 +529,14 @@ + } + + #ifdef CONFIG_IRQ_WORK ++#ifndef CONFIG_PREEMPT_RT_FULL + void arch_irq_work_raise(void) + { + if (__smp_cross_call) + smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK); + } + #endif ++#endif + + static DEFINE_RAW_SPINLOCK(stop_lock); + +diff -Nur linux-3.18.8.orig/arch/avr32/mm/fault.c linux-3.18.8/arch/avr32/mm/fault.c +--- linux-3.18.8.orig/arch/avr32/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/avr32/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 +@@ -81,7 +81,7 @@ + * If we're in an interrupt or have no user context, we must + * not take the fault... + */ +- if (in_atomic() || !mm || regs->sr & SYSREG_BIT(GM)) ++ if (!mm || regs->sr & SYSREG_BIT(GM) || pagefault_disabled()) + goto no_context; + + local_irq_enable(); +diff -Nur linux-3.18.8.orig/arch/cris/mm/fault.c linux-3.18.8/arch/cris/mm/fault.c +--- linux-3.18.8.orig/arch/cris/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/cris/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 +@@ -113,7 +113,7 @@ + * user context, we must not take the fault. + */ + +- if (in_atomic() || !mm) ++ if (!mm || pagefault_disabled()) + goto no_context; + + if (user_mode(regs)) +diff -Nur linux-3.18.8.orig/arch/frv/mm/fault.c linux-3.18.8/arch/frv/mm/fault.c +--- linux-3.18.8.orig/arch/frv/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/frv/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 +@@ -78,7 +78,7 @@ + * If we're in an interrupt or have no user + * context, we must not take the fault.. + */ +- if (in_atomic() || !mm) ++ if (!mm || pagefault_disabled()) + goto no_context; + + if (user_mode(__frame)) +diff -Nur linux-3.18.8.orig/arch/ia64/mm/fault.c linux-3.18.8/arch/ia64/mm/fault.c +--- linux-3.18.8.orig/arch/ia64/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/ia64/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 +@@ -96,7 +96,7 @@ + /* + * If we're in an interrupt or have no user context, we must not take the fault.. + */ +- if (in_atomic() || !mm) ++ if (!mm || pagefault_disabled()) + goto no_context; + + #ifdef CONFIG_VIRTUAL_MEM_MAP +diff -Nur linux-3.18.8.orig/arch/Kconfig linux-3.18.8/arch/Kconfig +--- linux-3.18.8.orig/arch/Kconfig 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/Kconfig 2015-03-03 08:05:17.000000000 +0100 +@@ -6,6 +6,7 @@ + tristate "OProfile system profiling" + depends on PROFILING + depends on HAVE_OPROFILE ++ depends on !PREEMPT_RT_FULL + select RING_BUFFER + select RING_BUFFER_ALLOW_SWAP + help +diff -Nur linux-3.18.8.orig/arch/m32r/mm/fault.c linux-3.18.8/arch/m32r/mm/fault.c +--- linux-3.18.8.orig/arch/m32r/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/m32r/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 +@@ -114,7 +114,7 @@ + * If we're in an interrupt or have no user context or are running in an + * atomic region then we must not take the fault.. + */ +- if (in_atomic() || !mm) ++ if (!mm || pagefault_disabled()) + goto bad_area_nosemaphore; + + if (error_code & ACE_USERMODE) +diff -Nur linux-3.18.8.orig/arch/m68k/mm/fault.c linux-3.18.8/arch/m68k/mm/fault.c +--- linux-3.18.8.orig/arch/m68k/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/m68k/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 +@@ -81,7 +81,7 @@ + * If we're in an interrupt or have no user + * context, we must not take the fault.. + */ +- if (in_atomic() || !mm) ++ if (!mm || pagefault_disabled()) + goto no_context; + + if (user_mode(regs)) +diff -Nur linux-3.18.8.orig/arch/microblaze/mm/fault.c linux-3.18.8/arch/microblaze/mm/fault.c +--- linux-3.18.8.orig/arch/microblaze/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/microblaze/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 +@@ -107,7 +107,7 @@ + if ((error_code & 0x13) == 0x13 || (error_code & 0x11) == 0x11) + is_write = 0; + +- if (unlikely(in_atomic() || !mm)) { ++ if (unlikely(!mm || pagefault_disabled())) { + if (kernel_mode(regs)) + goto bad_area_nosemaphore; + +diff -Nur linux-3.18.8.orig/arch/mips/Kconfig linux-3.18.8/arch/mips/Kconfig +--- linux-3.18.8.orig/arch/mips/Kconfig 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/mips/Kconfig 2015-03-03 08:05:17.000000000 +0100 +@@ -2196,7 +2196,7 @@ + # + config HIGHMEM + bool "High Memory Support" +- depends on 32BIT && CPU_SUPPORTS_HIGHMEM && SYS_SUPPORTS_HIGHMEM && !CPU_MIPS32_3_5_EVA ++ depends on 32BIT && CPU_SUPPORTS_HIGHMEM && SYS_SUPPORTS_HIGHMEM && !CPU_MIPS32_3_5_EVA && !PREEMPT_RT_FULL + + config CPU_SUPPORTS_HIGHMEM + bool +diff -Nur linux-3.18.8.orig/arch/mips/kernel/signal.c linux-3.18.8/arch/mips/kernel/signal.c +--- linux-3.18.8.orig/arch/mips/kernel/signal.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/mips/kernel/signal.c 2015-03-03 08:05:17.000000000 +0100 +@@ -613,6 +613,7 @@ + __u32 thread_info_flags) + { + local_irq_enable(); ++ preempt_check_resched(); + + user_exit(); + +diff -Nur linux-3.18.8.orig/arch/mips/mm/fault.c linux-3.18.8/arch/mips/mm/fault.c +--- linux-3.18.8.orig/arch/mips/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/mips/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 +@@ -89,7 +89,7 @@ + * If we're in an interrupt or have no user + * context, we must not take the fault.. + */ +- if (in_atomic() || !mm) ++ if (!mm || pagefault_disabled()) + goto bad_area_nosemaphore; + + if (user_mode(regs)) +diff -Nur linux-3.18.8.orig/arch/mips/mm/init.c linux-3.18.8/arch/mips/mm/init.c +--- linux-3.18.8.orig/arch/mips/mm/init.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/mips/mm/init.c 2015-03-03 08:05:17.000000000 +0100 +@@ -90,7 +90,7 @@ + + BUG_ON(Page_dcache_dirty(page)); + +- pagefault_disable(); ++ raw_pagefault_disable(); + idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1); + idx += in_interrupt() ? FIX_N_COLOURS : 0; + vaddr = __fix_to_virt(FIX_CMAP_END - idx); +@@ -146,7 +146,7 @@ + tlbw_use_hazard(); + write_c0_entryhi(old_ctx); + local_irq_restore(flags); +- pagefault_enable(); ++ raw_pagefault_enable(); + } + + void copy_user_highpage(struct page *to, struct page *from, +diff -Nur linux-3.18.8.orig/arch/mn10300/mm/fault.c linux-3.18.8/arch/mn10300/mm/fault.c +--- linux-3.18.8.orig/arch/mn10300/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/mn10300/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 +@@ -168,7 +168,7 @@ + * If we're in an interrupt or have no user + * context, we must not take the fault.. + */ +- if (in_atomic() || !mm) ++ if (!mm || pagefault_disabled()) + goto no_context; + + if ((fault_code & MMUFCR_xFC_ACCESS) == MMUFCR_xFC_ACCESS_USR) +diff -Nur linux-3.18.8.orig/arch/parisc/mm/fault.c linux-3.18.8/arch/parisc/mm/fault.c +--- linux-3.18.8.orig/arch/parisc/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/parisc/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 +@@ -207,7 +207,7 @@ + int fault; + unsigned int flags; + +- if (in_atomic()) ++ if (pagefault_disabled()) + goto no_context; + + tsk = current; +diff -Nur linux-3.18.8.orig/arch/powerpc/include/asm/thread_info.h linux-3.18.8/arch/powerpc/include/asm/thread_info.h +--- linux-3.18.8.orig/arch/powerpc/include/asm/thread_info.h 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/powerpc/include/asm/thread_info.h 2015-03-03 08:05:17.000000000 +0100 +@@ -43,6 +43,8 @@ + int cpu; /* cpu we're on */ + int preempt_count; /* 0 => preemptable, + <0 => BUG */ ++ int preempt_lazy_count; /* 0 => preemptable, ++ <0 => BUG */ + struct restart_block restart_block; + unsigned long local_flags; /* private flags for thread */ + +@@ -88,8 +90,7 @@ + #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ + #define TIF_SIGPENDING 1 /* signal pending */ + #define TIF_NEED_RESCHED 2 /* rescheduling necessary */ +-#define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling +- TIF_NEED_RESCHED */ ++#define TIF_NEED_RESCHED_LAZY 3 /* lazy rescheduling necessary */ + #define TIF_32BIT 4 /* 32 bit binary */ + #define TIF_RESTORE_TM 5 /* need to restore TM FP/VEC/VSX */ + #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ +@@ -107,6 +108,8 @@ + #if defined(CONFIG_PPC64) + #define TIF_ELF2ABI 18 /* function descriptors must die! */ + #endif ++#define TIF_POLLING_NRFLAG 19 /* true if poll_idle() is polling ++ TIF_NEED_RESCHED */ + + /* as above, but as bit values */ + #define _TIF_SYSCALL_TRACE (1<flags) + set_bits(irqtp->flags, &curtp->flags); + } ++#endif + + irq_hw_number_t virq_to_hw(unsigned int virq) + { +diff -Nur linux-3.18.8.orig/arch/powerpc/kernel/misc_32.S linux-3.18.8/arch/powerpc/kernel/misc_32.S +--- linux-3.18.8.orig/arch/powerpc/kernel/misc_32.S 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/powerpc/kernel/misc_32.S 2015-03-03 08:05:17.000000000 +0100 +@@ -40,6 +40,7 @@ + * We store the saved ksp_limit in the unused part + * of the STACK_FRAME_OVERHEAD + */ ++#ifndef CONFIG_PREEMPT_RT_FULL + _GLOBAL(call_do_softirq) + mflr r0 + stw r0,4(r1) +@@ -56,6 +57,7 @@ + stw r10,THREAD+KSP_LIMIT(r2) + mtlr r0 + blr ++#endif + + /* + * void call_do_irq(struct pt_regs *regs, struct thread_info *irqtp); +diff -Nur linux-3.18.8.orig/arch/powerpc/kernel/misc_64.S linux-3.18.8/arch/powerpc/kernel/misc_64.S +--- linux-3.18.8.orig/arch/powerpc/kernel/misc_64.S 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/powerpc/kernel/misc_64.S 2015-03-03 08:05:17.000000000 +0100 +@@ -29,6 +29,7 @@ + + .text + ++#ifndef CONFIG_PREEMPT_RT_FULL + _GLOBAL(call_do_softirq) + mflr r0 + std r0,16(r1) +@@ -39,6 +40,7 @@ + ld r0,16(r1) + mtlr r0 + blr ++#endif + + _GLOBAL(call_do_irq) + mflr r0 +diff -Nur linux-3.18.8.orig/arch/powerpc/kernel/time.c linux-3.18.8/arch/powerpc/kernel/time.c +--- linux-3.18.8.orig/arch/powerpc/kernel/time.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/powerpc/kernel/time.c 2015-03-03 08:05:17.000000000 +0100 +@@ -424,7 +424,7 @@ + EXPORT_SYMBOL(profile_pc); + #endif + +-#ifdef CONFIG_IRQ_WORK ++#if defined(CONFIG_IRQ_WORK) && !defined(CONFIG_PREEMPT_RT_FULL) + + /* + * 64-bit uses a byte in the PACA, 32-bit uses a per-cpu variable... +diff -Nur linux-3.18.8.orig/arch/powerpc/mm/fault.c linux-3.18.8/arch/powerpc/mm/fault.c +--- linux-3.18.8.orig/arch/powerpc/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/powerpc/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 +@@ -273,7 +273,7 @@ + if (!arch_irq_disabled_regs(regs)) + local_irq_enable(); + +- if (in_atomic() || mm == NULL) { ++ if (in_atomic() || mm == NULL || pagefault_disabled()) { + if (!user_mode(regs)) { + rc = SIGSEGV; + goto bail; +diff -Nur linux-3.18.8.orig/arch/s390/mm/fault.c linux-3.18.8/arch/s390/mm/fault.c +--- linux-3.18.8.orig/arch/s390/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/s390/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 +@@ -435,7 +435,8 @@ + * user context. + */ + fault = VM_FAULT_BADCONTEXT; +- if (unlikely(!user_space_fault(regs) || in_atomic() || !mm)) ++ if (unlikely(!user_space_fault(regs) || !mm || ++ tsk->pagefault_disabled)) + goto out; + + address = trans_exc_code & __FAIL_ADDR_MASK; +diff -Nur linux-3.18.8.orig/arch/score/mm/fault.c linux-3.18.8/arch/score/mm/fault.c +--- linux-3.18.8.orig/arch/score/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/score/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 +@@ -73,7 +73,7 @@ + * If we're in an interrupt or have no user + * context, we must not take the fault.. + */ +- if (in_atomic() || !mm) ++ if (!mm || pagefault_disabled()) + goto bad_area_nosemaphore; + + if (user_mode(regs)) +diff -Nur linux-3.18.8.orig/arch/sh/kernel/irq.c linux-3.18.8/arch/sh/kernel/irq.c +--- linux-3.18.8.orig/arch/sh/kernel/irq.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/sh/kernel/irq.c 2015-03-03 08:05:17.000000000 +0100 +@@ -149,6 +149,7 @@ + hardirq_ctx[cpu] = NULL; + } + ++#ifndef CONFIG_PREEMPT_RT_FULL + void do_softirq_own_stack(void) + { + struct thread_info *curctx; +@@ -176,6 +177,7 @@ + "r5", "r6", "r7", "r8", "r9", "r15", "t", "pr" + ); + } ++#endif + #else + static inline void handle_one_irq(unsigned int irq) + { +diff -Nur linux-3.18.8.orig/arch/sh/mm/fault.c linux-3.18.8/arch/sh/mm/fault.c +--- linux-3.18.8.orig/arch/sh/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/sh/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 +@@ -440,7 +440,7 @@ + * If we're in an interrupt, have no user context or are running + * in an atomic region then we must not take the fault: + */ +- if (unlikely(in_atomic() || !mm)) { ++ if (unlikely(!mm || pagefault_disabled())) { + bad_area_nosemaphore(regs, error_code, address); + return; + } +diff -Nur linux-3.18.8.orig/arch/sparc/Kconfig linux-3.18.8/arch/sparc/Kconfig +--- linux-3.18.8.orig/arch/sparc/Kconfig 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/sparc/Kconfig 2015-03-03 08:05:17.000000000 +0100 +@@ -182,12 +182,10 @@ + source kernel/Kconfig.hz + + config RWSEM_GENERIC_SPINLOCK +- bool +- default y if SPARC32 ++ def_bool PREEMPT_RT_FULL + + config RWSEM_XCHGADD_ALGORITHM +- bool +- default y if SPARC64 ++ def_bool !RWSEM_GENERIC_SPINLOCK && !PREEMPT_RT_FULL + + config GENERIC_HWEIGHT + bool +@@ -528,6 +526,10 @@ + + source "fs/Kconfig.binfmt" + ++config EARLY_PRINTK ++ bool ++ default y ++ + config COMPAT + bool + depends on SPARC64 +diff -Nur linux-3.18.8.orig/arch/sparc/kernel/irq_64.c linux-3.18.8/arch/sparc/kernel/irq_64.c +--- linux-3.18.8.orig/arch/sparc/kernel/irq_64.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/sparc/kernel/irq_64.c 2015-03-03 08:05:17.000000000 +0100 +@@ -849,6 +849,7 @@ + set_irq_regs(old_regs); + } + ++#ifndef CONFIG_PREEMPT_RT_FULL + void do_softirq_own_stack(void) + { + void *orig_sp, *sp = softirq_stack[smp_processor_id()]; +@@ -863,6 +864,7 @@ + __asm__ __volatile__("mov %0, %%sp" + : : "r" (orig_sp)); + } ++#endif + + #ifdef CONFIG_HOTPLUG_CPU + void fixup_irqs(void) +diff -Nur linux-3.18.8.orig/arch/sparc/kernel/pcr.c linux-3.18.8/arch/sparc/kernel/pcr.c +--- linux-3.18.8.orig/arch/sparc/kernel/pcr.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/sparc/kernel/pcr.c 2015-03-03 08:05:17.000000000 +0100 +@@ -43,10 +43,12 @@ + set_irq_regs(old_regs); + } + ++#ifndef CONFIG_PREEMPT_RT_FULL + void arch_irq_work_raise(void) + { + set_softint(1 << PIL_DEFERRED_PCR_WORK); + } ++#endif + + const struct pcr_ops *pcr_ops; + EXPORT_SYMBOL_GPL(pcr_ops); +diff -Nur linux-3.18.8.orig/arch/sparc/kernel/setup_32.c linux-3.18.8/arch/sparc/kernel/setup_32.c +--- linux-3.18.8.orig/arch/sparc/kernel/setup_32.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/sparc/kernel/setup_32.c 2015-03-03 08:05:17.000000000 +0100 +@@ -309,6 +309,7 @@ + + boot_flags_init(*cmdline_p); + ++ early_console = &prom_early_console; + register_console(&prom_early_console); + + printk("ARCH: "); +diff -Nur linux-3.18.8.orig/arch/sparc/kernel/setup_64.c linux-3.18.8/arch/sparc/kernel/setup_64.c +--- linux-3.18.8.orig/arch/sparc/kernel/setup_64.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/sparc/kernel/setup_64.c 2015-03-03 08:05:17.000000000 +0100 +@@ -563,6 +563,12 @@ + pause_patch(); + } + ++static inline void register_prom_console(void) ++{ ++ early_console = &prom_early_console; ++ register_console(&prom_early_console); ++} ++ + void __init setup_arch(char **cmdline_p) + { + /* Initialize PROM console and command line. */ +@@ -574,7 +580,7 @@ + #ifdef CONFIG_EARLYFB + if (btext_find_display()) + #endif +- register_console(&prom_early_console); ++ register_prom_console(); + + if (tlb_type == hypervisor) + printk("ARCH: SUN4V\n"); +diff -Nur linux-3.18.8.orig/arch/sparc/mm/fault_32.c linux-3.18.8/arch/sparc/mm/fault_32.c +--- linux-3.18.8.orig/arch/sparc/mm/fault_32.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/sparc/mm/fault_32.c 2015-03-03 08:05:17.000000000 +0100 +@@ -196,7 +196,7 @@ + * If we're in an interrupt or have no user + * context, we must not take the fault.. + */ +- if (in_atomic() || !mm) ++ if (!mm || pagefault_disabled()) + goto no_context; + + perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); +diff -Nur linux-3.18.8.orig/arch/sparc/mm/fault_64.c linux-3.18.8/arch/sparc/mm/fault_64.c +--- linux-3.18.8.orig/arch/sparc/mm/fault_64.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/sparc/mm/fault_64.c 2015-03-03 08:05:17.000000000 +0100 +@@ -330,7 +330,7 @@ + * If we're in an interrupt or have no user + * context, we must not take the fault.. + */ +- if (in_atomic() || !mm) ++ if (!mm || pagefault_disabled()) + goto intr_or_no_mm; + + perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); +diff -Nur linux-3.18.8.orig/arch/tile/mm/fault.c linux-3.18.8/arch/tile/mm/fault.c +--- linux-3.18.8.orig/arch/tile/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/tile/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 +@@ -357,7 +357,7 @@ + * If we're in an interrupt, have no user context or are running in an + * atomic region then we must not take the fault. + */ +- if (in_atomic() || !mm) { ++ if (!mm || pagefault_disabled()) { + vma = NULL; /* happy compiler */ + goto bad_area_nosemaphore; + } +diff -Nur linux-3.18.8.orig/arch/um/kernel/trap.c linux-3.18.8/arch/um/kernel/trap.c +--- linux-3.18.8.orig/arch/um/kernel/trap.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/um/kernel/trap.c 2015-03-03 08:05:17.000000000 +0100 +@@ -38,7 +38,7 @@ + * If the fault was during atomic operation, don't take the fault, just + * fail. + */ +- if (in_atomic()) ++ if (pagefault_disabled()) + goto out_nosemaphore; + + if (is_user) +diff -Nur linux-3.18.8.orig/arch/x86/crypto/aesni-intel_glue.c linux-3.18.8/arch/x86/crypto/aesni-intel_glue.c +--- linux-3.18.8.orig/arch/x86/crypto/aesni-intel_glue.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/x86/crypto/aesni-intel_glue.c 2015-03-03 08:05:17.000000000 +0100 +@@ -381,14 +381,14 @@ + err = blkcipher_walk_virt(desc, &walk); + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + +- kernel_fpu_begin(); + while ((nbytes = walk.nbytes)) { ++ kernel_fpu_begin(); + aesni_ecb_enc(ctx, walk.dst.virt.addr, walk.src.virt.addr, +- nbytes & AES_BLOCK_MASK); ++ nbytes & AES_BLOCK_MASK); ++ kernel_fpu_end(); + nbytes &= AES_BLOCK_SIZE - 1; + err = blkcipher_walk_done(desc, &walk, nbytes); + } +- kernel_fpu_end(); + + return err; + } +@@ -405,14 +405,14 @@ + err = blkcipher_walk_virt(desc, &walk); + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + +- kernel_fpu_begin(); + while ((nbytes = walk.nbytes)) { ++ kernel_fpu_begin(); + aesni_ecb_dec(ctx, walk.dst.virt.addr, walk.src.virt.addr, + nbytes & AES_BLOCK_MASK); ++ kernel_fpu_end(); + nbytes &= AES_BLOCK_SIZE - 1; + err = blkcipher_walk_done(desc, &walk, nbytes); + } +- kernel_fpu_end(); + + return err; + } +@@ -429,14 +429,14 @@ + err = blkcipher_walk_virt(desc, &walk); + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + +- kernel_fpu_begin(); + while ((nbytes = walk.nbytes)) { ++ kernel_fpu_begin(); + aesni_cbc_enc(ctx, walk.dst.virt.addr, walk.src.virt.addr, + nbytes & AES_BLOCK_MASK, walk.iv); ++ kernel_fpu_end(); + nbytes &= AES_BLOCK_SIZE - 1; + err = blkcipher_walk_done(desc, &walk, nbytes); + } +- kernel_fpu_end(); + + return err; + } +@@ -453,14 +453,14 @@ + err = blkcipher_walk_virt(desc, &walk); + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + +- kernel_fpu_begin(); + while ((nbytes = walk.nbytes)) { ++ kernel_fpu_begin(); + aesni_cbc_dec(ctx, walk.dst.virt.addr, walk.src.virt.addr, + nbytes & AES_BLOCK_MASK, walk.iv); ++ kernel_fpu_end(); + nbytes &= AES_BLOCK_SIZE - 1; + err = blkcipher_walk_done(desc, &walk, nbytes); + } +- kernel_fpu_end(); + + return err; + } +@@ -512,18 +512,20 @@ + err = blkcipher_walk_virt_block(desc, &walk, AES_BLOCK_SIZE); + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + +- kernel_fpu_begin(); + while ((nbytes = walk.nbytes) >= AES_BLOCK_SIZE) { ++ kernel_fpu_begin(); + aesni_ctr_enc_tfm(ctx, walk.dst.virt.addr, walk.src.virt.addr, + nbytes & AES_BLOCK_MASK, walk.iv); ++ kernel_fpu_end(); + nbytes &= AES_BLOCK_SIZE - 1; + err = blkcipher_walk_done(desc, &walk, nbytes); + } + if (walk.nbytes) { ++ kernel_fpu_begin(); + ctr_crypt_final(ctx, &walk); ++ kernel_fpu_end(); + err = blkcipher_walk_done(desc, &walk, 0); + } +- kernel_fpu_end(); + + return err; + } +diff -Nur linux-3.18.8.orig/arch/x86/crypto/cast5_avx_glue.c linux-3.18.8/arch/x86/crypto/cast5_avx_glue.c +--- linux-3.18.8.orig/arch/x86/crypto/cast5_avx_glue.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/x86/crypto/cast5_avx_glue.c 2015-03-03 08:05:17.000000000 +0100 +@@ -60,7 +60,7 @@ + static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk, + bool enc) + { +- bool fpu_enabled = false; ++ bool fpu_enabled; + struct cast5_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + const unsigned int bsize = CAST5_BLOCK_SIZE; + unsigned int nbytes; +@@ -76,7 +76,7 @@ + u8 *wsrc = walk->src.virt.addr; + u8 *wdst = walk->dst.virt.addr; + +- fpu_enabled = cast5_fpu_begin(fpu_enabled, nbytes); ++ fpu_enabled = cast5_fpu_begin(false, nbytes); + + /* Process multi-block batch */ + if (nbytes >= bsize * CAST5_PARALLEL_BLOCKS) { +@@ -104,10 +104,9 @@ + } while (nbytes >= bsize); + + done: ++ cast5_fpu_end(fpu_enabled); + err = blkcipher_walk_done(desc, walk, nbytes); + } +- +- cast5_fpu_end(fpu_enabled); + return err; + } + +@@ -228,7 +227,7 @@ + static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) + { +- bool fpu_enabled = false; ++ bool fpu_enabled; + struct blkcipher_walk walk; + int err; + +@@ -237,12 +236,11 @@ + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + + while ((nbytes = walk.nbytes)) { +- fpu_enabled = cast5_fpu_begin(fpu_enabled, nbytes); ++ fpu_enabled = cast5_fpu_begin(false, nbytes); + nbytes = __cbc_decrypt(desc, &walk); ++ cast5_fpu_end(fpu_enabled); + err = blkcipher_walk_done(desc, &walk, nbytes); + } +- +- cast5_fpu_end(fpu_enabled); + return err; + } + +@@ -312,7 +310,7 @@ + static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) + { +- bool fpu_enabled = false; ++ bool fpu_enabled; + struct blkcipher_walk walk; + int err; + +@@ -321,13 +319,12 @@ + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + + while ((nbytes = walk.nbytes) >= CAST5_BLOCK_SIZE) { +- fpu_enabled = cast5_fpu_begin(fpu_enabled, nbytes); ++ fpu_enabled = cast5_fpu_begin(false, nbytes); + nbytes = __ctr_crypt(desc, &walk); ++ cast5_fpu_end(fpu_enabled); + err = blkcipher_walk_done(desc, &walk, nbytes); + } + +- cast5_fpu_end(fpu_enabled); +- + if (walk.nbytes) { + ctr_crypt_final(desc, &walk); + err = blkcipher_walk_done(desc, &walk, 0); +diff -Nur linux-3.18.8.orig/arch/x86/crypto/glue_helper.c linux-3.18.8/arch/x86/crypto/glue_helper.c +--- linux-3.18.8.orig/arch/x86/crypto/glue_helper.c 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/x86/crypto/glue_helper.c 2015-03-03 08:05:17.000000000 +0100 +@@ -39,7 +39,7 @@ + void *ctx = crypto_blkcipher_ctx(desc->tfm); + const unsigned int bsize = 128 / 8; + unsigned int nbytes, i, func_bytes; +- bool fpu_enabled = false; ++ bool fpu_enabled; + int err; + + err = blkcipher_walk_virt(desc, walk); +@@ -49,7 +49,7 @@ + u8 *wdst = walk->dst.virt.addr; + + fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, +- desc, fpu_enabled, nbytes); ++ desc, false, nbytes); + + for (i = 0; i < gctx->num_funcs; i++) { + func_bytes = bsize * gctx->funcs[i].num_blocks; +@@ -71,10 +71,10 @@ + } + + done: ++ glue_fpu_end(fpu_enabled); + err = blkcipher_walk_done(desc, walk, nbytes); + } + +- glue_fpu_end(fpu_enabled); + return err; + } + +@@ -194,7 +194,7 @@ + struct scatterlist *src, unsigned int nbytes) + { + const unsigned int bsize = 128 / 8; +- bool fpu_enabled = false; ++ bool fpu_enabled; + struct blkcipher_walk walk; + int err; + +@@ -203,12 +203,12 @@ + + while ((nbytes = walk.nbytes)) { + fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, +- desc, fpu_enabled, nbytes); ++ desc, false, nbytes); + nbytes = __glue_cbc_decrypt_128bit(gctx, desc, &walk); ++ glue_fpu_end(fpu_enabled); + err = blkcipher_walk_done(desc, &walk, nbytes); + } + +- glue_fpu_end(fpu_enabled); + return err; + } + EXPORT_SYMBOL_GPL(glue_cbc_decrypt_128bit); +@@ -278,7 +278,7 @@ + struct scatterlist *src, unsigned int nbytes) + { + const unsigned int bsize = 128 / 8; +- bool fpu_enabled = false; ++ bool fpu_enabled; + struct blkcipher_walk walk; + int err; + +@@ -287,13 +287,12 @@ + + while ((nbytes = walk.nbytes) >= bsize) { + fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, +- desc, fpu_enabled, nbytes); ++ desc, false, nbytes); + nbytes = __glue_ctr_crypt_128bit(gctx, desc, &walk); ++ glue_fpu_end(fpu_enabled); + err = blkcipher_walk_done(desc, &walk, nbytes); + } + +- glue_fpu_end(fpu_enabled); +- + if (walk.nbytes) { + glue_ctr_crypt_final_128bit( + gctx->funcs[gctx->num_funcs - 1].fn_u.ctr, desc, &walk); +@@ -348,7 +347,7 @@ + void *tweak_ctx, void *crypt_ctx) + { + const unsigned int bsize = 128 / 8; +- bool fpu_enabled = false; ++ bool fpu_enabled; + struct blkcipher_walk walk; + int err; + +@@ -361,21 +360,21 @@ + + /* set minimum length to bsize, for tweak_fn */ + fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, +- desc, fpu_enabled, ++ desc, false, + nbytes < bsize ? bsize : nbytes); +- + /* calculate first value of T */ + tweak_fn(tweak_ctx, walk.iv, walk.iv); ++ glue_fpu_end(fpu_enabled); + + while (nbytes) { ++ fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, ++ desc, false, nbytes); + nbytes = __glue_xts_crypt_128bit(gctx, crypt_ctx, desc, &walk); + ++ glue_fpu_end(fpu_enabled); + err = blkcipher_walk_done(desc, &walk, nbytes); + nbytes = walk.nbytes; + } +- +- glue_fpu_end(fpu_enabled); +- + return err; + } + EXPORT_SYMBOL_GPL(glue_xts_crypt_128bit); +diff -Nur linux-3.18.8.orig/arch/x86/include/asm/preempt.h linux-3.18.8/arch/x86/include/asm/preempt.h +--- linux-3.18.8.orig/arch/x86/include/asm/preempt.h 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/x86/include/asm/preempt.h 2015-03-03 08:05:17.000000000 +0100 +@@ -85,17 +85,33 @@ + * a decrement which hits zero means we have no preempt_count and should + * reschedule. + */ +-static __always_inline bool __preempt_count_dec_and_test(void) ++static __always_inline bool ____preempt_count_dec_and_test(void) + { + GEN_UNARY_RMWcc("decl", __preempt_count, __percpu_arg(0), "e"); + } + ++static __always_inline bool __preempt_count_dec_and_test(void) ++{ ++ if (____preempt_count_dec_and_test()) ++ return true; ++#ifdef CONFIG_PREEMPT_LAZY ++ return test_thread_flag(TIF_NEED_RESCHED_LAZY); ++#else ++ return false; ++#endif ++} ++ + /* + * Returns true when we need to resched and can (barring IRQ state). + */ + static __always_inline bool should_resched(void) + { ++#ifdef CONFIG_PREEMPT_LAZY ++ return unlikely(!raw_cpu_read_4(__preempt_count) || \ ++ test_thread_flag(TIF_NEED_RESCHED_LAZY)); ++#else + return unlikely(!raw_cpu_read_4(__preempt_count)); ++#endif + } + + #ifdef CONFIG_PREEMPT +diff -Nur linux-3.18.8.orig/arch/x86/include/asm/signal.h linux-3.18.8/arch/x86/include/asm/signal.h +--- linux-3.18.8.orig/arch/x86/include/asm/signal.h 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/x86/include/asm/signal.h 2015-03-03 08:05:17.000000000 +0100 +@@ -23,6 +23,19 @@ + unsigned long sig[_NSIG_WORDS]; + } sigset_t; + ++/* ++ * Because some traps use the IST stack, we must keep preemption ++ * disabled while calling do_trap(), but do_trap() may call ++ * force_sig_info() which will grab the signal spin_locks for the ++ * task, which in PREEMPT_RT_FULL are mutexes. By defining ++ * ARCH_RT_DELAYS_SIGNAL_SEND the force_sig_info() will set ++ * TIF_NOTIFY_RESUME and set up the signal to be sent on exit of the ++ * trap. ++ */ ++#if defined(CONFIG_PREEMPT_RT_FULL) && defined(CONFIG_X86_64) ++#define ARCH_RT_DELAYS_SIGNAL_SEND ++#endif ++ + #ifndef CONFIG_COMPAT + typedef sigset_t compat_sigset_t; + #endif +diff -Nur linux-3.18.8.orig/arch/x86/include/asm/stackprotector.h linux-3.18.8/arch/x86/include/asm/stackprotector.h +--- linux-3.18.8.orig/arch/x86/include/asm/stackprotector.h 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/x86/include/asm/stackprotector.h 2015-03-03 08:05:17.000000000 +0100 +@@ -57,7 +57,7 @@ + */ + static __always_inline void boot_init_stack_canary(void) + { +- u64 canary; ++ u64 uninitialized_var(canary); + u64 tsc; + + #ifdef CONFIG_X86_64 +@@ -68,8 +68,16 @@ + * of randomness. The TSC only matters for very early init, + * there it already has some randomness on most systems. Later + * on during the bootup the random pool has true entropy too. ++ * ++ * For preempt-rt we need to weaken the randomness a bit, as ++ * we can't call into the random generator from atomic context ++ * due to locking constraints. We just leave canary ++ * uninitialized and use the TSC based randomness on top of ++ * it. + */ ++#ifndef CONFIG_PREEMPT_RT_FULL + get_random_bytes(&canary, sizeof(canary)); ++#endif + tsc = __native_read_tsc(); + canary += tsc + (tsc << 32UL); + +diff -Nur linux-3.18.8.orig/arch/x86/include/asm/thread_info.h linux-3.18.8/arch/x86/include/asm/thread_info.h +--- linux-3.18.8.orig/arch/x86/include/asm/thread_info.h 2015-02-27 02:49:36.000000000 +0100 ++++ linux-3.18.8/arch/x86/include/asm/thread_info.h 2015-03-03 08:05:17.000000000 +0100 +@@ -30,6 +30,8 @@ + __u32 status; /* thread synchronous flags */ + __u32 cpu; /* current CPU */ + int saved_preempt_count; ++ int preempt_lazy_count; /* 0 => lazy preemptable ++ <0 => BUG */ + mm_segment_t addr_limit; + struct restart_block restart_block; + void __user *sysenter_return; +@@ -75,6 +77,7 @@ + #define TIF_SYSCALL_EMU 6 /* syscall emulation active */ + #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ + #define TIF_SECCOMP 8 /* secure computing */ ++#define TIF_NEED_RESCHED_LAZY 9 /* lazy rescheduling necessary */ + #define TIF_MCE_NOTIFY 10 /* notify userspace of an MCE */ + #define TIF_USER_RETURN_NOTIFY 11 /* notify kernel of userspace return */ + #define TIF_UPROBE 12 /* breakpointed or singlestepping */ +@@ -100,6 +103,7 @@ + #define _TIF_SYSCALL_EMU (1 << TIF_SYSCALL_EMU) + #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) + #define _TIF_SECCOMP (1 << TIF_SECCOMP) ++#define _TIF_NEED_RESCHED_LAZY (1 << TIF_NEED_RESCHED_LAZY) + #define _TIF_MCE_NOTIFY (1 << TIF_MCE_NOTIFY) + #define _TIF_USER_RETURN_NOTIFY (1 << TIF_USER_RETURN_NOTIFY) + #define _TIF_UPROBE (1 << TIF_UPROBE) +@@ -150,6 +154,8 @@ + #define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW|_TIF_USER_RETURN_NOTIFY) + #define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW) + ++#define _TIF_NEED_RESCHED_MASK (_TIF_NEED_RESCHED | _TIF_NEED_RESCHED