summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWaldemar Brodkorb <wbx@openadk.org>2015-03-05 13:54:09 +0100
committerWaldemar Brodkorb <wbx@openadk.org>2015-03-05 19:35:22 +0100
commit25ff0c99fa50b4e13079cf550c2b715eb630d055 (patch)
tree94e907c8e5f6fa4fe0ec87d965091eafbdc6e611
parent91c96ee1dd60781fb6990c5378e48d8e0aef1c18 (diff)
add realtime linux preempt_rt patch
Enable Kernel options for Realtime, HZ and HighRes Timer in menuconfig.
-rw-r--r--target/linux/config/Config.in.addons14
-rw-r--r--target/linux/config/Config.in.kernel51
-rw-r--r--target/linux/kernel.config1
-rw-r--r--target/linux/patches/3.18.8/patch-linuxrt23744
-rw-r--r--toolchain/kernel-headers/Makefile5
5 files changed, 23804 insertions, 11 deletions
diff --git a/target/linux/config/Config.in.addons b/target/linux/config/Config.in.addons
index 1ea6b7315..23ca9b8c1 100644
--- a/target/linux/config/Config.in.addons
+++ b/target/linux/config/Config.in.addons
@@ -3,22 +3,26 @@
config ADK_KERNEL_ADDON_YAFFS2
default y if ADK_TARGET_WITH_NAND
- boolean
+ bool
config ADK_KERNEL_ADDON_GRSEC
- boolean
+ bool
depends on ADK_KERNEL_VERSION_3_14
config ADK_KERNEL_ADDON_MPTCP
- boolean
+ bool
depends on ADK_KERNEL_VERSION_3_14
config ADK_KERNEL_ADDON_FBLOGO
- boolean
+ bool
depends on ADK_KERNEL_VERSION_3_14
config ADK_KERNEL_ADDON_DIETNET
- boolean
+ bool
depends on ADK_KERNEL_VERSION_3_14
depends on ADK_KERNEL_VERSION_3_12
depends on ADK_KERNEL_VERSION_3_10
+
+config ADK_KERNEL_ADDON_LINUXRT
+ bool
+ depends on ADK_KERNEL_VERSION_3_18
diff --git a/target/linux/config/Config.in.kernel b/target/linux/config/Config.in.kernel
index c6269056f..bba5ac246 100644
--- a/target/linux/config/Config.in.kernel
+++ b/target/linux/config/Config.in.kernel
@@ -227,11 +227,6 @@ config ADK_KERNEL_HIGHMEM
help
Enable high memory support.
-config ADK_KERNEL_PREEMPT
- bool "Enable preemptive kernel"
- help
- Enable preemptive mode.
-
config ADK_KERNEL_BCM2708_DT
bool "Enable Devicetree support"
depends on ADK_TARGET_SYSTEM_RASPBERRY_PI
@@ -248,6 +243,52 @@ config ADK_KERNEL_CC_OPTIMIZE_FOR_SIZE
depends on !ADK_TARGET_ARCH_MICROBLAZE
default y
+config ADK_KERNEL_PREEMPT
+ bool "Enable preemptive kernel"
+ help
+ Enable preemptive mode.
+
+config ADK_KERNEL_PREEMPT_RT_FULL
+ bool "Enable Realtime support"
+ select ADK_KERNEL_ADDON_LINUXRT
+ help
+ https://www.kernel.org/pub/linux/kernel/projects/rt/3.18/
+
+
+choice
+prompt "tick configuration"
+
+config ADK_KERNEL_NO_HZ_IDLE
+ bool "no HZ IDLE, dynamic tick"
+
+config ADK_KERNEL_NO_HZ_FULL
+ bool "no HZ FULL, dynamic tick"
+
+config ADK_KERNEL_HZ_PERIODIC
+ bool "periodic tick"
+
+endchoice
+
+choice
+prompt "HZ"
+depends on ADK_KERNEL_HZ_PERIODIC
+
+config ADK_KERNEL_HZ_100
+ bool "100 HZ"
+
+config ADK_KERNEL_HZ_500
+ bool "500 HZ"
+
+config ADK_KERNEL_HZ_1000
+ bool "1000 HZ"
+
+endchoice
+
+config ADK_KERNEL_HIGH_RES_TIMERS
+ bool "Enable high resolution timers"
+ help
+
+
choice
prompt "Page size"
depends on ADK_TARGET_ARCH_MIPS64
diff --git a/target/linux/kernel.config b/target/linux/kernel.config
index 6ca00150f..e1d0971bc 100644
--- a/target/linux/kernel.config
+++ b/target/linux/kernel.config
@@ -1,7 +1,6 @@
CONFIG_DEFAULT_HOSTNAME="openadk"
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE=""
-CONFIG_NO_HZ=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
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 <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.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.0000