Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6c81fe79 authored by Larry Bassel's avatar Larry Bassel Committed by Catalin Marinas
Browse files

arm64: enable context tracking



Make calls to ct_user_enter when the kernel is exited
and ct_user_exit when the kernel is entered (in el0_da,
el0_ia, el0_svc, el0_irq and all of the "error" paths).

These macros expand to function calls which will only work
properly if el0_sync and related code has been rearranged
(in a previous patch of this series).

The calls to ct_user_exit are made after hw debugging has been
enabled (enable_dbg_and_irq).

The call to ct_user_enter is made at the beginning of the
kernel_exit macro.

This patch is based on earlier work by Kevin Hilman.
Save/restore optimizations were also done by Kevin.

Acked-by: default avatarWill Deacon <will.deacon@arm.com>
Reviewed-by: default avatarKevin Hilman <khilman@linaro.org>
Tested-by: default avatarKevin Hilman <khilman@linaro.org>
Signed-off-by: default avatarLarry Bassel <larry.bassel@linaro.org>
Signed-off-by: default avatarKevin Hilman <khilman@linaro.org>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent 6ab6463a
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -63,6 +63,7 @@ config ARM64
	select RTC_LIB
	select RTC_LIB
	select SPARSE_IRQ
	select SPARSE_IRQ
	select SYSCTL_EXCEPTION_TRACE
	select SYSCTL_EXCEPTION_TRACE
	select HAVE_CONTEXT_TRACKING
	help
	help
	  ARM 64-bit (AArch64) Linux support.
	  ARM 64-bit (AArch64) Linux support.


+4 −1
Original line number Original line Diff line number Diff line
@@ -103,6 +103,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_NEED_RESCHED	1
#define TIF_NEED_RESCHED	1
#define TIF_NOTIFY_RESUME	2	/* callback before returning to user */
#define TIF_NOTIFY_RESUME	2	/* callback before returning to user */
#define TIF_FOREIGN_FPSTATE	3	/* CPU's FP state is not current's */
#define TIF_FOREIGN_FPSTATE	3	/* CPU's FP state is not current's */
#define TIF_NOHZ		7
#define TIF_SYSCALL_TRACE	8
#define TIF_SYSCALL_TRACE	8
#define TIF_SYSCALL_AUDIT	9
#define TIF_SYSCALL_AUDIT	9
#define TIF_SYSCALL_TRACEPOINT	10
#define TIF_SYSCALL_TRACEPOINT	10
@@ -118,6 +119,7 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
#define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
#define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
#define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
#define _TIF_FOREIGN_FPSTATE	(1 << TIF_FOREIGN_FPSTATE)
#define _TIF_FOREIGN_FPSTATE	(1 << TIF_FOREIGN_FPSTATE)
#define _TIF_NOHZ		(1 << TIF_NOHZ)
#define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
#define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
#define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
#define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
#define _TIF_SYSCALL_TRACEPOINT	(1 << TIF_SYSCALL_TRACEPOINT)
#define _TIF_SYSCALL_TRACEPOINT	(1 << TIF_SYSCALL_TRACEPOINT)
@@ -128,7 +130,8 @@ static inline struct thread_info *current_thread_info(void)
				 _TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE)
				 _TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE)


#define _TIF_SYSCALL_WORK	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
#define _TIF_SYSCALL_WORK	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
				 _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP)
				 _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \
				 _TIF_NOHZ)


#endif /* __KERNEL__ */
#endif /* __KERNEL__ */
#endif /* __ASM_THREAD_INFO_H */
#endif /* __ASM_THREAD_INFO_H */
+36 −0
Original line number Original line Diff line number Diff line
@@ -29,6 +29,32 @@
#include <asm/unistd.h>
#include <asm/unistd.h>
#include <asm/unistd32.h>
#include <asm/unistd32.h>


/*
 * Context tracking subsystem.  Used to instrument transitions
 * between user and kernel mode.
 */
	.macro ct_user_exit, syscall = 0
