summaryrefslogtreecommitdiffstats
path: root/target/linux/brcm2708/patches-4.4/0215-copy_from_user-CPU_SW_DOMAIN_PAN-compatibility.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/brcm2708/patches-4.4/0215-copy_from_user-CPU_SW_DOMAIN_PAN-compatibility.patch')
-rw-r--r--target/linux/brcm2708/patches-4.4/0215-copy_from_user-CPU_SW_DOMAIN_PAN-compatibility.patch53
1 files changed, 53 insertions, 0 deletions
diff --git a/target/linux/brcm2708/patches-4.4/0215-copy_from_user-CPU_SW_DOMAIN_PAN-compatibility.patch b/target/linux/brcm2708/patches-4.4/0215-copy_from_user-CPU_SW_DOMAIN_PAN-compatibility.patch
new file mode 100644
index 0000000000..0511407426
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.4/0215-copy_from_user-CPU_SW_DOMAIN_PAN-compatibility.patch
@@ -0,0 +1,53 @@
+From 250a9cb281e520a1c22ff9dd86d2fb44fddb4fe9 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Tue, 29 Mar 2016 15:32:30 +0100
+Subject: [PATCH 215/304] copy_from_user: CPU_SW_DOMAIN_PAN compatibility
+
+The downstream copy_from_user acceleration must also play nice with
+CONFIG_CPU_SW_DOMAIN_PAN.
+
+See: https://github.com/raspberrypi/linux/issues/1381
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ arch/arm/lib/uaccess_with_memcpy.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+--- a/arch/arm/lib/uaccess_with_memcpy.c
++++ b/arch/arm/lib/uaccess_with_memcpy.c
+@@ -186,6 +186,7 @@ out:
+ unsigned long noinline
+ __copy_from_user_memcpy(void *to, const void __user *from, unsigned long n)
+ {
++ unsigned long ua_flags;
+ int atomic;
+
+ if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
+@@ -217,7 +218,9 @@ __copy_from_user_memcpy(void *to, const
+ if (tocopy > n)
+ tocopy = n;
+
++ ua_flags = uaccess_save_and_enable();
+ memcpy(to, (const void *)from, tocopy);
++ uaccess_restore(ua_flags);
+ to += tocopy;
+ from += tocopy;
+ n -= tocopy;
+@@ -261,9 +264,14 @@ arm_copy_from_user(void *to, const void
+ * With frame pointer disabled, tail call optimization kicks in
+ * as well making this test almost invisible.
+ */
+- if (n < COPY_FROM_USER_THRESHOLD)
+- return __copy_from_user_std(to, from, n);
+- return __copy_from_user_memcpy(to, from, n);
++ if (n < COPY_TO_USER_THRESHOLD) {
++ unsigned long ua_flags = uaccess_save_and_enable();
++ n = __copy_from_user_std(to, from, n);
++ uaccess_restore(ua_flags);
++ } else {
++ n = __copy_from_user_memcpy(to, from, n);
++ }
++ return n;
+ }
+
+ static unsigned long noinline