[PATCH 4.9 05/16] ARM: 8794/1: uaccess: Prevent speculative use of the current addr_limit

2019-02-14 Thread David Long
From: Julien Thierry 

Commit 621afc677465db231662ed126ae1f355bf8eac47 upstream.

A mispredicted conditional call to set_fs could result in the wrong
addr_limit being forwarded under speculation to a subsequent access_ok
check, potentially forming part of a spectre-v1 attack using uaccess
routines.

This patch prevents this forwarding from taking place, but putting heavy
barriers in set_fs after writing the addr_limit.

Porting commit c2f0ad4fc089cff8 ("arm64: uaccess: Prevent speculative use
of the current addr_limit").

Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/include/asm/uaccess.h | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 7b17460127fd..9ae888775743 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -99,6 +99,14 @@ extern int __put_user_bad(void);
 static inline void set_fs(mm_segment_t fs)
 {
current_thread_info()->addr_limit = fs;
+
+   /*
+* Prevent a mispredicted conditional call to set_fs from forwarding
+* the wrong address limit to access_ok under speculation.
+*/
+   dsb(nsh);
+   isb();
+
modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_CLIENT : DOMAIN_MANAGER);
 }
 
-- 
2.17.1



[PATCH 4.9 07/16] ARM: 8796/1: spectre-v1,v1.1: provide helpers for address sanitization

2019-02-14 Thread David Long
From: Julien Thierry 

Commit afaf6838f4bc896a711180b702b388b8cfa638fc upstream.

Introduce C and asm helpers to sanitize user address, taking the
address range they target into account.

Use asm helper for existing sanitization in __copy_from_user().

Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/include/asm/assembler.h | 11 +++
 arch/arm/include/asm/uaccess.h   | 26 ++
 arch/arm/lib/copy_from_user.S|  6 +-
 3 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index e616f61f859d..7d727506096f 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -465,6 +465,17 @@ THUMB( orr \reg , \reg , #PSR_T_BIT)
 #endif
.endm
 
+   .macro uaccess_mask_range_ptr, addr:req, size:req, limit:req, tmp:req
+#ifdef CONFIG_CPU_SPECTRE
+   sub \tmp, \limit, #1
+   subs\tmp, \tmp, \addr   @ tmp = limit - 1 - addr
+   addhs   \tmp, \tmp, #1  @ if (tmp >= 0) {
+   subhss  \tmp, \tmp, \size   @ tmp = limit - (addr + size) }
+   movlo   \addr, #0   @ if (tmp < 0) addr = NULL
+   csdb
+#endif
+   .endm
+
.macro  uaccess_disable, tmp, isb=1
 #ifdef CONFIG_CPU_SW_DOMAIN_PAN
/*
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index b61acd62cffb..0f6c6b873bc5 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -129,6 +129,32 @@ static inline void set_fs(mm_segment_t fs)
 #define __inttype(x) \
__typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
 
+/*
+ * Sanitise a uaccess pointer such that it becomes NULL if addr+size
+ * is above the current addr_limit.
+ */
+#define uaccess_mask_range_ptr(ptr, size)  \
+   ((__typeof__(ptr))__uaccess_mask_range_ptr(ptr, size))
+static inline void __user *__uaccess_mask_range_ptr(const void __user *ptr,
+   size_t size)
+{
+   void __user *safe_ptr = (void __user *)ptr;
+   unsigned long tmp;
+
+   asm volatile(
+   "   sub %1, %3, #1\n"
+   "   subs%1, %1, %0\n"
+   "   addhs   %1, %1, #1\n"
+   "   subhss  %1, %1, %2\n"
+   "   movlo   %0, #0\n"
+   : "+r" (safe_ptr), "=" (tmp)
+   : "r" (size), "r" (current_thread_info()->addr_limit)
+   : "cc");
+
+   csdb();
+   return safe_ptr;
+}
+
 /*
  * Single-value transfer routines.  They automatically use the right
  * size if we just have the right pointer type.  Note that the functions
diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S
index a826df3d3814..6709a8d33963 100644
--- a/arch/arm/lib/copy_from_user.S
+++ b/arch/arm/lib/copy_from_user.S
@@ -93,11 +93,7 @@ ENTRY(arm_copy_from_user)
 #ifdef CONFIG_CPU_SPECTRE
get_thread_info r3
ldr r3, [r3, #TI_ADDR_LIMIT]
-   addsip, r1, r2  @ ip=addr+size
-   sub r3, r3, #1  @ addr_limit - 1
-   cmpcc   ip, r3  @ if (addr+size > addr_limit - 1)
-   movcs   r1, #0  @ addr = NULL
-   csdb
+   uaccess_mask_range_ptr r1, r2, r3, ip
 #endif
 
 #include "copy_template.S"
-- 
2.17.1



[PATCH 4.9 06/16] ARM: 8795/1: spectre-v1.1: use put_user() for __put_user()

2019-02-14 Thread David Long
From: Julien Thierry 

Commit e3aa6243434fd9a82e84bb79ab1abd14f2d9a5a7 upstream.

When Spectre mitigation is required, __put_user() needs to include
check_uaccess. This is already the case for put_user(), so just make
__put_user() an alias of put_user().

Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/include/asm/uaccess.h | 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 9ae888775743..b61acd62cffb 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -400,6 +400,14 @@ do {   
\
__pu_err;   \
 })
 
+#ifdef CONFIG_CPU_SPECTRE
+/*
+ * When mitigating Spectre variant 1.1, all accessors need to include
+ * verification of the address space.
+ */
+#define __put_user(x, ptr) put_user(x, ptr)
+
+#else
 #define __put_user(x, ptr) \
 ({ \
long __pu_err = 0;  \
@@ -407,12 +415,6 @@ do {   
\
__pu_err;   \
 })
 
-#define __put_user_error(x, ptr, err)  \
-({ \
-   __put_user_switch((x), (ptr), (err), __put_user_nocheck);   \
-   (void) 0;   \
-})
-
 #define __put_user_nocheck(x, __pu_ptr, __err, __size) \
do {\
unsigned long __pu_addr = (unsigned long)__pu_ptr;  \
@@ -492,6 +494,7 @@ do {
\
: "r" (x), "i" (-EFAULT)\
: "cc")
 
+#endif /* !CONFIG_CPU_SPECTRE */
 
 #ifdef CONFIG_MMU
 extern unsigned long __must_check
-- 
2.17.1



[PATCH 4.9 08/16] ARM: 8797/1: spectre-v1.1: harden __copy_to_user

2019-02-14 Thread David Long
From: Julien Thierry 

Commit a1d09e074250fad24f1b993f327b18cc6812eb7a upstream.

Sanitize user pointer given to __copy_to_user, both for standard version
and memcopy version of the user accessor.

Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/lib/copy_to_user.S| 6 +-
 arch/arm/lib/uaccess_with_memcpy.c | 3 ++-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S
index caf5019d8161..970abe521197 100644
--- a/arch/arm/lib/copy_to_user.S
+++ b/arch/arm/lib/copy_to_user.S
@@ -94,6 +94,11 @@
 
 ENTRY(__copy_to_user_std)
 WEAK(arm_copy_to_user)
+#ifdef CONFIG_CPU_SPECTRE
+   get_thread_info r3
+   ldr r3, [r3, #TI_ADDR_LIMIT]
+   uaccess_mask_range_ptr r0, r2, r3, ip
+#endif
 
 #include "copy_template.S"
 
@@ -108,4 +113,3 @@ ENDPROC(__copy_to_user_std)
rsb r0, r0, r2
copy_abort_end
.popsection
-
diff --git a/arch/arm/lib/uaccess_with_memcpy.c 
b/arch/arm/lib/uaccess_with_memcpy.c
index 6bd1089b07e0..f598d792bace 100644
--- a/arch/arm/lib/uaccess_with_memcpy.c
+++ b/arch/arm/lib/uaccess_with_memcpy.c
@@ -152,7 +152,8 @@ arm_copy_to_user(void __user *to, const void *from, 
unsigned long n)
n = __copy_to_user_std(to, from, n);
uaccess_restore(ua_flags);
} else {
-   n = __copy_to_user_memcpy(to, from, n);
+   n = __copy_to_user_memcpy(uaccess_mask_range_ptr(to, n),
+ from, n);
}
return n;
 }
-- 
2.17.1



[PATCH 4.9 02/16] ARM: 8791/1: vfp: use __copy_to_user() when saving VFP state

2019-02-14 Thread David Long
From: Julien Thierry 

Commit 3aa2df6ec2ca6bc143a65351cca4266d03a8bc41 upstream.

Use __copy_to_user() rather than __put_user_error() for individual
members when saving VFP state.
This has the benefit of disabling/enabling PAN once per copied struct
intead of once per write.

Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/include/asm/thread_info.h |  4 ++--
 arch/arm/kernel/signal.c   | 13 +++--
 arch/arm/vfp/vfpmodule.c   | 20 
 3 files changed, 17 insertions(+), 20 deletions(-)

diff --git a/arch/arm/include/asm/thread_info.h 
b/arch/arm/include/asm/thread_info.h
index 57d2ad9c75ca..df8420672c7e 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -124,8 +124,8 @@ extern void vfp_flush_hwstate(struct thread_info *);
 struct user_vfp;
 struct user_vfp_exc;
 
-extern int vfp_preserve_user_clear_hwstate(struct user_vfp __user *,
-  struct user_vfp_exc __user *);
+extern int vfp_preserve_user_clear_hwstate(struct user_vfp *,
+  struct user_vfp_exc *);
 extern int vfp_restore_user_hwstate(struct user_vfp *,
struct user_vfp_exc *);
 #endif
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index fbb325ff8acc..135b1a8e12eb 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -94,17 +94,18 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe 
*frame)
 
 static int preserve_vfp_context(struct vfp_sigframe __user *frame)
 {
-   const unsigned long magic = VFP_MAGIC;
-   const unsigned long size = VFP_STORAGE_SIZE;
+   struct vfp_sigframe kframe;
int err = 0;
 
-   __put_user_error(magic, >magic, err);
-   __put_user_error(size, >size, err);
+   memset(, 0, sizeof(kframe));
+   kframe.magic = VFP_MAGIC;
+   kframe.size = VFP_STORAGE_SIZE;
 
+   err = vfp_preserve_user_clear_hwstate(, _exc);
if (err)
-   return -EFAULT;
+   return err;
 
-   return vfp_preserve_user_clear_hwstate(>ufp, >ufp_exc);
+   return __copy_to_user(frame, , sizeof(kframe));
 }
 
 static int restore_vfp_context(struct vfp_sigframe __user *auxp)
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 8e5e97989fda..df3fa52c0aa3 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -554,12 +554,11 @@ void vfp_flush_hwstate(struct thread_info *thread)
  * Save the current VFP state into the provided structures and prepare
  * for entry into a new function (signal handler).
  */
