summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--target/linux/config/Config.in.kernel6
-rw-r--r--target/linux/patches/72134397d72079a533c8fc742701fdc7f5ae7c5b/patch-realtime26047
2 files changed, 26051 insertions, 2 deletions
diff --git a/target/linux/config/Config.in.kernel b/target/linux/config/Config.in.kernel
index 8086a4bf7..b53b5f025 100644
--- a/target/linux/config/Config.in.kernel
+++ b/target/linux/config/Config.in.kernel
@@ -168,7 +168,8 @@ config ADK_KERNEL_PREEMPT_RTB
depends on !ADK_KERNEL_OPROFILE
depends on ADK_TARGET_KERNEL_VERSION_4_1 \
|| ADK_TARGET_KERNEL_VERSION_4_4 \
- || ADK_TARGET_KERNEL_VERSION_4_9
+ || ADK_TARGET_KERNEL_VERSION_4_9 \
+ || (ADK_TARGET_KERNEL_VERSION_GIT && ADK_TARGET_BOARD_BCM28XX)
help
Preemptible Kernel (Basic RT)
@@ -179,7 +180,8 @@ config ADK_KERNEL_PREEMPT_RT_FULL
depends on !ADK_KERNEL_OPROFILE
depends on ADK_TARGET_KERNEL_VERSION_4_1 \
|| ADK_TARGET_KERNEL_VERSION_4_4 \
- || ADK_TARGET_KERNEL_VERSION_4_9
+ || ADK_TARGET_KERNEL_VERSION_4_9 \
+ || (ADK_TARGET_KERNEL_VERSION_GIT && ADK_TARGET_BOARD_BCM28XX)
help
Fully Preemptible Kernel (RealTime)
https://www.kernel.org/pub/linux/kernel/projects/rt/
diff --git a/target/linux/patches/72134397d72079a533c8fc742701fdc7f5ae7c5b/patch-realtime b/target/linux/patches/72134397d72079a533c8fc742701fdc7f5ae7c5b/patch-realtime
new file mode 100644
index 000000000..fe7c393a6
--- /dev/null
+++ b/target/linux/patches/72134397d72079a533c8fc742701fdc7f5ae7c5b/patch-realtime
@@ -0,0 +1,26047 @@
+diff -Nur linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/Documentation/sysrq.txt linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/Documentation/sysrq.txt
+--- linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/Documentation/sysrq.txt 2017-04-16 10:37:28.000000000 +0200
++++ linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/Documentation/sysrq.txt 2017-04-18 17:54:21.000000000 +0200
+@@ -59,10 +59,17 @@
+ On other - If you know of the key combos for other architectures, please
+ let me know so I can add them to this section.
+
+-On all - write a character to /proc/sysrq-trigger. e.g.:
+-
++On all - write a character to /proc/sysrq-trigger, e.g.:
+ echo t > /proc/sysrq-trigger
+
++On all - Enable network SysRq by writing a cookie to icmp_echo_sysrq, e.g.
++ echo 0x01020304 >/proc/sys/net/ipv4/icmp_echo_sysrq
++ Send an ICMP echo request with this pattern plus the particular
++ SysRq command key. Example:
++ # ping -c1 -s57 -p0102030468
++ will trigger the SysRq-H (help) command.
++
++
+ * What are the 'command' keys?
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ 'b' - Will immediately reboot the system without syncing or unmounting
+diff -Nur linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/Documentation/trace/histograms.txt linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/Documentation/trace/histograms.txt
+--- linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/Documentation/trace/histograms.txt 1970-01-01 01:00:00.000000000 +0100
++++ linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/Documentation/trace/histograms.txt 2017-04-18 17:54:22.000000000 +0200
+@@ -0,0 +1,186 @@
++ Using the Linux Kernel Latency Histograms
++
++
++This document gives a short explanation how to enable, configure and use
++latency histograms. Latency histograms are primarily relevant in the
++context of real-time enabled kernels (CONFIG_PREEMPT/CONFIG_PREEMPT_RT)
++and are used in the quality management of the Linux real-time
++capabilities.
++
++
++* Purpose of latency histograms
++
++A latency histogram continuously accumulates the frequencies of latency
++data. There are two types of histograms
++- potential sources of latencies
++- effective latencies
++
++
++* Potential sources of latencies
++
++Potential sources of latencies are code segments where interrupts,
++preemption or both are disabled (aka critical sections). To create
++histograms of potential sources of latency, the kernel stores the time
++stamp at the start of a critical section, determines the time elapsed
++when the end of the section is reached, and increments the frequency
++counter of that latency value - irrespective of whether any concurrently
++running process is affected by latency or not.
++- Configuration items (in the Kernel hacking/Tracers submenu)
++ CONFIG_INTERRUPT_OFF_LATENCY
++ CONFIG_PREEMPT_OFF_LATENCY
++
++
++* Effective latencies
++
++Effective latencies are actually occuring during wakeup of a process. To
++determine effective latencies, the kernel stores the time stamp when a
++process is scheduled to be woken up, and determines the duration of the
++wakeup time shortly before control is passed over to this process. Note
++that the apparent latency in user space may be somewhat longer, since the
++process may be interrupted after control is passed over to it but before
++the execution in user space takes place. Simply measuring the interval
++between enqueuing and wakeup may also not appropriate in cases when a
++process is scheduled as a result of a timer expiration. The timer may have
++missed its deadline, e.g. due to disabled interrupts, but this latency
++would not be registered. Therefore, the offsets of missed timers are
++recorded in a separate histogram. If both wakeup latency and missed timer
++offsets are configured and enabled, a third histogram may be enabled that
++records the overall latency as a sum of the timer latency, if any, and the
++wakeup latency. This histogram is called "timerandwakeup".
++- Configuration items (in the Kernel hacking/Tracers submenu)
++ CONFIG_WAKEUP_LATENCY
++ CONFIG_MISSED_TIMER_OFSETS
++
++
++* Usage
++
++The interface to the administration of the latency histograms is located
++in the debugfs file system. To mount it, either enter
++
++mount -t sysfs nodev /sys
++mount -t debugfs nodev /sys/kernel/debug
++
++from shell command line level, or add
++
++nodev /sys sysfs defaults 0 0
++nodev /sys/kernel/debug debugfs defaults 0 0
++
++to the file /etc/fstab. All latency histogram related files are then
++available in the directory /sys/kernel/debug/tracing/latency_hist. A
++particular histogram type is enabled by writing non-zero to the related
++variable in the /sys/kernel/debug/tracing/latency_hist/enable directory.
++Select "preemptirqsoff" for the histograms of potential sources of
++latencies and "wakeup" for histograms of effective latencies etc. The
++histogram data - one per CPU - are available in the files
++
++/sys/kernel/debug/tracing/latency_hist/preemptoff/CPUx
++/sys/kernel/debug/tracing/latency_hist/irqsoff/CPUx
++/sys/kernel/debug/tracing/latency_hist/preemptirqsoff/CPUx
++/sys/kernel/debug/tracing/latency_hist/wakeup/CPUx
++/sys/kernel/debug/tracing/latency_hist/wakeup/sharedprio/CPUx
++/sys/kernel/debug/tracing/latency_hist/missed_timer_offsets/CPUx
++/sys/kernel/debug/tracing/latency_hist/timerandwakeup/CPUx
++
++The histograms are reset by writing non-zero to the file "reset" in a
++particular latency directory. To reset all latency data, use
++
++#!/bin/sh
++
++TRACINGDIR=/sys/kernel/debug/tracing
++HISTDIR=$TRACINGDIR/latency_hist
++
++if test -d $HISTDIR
++then
++ cd $HISTDIR
++ for i in `find . | grep /reset$`
++ do
++ echo 1 >$i
++ done
++fi
++
++
++* Data format
++
++Latency data are stored with a resolution of one microsecond. The
++maximum latency is 10,240 microseconds. The data are only valid, if the
++overflow register is empty. Every output line contains the latency in
++microseconds in the first row and the number of samples in the second
++row. To display only lines with a positive latency count, use, for
++example,
++
++grep -v " 0$" /sys/kernel/debug/tracing/latency_hist/preemptoff/CPU0
++
++#Minimum latency: 0 microseconds.
++#Average latency: 0 microseconds.
++#Maximum latency: 25 microseconds.
++#Total samples: 3104770694
++#There are 0 samples greater or equal than 10240 microseconds
++#usecs samples
++ 0 2984486876
++ 1 49843506
++ 2 58219047
++ 3 5348126
++ 4 2187960
++ 5 3388262
++ 6 959289
++ 7 208294
++ 8 40420
++ 9 4485
++ 10 14918
++ 11 18340
++ 12 25052
++ 13 19455
++ 14 5602
++ 15 969
++ 16 47
++ 17 18
++ 18 14
++ 19 1
++ 20 3
++ 21 2
++ 22 5
++ 23 2
++ 25 1
++
++
++* Wakeup latency of a selected process
++
++To only collect wakeup latency data of a particular process, write the
++PID of the requested process to
++
++/sys/kernel/debug/tracing/latency_hist/wakeup/pid
++
++PIDs are not considered, if this variable is set to 0.
++
++
++* Details of the process with the highest wakeup latency so far
++
++Selected data of the process that suffered from the highest wakeup
++latency that occurred in a particular CPU are available in the file
++
++/sys/kernel/debug/tracing/latency_hist/wakeup/max_latency-CPUx.
++
++In addition, other relevant system data at the time when the
++latency occurred are given.
++
++The format of the data is (all in one line):
++<PID> <Priority> <Latency> (<Timeroffset>) <Command> \
++<- <PID> <Priority> <Command> <Timestamp>
++
++The value of <Timeroffset> is only relevant in the combined timer
++and wakeup latency recording. In the wakeup recording, it is
++always 0, in the missed_timer_offsets recording, it is the same
++as <Latency>.
++
++When retrospectively searching for the origin of a latency and
++tracing was not enabled, it may be helpful to know the name and
++some basic data of the task that (finally) was switching to the
++late real-tlme task. In addition to the victim's data, also the
++data of the possible culprit are therefore displayed after the
++"<-" symbol.
++
++Finally, the timestamp of the time when the latency occurred
++in <seconds>.<microseconds> after the most recent system boot
++is provided.
++
++These data are also reset when the wakeup histogram is reset.
+diff -Nur linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/Kconfig linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/Kconfig
+--- linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/Kconfig 2017-04-16 10:37:28.000000000 +0200
++++ linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/Kconfig 2017-04-18 17:54:20.000000000 +0200
+@@ -9,6 +9,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
+@@ -52,6 +53,7 @@
+ config JUMP_LABEL
+ bool "Optimize very unlikely/likely branches"
+ depends on HAVE_ARCH_JUMP_LABEL
++ depends on (!INTERRUPT_OFF_HIST && !PREEMPT_OFF_HIST && !WAKEUP_LATENCY_HIST && !MISSED_TIMER_OFFSETS_HIST)
+ help
+ This option enables a transparent branch optimization that
+ makes certain almost-always-true or almost-always-false branch
+diff -Nur linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/Kconfig linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/Kconfig
+--- linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/Kconfig 2017-04-16 10:37:29.000000000 +0200
++++ linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/Kconfig 2017-04-18 17:54:19.000000000 +0200
+@@ -36,7 +36,7 @@
+ select HAVE_ARCH_AUDITSYSCALL if (AEABI && !OABI_COMPAT)
+ select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6
+ select HAVE_ARCH_HARDENED_USERCOPY
+- select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU
++ select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU && !PREEMPT_RT_BASE
+ select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU
+ select HAVE_ARCH_MMAP_RND_BITS if MMU
+ select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT)
+@@ -75,6 +75,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-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/include/asm/irq.h linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/include/asm/irq.h
+--- linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/include/asm/irq.h 2017-04-16 10:37:30.000000000 +0200
++++ linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/include/asm/irq.h 2017-04-18 17:54:19.000000000 +0200
+@@ -22,6 +22,8 @@
+ #endif
+
+ #ifndef __ASSEMBLY__
++#include <linux/cpumask.h>
++
+ struct irqaction;
+ struct pt_regs;
+ extern void migrate_irqs(void);
+diff -Nur linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/include/asm/switch_to.h linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/include/asm/switch_to.h
+--- linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/include/asm/switch_to.h 2017-04-16 10:37:30.000000000 +0200
++++ linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/include/asm/switch_to.h 2017-04-18 17:54:19.000000000 +0200
+@@ -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
+@@ -25,6 +32,7 @@
+ #define switch_to(prev,next,last) \
+ do { \
+ __complete_pending_tlbi(); \
++ switch_kmaps(prev, next); \
+ last = __switch_to(prev,task_thread_info(prev), task_thread_info(next)); \
+ } while (0)
+
+diff -Nur linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/include/asm/thread_info.h linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/include/asm/thread_info.h
+--- linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/include/asm/thread_info.h 2017-04-16 10:37:30.000000000 +0200
++++ linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/include/asm/thread_info.h 2017-04-18 17:54:19.000000000 +0200
+@@ -49,6 +49,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 */
+ __u32 cpu; /* cpu */
+@@ -142,7 +143,8 @@
+ #define TIF_SYSCALL_TRACE 4 /* syscall trace active */
+ #define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */
+ #define TIF_SYSCALL_TRACEPOINT 6 /* syscall tracepoint instrumentation */
+-#define TIF_SECCOMP 7 /* seccomp syscall filtering active */
++#define TIF_SECCOMP 8 /* seccomp syscall filtering active */
++#define TIF_NEED_RESCHED_LAZY 7
+
+ #define TIF_NOHZ 12 /* in adaptive nohz mode */
+ #define TIF_USING_IWMMXT 17
+@@ -152,6 +154,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)
+@@ -167,7 +170,8 @@
+ * Change these and you break ASM code in entry-common.S
+ */
+ #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \
+- _TIF_NOTIFY_RESUME | _TIF_UPROBE)
++ _TIF_NOTIFY_RESUME | _TIF_UPROBE | \
++ _TIF_NEED_RESCHED_LAZY)
+
+ #endif /* __KERNEL__ */
+ #endif /* __ASM_ARM_THREAD_INFO_H */
+diff -Nur linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/kernel/asm-offsets.c linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/kernel/asm-offsets.c
+--- linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/kernel/asm-offsets.c 2017-04-16 10:37:30.000000000 +0200
++++ linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/kernel/asm-offsets.c 2017-04-18 17:54:19.000000000 +0200
+@@ -65,6 +65,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_CPU, offsetof(struct thread_info, cpu));
+diff -Nur linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/kernel/entry-armv.S linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/kernel/entry-armv.S
+--- linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/kernel/entry-armv.S 2017-04-16 10:37:30.000000000 +0200
++++ linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/kernel/entry-armv.S 2017-04-18 17:54:19.000000000 +0200
+@@ -220,11 +220,18 @@
+
+ #ifdef CONFIG_PREEMPT
+ 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
+@@ -239,8 +246,14 @@
+ 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
++ ldr r0, [tsk, #TI_PREEMPT_LAZY] @ get preempt lazy count
++ teq r0, #0 @ if preempt lazy count != 0
++ beq 1b
++ ret r8 @ go again
++
+ #endif
+
+ __und_fault:
+diff -Nur linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/kernel/entry-common.S linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/kernel/entry-common.S
+--- linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/kernel/entry-common.S 2017-04-16 10:37:30.000000000 +0200
++++ linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/kernel/entry-common.S 2017-04-18 17:54:19.000000000 +0200
+@@ -36,7 +36,9 @@
+ UNWIND(.cantunwind )
+ disable_irq_notrace @ disable interrupts
+ ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing
+- tst r1, #_TIF_SYSCALL_WORK | _TIF_WORK_MASK
++ tst r1, #((_TIF_SYSCALL_WORK | _TIF_WORK_MASK) & ~_TIF_SECCOMP)
++ bne fast_work_pending
++ tst r1, #_TIF_SECCOMP
+ bne fast_work_pending
+
+ /* perform architecture specific actions before user return */
+@@ -62,8 +64,11 @@
+ str r0, [sp, #S_R0 + S_OFF]! @ save returned r0
+ disable_irq_notrace @ disable interrupts
+ ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing
+- tst r1, #_TIF_SYSCALL_WORK | _TIF_WORK_MASK
++ tst r1, #((_TIF_SYSCALL_WORK | _TIF_WORK_MASK) & ~_TIF_SECCOMP)
++ bne do_slower_path
++ tst r1, #_TIF_SECCOMP
+ beq no_work_pending
++do_slower_path:
+ UNWIND(.fnend )
+ ENDPROC(ret_fast_syscall)
+
+diff -Nur linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/kernel/patch.c linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/kernel/patch.c
+--- linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/kernel/patch.c 2017-04-16 10:37:30.000000000 +0200
++++ linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/kernel/patch.c 2017-04-18 17:54:19.000000000 +0200
+@@ -15,7 +15,7 @@
+ unsigned int insn;
+ };
+
+-static DEFINE_SPINLOCK(patch_lock);
++static DEFINE_RAW_SPINLOCK(patch_lock);
+
+ static void __kprobes *patch_map(void *addr, int fixmap, unsigned long *flags)
+ __acquires(&patch_lock)
+@@ -32,7 +32,7 @@
+ return addr;
+
+ if (flags)
+- spin_lock_irqsave(&patch_lock, *flags);
++ raw_spin_lock_irqsave(&patch_lock, *flags);
+ else
+ __acquire(&patch_lock);
+
+@@ -47,7 +47,7 @@
+ clear_fixmap(fixmap);
+
+ if (flags)
+- spin_unlock_irqrestore(&patch_lock, *flags);
++ raw_spin_unlock_irqrestore(&patch_lock, *flags);
+ else
+ __release(&patch_lock);
+ }
+diff -Nur linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/kernel/process.c linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/kernel/process.c
+--- linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/kernel/process.c 2017-04-16 10:37:30.000000000 +0200
++++ linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/kernel/process.c 2017-04-18 17:54:19.000000000 +0200
+@@ -322,6 +322,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-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/kernel/signal.c linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/kernel/signal.c
+--- linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/kernel/signal.c 2017-04-16 10:37:30.000000000 +0200
++++ linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/kernel/signal.c 2017-04-18 17:54:19.000000000 +0200
+@@ -572,7 +572,8 @@
+ */
+ trace_hardirqs_off();
+ 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-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/kernel/smp.c linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/kernel/smp.c
+--- linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/kernel/smp.c 2017-04-16 10:37:30.000000000 +0200
++++ linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/kernel/smp.c 2017-04-18 17:54:19.000000000 +0200
+@@ -234,8 +234,6 @@
+ flush_cache_louis();
+ local_flush_tlb_all();
+
+- clear_tasks_mm_cpumask(cpu);
+-
+ return 0;
+ }
+
+@@ -251,6 +249,9 @@
+ pr_err("CPU%u: cpu didn't die\n", cpu);
+ return;
+ }
++
++ clear_tasks_mm_cpumask(cpu);
++
+ pr_notice("CPU%u: shutdown\n", cpu);
+
+ /*
+diff -Nur linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/kernel/unwind.c linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/kernel/unwind.c
+--- linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/kernel/unwind.c 2017-04-16 10:37:30.000000000 +0200
++++ linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/kernel/unwind.c 2017-04-18 17:54:19.000000000 +0200
+@@ -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);
+@@ -529,9 +529,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;
+ }
+@@ -543,9 +543,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-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/kvm/arm.c linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/kvm/arm.c
+--- linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/kvm/arm.c 2017-04-16 10:37:30.000000000 +0200
++++ linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/kvm/arm.c 2017-04-18 17:54:19.000000000 +0200
+@@ -619,7 +619,7 @@
+ * involves poking the GIC, which must be done in a
+ * non-preemptible context.
+ */
+- preempt_disable();
++ migrate_disable();
+ kvm_pmu_flush_hwstate(vcpu);
+ kvm_timer_flush_hwstate(vcpu);
+ kvm_vgic_flush_hwstate(vcpu);
+@@ -640,7 +640,7 @@
+ kvm_pmu_sync_hwstate(vcpu);
+ kvm_timer_sync_hwstate(vcpu);
+ kvm_vgic_sync_hwstate(vcpu);
+- preempt_enable();
++ migrate_enable();
+ continue;
+ }
+
+@@ -696,7 +696,7 @@
+
+ kvm_vgic_sync_hwstate(vcpu);
+
+- preempt_enable();
++ migrate_enable();
+
+ ret = handle_exit(vcpu, run, ret);
+ }
+diff -Nur linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/mach-exynos/platsmp.c linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/mach-exynos/platsmp.c
+--- linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/mach-exynos/platsmp.c 2017-04-16 10:37:30.000000000 +0200
++++ linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/mach-exynos/platsmp.c 2017-04-18 17:54:19.000000000 +0200
+@@ -229,7 +229,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)
+ {
+@@ -242,8 +242,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 exynos_set_boot_addr(u32 core_id, unsigned long boot_addr)
+@@ -307,7 +307,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
+@@ -334,7 +334,7 @@
+
+ if (timeout == 0) {
+ printk(KERN_ERR "cpu1 power enable failed");
+- spin_unlock(&boot_lock);
++ raw_spin_unlock(&boot_lock);
+ return -ETIMEDOUT;
+ }
+ }
+@@ -380,7 +380,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-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/mach-hisi/platmcpm.c linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/mach-hisi/platmcpm.c
+--- linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/mach-hisi/platmcpm.c 2017-04-16 10:37:30.000000000 +0200
++++ linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/mach-hisi/platmcpm.c 2017-04-18 17:54:19.000000000 +0200
+@@ -61,7 +61,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
+@@ -113,7 +113,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;
+@@ -147,7 +147,7 @@
+
+ out:
+ hip04_cpu_table[cluster][cpu]++;
+- spin_unlock_irq(&boot_lock);
++ raw_spin_unlock_irq(&boot_lock);
+
+ return 0;
+ }
+@@ -162,11 +162,11 @@
+ cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+ cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+
+- spin_lock(&boot_lock);
++ raw_spin_lock(&boot_lock);
+ hip04_cpu_table[cluster][cpu]--;
+ if (hip04_cpu_table[cluster][cpu] == 1) {
+ /* A power_up request went ahead of us. */
+- spin_unlock(&boot_lock);
++ raw_spin_unlock(&boot_lock);
+ return;
+ } else if (hip04_cpu_table[cluster][cpu] > 1) {
+ pr_err("Cluster %d CPU%d boots multiple times\n", cluster, cpu);
+@@ -174,7 +174,7 @@
+ }
+
+ last_man = hip04_cluster_is_down(cluster);
+- spin_unlock(&boot_lock);
++ raw_spin_unlock(&boot_lock);
+ if (last_man) {
+ /* Since it's Cortex A15, disable L2 prefetching. */
+ asm volatile(
+@@ -203,7 +203,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])
+ goto err;
+@@ -211,10 +211,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;
+@@ -231,10 +231,10 @@
+ goto err;
+ if (hip04_cluster_is_down(cluster))
+ hip04_set_snoop_filter(cluster, 0);
+- spin_unlock_irq(&boot_lock);
++ raw_spin_unlock_irq(&boot_lock);
+ return 1;
+ err:
+- spin_unlock_irq(&boot_lock);
++ raw_spin_unlock_irq(&boot_lock);
+ return 0;
+ }
+ #endif
+diff -Nur linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/mach-omap2/omap-smp.c linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/mach-omap2/omap-smp.c
+--- linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/mach-omap2/omap-smp.c 2017-04-16 10:37:31.000000000 +0200
++++ linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/mach-omap2/omap-smp.c 2017-04-18 17:54:19.000000000 +0200
+@@ -64,7 +64,7 @@
+ .startup_addr = omap5_secondary_startup,
+ };
+
+-static DEFINE_SPINLOCK(boot_lock);
++static DEFINE_RAW_SPINLOCK(boot_lock);
+
+ void __iomem *omap4_get_scu_base(void)
+ {
+@@ -131,8 +131,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)
+@@ -146,7 +146,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.
+@@ -223,7 +223,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-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/mach-prima2/platsmp.c linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/mach-prima2/platsmp.c
+--- linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/mach-prima2/platsmp.c 2017-04-16 10:37:31.000000000 +0200
++++ linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/mach-prima2/platsmp.c 2017-04-18 17:54:19.000000000 +0200
+@@ -22,7 +22,7 @@
+
+ static void __iomem *clk_base;
+
+-static DEFINE_SPINLOCK(boot_lock);
++static DEFINE_RAW_SPINLOCK(boot_lock);
+
+ static void sirfsoc_secondary_init(unsigned int cpu)
+ {
+@@ -36,8 +36,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 const struct of_device_id clk_ids[] = {
+@@ -75,7 +75,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
+@@ -107,7 +107,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-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/mach-qcom/platsmp.c linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/mach-qcom/platsmp.c
+--- linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/mach-qcom/platsmp.c 2017-04-16 10:37:31.000000000 +0200
++++ linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/mach-qcom/platsmp.c 2017-04-18 17:54:20.000000000 +0200
+@@ -46,7 +46,7 @@
+
+ extern void secondary_startup_arm(void);
+
+-static DEFINE_SPINLOCK(boot_lock);
++static DEFINE_RAW_SPINLOCK(boot_lock);
+
+ #ifdef CONFIG_HOTPLUG_CPU
+ static void 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-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/mach-spear/platsmp.c linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/mach-spear/platsmp.c
+--- linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/mach-spear/platsmp.c 2017-04-16 10:37:31.000000000 +0200
++++ linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/mach-spear/platsmp.c 2017-04-18 17:54:20.000000000 +0200
+@@ -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-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/mach-sti/platsmp.c linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/mach-sti/platsmp.c
+--- linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/mach-sti/platsmp.c 2017-04-16 10:37:31.000000000 +0200
++++ linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/mach-sti/platsmp.c 2017-04-18 17:54:20.000000000 +0200
+@@ -35,7 +35,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)
+ {
+@@ -48,8 +48,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)
+@@ -60,7 +60,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
+@@ -91,7 +91,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-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/mm/fault.c linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/mm/fault.c
+--- linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/mm/fault.c 2017-04-16 10:37:31.000000000 +0200
++++ linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/mm/fault.c 2017-04-18 17:54:20.000000000 +0200
+@@ -430,6 +430,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;
+
+@@ -497,6 +500,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-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/mm/highmem.c linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/mm/highmem.c
+--- linux-72134397d72079a533c8fc742701fdc7f5ae7c5b.orig/arch/arm/mm/highmem.c 2017-04-16 10:37:31.000000000 +0200
++++ linux-72134397d72079a533c8fc742701fdc7f5ae7c5b/arch/arm/mm/highmem.c 2017-04-18 17:54:20.000000000 +0200
+@@ -34,6 +34,11 @@
+ return *ptep