diff options
-rw-r--r-- | arch/arm64/Kconfig.debug | 8 | ||||
-rw-r--r-- | arch/arm64/include/asm/mmu_context.h | 15 | ||||
-rw-r--r-- | arch/arm64/kernel/process.c | 4 |
3 files changed, 26 insertions, 1 deletions
diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug index 79871cd78da8..51493430f142 100644 --- a/arch/arm64/Kconfig.debug +++ b/arch/arm64/Kconfig.debug | |||
@@ -33,4 +33,12 @@ config EARLY_PRINTK | |||
33 | is assumed that the early console device has been initialised | 33 | is assumed that the early console device has been initialised |
34 | by the boot loader prior to starting the Linux kernel. | 34 | by the boot loader prior to starting the Linux kernel. |
35 | 35 | ||
36 | config PID_IN_CONTEXTIDR | ||
37 | bool "Write the current PID to the CONTEXTIDR register" | ||
38 | help | ||
39 | Enabling this option causes the kernel to write the current PID to | ||
40 | the CONTEXTIDR register, at the expense of some additional | ||
41 | instructions during context switch. Say Y here only if you are | ||
42 | planning to use hardware trace tools with this kernel. | ||
43 | |||
36 | endmenu | 44 | endmenu |
diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h index f68465dee026..e2bc385adb6b 100644 --- a/arch/arm64/include/asm/mmu_context.h +++ b/arch/arm64/include/asm/mmu_context.h | |||
@@ -35,6 +35,21 @@ extern unsigned int cpu_last_asid; | |||
35 | void __init_new_context(struct task_struct *tsk, struct mm_struct *mm); | 35 | void __init_new_context(struct task_struct *tsk, struct mm_struct *mm); |
36 | void __new_context(struct mm_struct *mm); | 36 | void __new_context(struct mm_struct *mm); |
37 | 37 | ||
38 | #ifdef CONFIG_PID_IN_CONTEXTIDR | ||
39 | static inline void contextidr_thread_switch(struct task_struct *next) | ||
40 | { | ||
41 | asm( | ||
42 | " msr contextidr_el1, %0\n" | ||
43 | " isb" | ||
44 | : | ||
45 | : "r" (task_pid_nr(next))); | ||
46 | } | ||
47 | #else | ||
48 | static inline void contextidr_thread_switch(struct task_struct *next) | ||
49 | { | ||
50 | } | ||
51 | #endif | ||
52 | |||
38 | /* | 53 | /* |
39 | * Set TTBR0 to empty_zero_page. No translations will be possible via TTBR0. | 54 | * Set TTBR0 to empty_zero_page. No translations will be possible via TTBR0. |
40 | */ | 55 | */ |
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index cb0956bc96ed..a8fbd7eaa2ed 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c | |||
@@ -45,9 +45,10 @@ | |||
45 | 45 | ||
46 | #include <asm/compat.h> | 46 | #include <asm/compat.h> |
47 | #include <asm/cacheflush.h> | 47 | #include <asm/cacheflush.h> |
48 | #include <asm/fpsimd.h> | ||
49 | #include <asm/mmu_context.h> | ||
48 | #include <asm/processor.h> | 50 | #include <asm/processor.h> |
49 | #include <asm/stacktrace.h> | 51 | #include <asm/stacktrace.h> |
50 | #include <asm/fpsimd.h> | ||
51 | 52 | ||
52 | static void setup_restart(void) | 53 | static void setup_restart(void) |
53 | { | 54 | { |
@@ -319,6 +320,7 @@ struct task_struct *__switch_to(struct task_struct *prev, | |||
319 | /* the actual thread switch */ | 320 | /* the actual thread switch */ |
320 | last = cpu_switch_to(prev, next); | 321 | last = cpu_switch_to(prev, next); |
321 | 322 | ||
323 | contextidr_thread_switch(next); | ||
322 | return last; | 324 | return last; |
323 | } | 325 | } |
324 | 326 | ||