diff options
author | Larry Bassel <larry.bassel@linaro.org> | 2014-05-30 15:34:15 -0400 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2014-07-10 05:10:21 -0400 |
commit | 6c81fe7925cc4c42de49e17be21eb86d1173c3a7 (patch) | |
tree | 386156dd2370309268d9455d09782dc0638428a0 /arch/arm64/kernel/entry.S | |
parent | 6ab6463aeb5fbc75fa3227befb508fc33b34dbf1 (diff) |
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: Will Deacon <will.deacon@arm.com>
Reviewed-by: Kevin Hilman <khilman@linaro.org>
Tested-by: Kevin Hilman <khilman@linaro.org>
Signed-off-by: Larry Bassel <larry.bassel@linaro.org>
Signed-off-by: Kevin Hilman <khilman@linaro.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm64/kernel/entry.S')
-rw-r--r-- | arch/arm64/kernel/entry.S | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index d7230bf68ad1..93ac58dbf07c 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S | |||
@@ -30,6 +30,32 @@ | |||
30 | #include <asm/unistd32.h> | 30 | #include <asm/unistd32.h> |
31 | 31 | ||
32 | /* | 32 | /* |
33 | * Context tracking subsystem. Used to instrument transitions | ||
34 | * between user and kernel mode. | ||
35 | */ | ||
36 | .macro ct_user_exit, syscall = 0 | ||
37 | #ifdef CONFIG_CONTEXT_TRACKING | ||
38 | bl context_tracking_user_exit | ||
39 | .if \syscall == 1 | ||
40 | /* | ||
41 | * Save/restore needed during syscalls. Restore syscall arguments from | ||
42 | * the values already saved on stack during kernel_entry. | ||
43 | */ | ||
44 | ldp x0, x1, [sp] | ||
45 | ldp x2, x3, [sp, #S_X2] | ||
46 | ldp x4, x5, [sp, #S_X4] | ||
47 | ldp x6, x7, [sp, #S_X6] | ||
48 | .endif | ||
49 | #endif | ||
50 | .endm | ||
51 | |||
52 | .macro ct_user_enter | ||
53 | #ifdef CONFIG_CONTEXT_TRACKING | ||
54 | bl context_tracking_user_enter | ||
55 | #endif | ||
56 | .endm | ||
57 | |||
58 | /* | ||
33 | * Bad Abort numbers | 59 | * Bad Abort numbers |
34 | *----------------- | 60 | *----------------- |
35 | */ | 61 | */ |
@@ -91,6 +117,7 @@ | |||
91 | .macro kernel_exit, el, ret = 0 | 117 | .macro kernel_exit, el, ret = 0 |
92 | ldp x21, x22, [sp, #S_PC] // load ELR, SPSR | 118 | ldp x21, x22, [sp, #S_PC] // load ELR, SPSR |
93 | .if \el == 0 | 119 | .if \el == 0 |
120 | ct_user_enter | ||
94 | ldr x23, [sp, #S_SP] // load return stack pointer | 121 | ldr x23, [sp, #S_SP] // load return stack pointer |
95 | .endif | 122 | .endif |
96 | .if \ret | 123 | .if \ret |
@@ -426,6 +453,7 @@ el0_da: | |||
426 | mrs x26, far_el1 | 453 | mrs x26, far_el1 |
427 | // enable interrupts before calling the main handler | 454 | // enable interrupts before calling the main handler |
428 | enable_dbg_and_irq | 455 | enable_dbg_and_irq |
456 | ct_user_exit | ||
429 | bic x0, x26, #(0xff << 56) | 457 | bic x0, x26, #(0xff << 56) |
430 | mov x1, x25 | 458 | mov x1, x25 |
431 | mov x2, sp | 459 | mov x2, sp |
@@ -438,6 +466,7 @@ el0_ia: | |||
438 | mrs x26, far_el1 | 466 | mrs x26, far_el1 |
439 | // enable interrupts before calling the main handler | 467 | // enable interrupts before calling the main handler |
440 | enable_dbg_and_irq | 468 | enable_dbg_and_irq |
469 | ct_user_exit | ||
441 | mov x0, x26 | 470 | mov x0, x26 |
442 | orr x1, x25, #1 << 24 // use reserved ISS bit for instruction aborts | 471 | orr x1, x25, #1 << 24 // use reserved ISS bit for instruction aborts |
443 | mov x2, sp | 472 | mov x2, sp |
@@ -448,6 +477,7 @@ el0_fpsimd_acc: | |||
448 | * Floating Point or Advanced SIMD access | 477 | * Floating Point or Advanced SIMD access |
449 | */ | 478 | */ |
450 | enable_dbg | 479 | enable_dbg |
480 | ct_user_exit | ||
451 | mov x0, x25 | 481 | mov x0, x25 |
452 | mov x1, sp | 482 | mov x1, sp |
453 | adr lr, ret_to_user | 483 | adr lr, ret_to_user |
@@ -457,6 +487,7 @@ el0_fpsimd_exc: | |||
457 | * Floating Point or Advanced SIMD exception | 487 | * Floating Point or Advanced SIMD exception |
458 | */ | 488 | */ |
459 | enable_dbg | 489 | enable_dbg |
490 | ct_user_exit | ||
460 | mov x0, x25 | 491 | mov x0, x25 |
461 | mov x1, sp | 492 | mov x1, sp |
462 | adr lr, ret_to_user | 493 | adr lr, ret_to_user |
@@ -479,6 +510,7 @@ el0_undef: | |||
479 | */ | 510 | */ |
480 | // enable interrupts before calling the main handler | 511 | // enable interrupts before calling the main handler |
481 | enable_dbg_and_irq | 512 | enable_dbg_and_irq |
513 | ct_user_exit | ||
482 | mov x0, sp | 514 | mov x0, sp |
483 | adr lr, ret_to_user | 515 | adr lr, ret_to_user |
484 | b do_undefinstr | 516 | b do_undefinstr |
@@ -492,9 +524,11 @@ el0_dbg: | |||
492 | mov x2, sp | 524 | mov x2, sp |
493 | bl do_debug_exception | 525 | bl do_debug_exception |
494 | enable_dbg | 526 | enable_dbg |
527 | ct_user_exit | ||
495 | b ret_to_user | 528 | b ret_to_user |
496 | el0_inv: | 529 | el0_inv: |
497 | enable_dbg | 530 | enable_dbg |
531 | ct_user_exit | ||
498 | mov x0, sp | 532 | mov x0, sp |
499 | mov x1, #BAD_SYNC | 533 | mov x1, #BAD_SYNC |
500 | mrs x2, esr_el1 | 534 | mrs x2, esr_el1 |
@@ -511,6 +545,7 @@ el0_irq_naked: | |||
511 | bl trace_hardirqs_off | 545 | bl trace_hardirqs_off |
512 | #endif | 546 | #endif |
513 | 547 | ||
548 | ct_user_exit | ||
514 | irq_handler | 549 | irq_handler |
515 | 550 | ||
516 | #ifdef CONFIG_TRACE_IRQFLAGS | 551 | #ifdef CONFIG_TRACE_IRQFLAGS |
@@ -615,6 +650,7 @@ el0_svc: | |||
615 | el0_svc_naked: // compat entry point | 650 | el0_svc_naked: // compat entry point |
616 | stp x0, scno, [sp, #S_ORIG_X0] // save the original x0 and syscall number | 651 | stp x0, scno, [sp, #S_ORIG_X0] // save the original x0 and syscall number |
617 | enable_dbg_and_irq | 652 | enable_dbg_and_irq |
653 | ct_user_exit 1 | ||
618 | 654 | ||
619 | ldr x16, [tsk, #TI_FLAGS] // check for syscall hooks | 655 | ldr x16, [tsk, #TI_FLAGS] // check for syscall hooks |
620 | tst x16, #_TIF_SYSCALL_WORK | 656 | tst x16, #_TIF_SYSCALL_WORK |