#ifdef CONFIG_CONTEXT_TRACKING
	bl	context_tracking_user_exit
	.if \syscall == 1
	/*
	 * Save/restore needed during syscalls.  Restore syscall arguments from
	 * the values already saved on stack during kernel_entry.
	 */
	ldp	x0, x1, [sp]
	ldp	x2, x3, [sp, #S_X2]
	ldp	x4, x5, [sp, #S_X4]
	ldp	x6, x7, [sp, #S_X6]
	.endif
#endif
	.endm

	.macro ct_user_enter
#ifdef CONFIG_CONTEXT_TRACKING
	bl	context_tracking_user_enter
#endif
	.endm

/*
/*
 * Bad Abort numbers
 * Bad Abort numbers
 *-----------------
 *-----------------
@@ -91,6 +117,7 @@
	.macro	kernel_exit, el, ret = 0
	.macro	kernel_exit, el, ret = 0
	ldp	x21, x22, [sp, #S_PC]		// load ELR, SPSR
	ldp	x21, x22, [sp, #S_PC]		// load ELR, SPSR
	.if	\el == 0
	.if	\el == 0
	ct_user_enter
	ldr	x23, [sp, #S_SP]		// load return stack pointer
	ldr	x23, [sp, #S_SP]		// load return stack pointer
	.endif
	.endif
	.if	\ret
	.if	\ret
@@ -426,6 +453,7 @@ el0_da:
	mrs	x26, far_el1
	mrs	x26, far_el1
	// enable interrupts before calling the main handler
	// enable interrupts before calling the main handler
	enable_dbg_and_irq
	enable_dbg_and_irq
	ct_user_exit
	bic	x0, x26, #(0xff << 56)
	bic	x0, x26, #(0xff << 56)
	mov	x1, x25
	mov	x1, x25
	mov	x2, sp
	mov	x2, sp
@@ -438,6 +466,7 @@ el0_ia:
	mrs	x26, far_el1
	mrs	x26, far_el1
	// enable interrupts before calling the main handler
	// enable interrupts before calling the main handler
	enable_dbg_and_irq
	enable_dbg_and_irq
	ct_user_exit
	mov	x0, x26
	mov	x0, x26
	orr	x1, x25, #1 << 24		// use reserved ISS bit for instruction aborts
	orr	x1, x25, #1 << 24		// use reserved ISS bit for instruction aborts
	mov	x2, sp
	mov	x2, sp
@@ -448,6 +477,7 @@ el0_fpsimd_acc:
	 * Floating Point or Advanced SIMD access
	 * Floating Point or Advanced SIMD access
	 */
	 */
	enable_dbg
	enable_dbg
	ct_user_exit
	mov	x0, x25
	mov	x0, x25
	mov	x1, sp
	mov	x1, sp
	adr	lr, ret_to_user
	adr	lr, ret_to_user
@@ -457,6 +487,7 @@ el0_fpsimd_exc:
	 * Floating Point or Advanced SIMD exception
	 * Floating Point or Advanced SIMD exception
	 */
	 */
	enable_dbg
	enable_dbg
	ct_user_exit
	mov	x0, x25
	mov	x0, x25
	mov	x1, sp
	mov	x1, sp
	adr	lr, ret_to_user
	adr	lr, ret_to_user
@@ -479,6 +510,7 @@ el0_undef:
	 */
	 */
	// enable interrupts before calling the main handler
	// enable interrupts before calling the main handler
	enable_dbg_and_irq
	enable_dbg_and_irq
	ct_user_exit
	mov	x0, sp
	mov	x0, sp
	adr	lr, ret_to_user
	adr	lr, ret_to_user
	b	do_undefinstr
	b	do_undefinstr
@@ -492,9 +524,11 @@ el0_dbg:
	mov	x2, sp
	mov	x2, sp
	bl	do_debug_exception
	bl	do_debug_exception
	enable_dbg
	enable_dbg
	ct_user_exit
	b	ret_to_user
	b	ret_to_user
el0_inv:
el0_inv:
	enable_dbg
	enable_dbg
	ct_user_exit
	mov	x0, sp
	mov	x0, sp
	mov	x1, #BAD_SYNC
	mov	x1, #BAD_SYNC
	mrs	x2, esr_el1
	mrs	x2, esr_el1
@@ -511,6 +545,7 @@ el0_irq_naked:
	bl	trace_hardirqs_off
	bl	trace_hardirqs_off
#endif
#endif


	ct_user_exit
	irq_handler
	irq_handler


#ifdef CONFIG_TRACE_IRQFLAGS
#ifdef CONFIG_TRACE_IRQFLAGS
@@ -615,6 +650,7 @@ el0_svc:
el0_svc_naked:					// compat entry point
el0_svc_naked:					// compat entry point
	stp	x0, scno, [sp, #S_ORIG_X0]	// save the original x0 and syscall number
	stp	x0, scno, [sp, #S_ORIG_X0]	// save the original x0 and syscall number
	enable_dbg_and_irq
	enable_dbg_and_irq
	ct_user_exit 1


	ldr	x16, [tsk, #TI_FLAGS]		// check for syscall hooks
	ldr	x16, [tsk, #TI_FLAGS]		// check for syscall hooks
	tst	x16, #_TIF_SYSCALL_WORK
	tst	x16, #_TIF_SYSCALL_WORK