-int vfp_preserve_user_clear_hwstate(struct user_vfp __user *ufp,
-   struct user_vfp_exc __user *ufp_exc)
+int vfp_preserve_user_clear_hwstate(struct user_vfp *ufp,
+   struct user_vfp_exc *ufp_exc)
 {
struct thread_info *thread = current_thread_info();
struct vfp_hard_struct *hwstate = >vfpstate.hard;
-   int err = 0;
 
/* Ensure that the saved hwstate is up-to-date. */
vfp_sync_hwstate(thread);
@@ -568,22 +567,19 @@ int vfp_preserve_user_clear_hwstate(struct user_vfp 
__user *ufp,
 * Copy the floating point registers. There can be unused
 * registers see asm/hwcap.h for details.
 */
-   err |= __copy_to_user(>fpregs, >fpregs,
- sizeof(hwstate->fpregs));
+   memcpy(>fpregs, >fpregs, sizeof(hwstate->fpregs));
+
/*
 * Copy the status and control register.
 */
-   __put_user_error(hwstate->fpscr, >fpscr, err);
+   ufp->fpscr = hwstate->fpscr;
 
/*
 * Copy the exception registers.
 */
-   __put_user_error(hwstate->fpexc, _exc->fpexc, err);
-   __put_user_error(hwstate->fpinst, _exc->fpinst, err);
-   __put_user_error(hwstate->fpinst2, _exc->fpinst2, err);
-
-   if (err)
-   return -EFAULT;
+   ufp_exc->fpexc = hwstate->fpexc;
+   ufp_exc->fpinst = hwstate->fpinst;
+   ufp_exc->fpinst2 = ufp_exc->fpinst2;
 
/* Ensure that VFP is disabled. */
vfp_flush_hwstate(thread);
-- 
2.17.1



[PATCH 4.9 03/16] ARM: 8792/1: oabi-compat: copy oabi events using __copy_to_user()

2019-02-14 Thread David Long
From: Julien Thierry 

Commit 319508902600c2688e057750148487996396e9ca upstream.

Copy events to user using __copy_to_user() rather than copy members of
individually with __put_user_error().
This has the benefit of disabling/enabling PAN once per event intead of
once per event member.

Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/kernel/sys_oabi-compat.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/arm/kernel/sys_oabi-compat.c 
b/arch/arm/kernel/sys_oabi-compat.c
index 640748e27035..d844c5c9364b 100644
--- a/arch/arm/kernel/sys_oabi-compat.c
+++ b/arch/arm/kernel/sys_oabi-compat.c
@@ -276,6 +276,7 @@ asmlinkage long sys_oabi_epoll_wait(int epfd,
int maxevents, int timeout)
 {
struct epoll_event *kbuf;
+   struct oabi_epoll_event e;
mm_segment_t fs;
long ret, err, i;
 
@@ -294,8 +295,11 @@ asmlinkage long sys_oabi_epoll_wait(int epfd,
set_fs(fs);
err = 0;
for (i = 0; i < ret; i++) {
-   __put_user_error(kbuf[i].events, >events, err);
-   __put_user_error(kbuf[i].data,   >data,   err);
+   e.events = kbuf[i].events;
+   e.data = kbuf[i].data;
+   err = __copy_to_user(events, , sizeof(e));
+   if (err)
+   break;
events++;
}
kfree(kbuf);
-- 
2.17.1



[PATCH 4.9 10/16] ARM: make lookup_processor_type() non-__init

2019-02-14 Thread David Long
From: Russell King 

Commit 899a42f836678a595f7d2bc36a5a0c2b03d08cbc upstream.

Move lookup_processor_type() out of the __init section so it is callable
from (eg) the secondary startup code during hotplug.

Reviewed-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/kernel/head-common.S | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
index 8733012d231f..7e662bdd5cb3 100644
--- a/arch/arm/kernel/head-common.S
+++ b/arch/arm/kernel/head-common.S
@@ -122,6 +122,9 @@ __mmap_switched_data:
.long   init_thread_union + THREAD_START_SP @ sp
.size   __mmap_switched_data, . - __mmap_switched_data
 
+   __FINIT
+   .text
+
 /*
  * This provides a C-API version of __lookup_processor_type
  */
@@ -133,9 +136,6 @@ ENTRY(lookup_processor_type)
ldmfd   sp!, {r4 - r6, r9, pc}
 ENDPROC(lookup_processor_type)
 
-   __FINIT
-   .text
-
 /*
  * Read processor ID register (CP#15, CR0), and look up in the linker-built
  * supported processor list.  Note that we can't use the absolute addresses
-- 
2.17.1



[PATCH 4.9 09/16] ARM: 8810/1: vfp: Fix wrong assignement to ufp_exc

2019-02-14 Thread David Long
From: Julien Thierry 

Commit 5df7a99bdd0de4a0480320264c44c04543c29d5a upstream.

In vfp_preserve_user_clear_hwstate, ufp_exc->fpinst2 gets assigned to
itself. It should actually be hwstate->fpinst2 that gets assigned to the
ufp_exc field.

Fixes commit 3aa2df6ec2ca6bc143a65351cca4266d03a8bc41 ("ARM: 8791/1:
vfp: use __copy_to_user() when saving VFP state").

Reported-by: David Binderman 
Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/vfp/vfpmodule.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index df3fa52c0aa3..00dd8cf36632 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -579,7 +579,7 @@ int vfp_preserve_user_clear_hwstate(struct user_vfp *ufp,
 */
ufp_exc->fpexc = hwstate->fpexc;
ufp_exc->fpinst = hwstate->fpinst;
-   ufp_exc->fpinst2 = ufp_exc->fpinst2;
+   ufp_exc->fpinst2 = hwstate->fpinst2;
 
/* Ensure that VFP is disabled. */
vfp_flush_hwstate(thread);
-- 
2.17.1



[PATCH 4.9 11/16] ARM: split out processor lookup

2019-02-14 Thread David Long
From: Russell King 

Commit 65987a8553061515b5851b472081aedb9837a391 upstream.

Split out the lookup of the processor type and associated error handling
from the rest of setup_processor() - we will need to use this in the
secondary CPU bringup path for big.Little Spectre variant 2 mitigation.

Reviewed-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/include/asm/cputype.h |  1 +
 arch/arm/kernel/setup.c| 31 +++
 2 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
index c55db1e22f0c..b9356dbfded0 100644
--- a/arch/arm/include/asm/cputype.h
+++ b/arch/arm/include/asm/cputype.h
@@ -106,6 +106,7 @@
 #define ARM_CPU_PART_SCORPION  0x510002d0
 
 extern unsigned int processor_id;
+struct proc_info_list *lookup_processor(u32 midr);
 
 #ifdef CONFIG_CPU_CP15
 #define read_cpuid(reg)
\
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index f4e54503afa9..8d5c3a118abe 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -667,22 +667,29 @@ static void __init smp_build_mpidr_hash(void)
 }
 #endif
 
-static void __init setup_processor(void)
+/*
+ * locate processor in the list of supported processor types.  The linker
+ * builds this table for us from the entries in arch/arm/mm/proc-*.S
+ */
+struct proc_info_list *lookup_processor(u32 midr)
 {
-   struct proc_info_list *list;
+   struct proc_info_list *list = lookup_processor_type(midr);
 
-   /*
-* locate processor in the list of supported processor
-* types.  The linker builds this table for us from the
-* entries in arch/arm/mm/proc-*.S
-*/
-   list = lookup_processor_type(read_cpuid_id());
if (!list) {
-   pr_err("CPU configuration botched (ID %08x), unable to 
continue.\n",
-  read_cpuid_id());
-   while (1);
+   pr_err("CPU%u: configuration botched (ID %08x), CPU halted\n",
+  smp_processor_id(), midr);
+   while (1)
+   /* can't use cpu_relax() here as it may require MMU setup */;
}
 
+   return list;
+}
+
+static void __init setup_processor(void)
+{
+   unsigned int midr = read_cpuid_id();
+   struct proc_info_list *list = lookup_processor(midr);
+
cpu_name = list->cpu_name;
__cpu_architecture = __get_cpu_architecture();
 
@@ -700,7 +707,7 @@ static void __init setup_processor(void)
 #endif
 
pr_info("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n",
-   cpu_name, read_cpuid_id(), read_cpuid_id() & 15,
+   list->cpu_name, midr, midr & 15,
proc_arch[cpu_architecture()], get_cr());
 
snprintf(init_utsname()->machine, __NEW_UTS_LEN + 1, "%s%c",
-- 
2.17.1



[PATCH 4.9 13/16] ARM: add PROC_VTABLE and PROC_TABLE macros

2019-02-14 Thread David Long
From: Russell King 

Commit e209950fdd065d2cc46e6338e47e52841b830cba upstream.

Allow the way we access members of the processor vtable to be changed
at compile time.  We will need to move to per-CPU vtables to fix the
Spectre variant 2 issues on big.Little systems.

However, we have a couple of calls that do not need the vtable
treatment, and indeed cause a kernel warning due to the (later) use
of smp_processor_id(), so also introduce the PROC_TABLE macro for
these which always use CPU 0's function pointers.

Reviewed-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/include/asm/proc-fns.h | 39 ++---
 arch/arm/kernel/setup.c |  4 +---
 2 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index 19939e88efca..a1a71b068edc 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -23,7 +23,7 @@ struct mm_struct;
 /*
  * Don't change this structure - ASM code relies on it.
  */
-extern struct processor {
+struct processor {
/* MISC
 * get data abort address/flags
 */
@@ -79,9 +79,13 @@ extern struct processor {
unsigned int suspend_size;
void (*do_suspend)(void *);
void (*do_resume)(void *);
-} processor;
+};
 
 #ifndef MULTI_CPU
+static inline void init_proc_vtable(const struct processor *p)
+{
+}
+
 extern void cpu_proc_init(void);
 extern void cpu_proc_fin(void);
 extern int cpu_do_idle(void);
@@ -98,18 +102,27 @@ extern void cpu_reset(unsigned long addr) 
__attribute__((noreturn));
 extern void cpu_do_suspend(void *);
 extern void cpu_do_resume(void *);
 #else
-#define cpu_proc_init  processor._proc_init
-#define cpu_check_bugs processor.check_bugs
-#define cpu_proc_fin   processor._proc_fin
-#define cpu_reset  processor.reset
-#define cpu_do_idleprocessor._do_idle
-#define cpu_dcache_clean_area  processor.dcache_clean_area
-#define cpu_set_pte_extprocessor.set_pte_ext
-#define cpu_do_switch_mm   processor.switch_mm
 
-/* These three are private to arch/arm/kernel/suspend.c */
-#define cpu_do_suspend processor.do_suspend
-#define cpu_do_resume  processor.do_resume
+extern struct processor processor;
+#define PROC_VTABLE(f) processor.f
+#define PROC_TABLE(f)  processor.f
+static inline void init_proc_vtable(const struct processor *p)
+{
+   processor = *p;
+}
+
+#define cpu_proc_init  PROC_VTABLE(_proc_init)
+#define cpu_check_bugs PROC_VTABLE(check_bugs)
+#define cpu_proc_fin   PROC_VTABLE(_proc_fin)
+#define cpu_reset  PROC_VTABLE(reset)
+#define cpu_do_idlePROC_VTABLE(_do_idle)
+#define cpu_dcache_clean_area  PROC_TABLE(dcache_clean_area)
+#define cpu_set_pte_extPROC_TABLE(set_pte_ext)
+#define cpu_do_switch_mm   PROC_VTABLE(switch_mm)
+
+/* These two are private to arch/arm/kernel/suspend.c */
+#define cpu_do_suspend PROC_VTABLE(do_suspend)
+#define cpu_do_resume  PROC_VTABLE(do_resume)
 #endif
 
 extern void cpu_resume(void);
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 8d5c3a118abe..2eebb67fa08b 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -693,9 +693,7 @@ static void __init setup_processor(void)
cpu_name = list->cpu_name;
__cpu_architecture = __get_cpu_architecture();
 
-#ifdef MULTI_CPU
-   processor = *list->proc;
-#endif
+   init_proc_vtable(list->proc);
 #ifdef MULTI_TLB
cpu_tlb = *list->tlb;
 #endif
-- 
2.17.1



[PATCH 4.9 12/16] ARM: clean up per-processor check_bugs method call

2019-02-14 Thread David Long
From: Russell King 

Commit 945aceb1db8885d3a35790cf2e810f681db52756 upstream.

Call the per-processor type check_bugs() method in the same way as we
do other per-processor functions - move the "processor." detail into
proc-fns.h.

Reviewed-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/include/asm/proc-fns.h | 1 +
 arch/arm/kernel/bugs.c  | 4 ++--
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index f379f5f849a9..19939e88efca 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -99,6 +99,7 @@ extern void cpu_do_suspend(void *);
 extern void cpu_do_resume(void *);
 #else
 #define cpu_proc_init  processor._proc_init
+#define cpu_check_bugs processor.check_bugs
 #define cpu_proc_fin   processor._proc_fin
 #define cpu_reset  processor.reset
 #define cpu_do_idleprocessor._do_idle
diff --git a/arch/arm/kernel/bugs.c b/arch/arm/kernel/bugs.c
index 7be511310191..d41d3598e5e5 100644
--- a/arch/arm/kernel/bugs.c
+++ b/arch/arm/kernel/bugs.c
@@ -6,8 +6,8 @@
 void check_other_bugs(void)
 {
 #ifdef MULTI_CPU
-   if (processor.check_bugs)
-   processor.check_bugs();
+   if (cpu_check_bugs)
+   cpu_check_bugs();
 #endif
 }
 
-- 
2.17.1



[PATCH 4.9 14/16] ARM: spectre-v2: per-CPU vtables to work around big.Little systems

2019-02-14 Thread David Long
From: Russell King 

Commit 383fb3ee8024d596f488d2dbaf45e572897acbdb upstream.

In big.Little systems, some CPUs require the Spectre workarounds in
paths such as the context switch, but other CPUs do not.  In order
to handle these differences, we need per-CPU vtables.

We are unable to use the kernel's per-CPU variables to support this
as per-CPU is not initialised at times when we need access to the
vtables, so we have to use an array indexed by logical CPU number.

We use an array-of-pointers to avoid having function pointers in
the kernel's read/write .data section.

Note: Added include of linux/slab.h in arch/arm/smp.c.

Reviewed-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/include/asm/proc-fns.h | 23 +++
 arch/arm/kernel/setup.c |  5 +
 arch/arm/kernel/smp.c   | 32 
 arch/arm/mm/proc-v7-bugs.c  | 17 ++---
 4 files changed, 62 insertions(+), 15 deletions(-)

diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index a1a71b068edc..1bfcc3bcfc6d 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -104,12 +104,35 @@ extern void cpu_do_resume(void *);
 #else
 
 extern struct processor processor;
+#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+#include 
+/*
+ * This can't be a per-cpu variable because we need to access it before
+ * per-cpu has been initialised.  We have a couple of functions that are
+ * called in a pre-emptible context, and so can't use smp_processor_id()
+ * there, hence PROC_TABLE().  We insist in init_proc_vtable() that the
+ * function pointers for these are identical across all CPUs.
+ */
+extern struct processor *cpu_vtable[];
+#define PROC_VTABLE(f) cpu_vtable[smp_processor_id()]->f
+#define PROC_TABLE(f)  cpu_vtable[0]->f
+static inline void init_proc_vtable(const struct processor *p)
+{
+   unsigned int cpu = smp_processor_id();
+   *cpu_vtable[cpu] = *p;
+   WARN_ON_ONCE(cpu_vtable[cpu]->dcache_clean_area !=
+cpu_vtable[0]->dcache_clean_area);
+   WARN_ON_ONCE(cpu_vtable[cpu]->set_pte_ext !=
+cpu_vtable[0]->set_pte_ext);
+}
+#else
 #define PROC_VTABLE(f) processor.f
 #define PROC_TABLE(f)  processor.f
 static inline void init_proc_vtable(const struct processor *p)
 {
processor = *p;
 }
+#endif
 
 #define cpu_proc_init  PROC_VTABLE(_proc_init)
 #define cpu_check_bugs PROC_VTABLE(check_bugs)
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 2eebb67fa08b..4764742db7b0 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -115,6 +115,11 @@ EXPORT_SYMBOL(elf_hwcap2);
 
 #ifdef MULTI_CPU
 struct processor processor __ro_after_init;
+#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+struct processor *cpu_vtable[NR_CPUS] = {
+   [0] = ,
+};
+#endif
 #endif
 #ifdef MULTI_TLB
 struct cpu_tlb_fns cpu_tlb __ro_after_init;
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 4b129aac7233..8faf869e9fb2 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -40,6 +41,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -100,6 +102,30 @@ static unsigned long get_arch_pgd(pgd_t *pgd)
 #endif
 }
 
+#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+static int secondary_biglittle_prepare(unsigned int cpu)
+{
+   if (!cpu_vtable[cpu])
+   cpu_vtable[cpu] = kzalloc(sizeof(*cpu_vtable[cpu]), GFP_KERNEL);
+
+   return cpu_vtable[cpu] ? 0 : -ENOMEM;
+}
+
+static void secondary_biglittle_init(void)
+{
+   init_proc_vtable(lookup_processor(read_cpuid_id())->proc);
+}
+#else
+static int secondary_biglittle_prepare(unsigned int cpu)
+{
+   return 0;
+}
+
+static void secondary_biglittle_init(void)
+{
+}
+#endif
+
 int __cpu_up(unsigned int cpu, struct task_struct *idle)
 {
int ret;
@@ -107,6 +133,10 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
if (!smp_ops.smp_boot_secondary)
return -ENOSYS;
 
+   ret = secondary_biglittle_prepare(cpu);
+   if (ret)
+   return ret;
+
/*
 * We need to tell the secondary core where to find
 * its stack and the page tables.
@@ -358,6 +388,8 @@ asmlinkage void secondary_start_kernel(void)
struct mm_struct *mm = _mm;
unsigned int cpu;
 
+   secondary_biglittle_init();
+
/*
 * The identity mapping is uncached (strongly ordered), so
 * switch away from it before attempting any exclusive accesses.
diff --git a/arch/arm/mm/proc-v7-bugs.c b/arch/arm/mm/proc-v7-bugs.c
index 5544b82a2e7a..9a07916af8dd 100644
--- 

[PATCH 4.9 16/16] ARM: fix the cockup in the previous patch

2019-02-14 Thread David Long
From: Russell King 

Commit d6951f582cc50ba0ad22ef46b599740966599b14 upstream.

The intention in the previous patch was to only place the processor
tables in the .rodata section if big.Little was being built and we
wanted the branch target hardening, but instead (due to the way it
was tested) it ended up always placing the tables into the .rodata
section.

Although harmless, let's correct this anyway.

Fixes: 3a4d0c2172bc ("ARM: ensure that processor vtables is not lost after 
boot")
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/mm/proc-macros.S | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index 7be1d7921342..f8bb65032b79 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -279,7 +279,7 @@
  * If we are building for big.Little with branch predictor hardening,
  * we need the processor function tables to remain available after boot.
  */
-#if 1 // defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
.section ".rodata"
 #endif
.type   \name\()_processor_functions, #object
@@ -317,7 +317,7 @@ ENTRY(\name\()_processor_functions)
.endif
 
.size   \name\()_processor_functions, . - \name\()_processor_functions
-#if 1 // defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
.previous
 #endif
 .endm
-- 
2.17.1



[PATCH 4.9 00/16] V4.9 backport of more 32-bit arm spectre patches

2019-02-14 Thread David Long
From: "David A. Long" 

V4.9 backport of spectre patches from Russell M. King's spectre branch.
Patches have been kvm-unit-test'ed on an arndale, run through kernelci, and
handed off to ARM for functional testing.

Julien Thierry (9):
  ARM: 8789/1: signal: copy registers using __copy_to_user()
  ARM: 8791/1: vfp: use __copy_to_user() when saving VFP state
  ARM: 8792/1: oabi-compat: copy oabi events using __copy_to_user()
  ARM: 8793/1: signal: replace __put_user_error with __put_user
  ARM: 8794/1: uaccess: Prevent speculative use of the current
addr_limit
  ARM: 8795/1: spectre-v1.1: use put_user() for __put_user()
  ARM: 8796/1: spectre-v1,v1.1: provide helpers for address sanitization
  ARM: 8797/1: spectre-v1.1: harden __copy_to_user
  ARM: 8810/1: vfp: Fix wrong assignement to ufp_exc

Russell King (7):
  ARM: make lookup_processor_type() non-__init
  ARM: split out processor lookup
  ARM: clean up per-processor check_bugs method call
  ARM: add PROC_VTABLE and PROC_TABLE macros
  ARM: spectre-v2: per-CPU vtables to work around big.Little systems
  ARM: ensure that processor vtables is not lost after boot
  ARM: fix the cockup in the previous patch

 arch/arm/include/asm/assembler.h   | 11 +
 arch/arm/include/asm/cputype.h |  1 +
 arch/arm/include/asm/proc-fns.h| 61 +-
 arch/arm/include/asm/thread_info.h |  4 +-
 arch/arm/include/asm/uaccess.h | 49 ++---
 arch/arm/kernel/bugs.c |  4 +-
 arch/arm/kernel/head-common.S  |  6 +--
 arch/arm/kernel/setup.c| 40 ++---
 arch/arm/kernel/signal.c   | 70 --
 arch/arm/kernel/smp.c  | 32 ++
 arch/arm/kernel/sys_oabi-compat.c  |  8 +++-
 arch/arm/lib/copy_from_user.S  |  6 +--
 arch/arm/lib/copy_to_user.S|  6 ++-
 arch/arm/lib/uaccess_with_memcpy.c |  3 +-
 arch/arm/mm/proc-macros.S  | 10 +
 arch/arm/mm/proc-v7-bugs.c | 17 +---
 arch/arm/vfp/vfpmodule.c   | 20 -
 17 files changed, 240 insertions(+), 108 deletions(-)

-- 
2.17.1



[PATCH 4.9 15/16] ARM: ensure that processor vtables is not lost after boot

2019-02-14 Thread David Long
From: Russell King 

Commit 3a4d0c2172bcf15b7a3d9d498b2b355f9864286b upstream.

Marek Szyprowski reported problems with CPU hotplug in current kernels.
This was tracked down to the processor vtables being located in an
init section, and therefore discarded after kernel boot, despite being
required after boot to properly initialise the non-boot CPUs.

Arrange for these tables to end up in .rodata when required.

Reported-by: Marek Szyprowski 
Tested-by: Krzysztof Kozlowski 
Fixes: 383fb3ee8024 ("ARM: spectre-v2: per-CPU vtables to work around 
big.Little systems")
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/mm/proc-macros.S | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index 7d9176c4a21d..7be1d7921342 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -275,6 +275,13 @@
.endm
 
 .macro define_processor_functions name:req, dabort:req, pabort:req, nommu=0, 
suspend=0, bugs=0
+/*
+ * If we are building for big.Little with branch predictor hardening,
+ * we need the processor function tables to remain available after boot.
+ */
+#if 1 // defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+   .section ".rodata"
+#endif
.type   \name\()_processor_functions, #object
.align 2
 ENTRY(\name\()_processor_functions)
@@ -310,6 +317,9 @@ ENTRY(\name\()_processor_functions)
.endif
 
.size   \name\()_processor_functions, . - \name\()_processor_functions
+#if 1 // defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+   .previous
+#endif
 .endm
 
 .macro define_cache_functions name:req
-- 
2.17.1



[PATCH 4.9 01/16] ARM: 8789/1: signal: copy registers using __copy_to_user()

2019-02-14 Thread David Long
From: Julien Thierry 

Commit 5ca451cf6ed04443774bbb7ee45332dafa42e99f upstream.

When saving the ARM integer registers, use __copy_to_user() to
copy them into user signal frame, rather than __put_user_error().
This has the benefit of disabling/enabling PAN once for the whole copy
intead of once per write.

Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/kernel/signal.c | 49 ++--
 1 file changed, 27 insertions(+), 22 deletions(-)

diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 6bee5c9b1133..fbb325ff8acc 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -256,30 +256,35 @@ static int
 setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set)
 {
struct aux_sigframe __user *aux;
+   struct sigcontext context;
int err = 0;
 
-   __put_user_error(regs->ARM_r0, >uc.uc_mcontext.arm_r0, err);
-   __put_user_error(regs->ARM_r1, >uc.uc_mcontext.arm_r1, err);
-   __put_user_error(regs->ARM_r2, >uc.uc_mcontext.arm_r2, err);
-   __put_user_error(regs->ARM_r3, >uc.uc_mcontext.arm_r3, err);
-   __put_user_error(regs->ARM_r4, >uc.uc_mcontext.arm_r4, err);
-   __put_user_error(regs->ARM_r5, >uc.uc_mcontext.arm_r5, err);
-   __put_user_error(regs->ARM_r6, >uc.uc_mcontext.arm_r6, err);
-   __put_user_error(regs->ARM_r7, >uc.uc_mcontext.arm_r7, err);
-   __put_user_error(regs->ARM_r8, >uc.uc_mcontext.arm_r8, err);
-   __put_user_error(regs->ARM_r9, >uc.uc_mcontext.arm_r9, err);
-   __put_user_error(regs->ARM_r10, >uc.uc_mcontext.arm_r10, err);
-   __put_user_error(regs->ARM_fp, >uc.uc_mcontext.arm_fp, err);
-   __put_user_error(regs->ARM_ip, >uc.uc_mcontext.arm_ip, err);
-   __put_user_error(regs->ARM_sp, >uc.uc_mcontext.arm_sp, err);
-   __put_user_error(regs->ARM_lr, >uc.uc_mcontext.arm_lr, err);
-   __put_user_error(regs->ARM_pc, >uc.uc_mcontext.arm_pc, err);
-   __put_user_error(regs->ARM_cpsr, >uc.uc_mcontext.arm_cpsr, err);
-
-   __put_user_error(current->thread.trap_no, >uc.uc_mcontext.trap_no, 
err);
-   __put_user_error(current->thread.error_code, 
>uc.uc_mcontext.error_code, err);
-   __put_user_error(current->thread.address, 
>uc.uc_mcontext.fault_address, err);
-   __put_user_error(set->sig[0], >uc.uc_mcontext.oldmask, err);
+   context = (struct sigcontext) {
+   .arm_r0= regs->ARM_r0,
+   .arm_r1= regs->ARM_r1,
+   .arm_r2= regs->ARM_r2,
+   .arm_r3= regs->ARM_r3,
+   .arm_r4= regs->ARM_r4,
+   .arm_r5= regs->ARM_r5,
+   .arm_r6= regs->ARM_r6,
+   .arm_r7= regs->ARM_r7,
+   .arm_r8= regs->ARM_r8,
+   .arm_r9= regs->ARM_r9,
+   .arm_r10   = regs->ARM_r10,
+   .arm_fp= regs->ARM_fp,
+   .arm_ip= regs->ARM_ip,
+   .arm_sp= regs->ARM_sp,
+   .arm_lr= regs->ARM_lr,
+   .arm_pc= regs->ARM_pc,
+   .arm_cpsr  = regs->ARM_cpsr,
+
+   .trap_no   = current->thread.trap_no,
+   .error_code= current->thread.error_code,
+   .fault_address = current->thread.address,
+   .oldmask   = set->sig[0],
+   };
+
+   err |= __copy_to_user(>uc.uc_mcontext, , sizeof(context));
 
err |= __copy_to_user(>uc.uc_sigmask, set, sizeof(*set));
 
-- 
2.17.1



[PATCH 4.9 04/16] ARM: 8793/1: signal: replace __put_user_error with __put_user

2019-02-14 Thread David Long
From: Julien Thierry 

Commit 18ea66bd6e7a95bdc598223d72757190916af28b upstream.

With Spectre-v1.1 mitigations, __put_user_error is pointless. In an attempt
to remove it, replace its references in frame setups with __put_user.

Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/kernel/signal.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 135b1a8e12eb..0a066f03b5ec 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -302,7 +302,7 @@ setup_sigframe(struct sigframe __user *sf, struct pt_regs 
*regs, sigset_t *set)
if (err == 0)
err |= preserve_vfp_context(>vfp);
 #endif
-   __put_user_error(0, >end_magic, err);
+   err |= __put_user(0, >end_magic);
 
return err;
 }
@@ -434,7 +434,7 @@ setup_frame(struct ksignal *ksig, sigset_t *set, struct 
pt_regs *regs)
/*
 * Set uc.uc_flags to a value which sc.trap_no would never have.
 */
-   __put_user_error(0x5ac3c35a, >uc.uc_flags, err);
+   err = __put_user(0x5ac3c35a, >uc.uc_flags);
 
err |= setup_sigframe(frame, regs, set);
if (err == 0)
@@ -454,8 +454,8 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct 
pt_regs *regs)
 
err |= copy_siginfo_to_user(>info, >info);
 
-   __put_user_error(0, >sig.uc.uc_flags, err);
-   __put_user_error(NULL, >sig.uc.uc_link, err);
+   err |= __put_user(0, >sig.uc.uc_flags);
+   err |= __put_user(NULL, >sig.uc.uc_link);
 
err |= __save_altstack(>sig.uc.uc_stack, regs->ARM_sp);
err |= setup_sigframe(>sig, regs, set);
-- 
2.17.1



[PATCH 4.14 V2 01/17] ARM: 8789/1: signal: copy registers using __copy_to_user()

2019-02-13 Thread David Long
From: Julien Thierry 

Commit 5ca451cf6ed04443774bbb7ee45332dafa42e99f upstream.

When saving the ARM integer registers, use __copy_to_user() to
copy them into user signal frame, rather than __put_user_error().
This has the benefit of disabling/enabling PAN once for the whole copy
intead of once per write.

Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/kernel/signal.c | 49 ++--
 1 file changed, 27 insertions(+), 22 deletions(-)

diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index cdfe52b15a0a..1dc1f39825b6 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -296,30 +296,35 @@ static int
 setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set)
 {
struct aux_sigframe __user *aux;
+   struct sigcontext context;
int err = 0;
 
-   __put_user_error(regs->ARM_r0, >uc.uc_mcontext.arm_r0, err);
-   __put_user_error(regs->ARM_r1, >uc.uc_mcontext.arm_r1, err);
-   __put_user_error(regs->ARM_r2, >uc.uc_mcontext.arm_r2, err);
-   __put_user_error(regs->ARM_r3, >uc.uc_mcontext.arm_r3, err);
-   __put_user_error(regs->ARM_r4, >uc.uc_mcontext.arm_r4, err);
-   __put_user_error(regs->ARM_r5, >uc.uc_mcontext.arm_r5, err);
-   __put_user_error(regs->ARM_r6, >uc.uc_mcontext.arm_r6, err);
-   __put_user_error(regs->ARM_r7, >uc.uc_mcontext.arm_r7, err);
-   __put_user_error(regs->ARM_r8, >uc.uc_mcontext.arm_r8, err);
-   __put_user_error(regs->ARM_r9, >uc.uc_mcontext.arm_r9, err);
-   __put_user_error(regs->ARM_r10, >uc.uc_mcontext.arm_r10, err);
-   __put_user_error(regs->ARM_fp, >uc.uc_mcontext.arm_fp, err);
-   __put_user_error(regs->ARM_ip, >uc.uc_mcontext.arm_ip, err);
-   __put_user_error(regs->ARM_sp, >uc.uc_mcontext.arm_sp, err);
-   __put_user_error(regs->ARM_lr, >uc.uc_mcontext.arm_lr, err);
-   __put_user_error(regs->ARM_pc, >uc.uc_mcontext.arm_pc, err);
-   __put_user_error(regs->ARM_cpsr, >uc.uc_mcontext.arm_cpsr, err);
-
-   __put_user_error(current->thread.trap_no, >uc.uc_mcontext.trap_no, 
err);
-   __put_user_error(current->thread.error_code, 
>uc.uc_mcontext.error_code, err);
-   __put_user_error(current->thread.address, 
>uc.uc_mcontext.fault_address, err);
-   __put_user_error(set->sig[0], >uc.uc_mcontext.oldmask, err);
+   context = (struct sigcontext) {
+   .arm_r0= regs->ARM_r0,
+   .arm_r1= regs->ARM_r1,
+   .arm_r2= regs->ARM_r2,
+   .arm_r3= regs->ARM_r3,
+   .arm_r4= regs->ARM_r4,
+   .arm_r5= regs->ARM_r5,
+   .arm_r6= regs->ARM_r6,
+   .arm_r7= regs->ARM_r7,
+   .arm_r8= regs->ARM_r8,
+   .arm_r9= regs->ARM_r9,
+   .arm_r10   = regs->ARM_r10,
+   .arm_fp= regs->ARM_fp,
+   .arm_ip= regs->ARM_ip,
+   .arm_sp= regs->ARM_sp,
+   .arm_lr= regs->ARM_lr,
+   .arm_pc= regs->ARM_pc,
+   .arm_cpsr  = regs->ARM_cpsr,
+
+   .trap_no   = current->thread.trap_no,
+   .error_code= current->thread.error_code,
+   .fault_address = current->thread.address,
+   .oldmask   = set->sig[0],
+   };
+
+   err |= __copy_to_user(>uc.uc_mcontext, , sizeof(context));
 
err |= __copy_to_user(>uc.uc_sigmask, set, sizeof(*set));
 
-- 
2.17.1



[PATCH 4.14 V2 05/17] ARM: 8793/1: signal: replace __put_user_error with __put_user

2019-02-13 Thread David Long
From: Julien Thierry 

Commit 18ea66bd6e7a95bdc598223d72757190916af28b upstream.

With Spectre-v1.1 mitigations, __put_user_error is pointless. In an attempt
to remove it, replace its references in frame setups with __put_user.

Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/kernel/signal.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 1eb83ee7e1cc..02e6b6dfffa7 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -344,7 +344,7 @@ setup_sigframe(struct sigframe __user *sf, struct pt_regs 
*regs, sigset_t *set)
if (err == 0)
err |= preserve_vfp_context(>vfp);
 #endif
-   __put_user_error(0, >end_magic, err);
+   err |= __put_user(0, >end_magic);
 
return err;
 }
@@ -476,7 +476,7 @@ setup_frame(struct ksignal *ksig, sigset_t *set, struct 
pt_regs *regs)
/*
 * Set uc.uc_flags to a value which sc.trap_no would never have.
 */
-   __put_user_error(0x5ac3c35a, >uc.uc_flags, err);
+   err = __put_user(0x5ac3c35a, >uc.uc_flags);
 
err |= setup_sigframe(frame, regs, set);
if (err == 0)
@@ -496,8 +496,8 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct 
pt_regs *regs)
 
err |= copy_siginfo_to_user(>info, >info);
 
-   __put_user_error(0, >sig.uc.uc_flags, err);
-   __put_user_error(NULL, >sig.uc.uc_link, err);
+   err |= __put_user(0, >sig.uc.uc_flags);
+   err |= __put_user(NULL, >sig.uc.uc_link);
 
err |= __save_altstack(>sig.uc.uc_stack, regs->ARM_sp);
err |= setup_sigframe(>sig, regs, set);
-- 
2.17.1



[PATCH 4.14 V2 06/17] ARM: 8794/1: uaccess: Prevent speculative use of the current addr_limit

2019-02-13 Thread David Long
From: Julien Thierry 

Commit 621afc677465db231662ed126ae1f355bf8eac47 upstream.

A mispredicted conditional call to set_fs could result in the wrong
addr_limit being forwarded under speculation to a subsequent access_ok
check, potentially forming part of a spectre-v1 attack using uaccess
routines.

This patch prevents this forwarding from taking place, but putting heavy
barriers in set_fs after writing the addr_limit.

Porting commit c2f0ad4fc089cff8 ("arm64: uaccess: Prevent speculative use
of the current addr_limit").

Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/include/asm/uaccess.h | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 4140be431087..7d19584f5c39 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -69,6 +69,14 @@ extern int __put_user_bad(void);
 static inline void set_fs(mm_segment_t fs)
 {
current_thread_info()->addr_limit = fs;
+
+   /*
+* Prevent a mispredicted conditional call to set_fs from forwarding
+* the wrong address limit to access_ok under speculation.
+*/
+   dsb(nsh);
+   isb();
+
modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_CLIENT : DOMAIN_MANAGER);
 }
 
-- 
2.17.1



[PATCH 4.14 V2 07/17] ARM: 8795/1: spectre-v1.1: use put_user() for __put_user()

2019-02-13 Thread David Long
From: Julien Thierry 

Commit e3aa6243434fd9a82e84bb79ab1abd14f2d9a5a7 upstream.

When Spectre mitigation is required, __put_user() needs to include
check_uaccess. This is already the case for put_user(), so just make
__put_user() an alias of put_user().

Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/include/asm/uaccess.h | 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 7d19584f5c39..cf50b030c62c 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -370,6 +370,14 @@ do {   
\
__pu_err;   \
 })
 
+#ifdef CONFIG_CPU_SPECTRE
+/*
+ * When mitigating Spectre variant 1.1, all accessors need to include
+ * verification of the address space.
+ */
+#define __put_user(x, ptr) put_user(x, ptr)
+
+#else
 #define __put_user(x, ptr) \
 ({ \
long __pu_err = 0;  \
@@ -377,12 +385,6 @@ do {   
\
__pu_err;   \
 })
 
-#define __put_user_error(x, ptr, err)  \
-({ \
-   __put_user_switch((x), (ptr), (err), __put_user_nocheck);   \
-   (void) 0;   \
-})
-
 #define __put_user_nocheck(x, __pu_ptr, __err, __size) \
do {\
unsigned long __pu_addr = (unsigned long)__pu_ptr;  \
@@ -462,6 +464,7 @@ do {
\
: "r" (x), "i" (-EFAULT)\
: "cc")
 
+#endif /* !CONFIG_CPU_SPECTRE */
 
 #ifdef CONFIG_MMU
 extern unsigned long __must_check
-- 
2.17.1



[PATCH 4.14 V2 12/17] ARM: split out processor lookup

2019-02-13 Thread David Long
From: Russell King 

Commit 65987a8553061515b5851b472081aedb9837a391 upstream.

Split out the lookup of the processor type and associated error handling
from the rest of setup_processor() - we will need to use this in the
secondary CPU bringup path for big.Little Spectre variant 2 mitigation.

Reviewed-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/include/asm/cputype.h |  1 +
 arch/arm/kernel/setup.c| 31 +++
 2 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
index 3379c2c684c2..25d523185c6a 100644
--- a/arch/arm/include/asm/cputype.h
+++ b/arch/arm/include/asm/cputype.h
@@ -107,6 +107,7 @@
 #define ARM_CPU_PART_SCORPION  0x510002d0
 
 extern unsigned int processor_id;
+struct proc_info_list *lookup_processor(u32 midr);
 
 #ifdef CONFIG_CPU_CP15
 #define read_cpuid(reg)
\
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 8e9a3e40d949..1a041ad4881e 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -667,22 +667,29 @@ static void __init smp_build_mpidr_hash(void)
 }
 #endif
 
-static void __init setup_processor(void)
+/*
+ * locate processor in the list of supported processor types.  The linker
+ * builds this table for us from the entries in arch/arm/mm/proc-*.S
+ */
+struct proc_info_list *lookup_processor(u32 midr)
 {
-   struct proc_info_list *list;
+   struct proc_info_list *list = lookup_processor_type(midr);
 
-   /*
-* locate processor in the list of supported processor
-* types.  The linker builds this table for us from the
-* entries in arch/arm/mm/proc-*.S
-*/
-   list = lookup_processor_type(read_cpuid_id());
if (!list) {
-   pr_err("CPU configuration botched (ID %08x), unable to 
continue.\n",
-  read_cpuid_id());
-   while (1);
+   pr_err("CPU%u: configuration botched (ID %08x), CPU halted\n",
+  smp_processor_id(), midr);
+   while (1)
+   /* can't use cpu_relax() here as it may require MMU setup */;
}
 
+   return list;
+}
+
+static void __init setup_processor(void)
+{
+   unsigned int midr = read_cpuid_id();
+   struct proc_info_list *list = lookup_processor(midr);
+
cpu_name = list->cpu_name;
__cpu_architecture = __get_cpu_architecture();
 
@@ -700,7 +707,7 @@ static void __init setup_processor(void)
 #endif
 
pr_info("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n",
-   cpu_name, read_cpuid_id(), read_cpuid_id() & 15,
+   list->cpu_name, midr, midr & 15,
proc_arch[cpu_architecture()], get_cr());
 
snprintf(init_utsname()->machine, __NEW_UTS_LEN + 1, "%s%c",
-- 
2.17.1



[PATCH 4.14 V2 04/17] ARM: 8792/1: oabi-compat: copy oabi events using __copy_to_user()

2019-02-13 Thread David Long
From: Julien Thierry 

Commit 319508902600c2688e057750148487996396e9ca upstream.

Copy events to user using __copy_to_user() rather than copy members of
individually with __put_user_error().
This has the benefit of disabling/enabling PAN once per event intead of
once per event member.

Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/kernel/sys_oabi-compat.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/arm/kernel/sys_oabi-compat.c 
b/arch/arm/kernel/sys_oabi-compat.c
index 4abe4909417f..a87684532327 100644
--- a/arch/arm/kernel/sys_oabi-compat.c
+++ b/arch/arm/kernel/sys_oabi-compat.c
@@ -277,6 +277,7 @@ asmlinkage long sys_oabi_epoll_wait(int epfd,
int maxevents, int timeout)
 {
struct epoll_event *kbuf;
+   struct oabi_epoll_event e;
mm_segment_t fs;
long ret, err, i;
 
@@ -295,8 +296,11 @@ asmlinkage long sys_oabi_epoll_wait(int epfd,
set_fs(fs);
err = 0;
for (i = 0; i < ret; i++) {
-   __put_user_error(kbuf[i].events, >events, err);
-   __put_user_error(kbuf[i].data,   >data,   err);
+   e.events = kbuf[i].events;
+   e.data = kbuf[i].data;
+   err = __copy_to_user(events, , sizeof(e));
+   if (err)
+   break;
events++;
}
kfree(kbuf);
-- 
2.17.1



[PATCH 4.14 V2 10/17] ARM: 8810/1: vfp: Fix wrong assignement to ufp_exc

2019-02-13 Thread David Long
From: Julien Thierry 

Commit 5df7a99bdd0de4a0480320264c44c04543c29d5a upstream.

In vfp_preserve_user_clear_hwstate, ufp_exc->fpinst2 gets assigned to
itself. It should actually be hwstate->fpinst2 that gets assigned to the
ufp_exc field.

Fixes commit 3aa2df6ec2ca6bc143a65351cca4266d03a8bc41 ("ARM: 8791/1:
vfp: use __copy_to_user() when saving VFP state").

Reported-by: David Binderman 
Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/vfp/vfpmodule.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 6bacd69c9e81..8e11223d32a1 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -579,7 +579,7 @@ int vfp_preserve_user_clear_hwstate(struct user_vfp *ufp,
 */
ufp_exc->fpexc = hwstate->fpexc;
ufp_exc->fpinst = hwstate->fpinst;
-   ufp_exc->fpinst2 = ufp_exc->fpinst2;
+   ufp_exc->fpinst2 = hwstate->fpinst2;
 
/* Ensure that VFP is disabled. */
vfp_flush_hwstate(thread);
-- 
2.17.1



[PATCH 4.14 V2 03/17] ARM: 8791/1: vfp: use __copy_to_user() when saving VFP state

2019-02-13 Thread David Long
From: Julien Thierry 

Commit 3aa2df6ec2ca6bc143a65351cca4266d03a8bc41 upstream.

Use __copy_to_user() rather than __put_user_error() for individual
members when saving VFP state.
This has the benefit of disabling/enabling PAN once per copied struct
intead of once per write.

Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/include/asm/thread_info.h |  4 ++--
 arch/arm/kernel/signal.c   | 13 +++--
 arch/arm/vfp/vfpmodule.c   | 20 
 3 files changed, 17 insertions(+), 20 deletions(-)

diff --git a/arch/arm/include/asm/thread_info.h 
b/arch/arm/include/asm/thread_info.h
index 57d2ad9c75ca..df8420672c7e 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -124,8 +124,8 @@ extern void vfp_flush_hwstate(struct thread_info *);
 struct user_vfp;
 struct user_vfp_exc;
 
-extern int vfp_preserve_user_clear_hwstate(struct user_vfp __user *,
-  struct user_vfp_exc __user *);
+extern int vfp_preserve_user_clear_hwstate(struct user_vfp *,
+  struct user_vfp_exc *);
 extern int vfp_restore_user_hwstate(struct user_vfp *,
struct user_vfp_exc *);
 #endif
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index b12499cc3582..1eb83ee7e1cc 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -136,17 +136,18 @@ static int restore_iwmmxt_context(char __user **auxp)
 
 static int preserve_vfp_context(struct vfp_sigframe __user *frame)
 {
-   const unsigned long magic = VFP_MAGIC;
-   const unsigned long size = VFP_STORAGE_SIZE;
+   struct vfp_sigframe kframe;
int err = 0;
 
-   __put_user_error(magic, >magic, err);
-   __put_user_error(size, >size, err);
+   memset(, 0, sizeof(kframe));
+   kframe.magic = VFP_MAGIC;
+   kframe.size = VFP_STORAGE_SIZE;
 
+   err = vfp_preserve_user_clear_hwstate(, _exc);
if (err)
-   return -EFAULT;
+   return err;
 
-   return vfp_preserve_user_clear_hwstate(>ufp, >ufp_exc);
+   return __copy_to_user(frame, , sizeof(kframe));
 }
 
 static int restore_vfp_context(char __user **auxp)
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 6abcd4af8274..6bacd69c9e81 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -554,12 +554,11 @@ void vfp_flush_hwstate(struct thread_info *thread)
  * Save the current VFP state into the provided structures and prepare
  * for entry into a new function (signal handler).
  */
-int vfp_preserve_user_clear_hwstate(struct user_vfp __user *ufp,
-   struct user_vfp_exc __user *ufp_exc)
+int vfp_preserve_user_clear_hwstate(struct user_vfp *ufp,
+   struct user_vfp_exc *ufp_exc)
 {
struct thread_info *thread = current_thread_info();
struct vfp_hard_struct *hwstate = >vfpstate.hard;
-   int err = 0;
 
/* Ensure that the saved hwstate is up-to-date. */
vfp_sync_hwstate(thread);
@@ -568,22 +567,19 @@ int vfp_preserve_user_clear_hwstate(struct user_vfp 
__user *ufp,
 * Copy the floating point registers. There can be unused
 * registers see asm/hwcap.h for details.
 */
-   err |= __copy_to_user(>fpregs, >fpregs,
- sizeof(hwstate->fpregs));
+   memcpy(>fpregs, >fpregs, sizeof(hwstate->fpregs));
+
/*
 * Copy the status and control register.
 */
-   __put_user_error(hwstate->fpscr, >fpscr, err);
+   ufp->fpscr = hwstate->fpscr;
 
/*
 * Copy the exception registers.
 */
-   __put_user_error(hwstate->fpexc, _exc->fpexc, err);
-   __put_user_error(hwstate->fpinst, _exc->fpinst, err);
-   __put_user_error(hwstate->fpinst2, _exc->fpinst2, err);
-
-   if (err)
-   return -EFAULT;
+   ufp_exc->fpexc = hwstate->fpexc;
+   ufp_exc->fpinst = hwstate->fpinst;
+   ufp_exc->fpinst2 = ufp_exc->fpinst2;
 
/* Ensure that VFP is disabled. */
vfp_flush_hwstate(thread);
-- 
2.17.1



[PATCH 4.14 V2 16/17] ARM: ensure that processor vtables is not lost after boot

2019-02-13 Thread David Long
From: Russell King 

Commit 3a4d0c2172bcf15b7a3d9d498b2b355f9864286b upstream.

Marek Szyprowski reported problems with CPU hotplug in current kernels.
This was tracked down to the processor vtables being located in an
init section, and therefore discarded after kernel boot, despite being
required after boot to properly initialise the non-boot CPUs.

Arrange for these tables to end up in .rodata when required.

Reported-by: Marek Szyprowski 
Tested-by: Krzysztof Kozlowski 
Fixes: 383fb3ee8024 ("ARM: spectre-v2: per-CPU vtables to work around 
big.Little systems")
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/mm/proc-macros.S | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index 81d0efb055c6..19516fbc2c55 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -274,6 +274,13 @@
.endm
 
 .macro define_processor_functions name:req, dabort:req, pabort:req, nommu=0, 
suspend=0, bugs=0
+/*
+ * If we are building for big.Little with branch predictor hardening,
+ * we need the processor function tables to remain available after boot.
+ */
+#if 1 // defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+   .section ".rodata"
+#endif
.type   \name\()_processor_functions, #object
.align 2
 ENTRY(\name\()_processor_functions)
@@ -309,6 +316,9 @@ ENTRY(\name\()_processor_functions)
.endif
 
.size   \name\()_processor_functions, . - \name\()_processor_functions
+#if 1 // defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+   .previous
+#endif
 .endm
 
 .macro define_cache_functions name:req
-- 
2.17.1



[PATCH 4.14 V2 08/17] ARM: 8796/1: spectre-v1,v1.1: provide helpers for address sanitization

2019-02-13 Thread David Long
From: Julien Thierry 

Commit afaf6838f4bc896a711180b702b388b8cfa638fc upstream.

Introduce C and asm helpers to sanitize user address, taking the
address range they target into account.

Use asm helper for existing sanitization in __copy_from_user().

Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/include/asm/assembler.h | 11 +++
 arch/arm/include/asm/uaccess.h   | 26 ++
 arch/arm/lib/copy_from_user.S|  6 +-
 3 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index b17ee03d280b..88286dd483ff 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -467,6 +467,17 @@ THUMB( orr \reg , \reg , #PSR_T_BIT)
 #endif
.endm
 
+   .macro uaccess_mask_range_ptr, addr:req, size:req, limit:req, tmp:req
+#ifdef CONFIG_CPU_SPECTRE
+   sub \tmp, \limit, #1
+   subs\tmp, \tmp, \addr   @ tmp = limit - 1 - addr
+   addhs   \tmp, \tmp, #1  @ if (tmp >= 0) {
+   subhss  \tmp, \tmp, \size   @ tmp = limit - (addr + size) }
+   movlo   \addr, #0   @ if (tmp < 0) addr = NULL
+   csdb
+#endif
+   .endm
+
.macro  uaccess_disable, tmp, isb=1
 #ifdef CONFIG_CPU_SW_DOMAIN_PAN
/*
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index cf50b030c62c..a5807b67ca8a 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -99,6 +99,32 @@ static inline void set_fs(mm_segment_t fs)
 #define __inttype(x) \
__typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
 
+/*
+ * Sanitise a uaccess pointer such that it becomes NULL if addr+size
+ * is above the current addr_limit.
+ */
+#define uaccess_mask_range_ptr(ptr, size)  \
+   ((__typeof__(ptr))__uaccess_mask_range_ptr(ptr, size))
+static inline void __user *__uaccess_mask_range_ptr(const void __user *ptr,
+   size_t size)
+{
+   void __user *safe_ptr = (void __user *)ptr;
+   unsigned long tmp;
+
+   asm volatile(
+   "   sub %1, %3, #1\n"
+   "   subs%1, %1, %0\n"
+   "   addhs   %1, %1, #1\n"
+   "   subhss  %1, %1, %2\n"
+   "   movlo   %0, #0\n"
+   : "+r" (safe_ptr), "=" (tmp)
+   : "r" (size), "r" (current_thread_info()->addr_limit)
+   : "cc");
+
+   csdb();
+   return safe_ptr;
+}
+
 /*
  * Single-value transfer routines.  They automatically use the right
  * size if we just have the right pointer type.  Note that the functions
diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S
index a826df3d3814..6709a8d33963 100644
--- a/arch/arm/lib/copy_from_user.S
+++ b/arch/arm/lib/copy_from_user.S
@@ -93,11 +93,7 @@ ENTRY(arm_copy_from_user)
 #ifdef CONFIG_CPU_SPECTRE
get_thread_info r3
ldr r3, [r3, #TI_ADDR_LIMIT]
-   addsip, r1, r2  @ ip=addr+size
-   sub r3, r3, #1  @ addr_limit - 1
-   cmpcc   ip, r3  @ if (addr+size > addr_limit - 1)
-   movcs   r1, #0  @ addr = NULL
-   csdb
+   uaccess_mask_range_ptr r1, r2, r3, ip
 #endif
 
 #include "copy_template.S"
-- 
2.17.1



[PATCH 4.14 V2 14/17] ARM: add PROC_VTABLE and PROC_TABLE macros

2019-02-13 Thread David Long
From: Russell King 

Commit e209950fdd065d2cc46e6338e47e52841b830cba upstream.

Allow the way we access members of the processor vtable to be changed
at compile time.  We will need to move to per-CPU vtables to fix the
Spectre variant 2 issues on big.Little systems.

However, we have a couple of calls that do not need the vtable
treatment, and indeed cause a kernel warning due to the (later) use
of smp_processor_id(), so also introduce the PROC_TABLE macro for
these which always use CPU 0's function pointers.

Reviewed-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/include/asm/proc-fns.h | 39 ++---
 arch/arm/kernel/setup.c |  4 +---
 2 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index 30c499146320..c259cc49c641 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -23,7 +23,7 @@ struct mm_struct;
 /*
  * Don't change this structure - ASM code relies on it.
  */
-extern struct processor {
+struct processor {
/* MISC
 * get data abort address/flags
 */
@@ -79,9 +79,13 @@ extern struct processor {
unsigned int suspend_size;
void (*do_suspend)(void *);
void (*do_resume)(void *);
-} processor;
+};
 
 #ifndef MULTI_CPU
+static inline void init_proc_vtable(const struct processor *p)
+{
+}
+
 extern void cpu_proc_init(void);
 extern void cpu_proc_fin(void);
 extern int cpu_do_idle(void);
@@ -98,18 +102,27 @@ extern void cpu_reset(unsigned long addr, bool hvc) 
__attribute__((noreturn));
 extern void cpu_do_suspend(void *);
 extern void cpu_do_resume(void *);
 #else
-#define cpu_proc_init  processor._proc_init
-#define cpu_check_bugs processor.check_bugs
-#define cpu_proc_fin   processor._proc_fin
-#define cpu_reset  processor.reset
-#define cpu_do_idleprocessor._do_idle
-#define cpu_dcache_clean_area  processor.dcache_clean_area
-#define cpu_set_pte_extprocessor.set_pte_ext
-#define cpu_do_switch_mm   processor.switch_mm
 
-/* These three are private to arch/arm/kernel/suspend.c */
-#define cpu_do_suspend processor.do_suspend
-#define cpu_do_resume  processor.do_resume
+extern struct processor processor;
+#define PROC_VTABLE(f) processor.f
+#define PROC_TABLE(f)  processor.f
+static inline void init_proc_vtable(const struct processor *p)
+{
+   processor = *p;
+}
+
+#define cpu_proc_init  PROC_VTABLE(_proc_init)
+#define cpu_check_bugs PROC_VTABLE(check_bugs)
+#define cpu_proc_fin   PROC_VTABLE(_proc_fin)
+#define cpu_reset  PROC_VTABLE(reset)
+#define cpu_do_idlePROC_VTABLE(_do_idle)
+#define cpu_dcache_clean_area  PROC_TABLE(dcache_clean_area)
+#define cpu_set_pte_extPROC_TABLE(set_pte_ext)
+#define cpu_do_switch_mm   PROC_VTABLE(switch_mm)
+
+/* These two are private to arch/arm/kernel/suspend.c */
+#define cpu_do_suspend PROC_VTABLE(do_suspend)
+#define cpu_do_resume  PROC_VTABLE(do_resume)
 #endif
 
 extern void cpu_resume(void);
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 1a041ad4881e..c1588e31aa83 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -693,9 +693,7 @@ static void __init setup_processor(void)
cpu_name = list->cpu_name;
__cpu_architecture = __get_cpu_architecture();
 
-#ifdef MULTI_CPU
-   processor = *list->proc;
-#endif
+   init_proc_vtable(list->proc);
 #ifdef MULTI_TLB
cpu_tlb = *list->tlb;
 #endif
-- 
2.17.1



[PATCH 4.14 V2 13/17] ARM: clean up per-processor check_bugs method call

2019-02-13 Thread David Long
From: Russell King 

Commit 945aceb1db8885d3a35790cf2e810f681db52756 upstream.

Call the per-processor type check_bugs() method in the same way as we
do other per-processor functions - move the "processor." detail into
proc-fns.h.

Reviewed-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/include/asm/proc-fns.h | 1 +
 arch/arm/kernel/bugs.c  | 4 ++--
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index e25f4392e1b2..30c499146320 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -99,6 +99,7 @@ extern void cpu_do_suspend(void *);
 extern void cpu_do_resume(void *);
 #else
 #define cpu_proc_init  processor._proc_init
+#define cpu_check_bugs processor.check_bugs
 #define cpu_proc_fin   processor._proc_fin
 #define cpu_reset  processor.reset
 #define cpu_do_idleprocessor._do_idle
diff --git a/arch/arm/kernel/bugs.c b/arch/arm/kernel/bugs.c
index 7be511310191..d41d3598e5e5 100644
--- a/arch/arm/kernel/bugs.c
+++ b/arch/arm/kernel/bugs.c
@@ -6,8 +6,8 @@
 void check_other_bugs(void)
 {
 #ifdef MULTI_CPU
-   if (processor.check_bugs)
-   processor.check_bugs();
+   if (cpu_check_bugs)
+   cpu_check_bugs();
 #endif
 }
 
-- 
2.17.1



[PATCH 4.14 V2 11/17] ARM: make lookup_processor_type() non-__init

2019-02-13 Thread David Long
From: Russell King 

Commit 899a42f836678a595f7d2bc36a5a0c2b03d08cbc upstream.

Move lookup_processor_type() out of the __init section so it is callable
from (eg) the secondary startup code during hotplug.

Reviewed-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/kernel/head-common.S | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
index 8733012d231f..7e662bdd5cb3 100644
--- a/arch/arm/kernel/head-common.S
+++ b/arch/arm/kernel/head-common.S
@@ -122,6 +122,9 @@ __mmap_switched_data:
.long   init_thread_union + THREAD_START_SP @ sp
.size   __mmap_switched_data, . - __mmap_switched_data
 
+   __FINIT
+   .text
+
 /*
  * This provides a C-API version of __lookup_processor_type
  */
@@ -133,9 +136,6 @@ ENTRY(lookup_processor_type)
ldmfd   sp!, {r4 - r6, r9, pc}
 ENDPROC(lookup_processor_type)
 
-   __FINIT
-   .text
-
 /*
  * Read processor ID register (CP#15, CR0), and look up in the linker-built
  * supported processor list.  Note that we can't use the absolute addresses
-- 
2.17.1



[PATCH 4.14 V2 15/17] ARM: spectre-v2: per-CPU vtables to work around big.Little systems

2019-02-13 Thread David Long
From: Russell King 

Commit 383fb3ee8024d596f488d2dbaf45e572897acbdb upstream.

In big.Little systems, some CPUs require the Spectre workarounds in
paths such as the context switch, but other CPUs do not.  In order
to handle these differences, we need per-CPU vtables.

We are unable to use the kernel's per-CPU variables to support this
as per-CPU is not initialised at times when we need access to the
vtables, so we have to use an array indexed by logical CPU number.

We use an array-of-pointers to avoid having function pointers in
the kernel's read/write .data section.

Reviewed-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/include/asm/proc-fns.h | 23 +++
 arch/arm/kernel/setup.c |  5 +
 arch/arm/kernel/smp.c   | 31 +++
 arch/arm/mm/proc-v7-bugs.c  | 17 ++---
 4 files changed, 61 insertions(+), 15 deletions(-)

diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index c259cc49c641..e1b6f280ab08 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -104,12 +104,35 @@ extern void cpu_do_resume(void *);
 #else
 
 extern struct processor processor;
+#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+#include 
+/*
+ * This can't be a per-cpu variable because we need to access it before
+ * per-cpu has been initialised.  We have a couple of functions that are
+ * called in a pre-emptible context, and so can't use smp_processor_id()
+ * there, hence PROC_TABLE().  We insist in init_proc_vtable() that the
+ * function pointers for these are identical across all CPUs.
+ */
+extern struct processor *cpu_vtable[];
+#define PROC_VTABLE(f) cpu_vtable[smp_processor_id()]->f
+#define PROC_TABLE(f)  cpu_vtable[0]->f
+static inline void init_proc_vtable(const struct processor *p)
+{
+   unsigned int cpu = smp_processor_id();
+   *cpu_vtable[cpu] = *p;
+   WARN_ON_ONCE(cpu_vtable[cpu]->dcache_clean_area !=
+cpu_vtable[0]->dcache_clean_area);
+   WARN_ON_ONCE(cpu_vtable[cpu]->set_pte_ext !=
+cpu_vtable[0]->set_pte_ext);
+}
+#else
 #define PROC_VTABLE(f) processor.f
 #define PROC_TABLE(f)  processor.f
 static inline void init_proc_vtable(const struct processor *p)
 {
processor = *p;
 }
+#endif
 
 #define cpu_proc_init  PROC_VTABLE(_proc_init)
 #define cpu_check_bugs PROC_VTABLE(check_bugs)
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index c1588e31aa83..a6d27284105a 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -115,6 +115,11 @@ EXPORT_SYMBOL(elf_hwcap2);
 
 #ifdef MULTI_CPU
 struct processor processor __ro_after_init;
+#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+struct processor *cpu_vtable[NR_CPUS] = {
+   [0] = ,
+};
+#endif
 #endif
 #ifdef MULTI_TLB
 struct cpu_tlb_fns cpu_tlb __ro_after_init;
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 5e31c62127a0..f57333f46242 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -42,6 +42,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -102,6 +103,30 @@ static unsigned long get_arch_pgd(pgd_t *pgd)
 #endif
 }
 
+#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+static int secondary_biglittle_prepare(unsigned int cpu)
+{
+   if (!cpu_vtable[cpu])
+   cpu_vtable[cpu] = kzalloc(sizeof(*cpu_vtable[cpu]), GFP_KERNEL);
+
+   return cpu_vtable[cpu] ? 0 : -ENOMEM;
+}
+
+static void secondary_biglittle_init(void)
+{
+   init_proc_vtable(lookup_processor(read_cpuid_id())->proc);
+}
+#else
+static int secondary_biglittle_prepare(unsigned int cpu)
+{
+   return 0;
+}
+
+static void secondary_biglittle_init(void)
+{
+}
+#endif
+
 int __cpu_up(unsigned int cpu, struct task_struct *idle)
 {
int ret;
@@ -109,6 +134,10 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
if (!smp_ops.smp_boot_secondary)
return -ENOSYS;
 
+   ret = secondary_biglittle_prepare(cpu);
+   if (ret)
+   return ret;
+
/*
 * We need to tell the secondary core where to find
 * its stack and the page tables.
@@ -360,6 +389,8 @@ asmlinkage void secondary_start_kernel(void)
struct mm_struct *mm = _mm;
unsigned int cpu;
 
+   secondary_biglittle_init();
+
/*
 * The identity mapping is uncached (strongly ordered), so
 * switch away from it before attempting any exclusive accesses.
diff --git a/arch/arm/mm/proc-v7-bugs.c b/arch/arm/mm/proc-v7-bugs.c
index 5544b82a2e7a..9a07916af8dd 100644
--- a/arch/arm/mm/proc-v7-bugs.c
+++ b/arch/arm/mm/proc-v7-bugs.c
@@ -52,8 +52,6 @@ static void cpu_v7_spectre_init(void)
case 

[PATCH 4.14 V2 00/17] V4.14 backport of more 32-bit arm spectre patches

2019-02-13 Thread David Long
From: "David A. Long" 

V4.14 backport of spectre patches from Russell M. King's spectre branch.
Patches have been kvm-unit-test'ed on an arndale, run through kernelci, and
handed off to ARM for functional testing.

Julien Thierry (10):
  ARM: 8789/1: signal: copy registers using __copy_to_user()
  ARM: 8790/1: signal: always use __copy_to_user to save iwmmxt context
  ARM: 8791/1: vfp: use __copy_to_user() when saving VFP state
  ARM: 8792/1: oabi-compat: copy oabi events using __copy_to_user()
  ARM: 8793/1: signal: replace __put_user_error with __put_user
  ARM: 8794/1: uaccess: Prevent speculative use of the current
addr_limit
  ARM: 8795/1: spectre-v1.1: use put_user() for __put_user()
  ARM: 8796/1: spectre-v1,v1.1: provide helpers for address sanitization
  ARM: 8797/1: spectre-v1.1: harden __copy_to_user
  ARM: 8810/1: vfp: Fix wrong assignement to ufp_exc

Russell King (7):
  ARM: make lookup_processor_type() non-__init
  ARM: split out processor lookup
  ARM: clean up per-processor check_bugs method call
  ARM: add PROC_VTABLE and PROC_TABLE macros
  ARM: spectre-v2: per-CPU vtables to work around big.Little systems
  ARM: ensure that processor vtables is not lost after boot
  ARM: fix the cockup in the previous patch

 arch/arm/include/asm/assembler.h   | 11 
 arch/arm/include/asm/cputype.h |  1 +
 arch/arm/include/asm/proc-fns.h| 61 ++-
 arch/arm/include/asm/thread_info.h |  4 +-
 arch/arm/include/asm/uaccess.h | 49 +++---
 arch/arm/kernel/bugs.c |  4 +-
 arch/arm/kernel/head-common.S  |  6 +--
 arch/arm/kernel/setup.c| 40 +--
 arch/arm/kernel/signal.c   | 80 --
 arch/arm/kernel/smp.c  | 31 
 arch/arm/kernel/sys_oabi-compat.c  |  8 ++-
 arch/arm/lib/copy_from_user.S  |  6 +--
 arch/arm/lib/copy_to_user.S|  6 ++-
 arch/arm/lib/uaccess_with_memcpy.c |  3 +-
 arch/arm/mm/proc-macros.S  | 10 
 arch/arm/mm/proc-v7-bugs.c | 17 +--
 arch/arm/vfp/vfpmodule.c   | 20 +++-
 17 files changed, 245 insertions(+), 112 deletions(-)

-- 
2.17.1



[PATCH 4.14 V2 02/17] ARM: 8790/1: signal: always use __copy_to_user to save iwmmxt context

2019-02-13 Thread David Long
From: Julien Thierry 

Commit 73839798af7ebc6c8d0c9271ebbbc148700e521f upstream.

When setting a dummy iwmmxt context, create a local instance and
use __copy_to_user both cases whether iwmmxt is being used or not.
This has the benefit of disabling/enabling PAN once for the whole copy
intead of once per write.

Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/kernel/signal.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 1dc1f39825b6..b12499cc3582 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -76,8 +76,6 @@ static int preserve_iwmmxt_context(struct iwmmxt_sigframe 
__user *frame)
kframe->magic = IWMMXT_MAGIC;
kframe->size = IWMMXT_STORAGE_SIZE;
iwmmxt_task_copy(current_thread_info(), >storage);
-
-   err = __copy_to_user(frame, kframe, sizeof(*frame));
} else {
/*
 * For bug-compatibility with older kernels, some space
@@ -85,10 +83,14 @@ static int preserve_iwmmxt_context(struct iwmmxt_sigframe 
__user *frame)
 * Set the magic and size appropriately so that properly
 * written userspace can skip it reliably:
 */
-   __put_user_error(DUMMY_MAGIC, >magic, err);
-   __put_user_error(IWMMXT_STORAGE_SIZE, >size, err);
+   *kframe = (struct iwmmxt_sigframe) {
+   .magic = DUMMY_MAGIC,
+   .size  = IWMMXT_STORAGE_SIZE,
+   };
}
 
+   err = __copy_to_user(frame, kframe, sizeof(*kframe));
+
return err;
 }
 
-- 
2.17.1



[PATCH 4.14 V2 09/17] ARM: 8797/1: spectre-v1.1: harden __copy_to_user

2019-02-13 Thread David Long
From: Julien Thierry 

Commit a1d09e074250fad24f1b993f327b18cc6812eb7a upstream.

Sanitize user pointer given to __copy_to_user, both for standard version
and memcopy version of the user accessor.

Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/lib/copy_to_user.S| 6 +-
 arch/arm/lib/uaccess_with_memcpy.c | 3 ++-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S
index caf5019d8161..970abe521197 100644
--- a/arch/arm/lib/copy_to_user.S
+++ b/arch/arm/lib/copy_to_user.S
@@ -94,6 +94,11 @@
 
 ENTRY(__copy_to_user_std)
 WEAK(arm_copy_to_user)
+#ifdef CONFIG_CPU_SPECTRE
+   get_thread_info r3
+   ldr r3, [r3, #TI_ADDR_LIMIT]
+   uaccess_mask_range_ptr r0, r2, r3, ip
+#endif
 
 #include "copy_template.S"
 
@@ -108,4 +113,3 @@ ENDPROC(__copy_to_user_std)
rsb r0, r0, r2
copy_abort_end
.popsection
-
diff --git a/arch/arm/lib/uaccess_with_memcpy.c 
b/arch/arm/lib/uaccess_with_memcpy.c
index 9b4ed1728616..73dc7360cbdd 100644
--- a/arch/arm/lib/uaccess_with_memcpy.c
+++ b/arch/arm/lib/uaccess_with_memcpy.c
@@ -152,7 +152,8 @@ arm_copy_to_user(void __user *to, const void *from, 
unsigned long n)
n = __copy_to_user_std(to, from, n);
uaccess_restore(ua_flags);
} else {
-   n = __copy_to_user_memcpy(to, from, n);
+   n = __copy_to_user_memcpy(uaccess_mask_range_ptr(to, n),
+ from, n);
}
return n;
 }
-- 
2.17.1



[PATCH 4.14 V2 17/17] ARM: fix the cockup in the previous patch

2019-02-13 Thread David Long
From: Russell King 

Commit d6951f582cc50ba0ad22ef46b599740966599b14 upstream.

The intention in the previous patch was to only place the processor
tables in the .rodata section if big.Little was being built and we
wanted the branch target hardening, but instead (due to the way it
was tested) it ended up always placing the tables into the .rodata
section.

Although harmless, let's correct this anyway.

Fixes: 3a4d0c2172bc ("ARM: ensure that processor vtables is not lost after 
boot")
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/mm/proc-macros.S | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index 19516fbc2c55..5461d589a1e2 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -278,7 +278,7 @@
  * If we are building for big.Little with branch predictor hardening,
  * we need the processor function tables to remain available after boot.
  */
-#if 1 // defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
.section ".rodata"
 #endif
.type   \name\()_processor_functions, #object
@@ -316,7 +316,7 @@ ENTRY(\name\()_processor_functions)
.endif
 
.size   \name\()_processor_functions, . - \name\()_processor_functions
-#if 1 // defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
.previous
 #endif
 .endm
-- 
2.17.1



[PATCH 4.19 01/17] ARM: 8789/1: signal: copy registers using __copy_to_user()

2019-02-13 Thread David Long
From: Julien Thierry 

Commit 5ca451cf6ed04443774bbb7ee45332dafa42e99f upstream.

When saving the ARM integer registers, use __copy_to_user() to
copy them into user signal frame, rather than __put_user_error().
This has the benefit of disabling/enabling PAN once for the whole copy
intead of once per write.

Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/kernel/signal.c | 49 ++--
 1 file changed, 27 insertions(+), 22 deletions(-)

diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index b8f766cf3a90..76fe75d36312 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -288,30 +288,35 @@ static int
 setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set)
 {
struct aux_sigframe __user *aux;
+   struct sigcontext context;
int err = 0;
 
-   __put_user_error(regs->ARM_r0, >uc.uc_mcontext.arm_r0, err);
-   __put_user_error(regs->ARM_r1, >uc.uc_mcontext.arm_r1, err);
-   __put_user_error(regs->ARM_r2, >uc.uc_mcontext.arm_r2, err);
-   __put_user_error(regs->ARM_r3, >uc.uc_mcontext.arm_r3, err);
-   __put_user_error(regs->ARM_r4, >uc.uc_mcontext.arm_r4, err);
-   __put_user_error(regs->ARM_r5, >uc.uc_mcontext.arm_r5, err);
-   __put_user_error(regs->ARM_r6, >uc.uc_mcontext.arm_r6, err);
-   __put_user_error(regs->ARM_r7, >uc.uc_mcontext.arm_r7, err);
-   __put_user_error(regs->ARM_r8, >uc.uc_mcontext.arm_r8, err);
-   __put_user_error(regs->ARM_r9, >uc.uc_mcontext.arm_r9, err);
-   __put_user_error(regs->ARM_r10, >uc.uc_mcontext.arm_r10, err);
-   __put_user_error(regs->ARM_fp, >uc.uc_mcontext.arm_fp, err);
-   __put_user_error(regs->ARM_ip, >uc.uc_mcontext.arm_ip, err);
-   __put_user_error(regs->ARM_sp, >uc.uc_mcontext.arm_sp, err);
-   __put_user_error(regs->ARM_lr, >uc.uc_mcontext.arm_lr, err);
-   __put_user_error(regs->ARM_pc, >uc.uc_mcontext.arm_pc, err);
-   __put_user_error(regs->ARM_cpsr, >uc.uc_mcontext.arm_cpsr, err);
-
-   __put_user_error(current->thread.trap_no, >uc.uc_mcontext.trap_no, 
err);
-   __put_user_error(current->thread.error_code, 
>uc.uc_mcontext.error_code, err);
-   __put_user_error(current->thread.address, 
>uc.uc_mcontext.fault_address, err);
-   __put_user_error(set->sig[0], >uc.uc_mcontext.oldmask, err);
+   context = (struct sigcontext) {
+   .arm_r0= regs->ARM_r0,
+   .arm_r1= regs->ARM_r1,
+   .arm_r2= regs->ARM_r2,
+   .arm_r3= regs->ARM_r3,
+   .arm_r4= regs->ARM_r4,
+   .arm_r5= regs->ARM_r5,
+   .arm_r6= regs->ARM_r6,
+   .arm_r7= regs->ARM_r7,
+   .arm_r8= regs->ARM_r8,
+   .arm_r9= regs->ARM_r9,
+   .arm_r10   = regs->ARM_r10,
+   .arm_fp= regs->ARM_fp,
+   .arm_ip= regs->ARM_ip,
+   .arm_sp= regs->ARM_sp,
+   .arm_lr= regs->ARM_lr,
+   .arm_pc= regs->ARM_pc,
+   .arm_cpsr  = regs->ARM_cpsr,
+
+   .trap_no   = current->thread.trap_no,
+   .error_code= current->thread.error_code,
+   .fault_address = current->thread.address,
+   .oldmask   = set->sig[0],
+   };
+
+   err |= __copy_to_user(>uc.uc_mcontext, , sizeof(context));
 
err |= __copy_to_user(>uc.uc_sigmask, set, sizeof(*set));
 
-- 
2.17.1



[PATCH 4.19 07/17] ARM: 8795/1: spectre-v1.1: use put_user() for __put_user()

2019-02-13 Thread David Long
From: Julien Thierry 

Commit e3aa6243434fd9a82e84bb79ab1abd14f2d9a5a7 upstream.

When Spectre mitigation is required, __put_user() needs to include
check_uaccess. This is already the case for put_user(), so just make
__put_user() an alias of put_user().

Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/include/asm/uaccess.h | 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index d65ef85fc617..1191e7da8fab 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -370,6 +370,14 @@ do {   
\
__pu_err;   \
 })
 
+#ifdef CONFIG_CPU_SPECTRE
+/*
+ * When mitigating Spectre variant 1.1, all accessors need to include
+ * verification of the address space.
+ */
+#define __put_user(x, ptr) put_user(x, ptr)
+
+#else
 #define __put_user(x, ptr) \
 ({ \
long __pu_err = 0;  \
@@ -377,12 +385,6 @@ do {   
\
__pu_err;   \
 })
 
-#define __put_user_error(x, ptr, err)  \
-({ \
-   __put_user_switch((x), (ptr), (err), __put_user_nocheck);   \
-   (void) 0;   \
-})
-
 #define __put_user_nocheck(x, __pu_ptr, __err, __size) \
do {\
unsigned long __pu_addr = (unsigned long)__pu_ptr;  \
@@ -462,6 +464,7 @@ do {
\
: "r" (x), "i" (-EFAULT)\
: "cc")
 
+#endif /* !CONFIG_CPU_SPECTRE */
 
 #ifdef CONFIG_MMU
 extern unsigned long __must_check
-- 
2.17.1



[PATCH 4.19 03/17] ARM: 8791/1: vfp: use __copy_to_user() when saving VFP state

2019-02-13 Thread David Long
From: Julien Thierry 

Commit 3aa2df6ec2ca6bc143a65351cca4266d03a8bc41 upstream.

Use __copy_to_user() rather than __put_user_error() for individual
members when saving VFP state.
This has the benefit of disabling/enabling PAN once per copied struct
intead of once per write.

Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/include/asm/thread_info.h |  4 ++--
 arch/arm/kernel/signal.c   | 13 +++--
 arch/arm/vfp/vfpmodule.c   | 20 
 3 files changed, 17 insertions(+), 20 deletions(-)

diff --git a/arch/arm/include/asm/thread_info.h 
b/arch/arm/include/asm/thread_info.h
index 9b37b6ab27fe..8f55dc520a3e 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -121,8 +121,8 @@ extern void vfp_flush_hwstate(struct thread_info *);
 struct user_vfp;
 struct user_vfp_exc;
 
-extern int vfp_preserve_user_clear_hwstate(struct user_vfp __user *,
-  struct user_vfp_exc __user *);
+extern int vfp_preserve_user_clear_hwstate(struct user_vfp *,
+  struct user_vfp_exc *);
 extern int vfp_restore_user_hwstate(struct user_vfp *,
struct user_vfp_exc *);
 #endif
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 464393d241e1..1e2ecfe080bb 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -137,17 +137,18 @@ static int restore_iwmmxt_context(char __user **auxp)
 
 static int preserve_vfp_context(struct vfp_sigframe __user *frame)
 {
-   const unsigned long magic = VFP_MAGIC;
-   const unsigned long size = VFP_STORAGE_SIZE;
+   struct vfp_sigframe kframe;
int err = 0;
 
-   __put_user_error(magic, >magic, err);
-   __put_user_error(size, >size, err);
+   memset(, 0, sizeof(kframe));
+   kframe.magic = VFP_MAGIC;
+   kframe.size = VFP_STORAGE_SIZE;
 
+   err = vfp_preserve_user_clear_hwstate(, _exc);
if (err)
-   return -EFAULT;
+   return err;
 
-   return vfp_preserve_user_clear_hwstate(>ufp, >ufp_exc);
+   return __copy_to_user(frame, , sizeof(kframe));
 }
 
 static int restore_vfp_context(char __user **auxp)
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index dc7e6b50ef67..2b287d0d6bc2 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -553,12 +553,11 @@ void vfp_flush_hwstate(struct thread_info *thread)
  * Save the current VFP state into the provided structures and prepare
  * for entry into a new function (signal handler).
  */
-int vfp_preserve_user_clear_hwstate(struct user_vfp __user *ufp,
-   struct user_vfp_exc __user *ufp_exc)
+int vfp_preserve_user_clear_hwstate(struct user_vfp *ufp,
+   struct user_vfp_exc *ufp_exc)
 {
struct thread_info *thread = current_thread_info();
struct vfp_hard_struct *hwstate = >vfpstate.hard;
-   int err = 0;
 
/* Ensure that the saved hwstate is up-to-date. */
vfp_sync_hwstate(thread);
@@ -567,22 +566,19 @@ int vfp_preserve_user_clear_hwstate(struct user_vfp 
__user *ufp,
 * Copy the floating point registers. There can be unused
 * registers see asm/hwcap.h for details.
 */
-   err |= __copy_to_user(>fpregs, >fpregs,
- sizeof(hwstate->fpregs));
+   memcpy(>fpregs, >fpregs, sizeof(hwstate->fpregs));
+
/*
 * Copy the status and control register.
 */
-   __put_user_error(hwstate->fpscr, >fpscr, err);
+   ufp->fpscr = hwstate->fpscr;
 
/*
 * Copy the exception registers.
 */
-   __put_user_error(hwstate->fpexc, _exc->fpexc, err);
-   __put_user_error(hwstate->fpinst, _exc->fpinst, err);
-   __put_user_error(hwstate->fpinst2, _exc->fpinst2, err);
-
-   if (err)
-   return -EFAULT;
+   ufp_exc->fpexc = hwstate->fpexc;
+   ufp_exc->fpinst = hwstate->fpinst;
+   ufp_exc->fpinst2 = ufp_exc->fpinst2;
 
/* Ensure that VFP is disabled. */
vfp_flush_hwstate(thread);
-- 
2.17.1



[PATCH 4.19 04/17] ARM: 8792/1: oabi-compat: copy oabi events using __copy_to_user()

2019-02-13 Thread David Long
From: Julien Thierry 

Commit 319508902600c2688e057750148487996396e9ca upstream.

Copy events to user using __copy_to_user() rather than copy members of
individually with __put_user_error().
This has the benefit of disabling/enabling PAN once per event intead of
once per event member.

Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/kernel/sys_oabi-compat.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/arm/kernel/sys_oabi-compat.c 
b/arch/arm/kernel/sys_oabi-compat.c
index f0dd4b6ebb63..40da0872170f 100644
--- a/arch/arm/kernel/sys_oabi-compat.c
+++ b/arch/arm/kernel/sys_oabi-compat.c
@@ -277,6 +277,7 @@ asmlinkage long sys_oabi_epoll_wait(int epfd,
int maxevents, int timeout)
 {
struct epoll_event *kbuf;
+   struct oabi_epoll_event e;
mm_segment_t fs;
long ret, err, i;
 
@@ -295,8 +296,11 @@ asmlinkage long sys_oabi_epoll_wait(int epfd,
set_fs(fs);
err = 0;
for (i = 0; i < ret; i++) {
-   __put_user_error(kbuf[i].events, >events, err);
-   __put_user_error(kbuf[i].data,   >data,   err);
+   e.events = kbuf[i].events;
+   e.data = kbuf[i].data;
+   err = __copy_to_user(events, , sizeof(e));
+   if (err)
+   break;
events++;
}
kfree(kbuf);
-- 
2.17.1



[PATCH 4.19 10/17] ARM: 8810/1: vfp: Fix wrong assignement to ufp_exc

2019-02-13 Thread David Long
From: Julien Thierry 

Commit 5df7a99bdd0de4a0480320264c44c04543c29d5a upstream.

In vfp_preserve_user_clear_hwstate, ufp_exc->fpinst2 gets assigned to
itself. It should actually be hwstate->fpinst2 that gets assigned to the
ufp_exc field.

Fixes commit 3aa2df6ec2ca6bc143a65351cca4266d03a8bc41 ("ARM: 8791/1:
vfp: use __copy_to_user() when saving VFP state").

Reported-by: David Binderman 
Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/vfp/vfpmodule.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 2b287d0d6bc2..66c5e693428a 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -578,7 +578,7 @@ int vfp_preserve_user_clear_hwstate(struct user_vfp *ufp,
 */
ufp_exc->fpexc = hwstate->fpexc;
ufp_exc->fpinst = hwstate->fpinst;
-   ufp_exc->fpinst2 = ufp_exc->fpinst2;
+   ufp_exc->fpinst2 = hwstate->fpinst2;
 
/* Ensure that VFP is disabled. */
vfp_flush_hwstate(thread);
-- 
2.17.1



[PATCH 4.19 05/17] ARM: 8793/1: signal: replace __put_user_error with __put_user

2019-02-13 Thread David Long
From: Julien Thierry 

Commit 18ea66bd6e7a95bdc598223d72757190916af28b upstream.

With Spectre-v1.1 mitigations, __put_user_error is pointless. In an attempt
to remove it, replace its references in frame setups with __put_user.

Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/kernel/signal.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 1e2ecfe080bb..b908382b69ff 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -336,7 +336,7 @@ setup_sigframe(struct sigframe __user *sf, struct pt_regs 
*regs, sigset_t *set)
if (err == 0)
err |= preserve_vfp_context(>vfp);
 #endif
-   __put_user_error(0, >end_magic, err);
+   err |= __put_user(0, >end_magic);
 
return err;
 }
@@ -499,7 +499,7 @@ setup_frame(struct ksignal *ksig, sigset_t *set, struct 
pt_regs *regs)
/*
 * Set uc.uc_flags to a value which sc.trap_no would never have.
 */
-   __put_user_error(0x5ac3c35a, >uc.uc_flags, err);
+   err = __put_user(0x5ac3c35a, >uc.uc_flags);
 
err |= setup_sigframe(frame, regs, set);
if (err == 0)
@@ -519,8 +519,8 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct 
pt_regs *regs)
 
err |= copy_siginfo_to_user(>info, >info);
 
-   __put_user_error(0, >sig.uc.uc_flags, err);
-   __put_user_error(NULL, >sig.uc.uc_link, err);
+   err |= __put_user(0, >sig.uc.uc_flags);
+   err |= __put_user(NULL, >sig.uc.uc_link);
 
err |= __save_altstack(>sig.uc.uc_stack, regs->ARM_sp);
err |= setup_sigframe(>sig, regs, set);
-- 
2.17.1



[PATCH 4.19 09/17] ARM: 8797/1: spectre-v1.1: harden __copy_to_user

2019-02-13 Thread David Long
From: Julien Thierry 

Commit a1d09e074250fad24f1b993f327b18cc6812eb7a upstream.

Sanitize user pointer given to __copy_to_user, both for standard version
and memcopy version of the user accessor.

Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/lib/copy_to_user.S| 6 +-
 arch/arm/lib/uaccess_with_memcpy.c | 3 ++-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S
index caf5019d8161..970abe521197 100644
--- a/arch/arm/lib/copy_to_user.S
+++ b/arch/arm/lib/copy_to_user.S
@@ -94,6 +94,11 @@
 
 ENTRY(__copy_to_user_std)
 WEAK(arm_copy_to_user)
+#ifdef CONFIG_CPU_SPECTRE
+   get_thread_info r3
+   ldr r3, [r3, #TI_ADDR_LIMIT]
+   uaccess_mask_range_ptr r0, r2, r3, ip
+#endif
 
 #include "copy_template.S"
 
@@ -108,4 +113,3 @@ ENDPROC(__copy_to_user_std)
rsb r0, r0, r2
copy_abort_end
.popsection
-
diff --git a/arch/arm/lib/uaccess_with_memcpy.c 
b/arch/arm/lib/uaccess_with_memcpy.c
index 9b4ed1728616..73dc7360cbdd 100644
--- a/arch/arm/lib/uaccess_with_memcpy.c
+++ b/arch/arm/lib/uaccess_with_memcpy.c
@@ -152,7 +152,8 @@ arm_copy_to_user(void __user *to, const void *from, 
unsigned long n)
n = __copy_to_user_std(to, from, n);
uaccess_restore(ua_flags);
} else {
-   n = __copy_to_user_memcpy(to, from, n);
+   n = __copy_to_user_memcpy(uaccess_mask_range_ptr(to, n),
+ from, n);
}
return n;
 }
-- 
2.17.1



[PATCH 4.19 08/17] ARM: 8796/1: spectre-v1,v1.1: provide helpers for address sanitization

2019-02-13 Thread David Long
From: Julien Thierry 

Commit afaf6838f4bc896a711180b702b388b8cfa638fc upstream.

Introduce C and asm helpers to sanitize user address, taking the
address range they target into account.

Use asm helper for existing sanitization in __copy_from_user().

Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/include/asm/assembler.h | 11 +++
 arch/arm/include/asm/uaccess.h   | 26 ++
 arch/arm/lib/copy_from_user.S|  6 +-
 3 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index b17ee03d280b..88286dd483ff 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -467,6 +467,17 @@ THUMB( orr \reg , \reg , #PSR_T_BIT)
 #endif
.endm
 
+   .macro uaccess_mask_range_ptr, addr:req, size:req, limit:req, tmp:req
+#ifdef CONFIG_CPU_SPECTRE
+   sub \tmp, \limit, #1
+   subs\tmp, \tmp, \addr   @ tmp = limit - 1 - addr
+   addhs   \tmp, \tmp, #1  @ if (tmp >= 0) {
+   subhss  \tmp, \tmp, \size   @ tmp = limit - (addr + size) }
+   movlo   \addr, #0   @ if (tmp < 0) addr = NULL
+   csdb
+#endif
+   .endm
+
.macro  uaccess_disable, tmp, isb=1
 #ifdef CONFIG_CPU_SW_DOMAIN_PAN
/*
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 1191e7da8fab..c136eef8f690 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -99,6 +99,32 @@ static inline void set_fs(mm_segment_t fs)
 #define __inttype(x) \
__typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
 
+/*
+ * Sanitise a uaccess pointer such that it becomes NULL if addr+size
+ * is above the current addr_limit.
+ */
+#define uaccess_mask_range_ptr(ptr, size)  \
+   ((__typeof__(ptr))__uaccess_mask_range_ptr(ptr, size))
+static inline void __user *__uaccess_mask_range_ptr(const void __user *ptr,
+   size_t size)
+{
+   void __user *safe_ptr = (void __user *)ptr;
+   unsigned long tmp;
+
+   asm volatile(
+   "   sub %1, %3, #1\n"
+   "   subs%1, %1, %0\n"
+   "   addhs   %1, %1, #1\n"
+   "   subhss  %1, %1, %2\n"
+   "   movlo   %0, #0\n"
+   : "+r" (safe_ptr), "=" (tmp)
+   : "r" (size), "r" (current_thread_info()->addr_limit)
+   : "cc");
+
+   csdb();
+   return safe_ptr;
+}
+
 /*
  * Single-value transfer routines.  They automatically use the right
  * size if we just have the right pointer type.  Note that the functions
diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S
index a826df3d3814..6709a8d33963 100644
--- a/arch/arm/lib/copy_from_user.S
+++ b/arch/arm/lib/copy_from_user.S
@@ -93,11 +93,7 @@ ENTRY(arm_copy_from_user)
 #ifdef CONFIG_CPU_SPECTRE
get_thread_info r3
ldr r3, [r3, #TI_ADDR_LIMIT]
-   addsip, r1, r2  @ ip=addr+size
-   sub r3, r3, #1  @ addr_limit - 1
-   cmpcc   ip, r3  @ if (addr+size > addr_limit - 1)
-   movcs   r1, #0  @ addr = NULL
-   csdb
+   uaccess_mask_range_ptr r1, r2, r3, ip
 #endif
 
 #include "copy_template.S"
-- 
2.17.1



[PATCH 4.19 14/17] ARM: add PROC_VTABLE and PROC_TABLE macros

2019-02-13 Thread David Long
From: Russell King 

Commit e209950fdd065d2cc46e6338e47e52841b830cba upstream.

Allow the way we access members of the processor vtable to be changed
at compile time.  We will need to move to per-CPU vtables to fix the
Spectre variant 2 issues on big.Little systems.

However, we have a couple of calls that do not need the vtable
treatment, and indeed cause a kernel warning due to the (later) use
of smp_processor_id(), so also introduce the PROC_TABLE macro for
these which always use CPU 0's function pointers.

Reviewed-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/include/asm/proc-fns.h | 39 ++---
 arch/arm/kernel/setup.c |  4 +---
 2 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index 30c499146320..c259cc49c641 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -23,7 +23,7 @@ struct mm_struct;
 /*
  * Don't change this structure - ASM code relies on it.
  */
-extern struct processor {
+struct processor {
/* MISC
 * get data abort address/flags
 */
@@ -79,9 +79,13 @@ extern struct processor {
unsigned int suspend_size;
void (*do_suspend)(void *);
void (*do_resume)(void *);
-} processor;
+};
 
 #ifndef MULTI_CPU
+static inline void init_proc_vtable(const struct processor *p)
+{
+}
+
 extern void cpu_proc_init(void);
 extern void cpu_proc_fin(void);
 extern int cpu_do_idle(void);
@@ -98,18 +102,27 @@ extern void cpu_reset(unsigned long addr, bool hvc) 
__attribute__((noreturn));
 extern void cpu_do_suspend(void *);
 extern void cpu_do_resume(void *);
 #else
-#define cpu_proc_init  processor._proc_init
-#define cpu_check_bugs processor.check_bugs
-#define cpu_proc_fin   processor._proc_fin
-#define cpu_reset  processor.reset
-#define cpu_do_idleprocessor._do_idle
-#define cpu_dcache_clean_area  processor.dcache_clean_area
-#define cpu_set_pte_extprocessor.set_pte_ext
-#define cpu_do_switch_mm   processor.switch_mm
 
-/* These three are private to arch/arm/kernel/suspend.c */
-#define cpu_do_suspend processor.do_suspend
-#define cpu_do_resume  processor.do_resume
+extern struct processor processor;
+#define PROC_VTABLE(f) processor.f
+#define PROC_TABLE(f)  processor.f
+static inline void init_proc_vtable(const struct processor *p)
+{
+   processor = *p;
+}
+
+#define cpu_proc_init  PROC_VTABLE(_proc_init)
+#define cpu_check_bugs PROC_VTABLE(check_bugs)
+#define cpu_proc_fin   PROC_VTABLE(_proc_fin)
+#define cpu_reset  PROC_VTABLE(reset)
+#define cpu_do_idlePROC_VTABLE(_do_idle)
+#define cpu_dcache_clean_area  PROC_TABLE(dcache_clean_area)
+#define cpu_set_pte_extPROC_TABLE(set_pte_ext)
+#define cpu_do_switch_mm   PROC_VTABLE(switch_mm)
+
+/* These two are private to arch/arm/kernel/suspend.c */
+#define cpu_do_suspend PROC_VTABLE(do_suspend)
+#define cpu_do_resume  PROC_VTABLE(do_resume)
 #endif
 
 extern void cpu_resume(void);
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 8fd7baa158a4..f269f4440496 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -693,9 +693,7 @@ static void __init setup_processor(void)
cpu_name = list->cpu_name;
__cpu_architecture = __get_cpu_architecture();
 
-#ifdef MULTI_CPU
-   processor = *list->proc;
-#endif
+   init_proc_vtable(list->proc);
 #ifdef MULTI_TLB
cpu_tlb = *list->tlb;
 #endif
-- 
2.17.1



[PATCH 4.19 15/17] ARM: spectre-v2: per-CPU vtables to work around big.Little systems

2019-02-13 Thread David Long
From: Russell King 

Commit 383fb3ee8024d596f488d2dbaf45e572897acbdb upstream.

In big.Little systems, some CPUs require the Spectre workarounds in
paths such as the context switch, but other CPUs do not.  In order
to handle these differences, we need per-CPU vtables.

We are unable to use the kernel's per-CPU variables to support this
as per-CPU is not initialised at times when we need access to the
vtables, so we have to use an array indexed by logical CPU number.

We use an array-of-pointers to avoid having function pointers in
the kernel's read/write .data section.

Reviewed-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/include/asm/proc-fns.h | 23 +++
 arch/arm/kernel/setup.c |  5 +
 arch/arm/kernel/smp.c   | 31 +++
 arch/arm/mm/proc-v7-bugs.c  | 17 ++---
 4 files changed, 61 insertions(+), 15 deletions(-)

diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index c259cc49c641..e1b6f280ab08 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -104,12 +104,35 @@ extern void cpu_do_resume(void *);
 #else
 
 extern struct processor processor;
+#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+#include 
+/*
+ * This can't be a per-cpu variable because we need to access it before
+ * per-cpu has been initialised.  We have a couple of functions that are
+ * called in a pre-emptible context, and so can't use smp_processor_id()
+ * there, hence PROC_TABLE().  We insist in init_proc_vtable() that the
+ * function pointers for these are identical across all CPUs.
+ */
+extern struct processor *cpu_vtable[];
+#define PROC_VTABLE(f) cpu_vtable[smp_processor_id()]->f
+#define PROC_TABLE(f)  cpu_vtable[0]->f
+static inline void init_proc_vtable(const struct processor *p)
+{
+   unsigned int cpu = smp_processor_id();
+   *cpu_vtable[cpu] = *p;
+   WARN_ON_ONCE(cpu_vtable[cpu]->dcache_clean_area !=
+cpu_vtable[0]->dcache_clean_area);
+   WARN_ON_ONCE(cpu_vtable[cpu]->set_pte_ext !=
+cpu_vtable[0]->set_pte_ext);
+}
+#else
 #define PROC_VTABLE(f) processor.f
 #define PROC_TABLE(f)  processor.f
 static inline void init_proc_vtable(const struct processor *p)
 {
processor = *p;
 }
+#endif
 
 #define cpu_proc_init  PROC_VTABLE(_proc_init)
 #define cpu_check_bugs PROC_VTABLE(check_bugs)
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index f269f4440496..7bbaa293a38c 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -115,6 +115,11 @@ EXPORT_SYMBOL(elf_hwcap2);
 
 #ifdef MULTI_CPU
 struct processor processor __ro_after_init;
+#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+struct processor *cpu_vtable[NR_CPUS] = {
+   [0] = ,
+};
+#endif
 #endif
 #ifdef MULTI_TLB
 struct cpu_tlb_fns cpu_tlb __ro_after_init;
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index f574a5e0d589..3bf82232b1be 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -42,6 +42,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -102,6 +103,30 @@ static unsigned long get_arch_pgd(pgd_t *pgd)
 #endif
 }
 
+#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+static int secondary_biglittle_prepare(unsigned int cpu)
+{
+   if (!cpu_vtable[cpu])
+   cpu_vtable[cpu] = kzalloc(sizeof(*cpu_vtable[cpu]), GFP_KERNEL);
+
+   return cpu_vtable[cpu] ? 0 : -ENOMEM;
+}
+
+static void secondary_biglittle_init(void)
+{
+   init_proc_vtable(lookup_processor(read_cpuid_id())->proc);
+}
+#else
+static int secondary_biglittle_prepare(unsigned int cpu)
+{
+   return 0;
+}
+
+static void secondary_biglittle_init(void)
+{
+}
+#endif
+
 int __cpu_up(unsigned int cpu, struct task_struct *idle)
 {
int ret;
@@ -109,6 +134,10 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
if (!smp_ops.smp_boot_secondary)
return -ENOSYS;
 
+   ret = secondary_biglittle_prepare(cpu);
+   if (ret)
+   return ret;
+
/*
 * We need to tell the secondary core where to find
 * its stack and the page tables.
@@ -359,6 +388,8 @@ asmlinkage void secondary_start_kernel(void)
struct mm_struct *mm = _mm;
unsigned int cpu;
 
+   secondary_biglittle_init();
+
/*
 * The identity mapping is uncached (strongly ordered), so
 * switch away from it before attempting any exclusive accesses.
diff --git a/arch/arm/mm/proc-v7-bugs.c b/arch/arm/mm/proc-v7-bugs.c
index 5544b82a2e7a..9a07916af8dd 100644
--- a/arch/arm/mm/proc-v7-bugs.c
+++ b/arch/arm/mm/proc-v7-bugs.c
@@ -52,8 +52,6 @@ static void cpu_v7_spectre_init(void)
case 

[PATCH 4.19 12/17] ARM: split out processor lookup

2019-02-13 Thread David Long
From: Russell King 

Commit 65987a8553061515b5851b472081aedb9837a391 upstream.

Split out the lookup of the processor type and associated error handling
from the rest of setup_processor() - we will need to use this in the
secondary CPU bringup path for big.Little Spectre variant 2 mitigation.

Reviewed-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/include/asm/cputype.h |  1 +
 arch/arm/kernel/setup.c| 31 +++
 2 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
index 0d289240b6ca..775cac3c02bb 100644
--- a/arch/arm/include/asm/cputype.h
+++ b/arch/arm/include/asm/cputype.h
@@ -111,6 +111,7 @@
 #include 
 
 extern unsigned int processor_id;
+struct proc_info_list *lookup_processor(u32 midr);
 
 #ifdef CONFIG_CPU_CP15
 #define read_cpuid(reg)
\
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 4c249cb261f3..8fd7baa158a4 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -667,22 +667,29 @@ static void __init smp_build_mpidr_hash(void)
 }
 #endif
 
-static void __init setup_processor(void)
+/*
+ * locate processor in the list of supported processor types.  The linker
+ * builds this table for us from the entries in arch/arm/mm/proc-*.S
+ */
+struct proc_info_list *lookup_processor(u32 midr)
 {
-   struct proc_info_list *list;
+   struct proc_info_list *list = lookup_processor_type(midr);
 
-   /*
-* locate processor in the list of supported processor
-* types.  The linker builds this table for us from the
-* entries in arch/arm/mm/proc-*.S
-*/
-   list = lookup_processor_type(read_cpuid_id());
if (!list) {
-   pr_err("CPU configuration botched (ID %08x), unable to 
continue.\n",
-  read_cpuid_id());
-   while (1);
+   pr_err("CPU%u: configuration botched (ID %08x), CPU halted\n",
+  smp_processor_id(), midr);
+   while (1)
+   /* can't use cpu_relax() here as it may require MMU setup */;
}
 
+   return list;
+}
+
+static void __init setup_processor(void)
+{
+   unsigned int midr = read_cpuid_id();
+   struct proc_info_list *list = lookup_processor(midr);
+
cpu_name = list->cpu_name;
__cpu_architecture = __get_cpu_architecture();
 
@@ -700,7 +707,7 @@ static void __init setup_processor(void)
 #endif
 
pr_info("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n",
-   cpu_name, read_cpuid_id(), read_cpuid_id() & 15,
+   list->cpu_name, midr, midr & 15,
proc_arch[cpu_architecture()], get_cr());
 
snprintf(init_utsname()->machine, __NEW_UTS_LEN + 1, "%s%c",
-- 
2.17.1



[PATCH 4.19 11/17] ARM: make lookup_processor_type() non-__init

2019-02-13 Thread David Long
From: Russell King 

Commit 899a42f836678a595f7d2bc36a5a0c2b03d08cbc upstream.

Move lookup_processor_type() out of the __init section so it is callable
from (eg) the secondary startup code during hotplug.

Reviewed-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/kernel/head-common.S | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
index 6e0375e7db05..997b02302c31 100644
--- a/arch/arm/kernel/head-common.S
+++ b/arch/arm/kernel/head-common.S
@@ -145,6 +145,9 @@ __mmap_switched_data:
 #endif
.size   __mmap_switched_data, . - __mmap_switched_data
 
+   __FINIT
+   .text
+
 /*
  * This provides a C-API version of __lookup_processor_type
  */
@@ -156,9 +159,6 @@ ENTRY(lookup_processor_type)
ldmfd   sp!, {r4 - r6, r9, pc}
 ENDPROC(lookup_processor_type)
 
-   __FINIT
-   .text
-
 /*
  * Read processor ID register (CP#15, CR0), and look up in the linker-built
  * supported processor list.  Note that we can't use the absolute addresses
-- 
2.17.1



[PATCH 4.19 16/17] ARM: ensure that processor vtables is not lost after boot

2019-02-13 Thread David Long
From: Russell King 

Commit 3a4d0c2172bcf15b7a3d9d498b2b355f9864286b upstream.

Marek Szyprowski reported problems with CPU hotplug in current kernels.
This was tracked down to the processor vtables being located in an
init section, and therefore discarded after kernel boot, despite being
required after boot to properly initialise the non-boot CPUs.

Arrange for these tables to end up in .rodata when required.

Reported-by: Marek Szyprowski 
Tested-by: Krzysztof Kozlowski 
Fixes: 383fb3ee8024 ("ARM: spectre-v2: per-CPU vtables to work around 
big.Little systems")
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/mm/proc-macros.S | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index 81d0efb055c6..19516fbc2c55 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -274,6 +274,13 @@
.endm
 
 .macro define_processor_functions name:req, dabort:req, pabort:req, nommu=0, 
suspend=0, bugs=0
+/*
+ * If we are building for big.Little with branch predictor hardening,
+ * we need the processor function tables to remain available after boot.
+ */
+#if 1 // defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+   .section ".rodata"
+#endif
.type   \name\()_processor_functions, #object
.align 2
 ENTRY(\name\()_processor_functions)
@@ -309,6 +316,9 @@ ENTRY(\name\()_processor_functions)
.endif
 
.size   \name\()_processor_functions, . - \name\()_processor_functions
+#if 1 // defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+   .previous
+#endif
 .endm
 
 .macro define_cache_functions name:req
-- 
2.17.1



[PATCH 4.19 17/17] ARM: fix the cockup in the previous patch

2019-02-13 Thread David Long
From: Russell King 

Commit d6951f582cc50ba0ad22ef46b599740966599b14 upstream.

The intention in the previous patch was to only place the processor
tables in the .rodata section if big.Little was being built and we
wanted the branch target hardening, but instead (due to the way it
was tested) it ended up always placing the tables into the .rodata
section.

Although harmless, let's correct this anyway.

Fixes: 3a4d0c2172bc ("ARM: ensure that processor vtables is not lost after 
boot")
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/mm/proc-macros.S | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index 19516fbc2c55..5461d589a1e2 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -278,7 +278,7 @@
  * If we are building for big.Little with branch predictor hardening,
  * we need the processor function tables to remain available after boot.
  */
-#if 1 // defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
.section ".rodata"
 #endif
.type   \name\()_processor_functions, #object
@@ -316,7 +316,7 @@ ENTRY(\name\()_processor_functions)
.endif
 
.size   \name\()_processor_functions, . - \name\()_processor_functions
-#if 1 // defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
.previous
 #endif
 .endm
-- 
2.17.1



[PATCH 4.19 13/17] ARM: clean up per-processor check_bugs method call

2019-02-13 Thread David Long
From: Russell King 

Commit 945aceb1db8885d3a35790cf2e810f681db52756 upstream.

Call the per-processor type check_bugs() method in the same way as we
do other per-processor functions - move the "processor." detail into
proc-fns.h.

Reviewed-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/include/asm/proc-fns.h | 1 +
 arch/arm/kernel/bugs.c  | 4 ++--
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index e25f4392e1b2..30c499146320 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -99,6 +99,7 @@ extern void cpu_do_suspend(void *);
 extern void cpu_do_resume(void *);
 #else
 #define cpu_proc_init  processor._proc_init
+#define cpu_check_bugs processor.check_bugs
 #define cpu_proc_fin   processor._proc_fin
 #define cpu_reset  processor.reset
 #define cpu_do_idleprocessor._do_idle
diff --git a/arch/arm/kernel/bugs.c b/arch/arm/kernel/bugs.c
index 7be511310191..d41d3598e5e5 100644
--- a/arch/arm/kernel/bugs.c
+++ b/arch/arm/kernel/bugs.c
@@ -6,8 +6,8 @@
 void check_other_bugs(void)
 {
 #ifdef MULTI_CPU
-   if (processor.check_bugs)
-   processor.check_bugs();
+   if (cpu_check_bugs)
+   cpu_check_bugs();
 #endif
 }
 
-- 
2.17.1



[PATCH 4.19 06/17] ARM: 8794/1: uaccess: Prevent speculative use of the current addr_limit

2019-02-13 Thread David Long
From: Julien Thierry 

Commit 621afc677465db231662ed126ae1f355bf8eac47 upstream.

A mispredicted conditional call to set_fs could result in the wrong
addr_limit being forwarded under speculation to a subsequent access_ok
check, potentially forming part of a spectre-v1 attack using uaccess
routines.

This patch prevents this forwarding from taking place, but putting heavy
barriers in set_fs after writing the addr_limit.

Porting commit c2f0ad4fc089cff8 ("arm64: uaccess: Prevent speculative use
of the current addr_limit").

Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/include/asm/uaccess.h | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 5451e1f05a19..d65ef85fc617 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -69,6 +69,14 @@ extern int __put_user_bad(void);
 static inline void set_fs(mm_segment_t fs)
 {
current_thread_info()->addr_limit = fs;
+
+   /*
+* Prevent a mispredicted conditional call to set_fs from forwarding
+* the wrong address limit to access_ok under speculation.
+*/
+   dsb(nsh);
+   isb();
+
modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_CLIENT : DOMAIN_MANAGER);
 }
 
-- 
2.17.1



[PATCH 4.19 02/17] ARM: 8790/1: signal: always use __copy_to_user to save iwmmxt context

2019-02-13 Thread David Long
From: Julien Thierry 

Commit 73839798af7ebc6c8d0c9271ebbbc148700e521f upstream.

When setting a dummy iwmmxt context, create a local instance and
use __copy_to_user both cases whether iwmmxt is being used or not.
This has the benefit of disabling/enabling PAN once for the whole copy
intead of once per write.

Signed-off-by: Julien Thierry 
Signed-off-by: Russell King 
Signed-off-by: David A. Long 
---
 arch/arm/kernel/signal.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 76fe75d36312..464393d241e1 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -77,8 +77,6 @@ static int preserve_iwmmxt_context(struct iwmmxt_sigframe 
__user *frame)
kframe->magic = IWMMXT_MAGIC;
kframe->size = IWMMXT_STORAGE_SIZE;
iwmmxt_task_copy(current_thread_info(), >storage);
-
-   err = __copy_to_user(frame, kframe, sizeof(*frame));
} else {
/*
 * For bug-compatibility with older kernels, some space
@@ -86,10 +84,14 @@ static int preserve_iwmmxt_context(struct iwmmxt_sigframe 
__user *frame)
 * Set the magic and size appropriately so that properly
 * written userspace can skip it reliably:
 */
-   __put_user_error(DUMMY_MAGIC, >magic, err);
-   __put_user_error(IWMMXT_STORAGE_SIZE, >size, err);
+   *kframe = (struct iwmmxt_sigframe) {
+   .magic = DUMMY_MAGIC,
+   .size  = IWMMXT_STORAGE_SIZE,
+   };
}
 
+   err = __copy_to_user(frame, kframe, sizeof(*kframe));
+
return err;
 }
 
-- 
2.17.1



[PATCH 4.19 00/17] V4.19 backport of more 32-bit arm spectre patches

2019-02-13 Thread David Long
From: "David A. Long" 

V4.19 backport of spectre patches from Russell M. King's spectre branch.
Patches have been kvm-unit-test'ed on an arndale, run through kernelci, and
handed off to ARM for functional testing.

Julien Thierry (10):
  ARM: 8789/1: signal: copy registers using __copy_to_user()
  ARM: 8790/1: signal: always use __copy_to_user to save iwmmxt context
  ARM: 8791/1: vfp: use __copy_to_user() when saving VFP state
  ARM: 8792/1: oabi-compat: copy oabi events using __copy_to_user()
  ARM: 8793/1: signal: replace __put_user_error with __put_user
  ARM: 8794/1: uaccess: Prevent speculative use of the current
addr_limit
  ARM: 8795/1: spectre-v1.1: use put_user() for __put_user()
  ARM: 8796/1: spectre-v1,v1.1: provide helpers for address sanitization
  ARM: 8797/1: spectre-v1.1: harden __copy_to_user
  ARM: 8810/1: vfp: Fix wrong assignement to ufp_exc

Russell King (7):
  ARM: make lookup_processor_type() non-__init
  ARM: split out processor lookup
  ARM: clean up per-processor check_bugs method call
  ARM: add PROC_VTABLE and PROC_TABLE macros
  ARM: spectre-v2: per-CPU vtables to work around big.Little systems
  ARM: ensure that processor vtables is not lost after boot
  ARM: fix the cockup in the previous patch

 arch/arm/include/asm/assembler.h   | 11 
 arch/arm/include/asm/cputype.h |  1 +
 arch/arm/include/asm/proc-fns.h| 61 ++-
 arch/arm/include/asm/thread_info.h |  4 +-
 arch/arm/include/asm/uaccess.h | 49 +++---
 arch/arm/kernel/bugs.c |  4 +-
 arch/arm/kernel/head-common.S  |  6 +--
 arch/arm/kernel/setup.c| 40 +--
 arch/arm/kernel/signal.c   | 80 --
 arch/arm/kernel/smp.c  | 31 
 arch/arm/kernel/sys_oabi-compat.c  |  8 ++-
 arch/arm/lib/copy_from_user.S  |  6 +--
 arch/arm/lib/copy_to_user.S|  6 ++-
 arch/arm/lib/uaccess_with_memcpy.c |  3 +-
 arch/arm/mm/proc-macros.S  | 10 
 arch/arm/mm/proc-v7-bugs.c | 17 +--
 arch/arm/vfp/vfpmodule.c   | 20 +++-
 17 files changed, 245 insertions(+), 112 deletions(-)

-- 
2.17.1



Re: [RESEND x3][PATCH 2/2 v4] drm/bridge: adv7511: Enable the audio data and clock pads on adv7533

2016-12-09 Thread David Long

On 11/28/2016 08:22 PM, John Stultz wrote:

From: Srinivas Kandagatla 

This patch enables the Audio Data and Clock pads to the adv7533 bridge.
Without this patch audio can not be played.

Cc: David Airlie 
Cc: Archit Taneja 
Cc: Laurent Pinchart 
Cc: Wolfram Sang 
Cc: Srinivas Kandagatla 
Cc: "Ville Syrjälä" 
Cc: Boris Brezillon 
Cc: Andy Green 
Cc: Dave Long 
Cc: Guodong Xu 
Cc: Zhangfei Gao 
Cc: Mark Brown 
Cc: Lars-Peter Clausen 
Cc: Jose Abreu 
Cc: Kuninori Morimoto 
Cc: dri-de...@lists.freedesktop.org
Reviewed-by: Archit Taneja 
Signed-off-by: Srinivas Kandagatla 
Signed-off-by: John Stultz 
---
  drivers/gpu/drm/bridge/adv7511/adv7533.c | 1 +
  1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c 
b/drivers/gpu/drm/bridge/adv7511/adv7533.c
index d7f7b7c..8b21037 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7533.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c
@@ -29,6 +29,7 @@ static const struct reg_sequence 
adv7533_cec_fixed_registers[] = {
{ 0x17, 0xd0 },
{ 0x24, 0x20 },
{ 0x57, 0x11 },
+   { 0x05, 0xc8 },
  };

  static const struct regmap_config adv7533_cec_regmap_config = {



Tested-by: David A. Long 

-dl



Re: [RESEND x3][PATCH 2/2 v4] drm/bridge: adv7511: Enable the audio data and clock pads on adv7533

2016-12-09 Thread David Long

On 11/28/2016 08:22 PM, John Stultz wrote:

From: Srinivas Kandagatla 

This patch enables the Audio Data and Clock pads to the adv7533 bridge.
Without this patch audio can not be played.

Cc: David Airlie 
Cc: Archit Taneja 
Cc: Laurent Pinchart 
Cc: Wolfram Sang 
Cc: Srinivas Kandagatla 
Cc: "Ville Syrjälä" 
Cc: Boris Brezillon 
Cc: Andy Green 
Cc: Dave Long 
Cc: Guodong Xu 
Cc: Zhangfei Gao 
Cc: Mark Brown 
Cc: Lars-Peter Clausen 
Cc: Jose Abreu 
Cc: Kuninori Morimoto 
Cc: dri-de...@lists.freedesktop.org
Reviewed-by: Archit Taneja 
Signed-off-by: Srinivas Kandagatla 
Signed-off-by: John Stultz 
---
  drivers/gpu/drm/bridge/adv7511/adv7533.c | 1 +
  1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c 
b/drivers/gpu/drm/bridge/adv7511/adv7533.c
index d7f7b7c..8b21037 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7533.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c
@@ -29,6 +29,7 @@ static const struct reg_sequence 
adv7533_cec_fixed_registers[] = {
{ 0x17, 0xd0 },
{ 0x24, 0x20 },
{ 0x57, 0x11 },
+   { 0x05, 0xc8 },
  };

  static const struct regmap_config adv7533_cec_regmap_config = {



Tested-by: David A. Long 

-dl



Re: [RESEND x3][PATCH 1/2 v4] drm/bridge: adv7511: Add Audio support.

2016-12-09 Thread David Long

On 11/28/2016 08:22 PM, John Stultz wrote:

This patch adds support to Audio for both adv7511 and adv7533
bridge chips.

This patch was originally from [1] by Lars-Peter Clausen 
and was adapted by Archit Taneja  and
Srinivas Kandagatla .

Then I heavily reworked it to use the hdmi-codec driver. And also
folded in some audio packet initialization done by Andy Green
. So credit to them, but blame to me.

[1] 
https://github.com/analogdevicesinc/linux/blob/xcomm_zynq/drivers/gpu/drm/i2c/adv7511_audio.c

Cc: David Airlie 
Cc: Archit Taneja 
Cc: Laurent Pinchart 
Cc: Wolfram Sang 
Cc: Srinivas Kandagatla 
Cc: "Ville Syrjälä" 
Cc: Boris Brezillon 
Cc: Andy Green 
Cc: Dave Long 
Cc: Guodong Xu 
Cc: Zhangfei Gao 
Cc: Mark Brown 
Cc: Lars-Peter Clausen 
Cc: Jose Abreu 
Cc: Kuninori Morimoto 
Cc: dri-de...@lists.freedesktop.org
Reviewed-by: Archit Taneja 
Acked-by: Lars-Peter Clausen 
Signed-off-by: John Stultz 
---
v4:
* Kconfig tweaks suggested by Lars-Peter Clausen
v3:
* Allowed audio support to be configured in or out, as suggested by Laurent
* Minor cleanups suggested by Laurent
* Folded in Andy's audio packet initialization patch, as suggested by Archit
---
  drivers/gpu/drm/bridge/adv7511/Kconfig |   8 +
  drivers/gpu/drm/bridge/adv7511/Makefile|   1 +
  drivers/gpu/drm/bridge/adv7511/adv7511.h   |  16 ++
  drivers/gpu/drm/bridge/adv7511/adv7511_audio.c | 213 +
  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c   |   4 +
  5 files changed, 242 insertions(+)
  create mode 100644 drivers/gpu/drm/bridge/adv7511/adv7511_audio.c

diff --git a/drivers/gpu/drm/bridge/adv7511/Kconfig 
b/drivers/gpu/drm/bridge/adv7511/Kconfig
index d2b0499..2fed567 100644
--- a/drivers/gpu/drm/bridge/adv7511/Kconfig
+++ b/drivers/gpu/drm/bridge/adv7511/Kconfig
@@ -6,6 +6,14 @@ config DRM_I2C_ADV7511
help
  Support for the Analog Device ADV7511(W) and ADV7513 HDMI encoders.

+config DRM_I2C_ADV7511_AUDIO
+   bool "ADV7511 HDMI Audio driver"
+   depends on DRM_I2C_ADV7511 && SND_SOC
+   select SND_SOC_HDMI_CODEC
+   help
+ Support the ADV7511 HDMI Audio interface. This is used in
+ conjunction with the AV7511  HDMI driver.
+
  config DRM_I2C_ADV7533
bool "ADV7533 encoder"
depends on DRM_I2C_ADV7511
diff --git a/drivers/gpu/drm/bridge/adv7511/Makefile 
b/drivers/gpu/drm/bridge/adv7511/Makefile
index 9019327..5ba6755 100644
--- a/drivers/gpu/drm/bridge/adv7511/Makefile
+++ b/drivers/gpu/drm/bridge/adv7511/Makefile
@@ -1,3 +1,4 @@
  adv7511-y := adv7511_drv.o
+adv7511-$(CONFIG_DRM_I2C_ADV7511_AUDIO) += adv7511_audio.o
  adv7511-$(CONFIG_DRM_I2C_ADV7533) += adv7533.o
  obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511.o
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h 
b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index 161c923..992d76c 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -309,6 +309,8 @@ struct adv7511 {
struct drm_display_mode curr_mode;

unsigned int f_tmds;
+   unsigned int f_audio;
+   unsigned int audio_source;

unsigned int current_edid_segment;
uint8_t edid_buf[256];
@@ -334,6 +336,7 @@ struct adv7511 {
bool use_timing_gen;

enum adv7511_type type;
+   struct platform_device *audio_pdev;
  };

  #ifdef CONFIG_DRM_I2C_ADV7533
@@ -389,4 +392,17 @@ static inline int adv7533_parse_dt(struct device_node *np, 
struct adv7511 *adv)
  }
  #endif

+#ifdef CONFIG_DRM_I2C_ADV7511_AUDIO
+int adv7511_audio_init(struct device *dev, struct adv7511 *adv7511);
+void adv7511_audio_exit(struct adv7511 *adv7511);
+#else /*CONFIG_DRM_I2C_ADV7511_AUDIO */
+static inline int adv7511_audio_init(struct device *dev, struct adv7511 
*adv7511)
+{
+   return 0;
+}
+static inline void adv7511_audio_exit(struct adv7511 *adv7511)
+{
+}
+#endif /* CONFIG_DRM_I2C_ADV7511_AUDIO */
+
  #endif /* __DRM_I2C_ADV7511_H__ */
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c 
b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
new file mode 100644
index 000..5ce29a5
--- /dev/null
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
@@ -0,0 +1,213 @@
+/*
+ * Analog Devices ADV7511 HDMI transmitter driver
+ *
+ * Copyright 2012 Analog Devices Inc.
+ * Copyright (c) 2016, Linaro Limited
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "adv7511.h"
+

Re: [RESEND x3][PATCH 1/2 v4] drm/bridge: adv7511: Add Audio support.

2016-12-09 Thread David Long

On 11/28/2016 08:22 PM, John Stultz wrote:

This patch adds support to Audio for both adv7511 and adv7533
bridge chips.

This patch was originally from [1] by Lars-Peter Clausen 
and was adapted by Archit Taneja  and
Srinivas Kandagatla .

Then I heavily reworked it to use the hdmi-codec driver. And also
folded in some audio packet initialization done by Andy Green
. So credit to them, but blame to me.

[1] 
https://github.com/analogdevicesinc/linux/blob/xcomm_zynq/drivers/gpu/drm/i2c/adv7511_audio.c

Cc: David Airlie 
Cc: Archit Taneja 
Cc: Laurent Pinchart 
Cc: Wolfram Sang 
Cc: Srinivas Kandagatla 
Cc: "Ville Syrjälä" 
Cc: Boris Brezillon 
Cc: Andy Green 
Cc: Dave Long 
Cc: Guodong Xu 
Cc: Zhangfei Gao 
Cc: Mark Brown 
Cc: Lars-Peter Clausen 
Cc: Jose Abreu 
Cc: Kuninori Morimoto 
Cc: dri-de...@lists.freedesktop.org
Reviewed-by: Archit Taneja 
Acked-by: Lars-Peter Clausen 
Signed-off-by: John Stultz 
---
v4:
* Kconfig tweaks suggested by Lars-Peter Clausen
v3:
* Allowed audio support to be configured in or out, as suggested by Laurent
* Minor cleanups suggested by Laurent
* Folded in Andy's audio packet initialization patch, as suggested by Archit
---
  drivers/gpu/drm/bridge/adv7511/Kconfig |   8 +
  drivers/gpu/drm/bridge/adv7511/Makefile|   1 +
  drivers/gpu/drm/bridge/adv7511/adv7511.h   |  16 ++
  drivers/gpu/drm/bridge/adv7511/adv7511_audio.c | 213 +
  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c   |   4 +
  5 files changed, 242 insertions(+)
  create mode 100644 drivers/gpu/drm/bridge/adv7511/adv7511_audio.c

diff --git a/drivers/gpu/drm/bridge/adv7511/Kconfig 
b/drivers/gpu/drm/bridge/adv7511/Kconfig
index d2b0499..2fed567 100644
--- a/drivers/gpu/drm/bridge/adv7511/Kconfig
+++ b/drivers/gpu/drm/bridge/adv7511/Kconfig
@@ -6,6 +6,14 @@ config DRM_I2C_ADV7511
help
  Support for the Analog Device ADV7511(W) and ADV7513 HDMI encoders.

+config DRM_I2C_ADV7511_AUDIO
+   bool "ADV7511 HDMI Audio driver"
+   depends on DRM_I2C_ADV7511 && SND_SOC
+   select SND_SOC_HDMI_CODEC
+   help
+ Support the ADV7511 HDMI Audio interface. This is used in
+ conjunction with the AV7511  HDMI driver.
+
  config DRM_I2C_ADV7533
bool "ADV7533 encoder"
depends on DRM_I2C_ADV7511
diff --git a/drivers/gpu/drm/bridge/adv7511/Makefile 
b/drivers/gpu/drm/bridge/adv7511/Makefile
index 9019327..5ba6755 100644
--- a/drivers/gpu/drm/bridge/adv7511/Makefile
+++ b/drivers/gpu/drm/bridge/adv7511/Makefile
@@ -1,3 +1,4 @@
  adv7511-y := adv7511_drv.o
+adv7511-$(CONFIG_DRM_I2C_ADV7511_AUDIO) += adv7511_audio.o
  adv7511-$(CONFIG_DRM_I2C_ADV7533) += adv7533.o
  obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511.o
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h 
b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index 161c923..992d76c 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -309,6 +309,8 @@ struct adv7511 {
struct drm_display_mode curr_mode;

unsigned int f_tmds;
+   unsigned int f_audio;
+   unsigned int audio_source;

unsigned int current_edid_segment;
uint8_t edid_buf[256];
@@ -334,6 +336,7 @@ struct adv7511 {
bool use_timing_gen;

enum adv7511_type type;
+   struct platform_device *audio_pdev;
  };

  #ifdef CONFIG_DRM_I2C_ADV7533
@@ -389,4 +392,17 @@ static inline int adv7533_parse_dt(struct device_node *np, 
struct adv7511 *adv)
  }
  #endif

+#ifdef CONFIG_DRM_I2C_ADV7511_AUDIO
+int adv7511_audio_init(struct device *dev, struct adv7511 *adv7511);
+void adv7511_audio_exit(struct adv7511 *adv7511);
+#else /*CONFIG_DRM_I2C_ADV7511_AUDIO */
+static inline int adv7511_audio_init(struct device *dev, struct adv7511 
*adv7511)
+{
+   return 0;
+}
+static inline void adv7511_audio_exit(struct adv7511 *adv7511)
+{
+}
+#endif /* CONFIG_DRM_I2C_ADV7511_AUDIO */
+
  #endif /* __DRM_I2C_ADV7511_H__ */
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c 
b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
new file mode 100644
index 000..5ce29a5
--- /dev/null
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
@@ -0,0 +1,213 @@
+/*
+ * Analog Devices ADV7511 HDMI transmitter driver
+ *
+ * Copyright 2012 Analog Devices Inc.
+ * Copyright (c) 2016, Linaro Limited
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "adv7511.h"
+
+static void adv7511_calc_cts_n(unsigned int f_tmds, unsigned int fs,
+  unsigned int *cts, unsigned int *n)
+{
+   switch (fs) {
+   case 32000:
+   *n = 4096;
+   break;
+   case 44100:
+   *n = 6272;
+   break;
+   case 48000:
+   *n = 6144;
+   break;
+   }
+
+   *cts = ((f_tmds * *n) / (128 * fs)) * 1000;
+}
+
+static int adv7511_update_cts_n(struct adv7511 *adv7511)
+{
+   unsigned int cts = 0;
+   unsigned int 

Re: [PATCH v4] arm64: Improve kprobes test for atomic sequence

2016-09-12 Thread David Long

On 09/12/2016 08:46 PM, Masami Hiramatsu wrote:

On Mon, 12 Sep 2016 14:21:27 -0400
David Long <dave.l...@linaro.org> wrote:


From: "David A. Long" <dave.l...@linaro.org>

Kprobes searches backwards a finite number of instructions to determine if
there is an attempt to probe a load/store exclusive sequence. It stops when
it hits the maximum number of instructions or a load or store exclusive.
However this means it can run up past the beginning of the function and
start looking at literal constants. This has been shown to cause a false
positive and blocks insertion of the probe. To fix this, further limit the
backwards search to stop if it hits a symbol address from kallsyms. The
presumption is that this is the entry point to this code (particularly for
the common case of placing probes at the beginning of functions).

This also improves efficiency by not searching code that is not part of the
function. There may be some possibility that the label might not denote the
entry path to the probed instruction but the likelihood seems low and this
is just another example of how the kprobes user really needs to be
careful about what they are doing.

Signed-off-by: David A. Long <dave.l...@linaro.org>
---
  arch/arm64/kernel/probes/decode-insn.c | 48 --
  1 file changed, 23 insertions(+), 25 deletions(-)

diff --git a/arch/arm64/kernel/probes/decode-insn.c 
b/arch/arm64/kernel/probes/decode-insn.c
index 37e47a9..d1731bf 100644
--- a/arch/arm64/kernel/probes/decode-insn.c
+++ b/arch/arm64/kernel/probes/decode-insn.c
@@ -16,6 +16,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
@@ -122,7 +123,7 @@ arm_probe_decode_insn(kprobe_opcode_t insn, struct 
arch_specific_insn *asi)
  static bool __kprobes
  is_probed_address_atomic(kprobe_opcode_t *scan_start, kprobe_opcode_t 
*scan_end)
  {
-   while (scan_start > scan_end) {
+   while (scan_start >= scan_end) {
/*
 * atomic region starts from exclusive load and ends with
 * exclusive store.
@@ -142,33 +143,30 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct 
arch_specific_insn *asi)
  {
enum kprobe_insn decoded;
kprobe_opcode_t insn = le32_to_cpu(*addr);
-   kprobe_opcode_t *scan_start = addr - 1;
-   kprobe_opcode_t *scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
-#if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
-   struct module *mod;
-#endif
-
-   if (addr >= (kprobe_opcode_t *)_text &&
-   scan_end < (kprobe_opcode_t *)_text)
-   scan_end = (kprobe_opcode_t *)_text;
-#if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
-   else {
-   preempt_disable();
-   mod = __module_address((unsigned long)addr);
-   if (mod && within_module_init((unsigned long)addr, mod) &&
-   !within_module_init((unsigned long)scan_end, mod))
-   scan_end = (kprobe_opcode_t *)mod->init_layout.base;
-   else if (mod && within_module_core((unsigned long)addr, mod) &&
-   !within_module_core((unsigned long)scan_end, mod))
-   scan_end = (kprobe_opcode_t *)mod->core_layout.base;
-   preempt_enable();
+   kprobe_opcode_t *scan_end = NULL;
+   unsigned long size = 0, offset = 0;
+
+   /*
+* If there's a symbol defined in front of and near enough to
+* the probe address assume it is the entry point to this
+* code and use it to further limit how far back we search
+* when determining if we're in an atomic sequence. If we could
+* not find any symbol skip the atomic test altogether as we
+* could otherwise end up searching irrelevant text/literals.
+* KPROBES depends on KALLSYMS so this last case should never
+* happen.
+*/
+   if (kallsyms_lookup_size_offset((unsigned long) addr, , )) {
+   if (offset < (MAX_ATOMIC_CONTEXT_SIZE*sizeof(kprobe_opcode_t)))
+   scan_end = addr - (offset / sizeof(kprobe_opcode_t));
+   else
+   scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
}


Hmm, could you tell me what will happen if kallsyms_lookup_size_offset()
failed here?

Thanks,


-#endif
decoded = arm_probe_decode_insn(insn, asi);

-   if (decoded == INSN_REJECTED ||
-   is_probed_address_atomic(scan_start, scan_end))
-   return INSN_REJECTED;
+   if (decoded != INSN_REJECTED && scan_end)
+   if (is_probed_address_atomic(addr - 1, scan_end))
+   return INSN_REJECTED;

return decoded;
  }
--
2.5.0






After the patch the function reads as follows:


enum kprobe_insn __kprobes
arm_kprobe_decode_insn(kprobe_opcode_t *addr, str

Re: [PATCH v4] arm64: Improve kprobes test for atomic sequence

2016-09-12 Thread David Long

On 09/12/2016 08:46 PM, Masami Hiramatsu wrote:

On Mon, 12 Sep 2016 14:21:27 -0400
David Long  wrote:


From: "David A. Long" 

Kprobes searches backwards a finite number of instructions to determine if
there is an attempt to probe a load/store exclusive sequence. It stops when
it hits the maximum number of instructions or a load or store exclusive.
However this means it can run up past the beginning of the function and
start looking at literal constants. This has been shown to cause a false
positive and blocks insertion of the probe. To fix this, further limit the
backwards search to stop if it hits a symbol address from kallsyms. The
presumption is that this is the entry point to this code (particularly for
the common case of placing probes at the beginning of functions).

This also improves efficiency by not searching code that is not part of the
function. There may be some possibility that the label might not denote the
entry path to the probed instruction but the likelihood seems low and this
is just another example of how the kprobes user really needs to be
careful about what they are doing.

Signed-off-by: David A. Long 
---
  arch/arm64/kernel/probes/decode-insn.c | 48 --
  1 file changed, 23 insertions(+), 25 deletions(-)

diff --git a/arch/arm64/kernel/probes/decode-insn.c 
b/arch/arm64/kernel/probes/decode-insn.c
index 37e47a9..d1731bf 100644
--- a/arch/arm64/kernel/probes/decode-insn.c
+++ b/arch/arm64/kernel/probes/decode-insn.c
@@ -16,6 +16,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
@@ -122,7 +123,7 @@ arm_probe_decode_insn(kprobe_opcode_t insn, struct 
arch_specific_insn *asi)
  static bool __kprobes
  is_probed_address_atomic(kprobe_opcode_t *scan_start, kprobe_opcode_t 
*scan_end)
  {
-   while (scan_start > scan_end) {
+   while (scan_start >= scan_end) {
/*
 * atomic region starts from exclusive load and ends with
 * exclusive store.
@@ -142,33 +143,30 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct 
arch_specific_insn *asi)
  {
enum kprobe_insn decoded;
kprobe_opcode_t insn = le32_to_cpu(*addr);
-   kprobe_opcode_t *scan_start = addr - 1;
-   kprobe_opcode_t *scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
-#if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
-   struct module *mod;
-#endif
-
-   if (addr >= (kprobe_opcode_t *)_text &&
-   scan_end < (kprobe_opcode_t *)_text)
-   scan_end = (kprobe_opcode_t *)_text;
-#if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
-   else {
-   preempt_disable();
-   mod = __module_address((unsigned long)addr);
-   if (mod && within_module_init((unsigned long)addr, mod) &&
-   !within_module_init((unsigned long)scan_end, mod))
-   scan_end = (kprobe_opcode_t *)mod->init_layout.base;
-   else if (mod && within_module_core((unsigned long)addr, mod) &&
-   !within_module_core((unsigned long)scan_end, mod))
-   scan_end = (kprobe_opcode_t *)mod->core_layout.base;
-   preempt_enable();
+   kprobe_opcode_t *scan_end = NULL;
+   unsigned long size = 0, offset = 0;
+
+   /*
+* If there's a symbol defined in front of and near enough to
+* the probe address assume it is the entry point to this
+* code and use it to further limit how far back we search
+* when determining if we're in an atomic sequence. If we could
+* not find any symbol skip the atomic test altogether as we
+* could otherwise end up searching irrelevant text/literals.
+* KPROBES depends on KALLSYMS so this last case should never
+* happen.
+*/
+   if (kallsyms_lookup_size_offset((unsigned long) addr, , )) {
+   if (offset < (MAX_ATOMIC_CONTEXT_SIZE*sizeof(kprobe_opcode_t)))
+   scan_end = addr - (offset / sizeof(kprobe_opcode_t));
+   else
+   scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
}


Hmm, could you tell me what will happen if kallsyms_lookup_size_offset()
failed here?

Thanks,


-#endif
decoded = arm_probe_decode_insn(insn, asi);

-   if (decoded == INSN_REJECTED ||
-   is_probed_address_atomic(scan_start, scan_end))
-   return INSN_REJECTED;
+   if (decoded != INSN_REJECTED && scan_end)
+   if (is_probed_address_atomic(addr - 1, scan_end))
+   return INSN_REJECTED;

return decoded;
  }
--
2.5.0






After the patch the function reads as follows:


enum kprobe_insn __kprobes
arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct arch_specific_insn *asi)
{
enum kprobe_insn decoded;
kprobe_opcode_t insn

[PATCH v4] arm64: Improve kprobes test for atomic sequence

2016-09-12 Thread David Long
From: "David A. Long" 

Kprobes searches backwards a finite number of instructions to determine if
there is an attempt to probe a load/store exclusive sequence. It stops when
it hits the maximum number of instructions or a load or store exclusive.
However this means it can run up past the beginning of the function and
start looking at literal constants. This has been shown to cause a false
positive and blocks insertion of the probe. To fix this, further limit the
backwards search to stop if it hits a symbol address from kallsyms. The
presumption is that this is the entry point to this code (particularly for
the common case of placing probes at the beginning of functions).

This also improves efficiency by not searching code that is not part of the
function. There may be some possibility that the label might not denote the
entry path to the probed instruction but the likelihood seems low and this
is just another example of how the kprobes user really needs to be
careful about what they are doing.

Signed-off-by: David A. Long 
---
 arch/arm64/kernel/probes/decode-insn.c | 48 --
 1 file changed, 23 insertions(+), 25 deletions(-)

diff --git a/arch/arm64/kernel/probes/decode-insn.c 
b/arch/arm64/kernel/probes/decode-insn.c
index 37e47a9..d1731bf 100644
--- a/arch/arm64/kernel/probes/decode-insn.c
+++ b/arch/arm64/kernel/probes/decode-insn.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -122,7 +123,7 @@ arm_probe_decode_insn(kprobe_opcode_t insn, struct 
arch_specific_insn *asi)
 static bool __kprobes
 is_probed_address_atomic(kprobe_opcode_t *scan_start, kprobe_opcode_t 
*scan_end)
 {
-   while (scan_start > scan_end) {
+   while (scan_start >= scan_end) {
/*
 * atomic region starts from exclusive load and ends with
 * exclusive store.
@@ -142,33 +143,30 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct 
arch_specific_insn *asi)
 {
enum kprobe_insn decoded;
kprobe_opcode_t insn = le32_to_cpu(*addr);
-   kprobe_opcode_t *scan_start = addr - 1;
-   kprobe_opcode_t *scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
-#if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
-   struct module *mod;
-#endif
-
-   if (addr >= (kprobe_opcode_t *)_text &&
-   scan_end < (kprobe_opcode_t *)_text)
-   scan_end = (kprobe_opcode_t *)_text;
-#if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
-   else {
-   preempt_disable();
-   mod = __module_address((unsigned long)addr);
-   if (mod && within_module_init((unsigned long)addr, mod) &&
-   !within_module_init((unsigned long)scan_end, mod))
-   scan_end = (kprobe_opcode_t *)mod->init_layout.base;
-   else if (mod && within_module_core((unsigned long)addr, mod) &&
-   !within_module_core((unsigned long)scan_end, mod))
-   scan_end = (kprobe_opcode_t *)mod->core_layout.base;
-   preempt_enable();
+   kprobe_opcode_t *scan_end = NULL;
+   unsigned long size = 0, offset = 0;
+
+   /*
+* If there's a symbol defined in front of and near enough to
+* the probe address assume it is the entry point to this
+* code and use it to further limit how far back we search
+* when determining if we're in an atomic sequence. If we could
+* not find any symbol skip the atomic test altogether as we
+* could otherwise end up searching irrelevant text/literals.
+* KPROBES depends on KALLSYMS so this last case should never
+* happen.
+*/
+   if (kallsyms_lookup_size_offset((unsigned long) addr, , )) {
+   if (offset < (MAX_ATOMIC_CONTEXT_SIZE*sizeof(kprobe_opcode_t)))
+   scan_end = addr - (offset / sizeof(kprobe_opcode_t));
+   else
+   scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
}
-#endif
decoded = arm_probe_decode_insn(insn, asi);
 
-   if (decoded == INSN_REJECTED ||
-   is_probed_address_atomic(scan_start, scan_end))
-   return INSN_REJECTED;
+   if (decoded != INSN_REJECTED && scan_end)
+   if (is_probed_address_atomic(addr - 1, scan_end))
+   return INSN_REJECTED;
 
return decoded;
 }
-- 
2.5.0



[PATCH v4] arm64: Improve kprobes test for atomic sequence

2016-09-12 Thread David Long
From: "David A. Long" 

Kprobes searches backwards a finite number of instructions to determine if
there is an attempt to probe a load/store exclusive sequence. It stops when
it hits the maximum number of instructions or a load or store exclusive.
However this means it can run up past the beginning of the function and
start looking at literal constants. This has been shown to cause a false
positive and blocks insertion of the probe. To fix this, further limit the
backwards search to stop if it hits a symbol address from kallsyms. The
presumption is that this is the entry point to this code (particularly for
the common case of placing probes at the beginning of functions).

This also improves efficiency by not searching code that is not part of the
function. There may be some possibility that the label might not denote the
entry path to the probed instruction but the likelihood seems low and this
is just another example of how the kprobes user really needs to be
careful about what they are doing.

Signed-off-by: David A. Long 
---
 arch/arm64/kernel/probes/decode-insn.c | 48 --
 1 file changed, 23 insertions(+), 25 deletions(-)

diff --git a/arch/arm64/kernel/probes/decode-insn.c 
b/arch/arm64/kernel/probes/decode-insn.c
index 37e47a9..d1731bf 100644
--- a/arch/arm64/kernel/probes/decode-insn.c
+++ b/arch/arm64/kernel/probes/decode-insn.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -122,7 +123,7 @@ arm_probe_decode_insn(kprobe_opcode_t insn, struct 
arch_specific_insn *asi)
 static bool __kprobes
 is_probed_address_atomic(kprobe_opcode_t *scan_start, kprobe_opcode_t 
*scan_end)
 {
-   while (scan_start > scan_end) {
+   while (scan_start >= scan_end) {
/*
 * atomic region starts from exclusive load and ends with
 * exclusive store.
@@ -142,33 +143,30 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct 
arch_specific_insn *asi)
 {
enum kprobe_insn decoded;
kprobe_opcode_t insn = le32_to_cpu(*addr);
-   kprobe_opcode_t *scan_start = addr - 1;
-   kprobe_opcode_t *scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
-#if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
-   struct module *mod;
-#endif
-
-   if (addr >= (kprobe_opcode_t *)_text &&
-   scan_end < (kprobe_opcode_t *)_text)
-   scan_end = (kprobe_opcode_t *)_text;
-#if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
-   else {
-   preempt_disable();
-   mod = __module_address((unsigned long)addr);
-   if (mod && within_module_init((unsigned long)addr, mod) &&
-   !within_module_init((unsigned long)scan_end, mod))
-   scan_end = (kprobe_opcode_t *)mod->init_layout.base;
-   else if (mod && within_module_core((unsigned long)addr, mod) &&
-   !within_module_core((unsigned long)scan_end, mod))
-   scan_end = (kprobe_opcode_t *)mod->core_layout.base;
-   preempt_enable();
+   kprobe_opcode_t *scan_end = NULL;
+   unsigned long size = 0, offset = 0;
+
+   /*
+* If there's a symbol defined in front of and near enough to
+* the probe address assume it is the entry point to this
+* code and use it to further limit how far back we search
+* when determining if we're in an atomic sequence. If we could
+* not find any symbol skip the atomic test altogether as we
+* could otherwise end up searching irrelevant text/literals.
+* KPROBES depends on KALLSYMS so this last case should never
+* happen.
+*/
+   if (kallsyms_lookup_size_offset((unsigned long) addr, , )) {
+   if (offset < (MAX_ATOMIC_CONTEXT_SIZE*sizeof(kprobe_opcode_t)))
+   scan_end = addr - (offset / sizeof(kprobe_opcode_t));
+   else
+   scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
}
-#endif
decoded = arm_probe_decode_insn(insn, asi);
 
-   if (decoded == INSN_REJECTED ||
-   is_probed_address_atomic(scan_start, scan_end))
-   return INSN_REJECTED;
+   if (decoded != INSN_REJECTED && scan_end)
+   if (is_probed_address_atomic(addr - 1, scan_end))
+   return INSN_REJECTED;
 
return decoded;
 }
-- 
2.5.0



Re: [PATCH v3] arm64: Improve kprobes test for atomic sequence

2016-09-12 Thread David Long

On 09/12/2016 12:29 PM, Masami Hiramatsu wrote:

On Sun, 11 Sep 2016 21:53:43 -0400
David Long <dave.l...@linaro.org> wrote:


On 09/10/2016 01:48 AM, Masami Hiramatsu wrote:

On Fri,  9 Sep 2016 15:26:09 -0400
David Long <dave.l...@linaro.org> wrote:


From: "David A. Long" <dave.l...@linaro.org>

Kprobes searches backwards a finite number of instructions to determine if
there is an attempt to probe a load/store exclusive sequence. It stops when
it hits the maximum number of instructions or a load or store exclusive.
However this means it can run up past the beginning of the function and
start looking at literal constants. This has been shown to cause a false
positive and blocks insertion of the probe. To fix this, further limit the
backwards search to stop if it hits a symbol address from kallsyms. The
presumption is that this is the entry point to this code (particularly for
the common case of placing probes at the beginning of functions).

This also improves efficiency by not searching code that is not part of the
function. There may be some possibility that the label might not denote the
entry path to the probed instruction but the likelihood seems low and this
is just another example of how the kprobes user really needs to be
careful about what they are doing.


Of course user should be careful, but also, in such case, kernel can reject
to probe it.



I'm not exactly sure what you mean.  I'm just saying when everything
goes right we still cannot promise perfection in detecting a probe
within an atomic sequence.  This patch will reject a probe that is after
a ldx and has no intervening kallsyms label (and assuming it's within
the defined maximum count of subsequent instructions).



Hmm, what I meant was the below code.


+   /*
+* If there's a symbol defined in front of and near enough to
+* the probe address assume it is the entry point to this
+* code and use it to further limit how far back we search
+* when determining if we're in an atomic sequence. If we could
+* not find any symbol skip the atomic test altogether as we
+* could otherwise end up searching irrelevant text/literals.
+* KPROBES depends on KALLSYMS so this last case should never
+* happen.
+*/
+   if (kallsyms_lookup_size_offset((unsigned long) addr, , )) {
+   if (offset < (MAX_ATOMIC_CONTEXT_SIZE*sizeof(kprobe_opcode_t)))
+   scan_end = addr - (offset / sizeof(kprobe_opcode_t));
+   else
+   scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;


  } else
 return INSN_REJECTED;

that is what I expected...


As you said above,


+* KPROBES depends on KALLSYMS so this last case should never
+* happen.


If it should never happen, it also would be better to reject it because
it is unexpected result.

Thank you,



OK, cool.  Sounds like we're on the same page.

-dl



Re: [PATCH v3] arm64: Improve kprobes test for atomic sequence

2016-09-12 Thread David Long

On 09/12/2016 12:29 PM, Masami Hiramatsu wrote:

On Sun, 11 Sep 2016 21:53:43 -0400
David Long  wrote:


On 09/10/2016 01:48 AM, Masami Hiramatsu wrote:

On Fri,  9 Sep 2016 15:26:09 -0400
David Long  wrote:


From: "David A. Long" 

Kprobes searches backwards a finite number of instructions to determine if
there is an attempt to probe a load/store exclusive sequence. It stops when
it hits the maximum number of instructions or a load or store exclusive.
However this means it can run up past the beginning of the function and
start looking at literal constants. This has been shown to cause a false
positive and blocks insertion of the probe. To fix this, further limit the
backwards search to stop if it hits a symbol address from kallsyms. The
presumption is that this is the entry point to this code (particularly for
the common case of placing probes at the beginning of functions).

This also improves efficiency by not searching code that is not part of the
function. There may be some possibility that the label might not denote the
entry path to the probed instruction but the likelihood seems low and this
is just another example of how the kprobes user really needs to be
careful about what they are doing.


Of course user should be careful, but also, in such case, kernel can reject
to probe it.



I'm not exactly sure what you mean.  I'm just saying when everything
goes right we still cannot promise perfection in detecting a probe
within an atomic sequence.  This patch will reject a probe that is after
a ldx and has no intervening kallsyms label (and assuming it's within
the defined maximum count of subsequent instructions).



Hmm, what I meant was the below code.


+   /*
+* If there's a symbol defined in front of and near enough to
+* the probe address assume it is the entry point to this
+* code and use it to further limit how far back we search
+* when determining if we're in an atomic sequence. If we could
+* not find any symbol skip the atomic test altogether as we
+* could otherwise end up searching irrelevant text/literals.
+* KPROBES depends on KALLSYMS so this last case should never
+* happen.
+*/
+   if (kallsyms_lookup_size_offset((unsigned long) addr, , )) {
+   if (offset < (MAX_ATOMIC_CONTEXT_SIZE*sizeof(kprobe_opcode_t)))
+   scan_end = addr - (offset / sizeof(kprobe_opcode_t));
+   else
+   scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;


  } else
 return INSN_REJECTED;

that is what I expected...


As you said above,


+* KPROBES depends on KALLSYMS so this last case should never
+* happen.


If it should never happen, it also would be better to reject it because
it is unexpected result.

Thank you,



OK, cool.  Sounds like we're on the same page.

-dl



Re: [PATCH v3] arm64: Improve kprobes test for atomic sequence

2016-09-11 Thread David Long

On 09/10/2016 01:48 AM, Masami Hiramatsu wrote:

On Fri,  9 Sep 2016 15:26:09 -0400
David Long <dave.l...@linaro.org> wrote:


From: "David A. Long" <dave.l...@linaro.org>

Kprobes searches backwards a finite number of instructions to determine if
there is an attempt to probe a load/store exclusive sequence. It stops when
it hits the maximum number of instructions or a load or store exclusive.
However this means it can run up past the beginning of the function and
start looking at literal constants. This has been shown to cause a false
positive and blocks insertion of the probe. To fix this, further limit the
backwards search to stop if it hits a symbol address from kallsyms. The
presumption is that this is the entry point to this code (particularly for
the common case of placing probes at the beginning of functions).

This also improves efficiency by not searching code that is not part of the
function. There may be some possibility that the label might not denote the
entry path to the probed instruction but the likelihood seems low and this
is just another example of how the kprobes user really needs to be
careful about what they are doing.


Of course user should be careful, but also, in such case, kernel can reject
to probe it.



I'm not exactly sure what you mean.  I'm just saying when everything 
goes right we still cannot promise perfection in detecting a probe 
within an atomic sequence.  This patch will reject a probe that is after 
a ldx and has no intervening kallsyms label (and assuming it's within 
the defined maximum count of subsequent instructions).






Signed-off-by: David A. Long <dave.l...@linaro.org>
---
  arch/arm64/kernel/probes/decode-insn.c | 48 --
  1 file changed, 23 insertions(+), 25 deletions(-)

diff --git a/arch/arm64/kernel/probes/decode-insn.c 
b/arch/arm64/kernel/probes/decode-insn.c
index 37e47a9..a691112 100644
--- a/arch/arm64/kernel/probes/decode-insn.c
+++ b/arch/arm64/kernel/probes/decode-insn.c
@@ -16,6 +16,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
@@ -122,7 +123,7 @@ arm_probe_decode_insn(kprobe_opcode_t insn, struct 
arch_specific_insn *asi)
  static bool __kprobes
  is_probed_address_atomic(kprobe_opcode_t *scan_start, kprobe_opcode_t 
*scan_end)
  {
-   while (scan_start > scan_end) {
+   while (scan_start >= scan_end) {
/*
 * atomic region starts from exclusive load and ends with
 * exclusive store.
@@ -142,33 +143,30 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct 
arch_specific_insn *asi)
  {
enum kprobe_insn decoded;
kprobe_opcode_t insn = le32_to_cpu(*addr);
-   kprobe_opcode_t *scan_start = addr - 1;
-   kprobe_opcode_t *scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
-#if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
-   struct module *mod;
-#endif
-
-   if (addr >= (kprobe_opcode_t *)_text &&
-   scan_end < (kprobe_opcode_t *)_text)
-   scan_end = (kprobe_opcode_t *)_text;
-#if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
-   else {
-   preempt_disable();
-   mod = __module_address((unsigned long)addr);
-   if (mod && within_module_init((unsigned long)addr, mod) &&
-   !within_module_init((unsigned long)scan_end, mod))
-   scan_end = (kprobe_opcode_t *)mod->init_layout.base;
-   else if (mod && within_module_core((unsigned long)addr, mod) &&
-   !within_module_core((unsigned long)scan_end, mod))
-   scan_end = (kprobe_opcode_t *)mod->core_layout.base;
-   preempt_enable();
+   kprobe_opcode_t *scan_end = 0;


Please use NULL for pointer.



A change has been made for v4.


+   unsigned long size = 0, offset = 0;
+
+   /*
+* If there's a symbol defined in front of and near enough to
+* the probe address assume it is the entry point to this
+* code and use it to further limit how far back we search
+* when determining if we're in an atomic sequence. If we could
+* not find any symbol skip the atomic test altogether as we
+* could otherwise end up searching irrelevant text/literals.
+* KPROBES depends on KALLSYMS so this last case should never
+* happen.
+*/
+   if (kallsyms_lookup_size_offset((unsigned long) addr, , )) {
+   if (offset < (MAX_ATOMIC_CONTEXT_SIZE*sizeof(kprobe_opcode_t)))
+   scan_end = addr - (offset / sizeof(kprobe_opcode_t));
+   else
+   scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;


 } else
return INSN_REJECTED;

   that is what I expected...

Thank you,


}
-#endif
decoded = arm_probe_decode_insn(insn, a

Re: [PATCH v3] arm64: Improve kprobes test for atomic sequence

2016-09-11 Thread David Long

On 09/10/2016 01:48 AM, Masami Hiramatsu wrote:

On Fri,  9 Sep 2016 15:26:09 -0400
David Long  wrote:


From: "David A. Long" 

Kprobes searches backwards a finite number of instructions to determine if
there is an attempt to probe a load/store exclusive sequence. It stops when
it hits the maximum number of instructions or a load or store exclusive.
However this means it can run up past the beginning of the function and
start looking at literal constants. This has been shown to cause a false
positive and blocks insertion of the probe. To fix this, further limit the
backwards search to stop if it hits a symbol address from kallsyms. The
presumption is that this is the entry point to this code (particularly for
the common case of placing probes at the beginning of functions).

This also improves efficiency by not searching code that is not part of the
function. There may be some possibility that the label might not denote the
entry path to the probed instruction but the likelihood seems low and this
is just another example of how the kprobes user really needs to be
careful about what they are doing.


Of course user should be careful, but also, in such case, kernel can reject
to probe it.



I'm not exactly sure what you mean.  I'm just saying when everything 
goes right we still cannot promise perfection in detecting a probe 
within an atomic sequence.  This patch will reject a probe that is after 
a ldx and has no intervening kallsyms label (and assuming it's within 
the defined maximum count of subsequent instructions).






Signed-off-by: David A. Long 
---
  arch/arm64/kernel/probes/decode-insn.c | 48 --
  1 file changed, 23 insertions(+), 25 deletions(-)

diff --git a/arch/arm64/kernel/probes/decode-insn.c 
b/arch/arm64/kernel/probes/decode-insn.c
index 37e47a9..a691112 100644
--- a/arch/arm64/kernel/probes/decode-insn.c
+++ b/arch/arm64/kernel/probes/decode-insn.c
@@ -16,6 +16,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
@@ -122,7 +123,7 @@ arm_probe_decode_insn(kprobe_opcode_t insn, struct 
arch_specific_insn *asi)
  static bool __kprobes
  is_probed_address_atomic(kprobe_opcode_t *scan_start, kprobe_opcode_t 
*scan_end)
  {
-   while (scan_start > scan_end) {
+   while (scan_start >= scan_end) {
/*
 * atomic region starts from exclusive load and ends with
 * exclusive store.
@@ -142,33 +143,30 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct 
arch_specific_insn *asi)
  {
enum kprobe_insn decoded;
kprobe_opcode_t insn = le32_to_cpu(*addr);
-   kprobe_opcode_t *scan_start = addr - 1;
-   kprobe_opcode_t *scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
-#if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
-   struct module *mod;
-#endif
-
-   if (addr >= (kprobe_opcode_t *)_text &&
-   scan_end < (kprobe_opcode_t *)_text)
-   scan_end = (kprobe_opcode_t *)_text;
-#if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
-   else {
-   preempt_disable();
-   mod = __module_address((unsigned long)addr);
-   if (mod && within_module_init((unsigned long)addr, mod) &&
-   !within_module_init((unsigned long)scan_end, mod))
-   scan_end = (kprobe_opcode_t *)mod->init_layout.base;
-   else if (mod && within_module_core((unsigned long)addr, mod) &&
-   !within_module_core((unsigned long)scan_end, mod))
-   scan_end = (kprobe_opcode_t *)mod->core_layout.base;
-   preempt_enable();
+   kprobe_opcode_t *scan_end = 0;


Please use NULL for pointer.



A change has been made for v4.


+   unsigned long size = 0, offset = 0;
+
+   /*
+* If there's a symbol defined in front of and near enough to
+* the probe address assume it is the entry point to this
+* code and use it to further limit how far back we search
+* when determining if we're in an atomic sequence. If we could
+* not find any symbol skip the atomic test altogether as we
+* could otherwise end up searching irrelevant text/literals.
+* KPROBES depends on KALLSYMS so this last case should never
+* happen.
+*/
+   if (kallsyms_lookup_size_offset((unsigned long) addr, , )) {
+   if (offset < (MAX_ATOMIC_CONTEXT_SIZE*sizeof(kprobe_opcode_t)))
+   scan_end = addr - (offset / sizeof(kprobe_opcode_t));
+   else
+   scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;


 } else
return INSN_REJECTED;

   that is what I expected...

Thank you,


}
-#endif
decoded = arm_probe_decode_insn(insn, asi);

-   if (decoded == INSN_REJECTED ||
-

[PATCH v3] arm64: Improve kprobes test for atomic sequence

2016-09-09 Thread David Long
From: "David A. Long" 

Kprobes searches backwards a finite number of instructions to determine if
there is an attempt to probe a load/store exclusive sequence. It stops when
it hits the maximum number of instructions or a load or store exclusive.
However this means it can run up past the beginning of the function and
start looking at literal constants. This has been shown to cause a false
positive and blocks insertion of the probe. To fix this, further limit the
backwards search to stop if it hits a symbol address from kallsyms. The
presumption is that this is the entry point to this code (particularly for
the common case of placing probes at the beginning of functions).

This also improves efficiency by not searching code that is not part of the
function. There may be some possibility that the label might not denote the
entry path to the probed instruction but the likelihood seems low and this
is just another example of how the kprobes user really needs to be
careful about what they are doing.

Signed-off-by: David A. Long 
---
 arch/arm64/kernel/probes/decode-insn.c | 48 --
 1 file changed, 23 insertions(+), 25 deletions(-)

diff --git a/arch/arm64/kernel/probes/decode-insn.c 
b/arch/arm64/kernel/probes/decode-insn.c
index 37e47a9..a691112 100644
--- a/arch/arm64/kernel/probes/decode-insn.c
+++ b/arch/arm64/kernel/probes/decode-insn.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -122,7 +123,7 @@ arm_probe_decode_insn(kprobe_opcode_t insn, struct 
arch_specific_insn *asi)
 static bool __kprobes
 is_probed_address_atomic(kprobe_opcode_t *scan_start, kprobe_opcode_t 
*scan_end)
 {
-   while (scan_start > scan_end) {
+   while (scan_start >= scan_end) {
/*
 * atomic region starts from exclusive load and ends with
 * exclusive store.
@@ -142,33 +143,30 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct 
arch_specific_insn *asi)
 {
enum kprobe_insn decoded;
kprobe_opcode_t insn = le32_to_cpu(*addr);
-   kprobe_opcode_t *scan_start = addr - 1;
-   kprobe_opcode_t *scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
-#if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
-   struct module *mod;
-#endif
-
-   if (addr >= (kprobe_opcode_t *)_text &&
-   scan_end < (kprobe_opcode_t *)_text)
-   scan_end = (kprobe_opcode_t *)_text;
-#if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
-   else {
-   preempt_disable();
-   mod = __module_address((unsigned long)addr);
-   if (mod && within_module_init((unsigned long)addr, mod) &&
-   !within_module_init((unsigned long)scan_end, mod))
-   scan_end = (kprobe_opcode_t *)mod->init_layout.base;
-   else if (mod && within_module_core((unsigned long)addr, mod) &&
-   !within_module_core((unsigned long)scan_end, mod))
-   scan_end = (kprobe_opcode_t *)mod->core_layout.base;
-   preempt_enable();
+   kprobe_opcode_t *scan_end = 0;
+   unsigned long size = 0, offset = 0;
+
+   /*
+* If there's a symbol defined in front of and near enough to
+* the probe address assume it is the entry point to this
+* code and use it to further limit how far back we search
+* when determining if we're in an atomic sequence. If we could
+* not find any symbol skip the atomic test altogether as we
+* could otherwise end up searching irrelevant text/literals.
+* KPROBES depends on KALLSYMS so this last case should never
+* happen.
+*/
+   if (kallsyms_lookup_size_offset((unsigned long) addr, , )) {
+   if (offset < (MAX_ATOMIC_CONTEXT_SIZE*sizeof(kprobe_opcode_t)))
+   scan_end = addr - (offset / sizeof(kprobe_opcode_t));
+   else
+   scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
}
-#endif
decoded = arm_probe_decode_insn(insn, asi);
 
-   if (decoded == INSN_REJECTED ||
-   is_probed_address_atomic(scan_start, scan_end))
-   return INSN_REJECTED;
+   if (decoded != INSN_REJECTED && scan_end)
+   if (is_probed_address_atomic(addr - 1, scan_end))
+   return INSN_REJECTED;
 
return decoded;
 }
-- 
2.5.0



[PATCH v3] arm64: Improve kprobes test for atomic sequence

2016-09-09 Thread David Long
From: "David A. Long" 

Kprobes searches backwards a finite number of instructions to determine if
there is an attempt to probe a load/store exclusive sequence. It stops when
it hits the maximum number of instructions or a load or store exclusive.
However this means it can run up past the beginning of the function and
start looking at literal constants. This has been shown to cause a false
positive and blocks insertion of the probe. To fix this, further limit the
backwards search to stop if it hits a symbol address from kallsyms. The
presumption is that this is the entry point to this code (particularly for
the common case of placing probes at the beginning of functions).

This also improves efficiency by not searching code that is not part of the
function. There may be some possibility that the label might not denote the
entry path to the probed instruction but the likelihood seems low and this
is just another example of how the kprobes user really needs to be
careful about what they are doing.

Signed-off-by: David A. Long 
---
 arch/arm64/kernel/probes/decode-insn.c | 48 --
 1 file changed, 23 insertions(+), 25 deletions(-)

diff --git a/arch/arm64/kernel/probes/decode-insn.c 
b/arch/arm64/kernel/probes/decode-insn.c
index 37e47a9..a691112 100644
--- a/arch/arm64/kernel/probes/decode-insn.c
+++ b/arch/arm64/kernel/probes/decode-insn.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -122,7 +123,7 @@ arm_probe_decode_insn(kprobe_opcode_t insn, struct 
arch_specific_insn *asi)
 static bool __kprobes
 is_probed_address_atomic(kprobe_opcode_t *scan_start, kprobe_opcode_t 
*scan_end)
 {
-   while (scan_start > scan_end) {
+   while (scan_start >= scan_end) {
/*
 * atomic region starts from exclusive load and ends with
 * exclusive store.
@@ -142,33 +143,30 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct 
arch_specific_insn *asi)
 {
enum kprobe_insn decoded;
kprobe_opcode_t insn = le32_to_cpu(*addr);
-   kprobe_opcode_t *scan_start = addr - 1;
-   kprobe_opcode_t *scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
-#if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
-   struct module *mod;
-#endif
-
-   if (addr >= (kprobe_opcode_t *)_text &&
-   scan_end < (kprobe_opcode_t *)_text)
-   scan_end = (kprobe_opcode_t *)_text;
-#if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
-   else {
-   preempt_disable();
-   mod = __module_address((unsigned long)addr);
-   if (mod && within_module_init((unsigned long)addr, mod) &&
-   !within_module_init((unsigned long)scan_end, mod))
-   scan_end = (kprobe_opcode_t *)mod->init_layout.base;
-   else if (mod && within_module_core((unsigned long)addr, mod) &&
-   !within_module_core((unsigned long)scan_end, mod))
-   scan_end = (kprobe_opcode_t *)mod->core_layout.base;
-   preempt_enable();
+   kprobe_opcode_t *scan_end = 0;
+   unsigned long size = 0, offset = 0;
+
+   /*
+* If there's a symbol defined in front of and near enough to
+* the probe address assume it is the entry point to this
+* code and use it to further limit how far back we search
+* when determining if we're in an atomic sequence. If we could
+* not find any symbol skip the atomic test altogether as we
+* could otherwise end up searching irrelevant text/literals.
+* KPROBES depends on KALLSYMS so this last case should never
+* happen.
+*/
+   if (kallsyms_lookup_size_offset((unsigned long) addr, , )) {
+   if (offset < (MAX_ATOMIC_CONTEXT_SIZE*sizeof(kprobe_opcode_t)))
+   scan_end = addr - (offset / sizeof(kprobe_opcode_t));
+   else
+   scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
}
-#endif
decoded = arm_probe_decode_insn(insn, asi);
 
-   if (decoded == INSN_REJECTED ||
-   is_probed_address_atomic(scan_start, scan_end))
-   return INSN_REJECTED;
+   if (decoded != INSN_REJECTED && scan_end)
+   if (is_probed_address_atomic(addr - 1, scan_end))
+   return INSN_REJECTED;
 
return decoded;
 }
-- 
2.5.0



Re: [PATCH v2] arm64: Improve kprobes test for atomic sequence

2016-09-07 Thread David Long

On 09/07/2016 01:52 AM, Masami Hiramatsu wrote:

On Tue,  6 Sep 2016 13:54:59 -0400
David Long <dave.l...@linaro.org> wrote:


From: "David A. Long" <dave.l...@linaro.org>

Kprobes searches backwards a finite number of instructions to determine if
there is an attempt to probe a load/store exclusive sequence. It stops when
it hits the maximum number of instructions or a load or store exclusive.
However this means it can run up past the beginning of the function and
start looking at literal constants. This has been shown to cause a false
positive and blocks insertion of the probe. To fix this, further limit the
backwards search to stop if it hits a symbol address from kallsyms. The
presumption is that this is the entry point to this code (particularly for
the common case of placing probes at the beginning of functions).

This also improves efficiency by not searching code that is not part of the
function. There may be some possibility that the label might not denote the
entry path to the probed instruction but the likelihood seems low and this
is just another example of how the kprobes user really needs to be
careful about what they are doing.


Hi Dave,

kallsyms_lookup_size_offset() part looks good to me. By the way,
is there any reason we'll check the _text and module's base address
boundary?
I think those are already searced by kallsyms_lookup_size_offset(),
so you don't need to check those. If the address is not found by
kallsyms_lookup_size_offset(), that address maybe out-of-text.



CONFIG KPROBES does currently select CONFIG_KALLSYMS, but is it wise for 
this code to depend on that?  Perhaps the text boundary checking should 
be moved under an else clause for the case of 
kallsyms_lookup_size_offset() failing?



Thank you,


Signed-off-by: David A. Long <dave.l...@linaro.org>
---
  arch/arm64/kernel/probes/decode-insn.c | 48 +++---
  1 file changed, 33 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/kernel/probes/decode-insn.c 
b/arch/arm64/kernel/probes/decode-insn.c
index 37e47a9..356ee52 100644
--- a/arch/arm64/kernel/probes/decode-insn.c
+++ b/arch/arm64/kernel/probes/decode-insn.c
@@ -16,6 +16,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
@@ -122,7 +123,7 @@ arm_probe_decode_insn(kprobe_opcode_t insn, struct 
arch_specific_insn *asi)
  static bool __kprobes
  is_probed_address_atomic(kprobe_opcode_t *scan_start, kprobe_opcode_t 
*scan_end)
  {
-   while (scan_start > scan_end) {
+   while (scan_start >= scan_end) {
/*
 * atomic region starts from exclusive load and ends with
 * exclusive store.
@@ -144,26 +145,43 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct 
arch_specific_insn *asi)
kprobe_opcode_t insn = le32_to_cpu(*addr);
kprobe_opcode_t *scan_start = addr - 1;
kprobe_opcode_t *scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
+   unsigned long size = 0, offset = 0;
  #if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
struct module *mod;
  #endif

-   if (addr >= (kprobe_opcode_t *)_text &&
-   scan_end < (kprobe_opcode_t *)_text)
-   scan_end = (kprobe_opcode_t *)_text;
+   /*
+* If there's a symbol defined in front of and near enough to
+* the probe address assume it is the entry point to this
+* code and use it to further limit how far back we search
+* when determining if we're in an atomic sequence.
+*/
+   if (kallsyms_lookup_size_offset((unsigned long) addr, , ))
+   if (offset < (MAX_ATOMIC_CONTEXT_SIZE*sizeof(kprobe_opcode_t)))
+   scan_end = addr - (offset / sizeof(kprobe_opcode_t));
+
+   if (scan_end <= scan_start) {
+   if (addr >= (kprobe_opcode_t *)_text &&
+   scan_end < (kprobe_opcode_t *)_text)
+   scan_end = (kprobe_opcode_t *)_text;
  #if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
-   else {
-   preempt_disable();
-   mod = __module_address((unsigned long)addr);
-   if (mod && within_module_init((unsigned long)addr, mod) &&
-   !within_module_init((unsigned long)scan_end, mod))
-   scan_end = (kprobe_opcode_t *)mod->init_layout.base;
-   else if (mod && within_module_core((unsigned long)addr, mod) &&
-   !within_module_core((unsigned long)scan_end, mod))
-   scan_end = (kprobe_opcode_t *)mod->core_layout.base;
-   preempt_enable();
-   }
+   else {
+   preempt_disable();
+   mod = __module_address((unsigned long)addr);
+   if (mod &&
+ 

Re: [PATCH v2] arm64: Improve kprobes test for atomic sequence

2016-09-07 Thread David Long

On 09/07/2016 01:52 AM, Masami Hiramatsu wrote:

On Tue,  6 Sep 2016 13:54:59 -0400
David Long  wrote:


From: "David A. Long" 

Kprobes searches backwards a finite number of instructions to determine if
there is an attempt to probe a load/store exclusive sequence. It stops when
it hits the maximum number of instructions or a load or store exclusive.
However this means it can run up past the beginning of the function and
start looking at literal constants. This has been shown to cause a false
positive and blocks insertion of the probe. To fix this, further limit the
backwards search to stop if it hits a symbol address from kallsyms. The
presumption is that this is the entry point to this code (particularly for
the common case of placing probes at the beginning of functions).

This also improves efficiency by not searching code that is not part of the
function. There may be some possibility that the label might not denote the
entry path to the probed instruction but the likelihood seems low and this
is just another example of how the kprobes user really needs to be
careful about what they are doing.


Hi Dave,

kallsyms_lookup_size_offset() part looks good to me. By the way,
is there any reason we'll check the _text and module's base address
boundary?
I think those are already searced by kallsyms_lookup_size_offset(),
so you don't need to check those. If the address is not found by
kallsyms_lookup_size_offset(), that address maybe out-of-text.



CONFIG KPROBES does currently select CONFIG_KALLSYMS, but is it wise for 
this code to depend on that?  Perhaps the text boundary checking should 
be moved under an else clause for the case of 
kallsyms_lookup_size_offset() failing?



Thank you,


Signed-off-by: David A. Long 
---
  arch/arm64/kernel/probes/decode-insn.c | 48 +++---
  1 file changed, 33 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/kernel/probes/decode-insn.c 
b/arch/arm64/kernel/probes/decode-insn.c
index 37e47a9..356ee52 100644
--- a/arch/arm64/kernel/probes/decode-insn.c
+++ b/arch/arm64/kernel/probes/decode-insn.c
@@ -16,6 +16,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
@@ -122,7 +123,7 @@ arm_probe_decode_insn(kprobe_opcode_t insn, struct 
arch_specific_insn *asi)
  static bool __kprobes
  is_probed_address_atomic(kprobe_opcode_t *scan_start, kprobe_opcode_t 
*scan_end)
  {
-   while (scan_start > scan_end) {
+   while (scan_start >= scan_end) {
/*
 * atomic region starts from exclusive load and ends with
 * exclusive store.
@@ -144,26 +145,43 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct 
arch_specific_insn *asi)
kprobe_opcode_t insn = le32_to_cpu(*addr);
kprobe_opcode_t *scan_start = addr - 1;
kprobe_opcode_t *scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
+   unsigned long size = 0, offset = 0;
  #if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
struct module *mod;
  #endif

-   if (addr >= (kprobe_opcode_t *)_text &&
-   scan_end < (kprobe_opcode_t *)_text)
-   scan_end = (kprobe_opcode_t *)_text;
+   /*
+* If there's a symbol defined in front of and near enough to
+* the probe address assume it is the entry point to this
+* code and use it to further limit how far back we search
+* when determining if we're in an atomic sequence.
+*/
+   if (kallsyms_lookup_size_offset((unsigned long) addr, , ))
+   if (offset < (MAX_ATOMIC_CONTEXT_SIZE*sizeof(kprobe_opcode_t)))
+   scan_end = addr - (offset / sizeof(kprobe_opcode_t));
+
+   if (scan_end <= scan_start) {
+   if (addr >= (kprobe_opcode_t *)_text &&
+   scan_end < (kprobe_opcode_t *)_text)
+   scan_end = (kprobe_opcode_t *)_text;
  #if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
-   else {
-   preempt_disable();
-   mod = __module_address((unsigned long)addr);
-   if (mod && within_module_init((unsigned long)addr, mod) &&
-   !within_module_init((unsigned long)scan_end, mod))
-   scan_end = (kprobe_opcode_t *)mod->init_layout.base;
-   else if (mod && within_module_core((unsigned long)addr, mod) &&
-   !within_module_core((unsigned long)scan_end, mod))
-   scan_end = (kprobe_opcode_t *)mod->core_layout.base;
-   preempt_enable();
-   }
+   else {
+   preempt_disable();
+   mod = __module_address((unsigned long)addr);
+   if (mod &&
+   within_module_init((unsigned long)addr, mod) &&
+   !within_module_init((unsig

Re: [PATCH 3/5] arm64: Handle TRAP_HWBRKPT for user mode as well

2016-09-06 Thread David Long

On 09/06/2016 12:11 PM, Catalin Marinas wrote:

On Tue, Aug 02, 2016 at 11:00:07AM +0530, Pratyush Anand wrote:

--- a/arch/arm64/kernel/debug-monitors.c
+++ b/arch/arm64/kernel/debug-monitors.c
@@ -246,6 +246,8 @@ static void send_user_sigtrap(int si_code)
  static int single_step_handler(unsigned long addr, unsigned int esr,
   struct pt_regs *regs)
  {
+   bool handler_found = false;
+
/*
 * If we are stepping a pending breakpoint, call the hw_breakpoint
 * handler first.
@@ -253,7 +255,14 @@ static int single_step_handler(unsigned long addr, 
unsigned int esr,
if (!reinstall_suspended_bps(regs))
return 0;

-   if (user_mode(regs)) {
+#ifdef CONFIG_KPROBES
+   if (kprobe_single_step_handler(regs, esr) == DBG_HOOK_HANDLED)
+   handler_found = true;
+#endif
+   if (!handler_found && call_step_hook(regs, esr) == DBG_HOOK_HANDLED)
+   handler_found = true;
+
+   if (!handler_found && user_mode(regs)) {
send_user_sigtrap(TRAP_HWBKPT);


Could we register kprobe_single_step_handler() via register_set_hook()
and only invoke call_step_hook() above?



I seem to recall a criticism of doing that in a much earlier kprobes64 
patch of mine.  The concern was that it would cause unnecessarily more 
kernel functions to be kprobes-blacklisted.  Hence the hardcoded check 
and call.


-dl



Re: [PATCH 3/5] arm64: Handle TRAP_HWBRKPT for user mode as well

2016-09-06 Thread David Long

On 09/06/2016 12:11 PM, Catalin Marinas wrote:

On Tue, Aug 02, 2016 at 11:00:07AM +0530, Pratyush Anand wrote:

--- a/arch/arm64/kernel/debug-monitors.c
+++ b/arch/arm64/kernel/debug-monitors.c
@@ -246,6 +246,8 @@ static void send_user_sigtrap(int si_code)
  static int single_step_handler(unsigned long addr, unsigned int esr,
   struct pt_regs *regs)
  {
+   bool handler_found = false;
+
/*
 * If we are stepping a pending breakpoint, call the hw_breakpoint
 * handler first.
@@ -253,7 +255,14 @@ static int single_step_handler(unsigned long addr, 
unsigned int esr,
if (!reinstall_suspended_bps(regs))
return 0;

-   if (user_mode(regs)) {
+#ifdef CONFIG_KPROBES
+   if (kprobe_single_step_handler(regs, esr) == DBG_HOOK_HANDLED)
+   handler_found = true;
+#endif
+   if (!handler_found && call_step_hook(regs, esr) == DBG_HOOK_HANDLED)
+   handler_found = true;
+
+   if (!handler_found && user_mode(regs)) {
send_user_sigtrap(TRAP_HWBKPT);


Could we register kprobe_single_step_handler() via register_set_hook()
and only invoke call_step_hook() above?



I seem to recall a criticism of doing that in a much earlier kprobes64 
patch of mine.  The concern was that it would cause unnecessarily more 
kernel functions to be kprobes-blacklisted.  Hence the hardcoded check 
and call.


-dl



[PATCH v2] arm64: Improve kprobes test for atomic sequence

2016-09-06 Thread David Long
From: "David A. Long" 

Kprobes searches backwards a finite number of instructions to determine if
there is an attempt to probe a load/store exclusive sequence. It stops when
it hits the maximum number of instructions or a load or store exclusive.
However this means it can run up past the beginning of the function and
start looking at literal constants. This has been shown to cause a false
positive and blocks insertion of the probe. To fix this, further limit the
backwards search to stop if it hits a symbol address from kallsyms. The
presumption is that this is the entry point to this code (particularly for
the common case of placing probes at the beginning of functions).

This also improves efficiency by not searching code that is not part of the
function. There may be some possibility that the label might not denote the
entry path to the probed instruction but the likelihood seems low and this
is just another example of how the kprobes user really needs to be
careful about what they are doing.

Signed-off-by: David A. Long 
---
 arch/arm64/kernel/probes/decode-insn.c | 48 +++---
 1 file changed, 33 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/kernel/probes/decode-insn.c 
b/arch/arm64/kernel/probes/decode-insn.c
index 37e47a9..356ee52 100644
--- a/arch/arm64/kernel/probes/decode-insn.c
+++ b/arch/arm64/kernel/probes/decode-insn.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -122,7 +123,7 @@ arm_probe_decode_insn(kprobe_opcode_t insn, struct 
arch_specific_insn *asi)
 static bool __kprobes
 is_probed_address_atomic(kprobe_opcode_t *scan_start, kprobe_opcode_t 
*scan_end)
 {
-   while (scan_start > scan_end) {
+   while (scan_start >= scan_end) {
/*
 * atomic region starts from exclusive load and ends with
 * exclusive store.
@@ -144,26 +145,43 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct 
arch_specific_insn *asi)
kprobe_opcode_t insn = le32_to_cpu(*addr);
kprobe_opcode_t *scan_start = addr - 1;
kprobe_opcode_t *scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
+   unsigned long size = 0, offset = 0;
 #if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
struct module *mod;
 #endif
 
-   if (addr >= (kprobe_opcode_t *)_text &&
-   scan_end < (kprobe_opcode_t *)_text)
-   scan_end = (kprobe_opcode_t *)_text;
+   /*
+* If there's a symbol defined in front of and near enough to
+* the probe address assume it is the entry point to this
+* code and use it to further limit how far back we search
+* when determining if we're in an atomic sequence.
+*/
+   if (kallsyms_lookup_size_offset((unsigned long) addr, , ))
+   if (offset < (MAX_ATOMIC_CONTEXT_SIZE*sizeof(kprobe_opcode_t)))
+   scan_end = addr - (offset / sizeof(kprobe_opcode_t));
+
+   if (scan_end <= scan_start) {
+   if (addr >= (kprobe_opcode_t *)_text &&
+   scan_end < (kprobe_opcode_t *)_text)
+   scan_end = (kprobe_opcode_t *)_text;
 #if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
-   else {
-   preempt_disable();
-   mod = __module_address((unsigned long)addr);
-   if (mod && within_module_init((unsigned long)addr, mod) &&
-   !within_module_init((unsigned long)scan_end, mod))
-   scan_end = (kprobe_opcode_t *)mod->init_layout.base;
-   else if (mod && within_module_core((unsigned long)addr, mod) &&
-   !within_module_core((unsigned long)scan_end, mod))
-   scan_end = (kprobe_opcode_t *)mod->core_layout.base;
-   preempt_enable();
-   }
+   else {
+   preempt_disable();
+   mod = __module_address((unsigned long)addr);
+   if (mod &&
+   within_module_init((unsigned long)addr, mod) &&
+   !within_module_init((unsigned long)scan_end, mod))
+   scan_end =
+   (kprobe_opcode_t *)mod->init_layout.base;
+   else if (mod &&
+   within_module_core((unsigned long)addr, mod) &&
+   !within_module_core((unsigned long)scan_end, mod))
+   scan_end =
+   (kprobe_opcode_t *)mod->core_layout.base;
+   preempt_enable();
+   }
 #endif
+   }
decoded = arm_probe_decode_insn(insn, asi);
 
if (decoded == INSN_REJECTED ||
-- 
2.5.0



[PATCH v2] arm64: Improve kprobes test for atomic sequence

2016-09-06 Thread David Long
From: "David A. Long" 

Kprobes searches backwards a finite number of instructions to determine if
there is an attempt to probe a load/store exclusive sequence. It stops when
it hits the maximum number of instructions or a load or store exclusive.
However this means it can run up past the beginning of the function and
start looking at literal constants. This has been shown to cause a false
positive and blocks insertion of the probe. To fix this, further limit the
backwards search to stop if it hits a symbol address from kallsyms. The
presumption is that this is the entry point to this code (particularly for
the common case of placing probes at the beginning of functions).

This also improves efficiency by not searching code that is not part of the
function. There may be some possibility that the label might not denote the
entry path to the probed instruction but the likelihood seems low and this
is just another example of how the kprobes user really needs to be
careful about what they are doing.

Signed-off-by: David A. Long 
---
 arch/arm64/kernel/probes/decode-insn.c | 48 +++---
 1 file changed, 33 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/kernel/probes/decode-insn.c 
b/arch/arm64/kernel/probes/decode-insn.c
index 37e47a9..356ee52 100644
--- a/arch/arm64/kernel/probes/decode-insn.c
+++ b/arch/arm64/kernel/probes/decode-insn.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -122,7 +123,7 @@ arm_probe_decode_insn(kprobe_opcode_t insn, struct 
arch_specific_insn *asi)
 static bool __kprobes
 is_probed_address_atomic(kprobe_opcode_t *scan_start, kprobe_opcode_t 
*scan_end)
 {
-   while (scan_start > scan_end) {
+   while (scan_start >= scan_end) {
/*
 * atomic region starts from exclusive load and ends with
 * exclusive store.
@@ -144,26 +145,43 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct 
arch_specific_insn *asi)
kprobe_opcode_t insn = le32_to_cpu(*addr);
kprobe_opcode_t *scan_start = addr - 1;
kprobe_opcode_t *scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
+   unsigned long size = 0, offset = 0;
 #if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
struct module *mod;
 #endif
 
-   if (addr >= (kprobe_opcode_t *)_text &&
-   scan_end < (kprobe_opcode_t *)_text)
-   scan_end = (kprobe_opcode_t *)_text;
+   /*
+* If there's a symbol defined in front of and near enough to
+* the probe address assume it is the entry point to this
+* code and use it to further limit how far back we search
+* when determining if we're in an atomic sequence.
+*/
+   if (kallsyms_lookup_size_offset((unsigned long) addr, , ))
+   if (offset < (MAX_ATOMIC_CONTEXT_SIZE*sizeof(kprobe_opcode_t)))
+   scan_end = addr - (offset / sizeof(kprobe_opcode_t));
+
+   if (scan_end <= scan_start) {
+   if (addr >= (kprobe_opcode_t *)_text &&
+   scan_end < (kprobe_opcode_t *)_text)
+   scan_end = (kprobe_opcode_t *)_text;
 #if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
-   else {
-   preempt_disable();
-   mod = __module_address((unsigned long)addr);
-   if (mod && within_module_init((unsigned long)addr, mod) &&
-   !within_module_init((unsigned long)scan_end, mod))
-   scan_end = (kprobe_opcode_t *)mod->init_layout.base;
-   else if (mod && within_module_core((unsigned long)addr, mod) &&
-   !within_module_core((unsigned long)scan_end, mod))
-   scan_end = (kprobe_opcode_t *)mod->core_layout.base;
-   preempt_enable();
-   }
+   else {
+   preempt_disable();
+   mod = __module_address((unsigned long)addr);
+   if (mod &&
+   within_module_init((unsigned long)addr, mod) &&
+   !within_module_init((unsigned long)scan_end, mod))
+   scan_end =
+   (kprobe_opcode_t *)mod->init_layout.base;
+   else if (mod &&
+   within_module_core((unsigned long)addr, mod) &&
+   !within_module_core((unsigned long)scan_end, mod))
+   scan_end =
+   (kprobe_opcode_t *)mod->core_layout.base;
+   preempt_enable();
+   }
 #endif
+   }
decoded = arm_probe_decode_insn(insn, asi);
 
if (decoded == INSN_REJECTED ||
-- 
2.5.0



Re: [PATCH] arm64: Improve kprobes test for atomic sequence

2016-09-01 Thread David Long

On 08/31/2016 10:38 PM, Masami Hiramatsu wrote:

Hi Dave,

On Wed, 31 Aug 2016 16:52:22 -0400
David Long <dave.l...@linaro.org> wrote:


From: "David A. Long" <dave.l...@linaro.org>

Kprobes searches backwards a finite number of instructions to determine if
there is an attempt to probe a load/store exclusive sequence. It stops when
it hits the maximum number of instructions or a load or store exclusive.


Hmm, so on aarch64, we can not put a kprobe between load exclusive and
store exclusive, because kprobe always breaks the atomicity, am I correct?


Yes.


If so, what happen if any branch in the sequence? e.g.

   load-ex
   (do something)
l1:
   store-ex
...
   load-ex
   (do something)
   branch l1;



I'm sure atomic code can be constructed in a way which we don't detect, 
and probably can't detect, this is just a "best effort".



However this means it can run up past the beginning of the function and
start looking at literal constants. This has been shown to cause a false
positive and blocks insertion of the probe. To fix this add a test to see
if the typical:

"stp x29, x30, [sp, #n]!"

instruction beginning a function gets hit. This also improves efficiency by
not testing code that is not part of the function. There is some
possibility that a function will not begin with this instruction, in which
case the fixed code will behave no worse than before.


If the function boundary is the problem, why you wouldn't use kallsyms 
information
as I did in can_optimize()@arch/x86/kernel/kprobes/opt.c ?

 /* Lookup symbol including addr */
 if (!kallsyms_lookup_size_offset(paddr, , ))
 return 0;

With this call, symbol start address is (paddr - offset) and end address
is (paddr - offset + size).



Thanks for pointing this out.  I shall work on a V2 patch ASAP.


Thank you,



There could also be the case that the stp instruction is found further in
the body of the function, which could theoretically allow probing of an
atomic squence. The likelihood of this seems low, and this would not be the
only aspect of kprobes where the user needs to be careful to avoid
problems.

Signed-off-by: David A. Long <dave.l...@linaro.org>
---
  arch/arm64/kernel/probes/decode-insn.c | 25 ++---
  1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/kernel/probes/decode-insn.c 
b/arch/arm64/kernel/probes/decode-insn.c
index 37e47a9..248e820 100644
--- a/arch/arm64/kernel/probes/decode-insn.c
+++ b/arch/arm64/kernel/probes/decode-insn.c
@@ -122,16 +122,28 @@ arm_probe_decode_insn(kprobe_opcode_t insn, struct 
arch_specific_insn *asi)
  static bool __kprobes
  is_probed_address_atomic(kprobe_opcode_t *scan_start, kprobe_opcode_t 
*scan_end)
  {
+   const u32 stp_x29_x30_sp_pre = 0xa9807bfd;
+   const u32 stp_ignore_index_mask = 0xffc07fff;
+   u32 instruction = le32_to_cpu(*scan_start);
+
while (scan_start > scan_end) {
/*
-* atomic region starts from exclusive load and ends with
-* exclusive store.
+* Atomic region starts from exclusive load and ends with
+* exclusive store. If we hit a "stp x29, x30, [sp, #n]!"
+* assume it is the beginning of the function and end the
+* search. This helps avoid false positives from literal
+* constants that look like a load-exclusive, in addition
+* to being more efficient.
 */
-   if (aarch64_insn_is_store_ex(le32_to_cpu(*scan_start)))
+   if ((instruction & stp_ignore_index_mask) == stp_x29_x30_sp_pre)
return false;
-   else if (aarch64_insn_is_load_ex(le32_to_cpu(*scan_start)))
-   return true;
+
scan_start--;
+   instruction = le32_to_cpu(*scan_start);
+   if (aarch64_insn_is_store_ex(instruction))
+   return false;
+   else if (aarch64_insn_is_load_ex(instruction))
+   return true;
}

return false;
@@ -142,7 +154,6 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct 
arch_specific_insn *asi)
  {
enum kprobe_insn decoded;
kprobe_opcode_t insn = le32_to_cpu(*addr);
-   kprobe_opcode_t *scan_start = addr - 1;
kprobe_opcode_t *scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
  #if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
struct module *mod;
@@ -167,7 +178,7 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct 
arch_specific_insn *asi)
decoded = arm_probe_decode_insn(insn, asi);

if (decoded == INSN_REJECTED ||
-   is_probed_address_atomic(scan_start, scan_end))
+   is_probed_address_atomic(addr, scan_end))
return INSN_REJECTED;

return decoded;
--
2.5.0






Thanks,
-dl


Re: [PATCH] arm64: Improve kprobes test for atomic sequence

2016-09-01 Thread David Long

On 08/31/2016 10:38 PM, Masami Hiramatsu wrote:

Hi Dave,

On Wed, 31 Aug 2016 16:52:22 -0400
David Long  wrote:


From: "David A. Long" 

Kprobes searches backwards a finite number of instructions to determine if
there is an attempt to probe a load/store exclusive sequence. It stops when
it hits the maximum number of instructions or a load or store exclusive.


Hmm, so on aarch64, we can not put a kprobe between load exclusive and
store exclusive, because kprobe always breaks the atomicity, am I correct?


Yes.


If so, what happen if any branch in the sequence? e.g.

   load-ex
   (do something)
l1:
   store-ex
...
   load-ex
   (do something)
   branch l1;



I'm sure atomic code can be constructed in a way which we don't detect, 
and probably can't detect, this is just a "best effort".



However this means it can run up past the beginning of the function and
start looking at literal constants. This has been shown to cause a false
positive and blocks insertion of the probe. To fix this add a test to see
if the typical:

"stp x29, x30, [sp, #n]!"

instruction beginning a function gets hit. This also improves efficiency by
not testing code that is not part of the function. There is some
possibility that a function will not begin with this instruction, in which
case the fixed code will behave no worse than before.


If the function boundary is the problem, why you wouldn't use kallsyms 
information
as I did in can_optimize()@arch/x86/kernel/kprobes/opt.c ?

 /* Lookup symbol including addr */
 if (!kallsyms_lookup_size_offset(paddr, , ))
 return 0;

With this call, symbol start address is (paddr - offset) and end address
is (paddr - offset + size).



Thanks for pointing this out.  I shall work on a V2 patch ASAP.


Thank you,



There could also be the case that the stp instruction is found further in
the body of the function, which could theoretically allow probing of an
atomic squence. The likelihood of this seems low, and this would not be the
only aspect of kprobes where the user needs to be careful to avoid
problems.

Signed-off-by: David A. Long 
---
  arch/arm64/kernel/probes/decode-insn.c | 25 ++---
  1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/kernel/probes/decode-insn.c 
b/arch/arm64/kernel/probes/decode-insn.c
index 37e47a9..248e820 100644
--- a/arch/arm64/kernel/probes/decode-insn.c
+++ b/arch/arm64/kernel/probes/decode-insn.c
@@ -122,16 +122,28 @@ arm_probe_decode_insn(kprobe_opcode_t insn, struct 
arch_specific_insn *asi)
  static bool __kprobes
  is_probed_address_atomic(kprobe_opcode_t *scan_start, kprobe_opcode_t 
*scan_end)
  {
+   const u32 stp_x29_x30_sp_pre = 0xa9807bfd;
+   const u32 stp_ignore_index_mask = 0xffc07fff;
+   u32 instruction = le32_to_cpu(*scan_start);
+
while (scan_start > scan_end) {
/*
-* atomic region starts from exclusive load and ends with
-* exclusive store.
+* Atomic region starts from exclusive load and ends with
+* exclusive store. If we hit a "stp x29, x30, [sp, #n]!"
+* assume it is the beginning of the function and end the
+* search. This helps avoid false positives from literal
+* constants that look like a load-exclusive, in addition
+* to being more efficient.
 */
-   if (aarch64_insn_is_store_ex(le32_to_cpu(*scan_start)))
+   if ((instruction & stp_ignore_index_mask) == stp_x29_x30_sp_pre)
return false;
-   else if (aarch64_insn_is_load_ex(le32_to_cpu(*scan_start)))
-   return true;
+
scan_start--;
+   instruction = le32_to_cpu(*scan_start);
+   if (aarch64_insn_is_store_ex(instruction))
+   return false;
+   else if (aarch64_insn_is_load_ex(instruction))
+   return true;
}

return false;
@@ -142,7 +154,6 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct 
arch_specific_insn *asi)
  {
enum kprobe_insn decoded;
kprobe_opcode_t insn = le32_to_cpu(*addr);
-   kprobe_opcode_t *scan_start = addr - 1;
kprobe_opcode_t *scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
  #if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
struct module *mod;
@@ -167,7 +178,7 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct 
arch_specific_insn *asi)
decoded = arm_probe_decode_insn(insn, asi);

if (decoded == INSN_REJECTED ||
-   is_probed_address_atomic(scan_start, scan_end))
+   is_probed_address_atomic(addr, scan_end))
return INSN_REJECTED;

return decoded;
--
2.5.0






Thanks,
-dl


[PATCH] arm64: Improve kprobes test for atomic sequence

2016-08-31 Thread David Long
From: "David A. Long" 

Kprobes searches backwards a finite number of instructions to determine if
there is an attempt to probe a load/store exclusive sequence. It stops when
it hits the maximum number of instructions or a load or store exclusive.
However this means it can run up past the beginning of the function and
start looking at literal constants. This has been shown to cause a false
positive and blocks insertion of the probe. To fix this add a test to see
if the typical:

"stp x29, x30, [sp, #n]!"

instruction beginning a function gets hit. This also improves efficiency by
not testing code that is not part of the function. There is some
possibility that a function will not begin with this instruction, in which
case the fixed code will behave no worse than before.

There could also be the case that the stp instruction is found further in
the body of the function, which could theoretically allow probing of an
atomic squence. The likelihood of this seems low, and this would not be the
only aspect of kprobes where the user needs to be careful to avoid
problems.

Signed-off-by: David A. Long 
---
 arch/arm64/kernel/probes/decode-insn.c | 25 ++---
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/kernel/probes/decode-insn.c 
b/arch/arm64/kernel/probes/decode-insn.c
index 37e47a9..248e820 100644
--- a/arch/arm64/kernel/probes/decode-insn.c
+++ b/arch/arm64/kernel/probes/decode-insn.c
@@ -122,16 +122,28 @@ arm_probe_decode_insn(kprobe_opcode_t insn, struct 
arch_specific_insn *asi)
 static bool __kprobes
 is_probed_address_atomic(kprobe_opcode_t *scan_start, kprobe_opcode_t 
*scan_end)
 {
+   const u32 stp_x29_x30_sp_pre = 0xa9807bfd;
+   const u32 stp_ignore_index_mask = 0xffc07fff;
+   u32 instruction = le32_to_cpu(*scan_start);
+
while (scan_start > scan_end) {
/*
-* atomic region starts from exclusive load and ends with
-* exclusive store.
+* Atomic region starts from exclusive load and ends with
+* exclusive store. If we hit a "stp x29, x30, [sp, #n]!"
+* assume it is the beginning of the function and end the
+* search. This helps avoid false positives from literal
+* constants that look like a load-exclusive, in addition
+* to being more efficient.
 */
-   if (aarch64_insn_is_store_ex(le32_to_cpu(*scan_start)))
+   if ((instruction & stp_ignore_index_mask) == stp_x29_x30_sp_pre)
return false;
-   else if (aarch64_insn_is_load_ex(le32_to_cpu(*scan_start)))
-   return true;
+
scan_start--;
+   instruction = le32_to_cpu(*scan_start);
+   if (aarch64_insn_is_store_ex(instruction))
+   return false;
+   else if (aarch64_insn_is_load_ex(instruction))
+   return true;
}
 
return false;
@@ -142,7 +154,6 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct 
arch_specific_insn *asi)
 {
enum kprobe_insn decoded;
kprobe_opcode_t insn = le32_to_cpu(*addr);
-   kprobe_opcode_t *scan_start = addr - 1;
kprobe_opcode_t *scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
 #if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
struct module *mod;
@@ -167,7 +178,7 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct 
arch_specific_insn *asi)
decoded = arm_probe_decode_insn(insn, asi);
 
if (decoded == INSN_REJECTED ||
-   is_probed_address_atomic(scan_start, scan_end))
+   is_probed_address_atomic(addr, scan_end))
return INSN_REJECTED;
 
return decoded;
-- 
2.5.0



[PATCH] arm64: Improve kprobes test for atomic sequence

2016-08-31 Thread David Long
From: "David A. Long" 

Kprobes searches backwards a finite number of instructions to determine if
there is an attempt to probe a load/store exclusive sequence. It stops when
it hits the maximum number of instructions or a load or store exclusive.
However this means it can run up past the beginning of the function and
start looking at literal constants. This has been shown to cause a false
positive and blocks insertion of the probe. To fix this add a test to see
if the typical:

"stp x29, x30, [sp, #n]!"

instruction beginning a function gets hit. This also improves efficiency by
not testing code that is not part of the function. There is some
possibility that a function will not begin with this instruction, in which
case the fixed code will behave no worse than before.

There could also be the case that the stp instruction is found further in
the body of the function, which could theoretically allow probing of an
atomic squence. The likelihood of this seems low, and this would not be the
only aspect of kprobes where the user needs to be careful to avoid
problems.

Signed-off-by: David A. Long 
---
 arch/arm64/kernel/probes/decode-insn.c | 25 ++---
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/kernel/probes/decode-insn.c 
b/arch/arm64/kernel/probes/decode-insn.c
index 37e47a9..248e820 100644
--- a/arch/arm64/kernel/probes/decode-insn.c
+++ b/arch/arm64/kernel/probes/decode-insn.c
@@ -122,16 +122,28 @@ arm_probe_decode_insn(kprobe_opcode_t insn, struct 
arch_specific_insn *asi)
 static bool __kprobes
 is_probed_address_atomic(kprobe_opcode_t *scan_start, kprobe_opcode_t 
*scan_end)
 {
+   const u32 stp_x29_x30_sp_pre = 0xa9807bfd;
+   const u32 stp_ignore_index_mask = 0xffc07fff;
+   u32 instruction = le32_to_cpu(*scan_start);
+
while (scan_start > scan_end) {
/*
-* atomic region starts from exclusive load and ends with
-* exclusive store.
+* Atomic region starts from exclusive load and ends with
+* exclusive store. If we hit a "stp x29, x30, [sp, #n]!"
+* assume it is the beginning of the function and end the
+* search. This helps avoid false positives from literal
+* constants that look like a load-exclusive, in addition
+* to being more efficient.
 */
-   if (aarch64_insn_is_store_ex(le32_to_cpu(*scan_start)))
+   if ((instruction & stp_ignore_index_mask) == stp_x29_x30_sp_pre)
return false;
-   else if (aarch64_insn_is_load_ex(le32_to_cpu(*scan_start)))
-   return true;
+
scan_start--;
+   instruction = le32_to_cpu(*scan_start);
+   if (aarch64_insn_is_store_ex(instruction))
+   return false;
+   else if (aarch64_insn_is_load_ex(instruction))
+   return true;
}
 
return false;
@@ -142,7 +154,6 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct 
arch_specific_insn *asi)
 {
enum kprobe_insn decoded;
kprobe_opcode_t insn = le32_to_cpu(*addr);
-   kprobe_opcode_t *scan_start = addr - 1;
kprobe_opcode_t *scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
 #if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
struct module *mod;
@@ -167,7 +178,7 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct 
arch_specific_insn *asi)
decoded = arm_probe_decode_insn(insn, asi);
 
if (decoded == INSN_REJECTED ||
-   is_probed_address_atomic(scan_start, scan_end))
+   is_probed_address_atomic(addr, scan_end))
return INSN_REJECTED;
 
return decoded;
-- 
2.5.0



Re: [PATCH] Documentation: kprobes: Document jprobes stack copying limitations

2016-08-15 Thread David Long

On 08/15/2016 11:32 AM, Jonathan Corbet wrote:

On Mon, 15 Aug 2016 10:49:36 -0400
David Long <dave.l...@linaro.org> wrote:


On 08/15/2016 10:25 AM, Jonathan Corbet wrote:

On Fri, 12 Aug 2016 16:24:44 -0400
David Long <dave.l...@linaro.org> wrote:


Some architectures (i.e.: sparc64 and arm64) make reasonable partial stack
duplication for jprobes problematic. Document this.


Applied to the docs tree, thanks.

jon



Was kind of hoping to see an ack (or critique) from a sparc maintainer.


So are you saying you don't want the patch applied at this point?

jon




I think we can apply it.  It's not looking like we're going to get 
comments from a sparc/kprobes maintainer.  The need for this change was 
first addressed on the sparc email alias exactly one week ago, which is 
maybe long enough to wait.


Sorry for the trouble,
-dl



Re: [PATCH] Documentation: kprobes: Document jprobes stack copying limitations

2016-08-15 Thread David Long

On 08/15/2016 11:32 AM, Jonathan Corbet wrote:

On Mon, 15 Aug 2016 10:49:36 -0400
David Long  wrote:


On 08/15/2016 10:25 AM, Jonathan Corbet wrote:

On Fri, 12 Aug 2016 16:24:44 -0400
David Long  wrote:


Some architectures (i.e.: sparc64 and arm64) make reasonable partial stack
duplication for jprobes problematic. Document this.


Applied to the docs tree, thanks.

jon



Was kind of hoping to see an ack (or critique) from a sparc maintainer.


So are you saying you don't want the patch applied at this point?

jon




I think we can apply it.  It's not looking like we're going to get 
comments from a sparc/kprobes maintainer.  The need for this change was 
first addressed on the sparc email alias exactly one week ago, which is 
maybe long enough to wait.


Sorry for the trouble,
-dl



Re: [PATCH] Documentation: kprobes: Document jprobes stack copying limitations

2016-08-15 Thread David Long

On 08/15/2016 10:25 AM, Jonathan Corbet wrote:

On Fri, 12 Aug 2016 16:24:44 -0400
David Long <dave.l...@linaro.org> wrote:


Some architectures (i.e.: sparc64 and arm64) make reasonable partial stack
duplication for jprobes problematic. Document this.


Applied to the docs tree, thanks.

jon



Was kind of hoping to see an ack (or critique) from a sparc maintainer.

Thanks,
-dl



Re: [PATCH] Documentation: kprobes: Document jprobes stack copying limitations

2016-08-15 Thread David Long

On 08/15/2016 10:25 AM, Jonathan Corbet wrote:

On Fri, 12 Aug 2016 16:24:44 -0400
David Long  wrote:


Some architectures (i.e.: sparc64 and arm64) make reasonable partial stack
duplication for jprobes problematic. Document this.


Applied to the docs tree, thanks.

jon



Was kind of hoping to see an ack (or critique) from a sparc maintainer.

Thanks,
-dl



[PATCH] Documentation: kprobes: Document jprobes stack copying limitations

2016-08-12 Thread David Long
From: "David A. Long" 

Some architectures (i.e.: sparc64 and arm64) make reasonable partial stack
duplication for jprobes problematic. Document this.

Signed-off-by: David A. Long 
---
 Documentation/kprobes.txt | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt
index 1f9b3e2..1f6d45a 100644
--- a/Documentation/kprobes.txt
+++ b/Documentation/kprobes.txt
@@ -103,6 +103,16 @@ Note that the probed function's args may be passed on the 
stack
 or in registers.  The jprobe will work in either case, so long as the
 handler's prototype matches that of the probed function.
 
+Note that in some architectures (e.g.: arm64 and sparc64) the stack
+copy is not done, as the actual location of stacked parameters may be
+outside of a reasonable MAX_STACK_SIZE value and because that location
+cannot be determined by the jprobes code. In this case the jprobes
+user must be careful to make certain the calling signature of the
+function does not cause parameters to be passed on the stack (e.g.:
+more than eight function arguments, an argument of more than sixteen
+bytes, or more than 64 bytes of argument data, depending on
+architecture).
+
 1.3 Return Probes
 
 1.3.1 How Does a Return Probe Work?
-- 
2.5.0



[PATCH] Documentation: kprobes: Document jprobes stack copying limitations

2016-08-12 Thread David Long
From: "David A. Long" 

Some architectures (i.e.: sparc64 and arm64) make reasonable partial stack
duplication for jprobes problematic. Document this.

Signed-off-by: David A. Long 
---
 Documentation/kprobes.txt | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt
index 1f9b3e2..1f6d45a 100644
--- a/Documentation/kprobes.txt
+++ b/Documentation/kprobes.txt
@@ -103,6 +103,16 @@ Note that the probed function's args may be passed on the 
stack
 or in registers.  The jprobe will work in either case, so long as the
 handler's prototype matches that of the probed function.
 
+Note that in some architectures (e.g.: arm64 and sparc64) the stack
+copy is not done, as the actual location of stacked parameters may be
+outside of a reasonable MAX_STACK_SIZE value and because that location
+cannot be determined by the jprobes code. In this case the jprobes
+user must be careful to make certain the calling signature of the
+function does not cause parameters to be passed on the stack (e.g.:
+more than eight function arguments, an argument of more than sixteen
+bytes, or more than 64 bytes of argument data, depending on
+architecture).
+
 1.3 Return Probes
 
 1.3.1 How Does a Return Probe Work?
-- 
2.5.0



Re: [PATCH v15 04/10] arm64: Kprobes with single stepping support

2016-08-10 Thread David Long

On 08/09/2016 01:23 PM, Catalin Marinas wrote:

On Mon, Aug 08, 2016 at 10:29:05AM -0400, David Long wrote:

On 08/08/2016 07:13 AM, Daniel Thompson wrote:

On 04/08/16 05:47, David Long wrote:
>From b451caa1adaf1d03e08a44b5dad3fca31cebd97a Mon Sep 17 00:00:00 2001

From: "David A. Long" <dave.l...@linaro.org>
Date: Thu, 4 Aug 2016 00:35:33 -0400
Subject: [PATCH] arm64: Remove stack duplicating code from jprobes

Because the arm64 calling standard allows stacked function arguments
to be
anywhere in the stack frame, do not attempt to duplicate the stack
frame for
jprobes handler functions.

Signed-off-by: David A. Long <dave.l...@linaro.org>
---
Documentation/kprobes.txt  |  7 +++
arch/arm64/include/asm/kprobes.h   |  2 --
arch/arm64/kernel/probes/kprobes.c | 31 +--
3 files changed, 12 insertions(+), 28 deletions(-)

diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt
index 1f9b3e2..bd01839 100644
--- a/Documentation/kprobes.txt
+++ b/Documentation/kprobes.txt
@@ -103,6 +103,13 @@ Note that the probed function's args may be
passed on the stack
or in registers.  The jprobe will work in either case, so long as the
handler's prototype matches that of the probed function.

+Note that in some architectures (e.g.: arm64) the stack copy is not


Could sparc64 be added to this list?

   For the sparc folks who are new to the thread, we've previously
   established that the sparc64 ABI passes large structures by
   allocating them from the caller's stack frame and passing a pointer
   to the stack frame (i.e. arguments may not be at top of the stack).
   We also noticed that sparc code does not save/restore anything from
   the stack.


I was reluctant to do that in the context of late changes to v4.8 for arm64
but now that any changes for this are going in as a new patch it would
indeed be useful to get involvement from sparc maintainers.


I'm happy to take the arm64 patch for 4.8 as it's mainly a clean-up.
Whether you can mention sparc64 as well, it depends on the sparc
maintainers. You can either cc them or send the series as two patches,
one for documentation and the other for arm64.



I didn't think that was going to be possible after v4.8-rc1.  I have 
separated the documentation and code changes.  I will send out the new 
code-only patch (otherwise unchanged in content) momentarily.


Thanks,
-dl



Re: [PATCH v15 04/10] arm64: Kprobes with single stepping support

2016-08-10 Thread David Long

On 08/09/2016 01:23 PM, Catalin Marinas wrote:

On Mon, Aug 08, 2016 at 10:29:05AM -0400, David Long wrote:

On 08/08/2016 07:13 AM, Daniel Thompson wrote:

On 04/08/16 05:47, David Long wrote:
>From b451caa1adaf1d03e08a44b5dad3fca31cebd97a Mon Sep 17 00:00:00 2001

From: "David A. Long" 
Date: Thu, 4 Aug 2016 00:35:33 -0400
Subject: [PATCH] arm64: Remove stack duplicating code from jprobes

Because the arm64 calling standard allows stacked function arguments
to be
anywhere in the stack frame, do not attempt to duplicate the stack
frame for
jprobes handler functions.

Signed-off-by: David A. Long 
---
Documentation/kprobes.txt  |  7 +++
arch/arm64/include/asm/kprobes.h   |  2 --
arch/arm64/kernel/probes/kprobes.c | 31 +--
3 files changed, 12 insertions(+), 28 deletions(-)

diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt
index 1f9b3e2..bd01839 100644
--- a/Documentation/kprobes.txt
+++ b/Documentation/kprobes.txt
@@ -103,6 +103,13 @@ Note that the probed function's args may be
passed on the stack
or in registers.  The jprobe will work in either case, so long as the
handler's prototype matches that of the probed function.

+Note that in some architectures (e.g.: arm64) the stack copy is not


Could sparc64 be added to this list?

   For the sparc folks who are new to the thread, we've previously
   established that the sparc64 ABI passes large structures by
   allocating them from the caller's stack frame and passing a pointer
   to the stack frame (i.e. arguments may not be at top of the stack).
   We also noticed that sparc code does not save/restore anything from
   the stack.


I was reluctant to do that in the context of late changes to v4.8 for arm64
but now that any changes for this are going in as a new patch it would
indeed be useful to get involvement from sparc maintainers.


I'm happy to take the arm64 patch for 4.8 as it's mainly a clean-up.
Whether you can mention sparc64 as well, it depends on the sparc
maintainers. You can either cc them or send the series as two patches,
one for documentation and the other for arm64.



I didn't think that was going to be possible after v4.8-rc1.  I have 
separated the documentation and code changes.  I will send out the new 
code-only patch (otherwise unchanged in content) momentarily.


Thanks,
-dl



[PATCH 1/1] arm64: Remove stack duplicating code from jprobes

2016-08-10 Thread David Long
From: "David A. Long" 

Because the arm64 calling standard allows stacked function arguments to be
anywhere in the stack frame, do not attempt to duplicate the stack frame for
jprobes handler functions.

Documenation changes to describe this issue have been broken out into a
separate patch in order to simultaneously address them in other
architecture(s).

Signed-off-by: David A. Long 
Acked-by: Masami Hiramatsu 
---
 arch/arm64/include/asm/kprobes.h   |  2 --
 arch/arm64/kernel/probes/kprobes.c | 31 +--
 2 files changed, 5 insertions(+), 28 deletions(-)

diff --git a/arch/arm64/include/asm/kprobes.h b/arch/arm64/include/asm/kprobes.h
index 61b4915..1737aec 100644
--- a/arch/arm64/include/asm/kprobes.h
+++ b/arch/arm64/include/asm/kprobes.h
@@ -22,7 +22,6 @@
 
 #define __ARCH_WANT_KPROBES_INSN_SLOT
 #define MAX_INSN_SIZE  1
-#define MAX_STACK_SIZE 128
 
 #define flush_insn_slot(p) do { } while (0)
 #define kretprobe_blacklist_size   0
@@ -47,7 +46,6 @@ struct kprobe_ctlblk {
struct prev_kprobe prev_kprobe;
struct kprobe_step_ctx ss_ctx;
struct pt_regs jprobe_saved_regs;
-   char jprobes_stack[MAX_STACK_SIZE];
 };
 
 void arch_remove_kprobe(struct kprobe *);
diff --git a/arch/arm64/kernel/probes/kprobes.c 
b/arch/arm64/kernel/probes/kprobes.c
index bf97685..c6b0f40 100644
--- a/arch/arm64/kernel/probes/kprobes.c
+++ b/arch/arm64/kernel/probes/kprobes.c
@@ -41,18 +41,6 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 static void __kprobes
 post_kprobe_handler(struct kprobe_ctlblk *, struct pt_regs *);
 
-static inline unsigned long min_stack_size(unsigned long addr)
-{
-   unsigned long size;
-
-   if (on_irq_stack(addr, raw_smp_processor_id()))
-   size = IRQ_STACK_PTR(raw_smp_processor_id()) - addr;
-   else
-   size = (unsigned long)current_thread_info() + THREAD_START_SP - 
addr;
-
-   return min(size, FIELD_SIZEOF(struct kprobe_ctlblk, jprobes_stack));
-}
-
 static void __kprobes arch_prepare_ss_slot(struct kprobe *p)
 {
/* prepare insn slot */
@@ -489,20 +477,15 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct 
pt_regs *regs)
 {
struct jprobe *jp = container_of(p, struct jprobe, kp);
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
-   long stack_ptr = kernel_stack_pointer(regs);
 
kcb->jprobe_saved_regs = *regs;
/*
-* As Linus pointed out, gcc assumes that the callee
-* owns the argument space and could overwrite it, e.g.
-* tailcall optimization. So, to be absolutely safe
-* we also save and restore enough stack bytes to cover
-* the argument area.
+* Since we can't be sure where in the stack frame "stacked"
+* pass-by-value arguments are stored we just don't try to
+* duplicate any of the stack. Do not use jprobes on functions that
+* use more than 64 bytes (after padding each to an 8 byte boundary)
+* of arguments, or pass individual arguments larger than 16 bytes.
 */
-   kasan_disable_current();
-   memcpy(kcb->jprobes_stack, (void *)stack_ptr,
-  min_stack_size(stack_ptr));
-   kasan_enable_current();
 
instruction_pointer_set(regs, (unsigned long) jp->entry);
preempt_disable();
@@ -554,10 +537,6 @@ int __kprobes longjmp_break_handler(struct kprobe *p, 
struct pt_regs *regs)
}
unpause_graph_tracing();
*regs = kcb->jprobe_saved_regs;
-   kasan_disable_current();
-   memcpy((void *)stack_addr, kcb->jprobes_stack,
-  min_stack_size(stack_addr));
-   kasan_enable_current();
preempt_enable_no_resched();
return 1;
 }
-- 
2.5.0



[PATCH 1/1] arm64: Remove stack duplicating code from jprobes

2016-08-10 Thread David Long
From: "David A. Long" 

Because the arm64 calling standard allows stacked function arguments to be
anywhere in the stack frame, do not attempt to duplicate the stack frame for
jprobes handler functions.

Documenation changes to describe this issue have been broken out into a
separate patch in order to simultaneously address them in other
architecture(s).

Signed-off-by: David A. Long 
Acked-by: Masami Hiramatsu 
---
 arch/arm64/include/asm/kprobes.h   |  2 --
 arch/arm64/kernel/probes/kprobes.c | 31 +--
 2 files changed, 5 insertions(+), 28 deletions(-)

diff --git a/arch/arm64/include/asm/kprobes.h b/arch/arm64/include/asm/kprobes.h
index 61b4915..1737aec 100644
--- a/arch/arm64/include/asm/kprobes.h
+++ b/arch/arm64/include/asm/kprobes.h
@@ -22,7 +22,6 @@
 
 #define __ARCH_WANT_KPROBES_INSN_SLOT
 #define MAX_INSN_SIZE  1
-#define MAX_STACK_SIZE 128
 
 #define flush_insn_slot(p) do { } while (0)
 #define kretprobe_blacklist_size   0
@@ -47,7 +46,6 @@ struct kprobe_ctlblk {
struct prev_kprobe prev_kprobe;
struct kprobe_step_ctx ss_ctx;
struct pt_regs jprobe_saved_regs;
-   char jprobes_stack[MAX_STACK_SIZE];
 };
 
 void arch_remove_kprobe(struct kprobe *);
diff --git a/arch/arm64/kernel/probes/kprobes.c 
b/arch/arm64/kernel/probes/kprobes.c
index bf97685..c6b0f40 100644
--- a/arch/arm64/kernel/probes/kprobes.c
+++ b/arch/arm64/kernel/probes/kprobes.c
@@ -41,18 +41,6 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 static void __kprobes
 post_kprobe_handler(struct kprobe_ctlblk *, struct pt_regs *);
 
-static inline unsigned long min_stack_size(unsigned long addr)
-{
-   unsigned long size;
-
-   if (on_irq_stack(addr, raw_smp_processor_id()))
-   size = IRQ_STACK_PTR(raw_smp_processor_id()) - addr;
-   else
-   size = (unsigned long)current_thread_info() + THREAD_START_SP - 
addr;
-
-   return min(size, FIELD_SIZEOF(struct kprobe_ctlblk, jprobes_stack));
-}
-
 static void __kprobes arch_prepare_ss_slot(struct kprobe *p)
 {
/* prepare insn slot */
@@ -489,20 +477,15 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct 
pt_regs *regs)
 {
struct jprobe *jp = container_of(p, struct jprobe, kp);
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
-   long stack_ptr = kernel_stack_pointer(regs);
 
kcb->jprobe_saved_regs = *regs;
/*
-* As Linus pointed out, gcc assumes that the callee
-* owns the argument space and could overwrite it, e.g.
-* tailcall optimization. So, to be absolutely safe
-* we also save and restore enough stack bytes to cover
-* the argument area.
+* Since we can't be sure where in the stack frame "stacked"
+* pass-by-value arguments are stored we just don't try to
+* duplicate any of the stack. Do not use jprobes on functions that
+* use more than 64 bytes (after padding each to an 8 byte boundary)
+* of arguments, or pass individual arguments larger than 16 bytes.
 */
-   kasan_disable_current();
-   memcpy(kcb->jprobes_stack, (void *)stack_ptr,
-  min_stack_size(stack_ptr));
-   kasan_enable_current();
 
instruction_pointer_set(regs, (unsigned long) jp->entry);
preempt_disable();
@@ -554,10 +537,6 @@ int __kprobes longjmp_break_handler(struct kprobe *p, 
struct pt_regs *regs)
}
unpause_graph_tracing();
*regs = kcb->jprobe_saved_regs;
-   kasan_disable_current();
-   memcpy((void *)stack_addr, kcb->jprobes_stack,
-  min_stack_size(stack_addr));
-   kasan_enable_current();
preempt_enable_no_resched();
return 1;
 }
-- 
2.5.0



Re: [PATCH v15 04/10] arm64: Kprobes with single stepping support

2016-08-08 Thread David Long

On 08/08/2016 07:13 AM, Daniel Thompson wrote:

On 04/08/16 05:47, David Long wrote:

From b451caa1adaf1d03e08a44b5dad3fca31cebd97a Mon Sep 17 00:00:00 2001
From: "David A. Long" <dave.l...@linaro.org>
Date: Thu, 4 Aug 2016 00:35:33 -0400
Subject: [PATCH] arm64: Remove stack duplicating code from jprobes

Because the arm64 calling standard allows stacked function arguments
to be
anywhere in the stack frame, do not attempt to duplicate the stack
frame for
jprobes handler functions.

Signed-off-by: David A. Long <dave.l...@linaro.org>
---
 Documentation/kprobes.txt  |  7 +++
 arch/arm64/include/asm/kprobes.h   |  2 --
 arch/arm64/kernel/probes/kprobes.c | 31 +--
 3 files changed, 12 insertions(+), 28 deletions(-)

diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt
index 1f9b3e2..bd01839 100644
--- a/Documentation/kprobes.txt
+++ b/Documentation/kprobes.txt
@@ -103,6 +103,13 @@ Note that the probed function's args may be
passed on the stack
 or in registers.  The jprobe will work in either case, so long as the
 handler's prototype matches that of the probed function.

+Note that in some architectures (e.g.: arm64) the stack copy is not


Could sparc64 be added to this list?

   For the sparc folks who are new to the thread, we've previously
   established that the sparc64 ABI passes large structures by
   allocating them from the caller's stack frame and passing a pointer
   to the stack frame (i.e. arguments may not be at top of the stack).
   We also noticed that sparc code does not save/restore anything from
   the stack.



I was reluctant to do that in the context of late changes to v4.8 for 
arm64 but now that any changes for this are going in as a new patch it 
would indeed be useful to get involvement from sparc maintainers.





+done, as the actual location of stacked parameters may be outside of
+a reasonable MAX_STACK_SIZE value and because that location cannot be
+determined by the jprobes code. In this case the jprobes user must be
+careful to make certain the calling signature of the function does
+not cause parameters to be passed on the stack.
+
 1.3 Return Probes

 1.3.1 How Does a Return Probe Work?
diff --git a/arch/arm64/include/asm/kprobes.h
b/arch/arm64/include/asm/kprobes.h
index 61b4915..1737aec 100644
--- a/arch/arm64/include/asm/kprobes.h
+++ b/arch/arm64/include/asm/kprobes.h
@@ -22,7 +22,6 @@

 #define __ARCH_WANT_KPROBES_INSN_SLOT
 #define MAX_INSN_SIZE1
-#define MAX_STACK_SIZE128

 #define flush_insn_slot(p)do { } while (0)
 #define kretprobe_blacklist_size0
@@ -47,7 +46,6 @@ struct kprobe_ctlblk {
 struct prev_kprobe prev_kprobe;
 struct kprobe_step_ctx ss_ctx;
 struct pt_regs jprobe_saved_regs;
-char jprobes_stack[MAX_STACK_SIZE];
 };

 void arch_remove_kprobe(struct kprobe *);
diff --git a/arch/arm64/kernel/probes/kprobes.c
b/arch/arm64/kernel/probes/kprobes.c
index bf97685..c6b0f40 100644
--- a/arch/arm64/kernel/probes/kprobes.c
+++ b/arch/arm64/kernel/probes/kprobes.c
@@ -41,18 +41,6 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 static void __kprobes
 post_kprobe_handler(struct kprobe_ctlblk *, struct pt_regs *);

-static inline unsigned long min_stack_size(unsigned long addr)
-{
-unsigned long size;
-
-if (on_irq_stack(addr, raw_smp_processor_id()))
-size = IRQ_STACK_PTR(raw_smp_processor_id()) - addr;
-else
-size = (unsigned long)current_thread_info() + THREAD_START_SP
- addr;
-
-return min(size, FIELD_SIZEOF(struct kprobe_ctlblk, jprobes_stack));
-}
-
 static void __kprobes arch_prepare_ss_slot(struct kprobe *p)
 {
 /* prepare insn slot */
@@ -489,20 +477,15 @@ int __kprobes setjmp_pre_handler(struct kprobe
*p, struct pt_regs *regs)
 {
 struct jprobe *jp = container_of(p, struct jprobe, kp);
 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
-long stack_ptr = kernel_stack_pointer(regs);

 kcb->jprobe_saved_regs = *regs;
 /*
- * As Linus pointed out, gcc assumes that the callee
- * owns the argument space and could overwrite it, e.g.
- * tailcall optimization. So, to be absolutely safe
- * we also save and restore enough stack bytes to cover
- * the argument area.
+ * Since we can't be sure where in the stack frame "stacked"
+ * pass-by-value arguments are stored we just don't try to
+ * duplicate any of the stack.

 > ...

  Do not use jprobes on functions
that
+ * use more than 64 bytes (after padding each to an 8 byte boundary)
+ * of arguments, or pass individual arguments larger than 16 bytes.


I like this wording. So much so that it really would be great to repeat
this in the Documentation/. Could this be included in the list of
architecture support/restrictions?



Are you thinking specifically of the "5. Kprobes Features and 
Limitations" section in Documentation/kprobes.txt?




Daniel.



Thanks,
-dl



Re: [PATCH v15 04/10] arm64: Kprobes with single stepping support

2016-08-08 Thread David Long

On 08/08/2016 07:13 AM, Daniel Thompson wrote:

On 04/08/16 05:47, David Long wrote:

From b451caa1adaf1d03e08a44b5dad3fca31cebd97a Mon Sep 17 00:00:00 2001
From: "David A. Long" 
Date: Thu, 4 Aug 2016 00:35:33 -0400
Subject: [PATCH] arm64: Remove stack duplicating code from jprobes

Because the arm64 calling standard allows stacked function arguments
to be
anywhere in the stack frame, do not attempt to duplicate the stack
frame for
jprobes handler functions.

Signed-off-by: David A. Long 
---
 Documentation/kprobes.txt  |  7 +++
 arch/arm64/include/asm/kprobes.h   |  2 --
 arch/arm64/kernel/probes/kprobes.c | 31 +--
 3 files changed, 12 insertions(+), 28 deletions(-)

diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt
index 1f9b3e2..bd01839 100644
--- a/Documentation/kprobes.txt
+++ b/Documentation/kprobes.txt
@@ -103,6 +103,13 @@ Note that the probed function's args may be
passed on the stack
 or in registers.  The jprobe will work in either case, so long as the
 handler's prototype matches that of the probed function.

+Note that in some architectures (e.g.: arm64) the stack copy is not


Could sparc64 be added to this list?

   For the sparc folks who are new to the thread, we've previously
   established that the sparc64 ABI passes large structures by
   allocating them from the caller's stack frame and passing a pointer
   to the stack frame (i.e. arguments may not be at top of the stack).
   We also noticed that sparc code does not save/restore anything from
   the stack.



I was reluctant to do that in the context of late changes to v4.8 for 
arm64 but now that any changes for this are going in as a new patch it 
would indeed be useful to get involvement from sparc maintainers.





+done, as the actual location of stacked parameters may be outside of
+a reasonable MAX_STACK_SIZE value and because that location cannot be
+determined by the jprobes code. In this case the jprobes user must be
+careful to make certain the calling signature of the function does
+not cause parameters to be passed on the stack.
+
 1.3 Return Probes

 1.3.1 How Does a Return Probe Work?
diff --git a/arch/arm64/include/asm/kprobes.h
b/arch/arm64/include/asm/kprobes.h
index 61b4915..1737aec 100644
--- a/arch/arm64/include/asm/kprobes.h
+++ b/arch/arm64/include/asm/kprobes.h
@@ -22,7 +22,6 @@

 #define __ARCH_WANT_KPROBES_INSN_SLOT
 #define MAX_INSN_SIZE1
-#define MAX_STACK_SIZE128

 #define flush_insn_slot(p)do { } while (0)
 #define kretprobe_blacklist_size0
@@ -47,7 +46,6 @@ struct kprobe_ctlblk {
 struct prev_kprobe prev_kprobe;
 struct kprobe_step_ctx ss_ctx;
 struct pt_regs jprobe_saved_regs;
-char jprobes_stack[MAX_STACK_SIZE];
 };

 void arch_remove_kprobe(struct kprobe *);
diff --git a/arch/arm64/kernel/probes/kprobes.c
b/arch/arm64/kernel/probes/kprobes.c
index bf97685..c6b0f40 100644
--- a/arch/arm64/kernel/probes/kprobes.c
+++ b/arch/arm64/kernel/probes/kprobes.c
@@ -41,18 +41,6 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 static void __kprobes
 post_kprobe_handler(struct kprobe_ctlblk *, struct pt_regs *);

-static inline unsigned long min_stack_size(unsigned long addr)
-{
-unsigned long size;
-
-if (on_irq_stack(addr, raw_smp_processor_id()))
-size = IRQ_STACK_PTR(raw_smp_processor_id()) - addr;
-else
-size = (unsigned long)current_thread_info() + THREAD_START_SP
- addr;
-
-return min(size, FIELD_SIZEOF(struct kprobe_ctlblk, jprobes_stack));
-}
-
 static void __kprobes arch_prepare_ss_slot(struct kprobe *p)
 {
 /* prepare insn slot */
@@ -489,20 +477,15 @@ int __kprobes setjmp_pre_handler(struct kprobe
*p, struct pt_regs *regs)
 {
 struct jprobe *jp = container_of(p, struct jprobe, kp);
 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
-long stack_ptr = kernel_stack_pointer(regs);

 kcb->jprobe_saved_regs = *regs;
 /*
- * As Linus pointed out, gcc assumes that the callee
- * owns the argument space and could overwrite it, e.g.
- * tailcall optimization. So, to be absolutely safe
- * we also save and restore enough stack bytes to cover
- * the argument area.
+ * Since we can't be sure where in the stack frame "stacked"
+ * pass-by-value arguments are stored we just don't try to
+ * duplicate any of the stack.

 > ...

  Do not use jprobes on functions
that
+ * use more than 64 bytes (after padding each to an 8 byte boundary)
+ * of arguments, or pass individual arguments larger than 16 bytes.


I like this wording. So much so that it really would be great to repeat
this in the Documentation/. Could this be included in the list of
architecture support/restrictions?



Are you thinking specifically of the "5. Kprobes Features and 
Limitations" section in Documentation/kprobes.txt?




Daniel.



Thanks,
-dl



Re: [PATCH v15 04/10] arm64: Kprobes with single stepping support

2016-08-03 Thread David Long
On 07/29/2016 05:01 AM, Daniel Thompson wrote:
> On 28/07/16 15:40, Catalin Marinas wrote:
>> On Wed, Jul 27, 2016 at 06:13:37PM -0400, David Long wrote:
>>> On 07/27/2016 07:50 AM, Daniel Thompson wrote:
>>>> On 25/07/16 23:27, David Long wrote:
>>>>> On 07/25/2016 01:13 PM, Catalin Marinas wrote:
>>>>>> The problem is that the original design was done on x86 for its 
>>>>>> PCS and
>>>>>> it doesn't always fit other architectures. So we could either 
>>>>>> ignore the
>>>>>> problem, hoping that no probed function requires argument passing on
>>>>>> stack or we copy all the valid data on the kernel stack:
>>>>>>
>>>>>> diff --git a/arch/arm64/include/asm/kprobes.h
>>>>>> b/arch/arm64/include/asm/kprobes.h
>>>>>> index 61b49150dfa3..157fd0d0aa08 100644
>>>>>> --- a/arch/arm64/include/asm/kprobes.h
>>>>>> +++ b/arch/arm64/include/asm/kprobes.h
>>>>>> @@ -22,7 +22,7 @@
>>>>>>
>>>>>>  #define __ARCH_WANT_KPROBES_INSN_SLOT
>>>>>>  #define MAX_INSN_SIZE1
>>>>>> -#define MAX_STACK_SIZE128
>>>>>> +#define MAX_STACK_SIZETHREAD_SIZE
>>>>>>
>>>>>>  #define flush_insn_slot(p)do { } while (0)
>>>>>>  #define kretprobe_blacklist_size0
>>>>>
>>>>> I doubt the ARM PCS is unusual.  At any rate I'm certain there are 
>>>>> other
>>>>> architectures that pass aggregate parameters on the stack. I suspect
>>>>> other RISC(-ish) architectures have similar PCS issues and I think 
>>>>> this
>>>>> is at least a big part of where this simple copy with a 64/128 limit
>>>>> comes from, or at least why it continues to exist.  That said, I'm not
>>>>> enthusiastic about researching that assertion in detail as it could be
>>>>> time consuming.
>>>>
>>>> Given Mark shared a test program I *was* curious enough to take a look
>>>> at this.
>>>>
>>>> The only architecture I can find that behaves like arm64 with the
>>>> implicit pass-by-reference described by Catalin/Mark is sparc64.
>>>>
>>>> In contrast alpha, arm (32-bit), hppa64, mips64 and powerpc64 all use a
>>>> hybrid approach where the first fragments of the structure are 
>>>> passed in
>>>> registers and the remainder on the stack.
>>>
>>> That's interesting.  It also looks like sparc64 does not copy any 
>>> stack for
>>> jprobes. I guess that approach at least makes it clear what will and 
>>> won't
>>> work.
>>
>> I suggest we do the same for arm64 - avoid the copying entirely as it's
>> not safe anyway. We don't know how much to copy, nor can we be sure it
>> is safe (see Dave's DMA to the stack example). This would need to be
>> documented in the kprobes.txt file and MAX_STACK_SIZE removed from the
>> arm64 kprobes support.
>>
>> There is also the case that Daniel was talking about - passing more than
>> 8 arguments. I don't think it's worth handling this
> 
> Its actually quite hard to document the (architecture specific) "no big 
> structures" *and* the "8 argument" limits. It ends up as something like:
> 
>Structures/unions >16 bytes must not be passed by value and the
>size of all arguments, after padding each to an 8 byte boundary, must
>be less than 64 bytes.
> 
> We cannot avoid tackling big structures through documentation but when 
> we impose additional limits like "only 8 arguments" we are swapping an 
> architecture neutral "gotcha" that affects almost all jprobes uses (and 
> can be inferred from the documentation) with an architecture specific one!
> 

See new patch below.  The documentation change in it could use some scrutiny.
I've tested with one-off jprobes functions in a test module and I've
verified NET_TCPPROBE doesn't cause misbehavior.

> 
>  > but we should at
>> least add a warning and skip the probe:
>>
>> diff --git a/arch/arm64/kernel/probes/kprobes.c 
>> b/arch/arm64/kernel/probes/kprobes.c
>> index bf9768588288..84e02606ec3d 100644
>> --- a/arch/arm64/kernel/probes/kprobes.c
>> +++ b/arch/arm64/kernel/probes/kprobes.c
>> @@ -491,6 +491,10 @@ int __kprobes setjmp_pre_handler(struct kprobe 
>> *p, struct pt_regs *regs)
>>  struct kpr

Re: [PATCH v15 04/10] arm64: Kprobes with single stepping support

2016-08-03 Thread David Long
On 07/29/2016 05:01 AM, Daniel Thompson wrote:
> On 28/07/16 15:40, Catalin Marinas wrote:
>> On Wed, Jul 27, 2016 at 06:13:37PM -0400, David Long wrote:
>>> On 07/27/2016 07:50 AM, Daniel Thompson wrote:
>>>> On 25/07/16 23:27, David Long wrote:
>>>>> On 07/25/2016 01:13 PM, Catalin Marinas wrote:
>>>>>> The problem is that the original design was done on x86 for its 
>>>>>> PCS and
>>>>>> it doesn't always fit other architectures. So we could either 
>>>>>> ignore the
>>>>>> problem, hoping that no probed function requires argument passing on
>>>>>> stack or we copy all the valid data on the kernel stack:
>>>>>>
>>>>>> diff --git a/arch/arm64/include/asm/kprobes.h
>>>>>> b/arch/arm64/include/asm/kprobes.h
>>>>>> index 61b49150dfa3..157fd0d0aa08 100644
>>>>>> --- a/arch/arm64/include/asm/kprobes.h
>>>>>> +++ b/arch/arm64/include/asm/kprobes.h
>>>>>> @@ -22,7 +22,7 @@
>>>>>>
>>>>>>  #define __ARCH_WANT_KPROBES_INSN_SLOT
>>>>>>  #define MAX_INSN_SIZE1
>>>>>> -#define MAX_STACK_SIZE128
>>>>>> +#define MAX_STACK_SIZETHREAD_SIZE
>>>>>>
>>>>>>  #define flush_insn_slot(p)do { } while (0)
>>>>>>  #define kretprobe_blacklist_size0
>>>>>
>>>>> I doubt the ARM PCS is unusual.  At any rate I'm certain there are 
>>>>> other
>>>>> architectures that pass aggregate parameters on the stack. I suspect
>>>>> other RISC(-ish) architectures have similar PCS issues and I think 
>>>>> this
>>>>> is at least a big part of where this simple copy with a 64/128 limit
>>>>> comes from, or at least why it continues to exist.  That said, I'm not
>>>>> enthusiastic about researching that assertion in detail as it could be
>>>>> time consuming.
>>>>
>>>> Given Mark shared a test program I *was* curious enough to take a look
>>>> at this.
>>>>
>>>> The only architecture I can find that behaves like arm64 with the
>>>> implicit pass-by-reference described by Catalin/Mark is sparc64.
>>>>
>>>> In contrast alpha, arm (32-bit), hppa64, mips64 and powerpc64 all use a
>>>> hybrid approach where the first fragments of the structure are 
>>>> passed in
>>>> registers and the remainder on the stack.
>>>
>>> That's interesting.  It also looks like sparc64 does not copy any 
>>> stack for
>>> jprobes. I guess that approach at least makes it clear what will and 
>>> won't
>>> work.
>>
>> I suggest we do the same for arm64 - avoid the copying entirely as it's
>> not safe anyway. We don't know how much to copy, nor can we be sure it
>> is safe (see Dave's DMA to the stack example). This would need to be
>> documented in the kprobes.txt file and MAX_STACK_SIZE removed from the
>> arm64 kprobes support.
>>
>> There is also the case that Daniel was talking about - passing more than
>> 8 arguments. I don't think it's worth handling this
> 
> Its actually quite hard to document the (architecture specific) "no big 
> structures" *and* the "8 argument" limits. It ends up as something like:
> 
>Structures/unions >16 bytes must not be passed by value and the
>size of all arguments, after padding each to an 8 byte boundary, must
>be less than 64 bytes.
> 
> We cannot avoid tackling big structures through documentation but when 
> we impose additional limits like "only 8 arguments" we are swapping an 
> architecture neutral "gotcha" that affects almost all jprobes uses (and 
> can be inferred from the documentation) with an architecture specific one!
> 

See new patch below.  The documentation change in it could use some scrutiny.
I've tested with one-off jprobes functions in a test module and I've
verified NET_TCPPROBE doesn't cause misbehavior.

> 
>  > but we should at
>> least add a warning and skip the probe:
>>
>> diff --git a/arch/arm64/kernel/probes/kprobes.c 
>> b/arch/arm64/kernel/probes/kprobes.c
>> index bf9768588288..84e02606ec3d 100644
>> --- a/arch/arm64/kernel/probes/kprobes.c
>> +++ b/arch/arm64/kernel/probes/kprobes.c
>> @@ -491,6 +491,10 @@ int __kprobes setjmp_pre_handler(struct kprobe 
>> *p, struct pt_regs *regs)
>>  

Re: [PATCH v15 04/10] arm64: Kprobes with single stepping support

2016-07-27 Thread David Long

On 07/27/2016 07:50 AM, Daniel Thompson wrote:

On 25/07/16 23:27, David Long wrote:

On 07/25/2016 01:13 PM, Catalin Marinas wrote:

On Fri, Jul 22, 2016 at 11:51:32AM -0400, David Long wrote:

On 07/22/2016 06:16 AM, Catalin Marinas wrote:

On Thu, Jul 21, 2016 at 02:33:52PM -0400, David Long wrote:

On 07/21/2016 01:23 PM, Marc Zyngier wrote:

On 21/07/16 17:33, David Long wrote:

On 07/20/2016 12:09 PM, Marc Zyngier wrote:

On 08/07/16 17:35, David Long wrote:

+#define MAX_INSN_SIZE1
+#define MAX_STACK_SIZE128


Where is that value coming from? Because even on my 6502, I have
a 256
byte stack.



Although I don't claim to know the original author's thoughts I
would
guess it is based on the seven other existing implementations for
kprobes on various architectures, all of which appear to use
either 64
or 128 for MAX_STACK_SIZE.  The code is not trying to duplicate the
whole stack.

[...]

My main worry is that whatever value you pick, it is always going
to be
wrong. This is used to preserve arguments that are passed on the
stack,
as opposed to passed by registers). We have no idea of what is
getting
passed there so saving nothing, 128 bytes or 2kB is about the
same. It
is always wrong.

A much better solution would be to check the frame pointer, and
copy the
delta between FP and SP, assuming it fits inside the allocated
buffer.
If it doesn't, or if FP is invalid, we just skip the hook,
because we
can't reliably execute it.


Well, this is the way it works literally everywhere else. It is a
documented
limitation (Documentation/kprobes.txt). Said documentation may need
to be
changed along with the suggested fix.


The document states: "Up to MAX_STACK_SIZE bytes are copied". That
means
the arch code could always copy less but never more than
MAX_STACK_SIZE.
What we are proposing is that we should try to guess how much to copy
based on the FP value (caller's frame) and, if larger than
MAX_STACK_SIZE, skip the probe hook entirely. I don't think this goes
against the kprobes.txt document but at least it (a) may improve the
performance slightly by avoiding unnecessary copy and (b) it avoids
undefined behaviour if we ever encounter a jprobe with arguments
passed
on the stack beyond MAX_STACK_SIZE.


OK, it sounds like an improvement. I do worry a little about
unexpected side
effects.


You get more unexpected side effects by not saving/restoring the whole
stack. We looked into this on Friday and came to the conclusion that
there is no safe way for kprobes to know which arguments passed on the
stack should be preserved, at least not with the current API.

Basically the AArch64 PCS states that for arguments passed on the stack
(e.g. they can't fit in registers), the caller allocates memory for them
(on its own stack) and passes the pointer to the callee. Unfortunately,
the frame pointer seems to be decremented correspondingly to cover the
arguments, so we don't really have a way to tell how much to copy.
Copying just the caller's stack frame isn't safe either since a
callee/caller receiving such argument on the stack may passed it down to
a callee without copying (I couldn't find anything in the PCS stating
that this isn't allowed).


OK, so I think we're pretty much back to our starting point.



I'm just asking if we can accept the existing code as now complete
enough (in that I believe it matches the other implementations) and
make
this enhancement something for the next release cycle, allowing the
existing
code to be exercised by a wider audience and providing ample time to
test
the new modification? I'd hate to get stuck in a mode where this
patch gets
repeatedly delayed for changes that go above and beyond the original
design.


The problem is that the original design was done on x86 for its PCS and
it doesn't always fit other architectures. So we could either ignore the
problem, hoping that no probed function requires argument passing on
stack or we copy all the valid data on the kernel stack:

diff --git a/arch/arm64/include/asm/kprobes.h
b/arch/arm64/include/asm/kprobes.h
index 61b49150dfa3..157fd0d0aa08 100644
--- a/arch/arm64/include/asm/kprobes.h
+++ b/arch/arm64/include/asm/kprobes.h
@@ -22,7 +22,7 @@

  #define __ARCH_WANT_KPROBES_INSN_SLOT
  #define MAX_INSN_SIZE1
-#define MAX_STACK_SIZE128
+#define MAX_STACK_SIZETHREAD_SIZE

  #define flush_insn_slot(p)do { } while (0)
  #define kretprobe_blacklist_size0



I doubt the ARM PCS is unusual.  At any rate I'm certain there are other
architectures that pass aggregate parameters on the stack. I suspect
other RISC(-ish) architectures have similar PCS issues and I think this
is at least a big part of where this simple copy with a 64/128 limit
comes from, or at least why it continues to exist.  That said, I'm not
enthusiastic about researching that assertion in detail as it could be
time consuming.


Given Mark shared a test program I *was* curious enough to t

Re: [PATCH v15 04/10] arm64: Kprobes with single stepping support

2016-07-27 Thread David Long

On 07/27/2016 07:50 AM, Daniel Thompson wrote:

On 25/07/16 23:27, David Long wrote:

On 07/25/2016 01:13 PM, Catalin Marinas wrote:

On Fri, Jul 22, 2016 at 11:51:32AM -0400, David Long wrote:

On 07/22/2016 06:16 AM, Catalin Marinas wrote:

On Thu, Jul 21, 2016 at 02:33:52PM -0400, David Long wrote:

On 07/21/2016 01:23 PM, Marc Zyngier wrote:

On 21/07/16 17:33, David Long wrote:

On 07/20/2016 12:09 PM, Marc Zyngier wrote:

On 08/07/16 17:35, David Long wrote:

+#define MAX_INSN_SIZE1
+#define MAX_STACK_SIZE128


Where is that value coming from? Because even on my 6502, I have
a 256
byte stack.



Although I don't claim to know the original author's thoughts I
would
guess it is based on the seven other existing implementations for
kprobes on various architectures, all of which appear to use
either 64
or 128 for MAX_STACK_SIZE.  The code is not trying to duplicate the
whole stack.

[...]

My main worry is that whatever value you pick, it is always going
to be
wrong. This is used to preserve arguments that are passed on the
stack,
as opposed to passed by registers). We have no idea of what is
getting
passed there so saving nothing, 128 bytes or 2kB is about the
same. It
is always wrong.

A much better solution would be to check the frame pointer, and
copy the
delta between FP and SP, assuming it fits inside the allocated
buffer.
If it doesn't, or if FP is invalid, we just skip the hook,
because we
can't reliably execute it.


Well, this is the way it works literally everywhere else. It is a
documented
limitation (Documentation/kprobes.txt). Said documentation may need
to be
changed along with the suggested fix.


The document states: "Up to MAX_STACK_SIZE bytes are copied". That
means
the arch code could always copy less but never more than
MAX_STACK_SIZE.
What we are proposing is that we should try to guess how much to copy
based on the FP value (caller's frame) and, if larger than
MAX_STACK_SIZE, skip the probe hook entirely. I don't think this goes
against the kprobes.txt document but at least it (a) may improve the
performance slightly by avoiding unnecessary copy and (b) it avoids
undefined behaviour if we ever encounter a jprobe with arguments
passed
on the stack beyond MAX_STACK_SIZE.


OK, it sounds like an improvement. I do worry a little about
unexpected side
effects.


You get more unexpected side effects by not saving/restoring the whole
stack. We looked into this on Friday and came to the conclusion that
there is no safe way for kprobes to know which arguments passed on the
stack should be preserved, at least not with the current API.

Basically the AArch64 PCS states that for arguments passed on the stack
(e.g. they can't fit in registers), the caller allocates memory for them
(on its own stack) and passes the pointer to the callee. Unfortunately,
the frame pointer seems to be decremented correspondingly to cover the
arguments, so we don't really have a way to tell how much to copy.
Copying just the caller's stack frame isn't safe either since a
callee/caller receiving such argument on the stack may passed it down to
a callee without copying (I couldn't find anything in the PCS stating
that this isn't allowed).


OK, so I think we're pretty much back to our starting point.



I'm just asking if we can accept the existing code as now complete
enough (in that I believe it matches the other implementations) and
make
this enhancement something for the next release cycle, allowing the
existing
code to be exercised by a wider audience and providing ample time to
test
the new modification? I'd hate to get stuck in a mode where this
patch gets
repeatedly delayed for changes that go above and beyond the original
design.


The problem is that the original design was done on x86 for its PCS and
it doesn't always fit other architectures. So we could either ignore the
problem, hoping that no probed function requires argument passing on
stack or we copy all the valid data on the kernel stack:

diff --git a/arch/arm64/include/asm/kprobes.h
b/arch/arm64/include/asm/kprobes.h
index 61b49150dfa3..157fd0d0aa08 100644
--- a/arch/arm64/include/asm/kprobes.h
+++ b/arch/arm64/include/asm/kprobes.h
@@ -22,7 +22,7 @@

  #define __ARCH_WANT_KPROBES_INSN_SLOT
  #define MAX_INSN_SIZE1
-#define MAX_STACK_SIZE128
+#define MAX_STACK_SIZETHREAD_SIZE

  #define flush_insn_slot(p)do { } while (0)
  #define kretprobe_blacklist_size0



I doubt the ARM PCS is unusual.  At any rate I'm certain there are other
architectures that pass aggregate parameters on the stack. I suspect
other RISC(-ish) architectures have similar PCS issues and I think this
is at least a big part of where this simple copy with a 64/128 limit
comes from, or at least why it continues to exist.  That said, I'm not
enthusiastic about researching that assertion in detail as it could be
time consuming.


Given Mark shared a test program I *was* curious enough to t

Re: [PATCH v15 04/10] arm64: Kprobes with single stepping support

2016-07-25 Thread David Long

On 07/25/2016 01:13 PM, Catalin Marinas wrote:

On Fri, Jul 22, 2016 at 11:51:32AM -0400, David Long wrote:

On 07/22/2016 06:16 AM, Catalin Marinas wrote:

On Thu, Jul 21, 2016 at 02:33:52PM -0400, David Long wrote:

On 07/21/2016 01:23 PM, Marc Zyngier wrote:

On 21/07/16 17:33, David Long wrote:

On 07/20/2016 12:09 PM, Marc Zyngier wrote:

On 08/07/16 17:35, David Long wrote:

+#define MAX_INSN_SIZE  1
+#define MAX_STACK_SIZE 128


Where is that value coming from? Because even on my 6502, I have a 256
byte stack.



Although I don't claim to know the original author's thoughts I would
guess it is based on the seven other existing implementations for
kprobes on various architectures, all of which appear to use either 64
or 128 for MAX_STACK_SIZE.  The code is not trying to duplicate the
whole stack.

[...]

My main worry is that whatever value you pick, it is always going to be
wrong. This is used to preserve arguments that are passed on the stack,
as opposed to passed by registers). We have no idea of what is getting
passed there so saving nothing, 128 bytes or 2kB is about the same. It
is always wrong.

A much better solution would be to check the frame pointer, and copy the
delta between FP and SP, assuming it fits inside the allocated buffer.
If it doesn't, or if FP is invalid, we just skip the hook, because we
can't reliably execute it.


Well, this is the way it works literally everywhere else. It is a documented
limitation (Documentation/kprobes.txt). Said documentation may need to be
changed along with the suggested fix.


The document states: "Up to MAX_STACK_SIZE bytes are copied". That means
the arch code could always copy less but never more than MAX_STACK_SIZE.
What we are proposing is that we should try to guess how much to copy
based on the FP value (caller's frame) and, if larger than
MAX_STACK_SIZE, skip the probe hook entirely. I don't think this goes
against the kprobes.txt document but at least it (a) may improve the
performance slightly by avoiding unnecessary copy and (b) it avoids
undefined behaviour if we ever encounter a jprobe with arguments passed
on the stack beyond MAX_STACK_SIZE.


OK, it sounds like an improvement. I do worry a little about unexpected side
effects.


You get more unexpected side effects by not saving/restoring the whole
stack. We looked into this on Friday and came to the conclusion that
there is no safe way for kprobes to know which arguments passed on the
stack should be preserved, at least not with the current API.

Basically the AArch64 PCS states that for arguments passed on the stack
(e.g. they can't fit in registers), the caller allocates memory for them
(on its own stack) and passes the pointer to the callee. Unfortunately,
the frame pointer seems to be decremented correspondingly to cover the
arguments, so we don't really have a way to tell how much to copy.
Copying just the caller's stack frame isn't safe either since a
callee/caller receiving such argument on the stack may passed it down to
a callee without copying (I couldn't find anything in the PCS stating
that this isn't allowed).


OK, so I think we're pretty much back to our starting point.



I'm just asking if we can accept the existing code as now complete
enough (in that I believe it matches the other implementations) and make
this enhancement something for the next release cycle, allowing the existing
code to be exercised by a wider audience and providing ample time to test
the new modification? I'd hate to get stuck in a mode where this patch gets
repeatedly delayed for changes that go above and beyond the original design.


The problem is that the original design was done on x86 for its PCS and
it doesn't always fit other architectures. So we could either ignore the
problem, hoping that no probed function requires argument passing on
stack or we copy all the valid data on the kernel stack:

diff --git a/arch/arm64/include/asm/kprobes.h b/arch/arm64/include/asm/kprobes.h
index 61b49150dfa3..157fd0d0aa08 100644
--- a/arch/arm64/include/asm/kprobes.h
+++ b/arch/arm64/include/asm/kprobes.h
@@ -22,7 +22,7 @@

  #define __ARCH_WANT_KPROBES_INSN_SLOT
  #define MAX_INSN_SIZE 1
-#define MAX_STACK_SIZE 128
+#define MAX_STACK_SIZE THREAD_SIZE

  #define flush_insn_slot(p)do { } while (0)
  #define kretprobe_blacklist_size  0



I doubt the ARM PCS is unusual.  At any rate I'm certain there are other 
architectures that pass aggregate parameters on the stack. I suspect 
other RISC(-ish) architectures have similar PCS issues and I think this 
is at least a big part of where this simple copy with a 64/128 limit 
comes from, or at least why it continues to exist.  That said, I'm not 
enthusiastic about researching that assertion in detail as it could be 
time consuming.


I think this (unchecked) limitation for stack frames is something users 
of jprobes understand, or at least should under

Re: [PATCH v15 04/10] arm64: Kprobes with single stepping support

2016-07-25 Thread David Long

On 07/25/2016 01:13 PM, Catalin Marinas wrote:

On Fri, Jul 22, 2016 at 11:51:32AM -0400, David Long wrote:

On 07/22/2016 06:16 AM, Catalin Marinas wrote:

On Thu, Jul 21, 2016 at 02:33:52PM -0400, David Long wrote:

On 07/21/2016 01:23 PM, Marc Zyngier wrote:

On 21/07/16 17:33, David Long wrote:

On 07/20/2016 12:09 PM, Marc Zyngier wrote:

On 08/07/16 17:35, David Long wrote:

+#define MAX_INSN_SIZE  1
+#define MAX_STACK_SIZE 128


Where is that value coming from? Because even on my 6502, I have a 256
byte stack.



Although I don't claim to know the original author's thoughts I would
guess it is based on the seven other existing implementations for
kprobes on various architectures, all of which appear to use either 64
or 128 for MAX_STACK_SIZE.  The code is not trying to duplicate the
whole stack.

[...]

My main worry is that whatever value you pick, it is always going to be
wrong. This is used to preserve arguments that are passed on the stack,
as opposed to passed by registers). We have no idea of what is getting
passed there so saving nothing, 128 bytes or 2kB is about the same. It
is always wrong.

A much better solution would be to check the frame pointer, and copy the
delta between FP and SP, assuming it fits inside the allocated buffer.
If it doesn't, or if FP is invalid, we just skip the hook, because we
can't reliably execute it.


Well, this is the way it works literally everywhere else. It is a documented
limitation (Documentation/kprobes.txt). Said documentation may need to be
changed along with the suggested fix.


The document states: "Up to MAX_STACK_SIZE bytes are copied". That means
the arch code could always copy less but never more than MAX_STACK_SIZE.
What we are proposing is that we should try to guess how much to copy
based on the FP value (caller's frame) and, if larger than
MAX_STACK_SIZE, skip the probe hook entirely. I don't think this goes
against the kprobes.txt document but at least it (a) may improve the
performance slightly by avoiding unnecessary copy and (b) it avoids
undefined behaviour if we ever encounter a jprobe with arguments passed
on the stack beyond MAX_STACK_SIZE.


OK, it sounds like an improvement. I do worry a little about unexpected side
effects.


You get more unexpected side effects by not saving/restoring the whole
stack. We looked into this on Friday and came to the conclusion that
there is no safe way for kprobes to know which arguments passed on the
stack should be preserved, at least not with the current API.

Basically the AArch64 PCS states that for arguments passed on the stack
(e.g. they can't fit in registers), the caller allocates memory for them
(on its own stack) and passes the pointer to the callee. Unfortunately,
the frame pointer seems to be decremented correspondingly to cover the
arguments, so we don't really have a way to tell how much to copy.
Copying just the caller's stack frame isn't safe either since a
callee/caller receiving such argument on the stack may passed it down to
a callee without copying (I couldn't find anything in the PCS stating
that this isn't allowed).


OK, so I think we're pretty much back to our starting point.



I'm just asking if we can accept the existing code as now complete
enough (in that I believe it matches the other implementations) and make
this enhancement something for the next release cycle, allowing the existing
code to be exercised by a wider audience and providing ample time to test
the new modification? I'd hate to get stuck in a mode where this patch gets
repeatedly delayed for changes that go above and beyond the original design.


The problem is that the original design was done on x86 for its PCS and
it doesn't always fit other architectures. So we could either ignore the
problem, hoping that no probed function requires argument passing on
stack or we copy all the valid data on the kernel stack:

diff --git a/arch/arm64/include/asm/kprobes.h b/arch/arm64/include/asm/kprobes.h
index 61b49150dfa3..157fd0d0aa08 100644
--- a/arch/arm64/include/asm/kprobes.h
+++ b/arch/arm64/include/asm/kprobes.h
@@ -22,7 +22,7 @@

  #define __ARCH_WANT_KPROBES_INSN_SLOT
  #define MAX_INSN_SIZE 1
-#define MAX_STACK_SIZE 128
+#define MAX_STACK_SIZE THREAD_SIZE

  #define flush_insn_slot(p)do { } while (0)
  #define kretprobe_blacklist_size  0



I doubt the ARM PCS is unusual.  At any rate I'm certain there are other 
architectures that pass aggregate parameters on the stack. I suspect 
other RISC(-ish) architectures have similar PCS issues and I think this 
is at least a big part of where this simple copy with a 64/128 limit 
comes from, or at least why it continues to exist.  That said, I'm not 
enthusiastic about researching that assertion in detail as it could be 
time consuming.


I think this (unchecked) limitation for stack frames is something users 
of jprobes understand, or at least should under

Re: [PATCH v15 04/10] arm64: Kprobes with single stepping support

2016-07-22 Thread David Long

On 07/22/2016 06:16 AM, Catalin Marinas wrote:

On Thu, Jul 21, 2016 at 02:33:52PM -0400, David Long wrote:

On 07/21/2016 01:23 PM, Marc Zyngier wrote:

On 21/07/16 17:33, David Long wrote:

On 07/20/2016 12:09 PM, Marc Zyngier wrote:

On 08/07/16 17:35, David Long wrote:

+#define MAX_INSN_SIZE  1
+#define MAX_STACK_SIZE 128


Where is that value coming from? Because even on my 6502, I have a 256
byte stack.



Although I don't claim to know the original author's thoughts I would
guess it is based on the seven other existing implementations for
kprobes on various architectures, all of which appear to use either 64
or 128 for MAX_STACK_SIZE.  The code is not trying to duplicate the
whole stack.

[...]

My main worry is that whatever value you pick, it is always going to be
wrong. This is used to preserve arguments that are passed on the stack,
as opposed to passed by registers). We have no idea of what is getting
passed there so saving nothing, 128 bytes or 2kB is about the same. It
is always wrong.

A much better solution would be to check the frame pointer, and copy the
delta between FP and SP, assuming it fits inside the allocated buffer.
If it doesn't, or if FP is invalid, we just skip the hook, because we
can't reliably execute it.


Well, this is the way it works literally everywhere else. It is a documented
limitation (Documentation/kprobes.txt). Said documentation may need to be
changed along with the suggested fix.


The document states: "Up to MAX_STACK_SIZE bytes are copied". That means
the arch code could always copy less but never more than MAX_STACK_SIZE.
What we are proposing is that we should try to guess how much to copy
based on the FP value (caller's frame) and, if larger than
MAX_STACK_SIZE, skip the probe hook entirely. I don't think this goes
against the kprobes.txt document but at least it (a) may improve the
performance slightly by avoiding unnecessary copy and (b) it avoids
undefined behaviour if we ever encounter a jprobe with arguments passed
on the stack beyond MAX_STACK_SIZE.



OK, it sounds like an improvement. I do worry a little about unexpected 
side effects.  I'm just asking if we can accept the existing code as now 
complete enough (in that I believe it matches the other implementations) 
and make this enhancement something for the next release cycle, allowing 
the existing code to be exercised by a wider audience and providing 
ample time to test the new modification? I'd hate to get stuck in a mode 
where this patch gets repeatedly delayed for changes that go above and 
beyond the original design.


Thanks,
-dl



Re: [PATCH v15 04/10] arm64: Kprobes with single stepping support

2016-07-22 Thread David Long

On 07/22/2016 06:16 AM, Catalin Marinas wrote:

On Thu, Jul 21, 2016 at 02:33:52PM -0400, David Long wrote:

On 07/21/2016 01:23 PM, Marc Zyngier wrote:

On 21/07/16 17:33, David Long wrote:

On 07/20/2016 12:09 PM, Marc Zyngier wrote:

On 08/07/16 17:35, David Long wrote:

+#define MAX_INSN_SIZE  1
+#define MAX_STACK_SIZE 128


Where is that value coming from? Because even on my 6502, I have a 256
byte stack.



Although I don't claim to know the original author's thoughts I would
guess it is based on the seven other existing implementations for
kprobes on various architectures, all of which appear to use either 64
or 128 for MAX_STACK_SIZE.  The code is not trying to duplicate the
whole stack.

[...]

My main worry is that whatever value you pick, it is always going to be
wrong. This is used to preserve arguments that are passed on the stack,
as opposed to passed by registers). We have no idea of what is getting
passed there so saving nothing, 128 bytes or 2kB is about the same. It
is always wrong.

A much better solution would be to check the frame pointer, and copy the
delta between FP and SP, assuming it fits inside the allocated buffer.
If it doesn't, or if FP is invalid, we just skip the hook, because we
can't reliably execute it.


Well, this is the way it works literally everywhere else. It is a documented
limitation (Documentation/kprobes.txt). Said documentation may need to be
changed along with the suggested fix.


The document states: "Up to MAX_STACK_SIZE bytes are copied". That means
the arch code could always copy less but never more than MAX_STACK_SIZE.
What we are proposing is that we should try to guess how much to copy
based on the FP value (caller's frame) and, if larger than
MAX_STACK_SIZE, skip the probe hook entirely. I don't think this goes
against the kprobes.txt document but at least it (a) may improve the
performance slightly by avoiding unnecessary copy and (b) it avoids
undefined behaviour if we ever encounter a jprobe with arguments passed
on the stack beyond MAX_STACK_SIZE.



OK, it sounds like an improvement. I do worry a little about unexpected 
side effects.  I'm just asking if we can accept the existing code as now 
complete enough (in that I believe it matches the other implementations) 
and make this enhancement something for the next release cycle, allowing 
the existing code to be exercised by a wider audience and providing 
ample time to test the new modification? I'd hate to get stuck in a mode 
where this patch gets repeatedly delayed for changes that go above and 
beyond the original design.


Thanks,
-dl



Re: [PATCH v15 04/10] arm64: Kprobes with single stepping support

2016-07-21 Thread David Long

On 07/21/2016 01:23 PM, Marc Zyngier wrote:

On 21/07/16 17:33, David Long wrote:

On 07/20/2016 12:09 PM, Marc Zyngier wrote:

On 08/07/16 17:35, David Long wrote:

From: Sandeepa Prabhu <sandeepa.s.pra...@gmail.com>

Add support for basic kernel probes(kprobes) and jump probes
(jprobes) for ARM64.

Kprobes utilizes software breakpoint and single step debug
exceptions supported on ARM v8.

A software breakpoint is placed at the probe address to trap the
kernel execution into the kprobe handler.

ARM v8 supports enabling single stepping before the break exception
return (ERET), with next PC in exception return address (ELR_EL1). The
kprobe handler prepares an executable memory slot for out-of-line
execution with a copy of the original instruction being probed, and
enables single stepping. The PC is set to the out-of-line slot address
before the ERET. With this scheme, the instruction is executed with the
exact same register context except for the PC (and DAIF) registers.

Debug mask (PSTATE.D) is enabled only when single stepping a recursive
kprobe, e.g.: during kprobes reenter so that probed instruction can be
single stepped within the kprobe handler -exception- context.
The recursion depth of kprobe is always 2, i.e. upon probe re-entry,
any further re-entry is prevented by not calling handlers and the case
counted as a missed kprobe).

Single stepping from the x-o-l slot has a drawback for PC-relative accesses
like branching and symbolic literals access as the offset from the new PC
(slot address) may not be ensured to fit in the immediate value of
the opcode. Such instructions need simulation, so reject
probing them.

Instructions generating exceptions or cpu mode change are rejected
for probing.

Exclusive load/store instructions are rejected too.  Additionally, the
code is checked to see if it is inside an exclusive load/store sequence
(code from Pratyush).

System instructions are mostly enabled for stepping, except MSR/MRS
accesses to "DAIF" flags in PSTATE, which are not safe for
probing.

This also changes arch/arm64/include/asm/ptrace.h to use
include/asm-generic/ptrace.h.

Thanks to Steve Capper and Pratyush Anand for several suggested
Changes.

Signed-off-by: Sandeepa Prabhu <sandeepa.s.pra...@gmail.com>
Signed-off-by: David A. Long <dave.l...@linaro.org>
Signed-off-by: Pratyush Anand <pan...@redhat.com>
Acked-by: Masami Hiramatsu <mhira...@kernel.org>
---
   arch/arm64/Kconfig  |   1 +
   arch/arm64/include/asm/debug-monitors.h |   5 +
   arch/arm64/include/asm/insn.h   |   2 +
   arch/arm64/include/asm/kprobes.h|  60 
   arch/arm64/include/asm/probes.h |  34 +++
   arch/arm64/include/asm/ptrace.h |  14 +-
   arch/arm64/kernel/Makefile  |   2 +-
   arch/arm64/kernel/debug-monitors.c  |  16 +-
   arch/arm64/kernel/probes/Makefile   |   1 +
   arch/arm64/kernel/probes/decode-insn.c  | 143 +
   arch/arm64/kernel/probes/decode-insn.h  |  34 +++
   arch/arm64/kernel/probes/kprobes.c  | 525 

   arch/arm64/kernel/vmlinux.lds.S |   1 +
   arch/arm64/mm/fault.c   |  26 ++
   14 files changed, 859 insertions(+), 5 deletions(-)
   create mode 100644 arch/arm64/include/asm/kprobes.h
   create mode 100644 arch/arm64/include/asm/probes.h
   create mode 100644 arch/arm64/kernel/probes/Makefile
   create mode 100644 arch/arm64/kernel/probes/decode-insn.c
   create mode 100644 arch/arm64/kernel/probes/decode-insn.h
   create mode 100644 arch/arm64/kernel/probes/kprobes.c



[...]


diff --git a/arch/arm64/include/asm/kprobes.h b/arch/arm64/include/asm/kprobes.h
new file mode 100644
index 000..79c9511
--- /dev/null
+++ b/arch/arm64/include/asm/kprobes.h
@@ -0,0 +1,60 @@
+/*
+ * arch/arm64/include/asm/kprobes.h
+ *
+ * Copyright (C) 2013 Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef _ARM_KPROBES_H
+#define _ARM_KPROBES_H
+
+#include 
+#include 
+#include 
+
+#define __ARCH_WANT_KPROBES_INSN_SLOT
+#define MAX_INSN_SIZE  1
+#define MAX_STACK_SIZE 128


Where is that value coming from? Because even on my 6502, I have a 256
byte stack.



Although I don't claim to know the original author's thoughts I would
guess it is based on the seven other existing implementations for
kprobes on various architectures, all of which appear to use either 64
or 128 for MAX_STACK_SIZE.  The code is not trying to duplicate the
whole stack.


I get that (this was supposed to be a humorous

Re: [PATCH v15 04/10] arm64: Kprobes with single stepping support

2016-07-21 Thread David Long

On 07/21/2016 01:23 PM, Marc Zyngier wrote:

On 21/07/16 17:33, David Long wrote:

On 07/20/2016 12:09 PM, Marc Zyngier wrote:

On 08/07/16 17:35, David Long wrote:

From: Sandeepa Prabhu 

Add support for basic kernel probes(kprobes) and jump probes
(jprobes) for ARM64.

Kprobes utilizes software breakpoint and single step debug
exceptions supported on ARM v8.

A software breakpoint is placed at the probe address to trap the
kernel execution into the kprobe handler.

ARM v8 supports enabling single stepping before the break exception
return (ERET), with next PC in exception return address (ELR_EL1). The
kprobe handler prepares an executable memory slot for out-of-line
execution with a copy of the original instruction being probed, and
enables single stepping. The PC is set to the out-of-line slot address
before the ERET. With this scheme, the instruction is executed with the
exact same register context except for the PC (and DAIF) registers.

Debug mask (PSTATE.D) is enabled only when single stepping a recursive
kprobe, e.g.: during kprobes reenter so that probed instruction can be
single stepped within the kprobe handler -exception- context.
The recursion depth of kprobe is always 2, i.e. upon probe re-entry,
any further re-entry is prevented by not calling handlers and the case
counted as a missed kprobe).

Single stepping from the x-o-l slot has a drawback for PC-relative accesses
like branching and symbolic literals access as the offset from the new PC
(slot address) may not be ensured to fit in the immediate value of
the opcode. Such instructions need simulation, so reject
probing them.

Instructions generating exceptions or cpu mode change are rejected
for probing.

Exclusive load/store instructions are rejected too.  Additionally, the
code is checked to see if it is inside an exclusive load/store sequence
(code from Pratyush).

System instructions are mostly enabled for stepping, except MSR/MRS
accesses to "DAIF" flags in PSTATE, which are not safe for
probing.

This also changes arch/arm64/include/asm/ptrace.h to use
include/asm-generic/ptrace.h.

Thanks to Steve Capper and Pratyush Anand for several suggested
Changes.

Signed-off-by: Sandeepa Prabhu 
Signed-off-by: David A. Long 
Signed-off-by: Pratyush Anand 
Acked-by: Masami Hiramatsu 
---
   arch/arm64/Kconfig  |   1 +
   arch/arm64/include/asm/debug-monitors.h |   5 +
   arch/arm64/include/asm/insn.h   |   2 +
   arch/arm64/include/asm/kprobes.h|  60 
   arch/arm64/include/asm/probes.h |  34 +++
   arch/arm64/include/asm/ptrace.h |  14 +-
   arch/arm64/kernel/Makefile  |   2 +-
   arch/arm64/kernel/debug-monitors.c  |  16 +-
   arch/arm64/kernel/probes/Makefile   |   1 +
   arch/arm64/kernel/probes/decode-insn.c  | 143 +
   arch/arm64/kernel/probes/decode-insn.h  |  34 +++
   arch/arm64/kernel/probes/kprobes.c  | 525 

   arch/arm64/kernel/vmlinux.lds.S |   1 +
   arch/arm64/mm/fault.c   |  26 ++
   14 files changed, 859 insertions(+), 5 deletions(-)
   create mode 100644 arch/arm64/include/asm/kprobes.h
   create mode 100644 arch/arm64/include/asm/probes.h
   create mode 100644 arch/arm64/kernel/probes/Makefile
   create mode 100644 arch/arm64/kernel/probes/decode-insn.c
   create mode 100644 arch/arm64/kernel/probes/decode-insn.h
   create mode 100644 arch/arm64/kernel/probes/kprobes.c



[...]


diff --git a/arch/arm64/include/asm/kprobes.h b/arch/arm64/include/asm/kprobes.h
new file mode 100644
index 000..79c9511
--- /dev/null
+++ b/arch/arm64/include/asm/kprobes.h
@@ -0,0 +1,60 @@
+/*
+ * arch/arm64/include/asm/kprobes.h
+ *
+ * Copyright (C) 2013 Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef _ARM_KPROBES_H
+#define _ARM_KPROBES_H
+
+#include 
+#include 
+#include 
+
+#define __ARCH_WANT_KPROBES_INSN_SLOT
+#define MAX_INSN_SIZE  1
+#define MAX_STACK_SIZE 128


Where is that value coming from? Because even on my 6502, I have a 256
byte stack.



Although I don't claim to know the original author's thoughts I would
guess it is based on the seven other existing implementations for
kprobes on various architectures, all of which appear to use either 64
or 128 for MAX_STACK_SIZE.  The code is not trying to duplicate the
whole stack.


I get that (this was supposed to be a humorous comment, but I guess
after spending too much time tracking this thing, my own sense of humour
was becoming limited).



It was only meant to be factual.

Re: [PATCH v15 04/10] arm64: Kprobes with single stepping support

2016-07-21 Thread David Long

On 07/20/2016 12:09 PM, Marc Zyngier wrote:

On 08/07/16 17:35, David Long wrote:

From: Sandeepa Prabhu <sandeepa.s.pra...@gmail.com>

Add support for basic kernel probes(kprobes) and jump probes
(jprobes) for ARM64.

Kprobes utilizes software breakpoint and single step debug
exceptions supported on ARM v8.

A software breakpoint is placed at the probe address to trap the
kernel execution into the kprobe handler.

ARM v8 supports enabling single stepping before the break exception
return (ERET), with next PC in exception return address (ELR_EL1). The
kprobe handler prepares an executable memory slot for out-of-line
execution with a copy of the original instruction being probed, and
enables single stepping. The PC is set to the out-of-line slot address
before the ERET. With this scheme, the instruction is executed with the
exact same register context except for the PC (and DAIF) registers.

Debug mask (PSTATE.D) is enabled only when single stepping a recursive
kprobe, e.g.: during kprobes reenter so that probed instruction can be
single stepped within the kprobe handler -exception- context.
The recursion depth of kprobe is always 2, i.e. upon probe re-entry,
any further re-entry is prevented by not calling handlers and the case
counted as a missed kprobe).

Single stepping from the x-o-l slot has a drawback for PC-relative accesses
like branching and symbolic literals access as the offset from the new PC
(slot address) may not be ensured to fit in the immediate value of
the opcode. Such instructions need simulation, so reject
probing them.

Instructions generating exceptions or cpu mode change are rejected
for probing.

Exclusive load/store instructions are rejected too.  Additionally, the
code is checked to see if it is inside an exclusive load/store sequence
(code from Pratyush).

System instructions are mostly enabled for stepping, except MSR/MRS
accesses to "DAIF" flags in PSTATE, which are not safe for
probing.

This also changes arch/arm64/include/asm/ptrace.h to use
include/asm-generic/ptrace.h.

Thanks to Steve Capper and Pratyush Anand for several suggested
Changes.

Signed-off-by: Sandeepa Prabhu <sandeepa.s.pra...@gmail.com>
Signed-off-by: David A. Long <dave.l...@linaro.org>
Signed-off-by: Pratyush Anand <pan...@redhat.com>
Acked-by: Masami Hiramatsu <mhira...@kernel.org>
---
  arch/arm64/Kconfig  |   1 +
  arch/arm64/include/asm/debug-monitors.h |   5 +
  arch/arm64/include/asm/insn.h   |   2 +
  arch/arm64/include/asm/kprobes.h|  60 
  arch/arm64/include/asm/probes.h |  34 +++
  arch/arm64/include/asm/ptrace.h |  14 +-
  arch/arm64/kernel/Makefile  |   2 +-
  arch/arm64/kernel/debug-monitors.c  |  16 +-
  arch/arm64/kernel/probes/Makefile   |   1 +
  arch/arm64/kernel/probes/decode-insn.c  | 143 +
  arch/arm64/kernel/probes/decode-insn.h  |  34 +++
  arch/arm64/kernel/probes/kprobes.c  | 525 
  arch/arm64/kernel/vmlinux.lds.S |   1 +
  arch/arm64/mm/fault.c   |  26 ++
  14 files changed, 859 insertions(+), 5 deletions(-)
  create mode 100644 arch/arm64/include/asm/kprobes.h
  create mode 100644 arch/arm64/include/asm/probes.h
  create mode 100644 arch/arm64/kernel/probes/Makefile
  create mode 100644 arch/arm64/kernel/probes/decode-insn.c
  create mode 100644 arch/arm64/kernel/probes/decode-insn.h
  create mode 100644 arch/arm64/kernel/probes/kprobes.c



[...]


diff --git a/arch/arm64/include/asm/kprobes.h b/arch/arm64/include/asm/kprobes.h
new file mode 100644
index 000..79c9511
--- /dev/null
+++ b/arch/arm64/include/asm/kprobes.h
@@ -0,0 +1,60 @@
+/*
+ * arch/arm64/include/asm/kprobes.h
+ *
+ * Copyright (C) 2013 Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef _ARM_KPROBES_H
+#define _ARM_KPROBES_H
+
+#include 
+#include 
+#include 
+
+#define __ARCH_WANT_KPROBES_INSN_SLOT
+#define MAX_INSN_SIZE  1
+#define MAX_STACK_SIZE 128


Where is that value coming from? Because even on my 6502, I have a 256
byte stack.



Although I don't claim to know the original author's thoughts I would 
guess it is based on the seven other existing implementations for 
kprobes on various architectures, all of which appear to use either 64 
or 128 for MAX_STACK_SIZE.  The code is not trying to duplicate the 
whole stack.



+
+#define flush_insn_slot(p) do { } while (0)
+#define kretprobe_blacklist_size   0
+
+#include 
+
+struct prev_kprobe {
+  

  1   2   3   4   5   6   7   8   9   >