From 2f3fc168789eb4952a99e19c046867516fc522f7 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 29 Mar 2016 15:32:30 +0100 Subject: [PATCH] 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 --- 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