arm64: mm: update CONTEXTIDR register to contain PID of current process
authorWill Deacon <will.deacon@arm.com>
Thu, 17 Jan 2013 12:31:45 +0000 (12:31 +0000)
committerCatalin Marinas <catalin.marinas@arm.com>
Mon, 11 Feb 2013 18:24:18 +0000 (18:24 +0000)
This patch is a port of 575320d62 ("ARM: 7445/1: mm: update CONTEXTIDR
register to contain PID of current process") from ARM that introduces a
new Kconfig option which, when enabled, causes the kernel to write the
PID of the current task into the CONTEXTIDR register on context switch.
This is useful when analysing hardware trace, since writes to this
register can be configured to emit an event into the trace stream.

Signed-off-by: Will Deacon <will.deacon@arm.com>
[catalin.marinas@arm.com: contextidr_thread_switch() moved to mmu_context.h]
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
arch/arm64/Kconfig.debug
arch/arm64/include/asm/mmu_context.h
arch/arm64/kernel/process.c

index 79871cd78da8fbabf8fb54120567e13205670a58..51493430f142d8c1cce428826bb8371d98250916 100644 (file)
@@ -33,4 +33,12 @@ config EARLY_PRINTK
          is assumed that the early console device has been initialised
          by the boot loader prior to starting the Linux kernel.
 
+config PID_IN_CONTEXTIDR
+       bool "Write the current PID to the CONTEXTIDR register"
+       help
+         Enabling this option causes the kernel to write the current PID to
+         the CONTEXTIDR register, at the expense of some additional
+         instructions during context switch. Say Y here only if you are
+         planning to use hardware trace tools with this kernel.
+
 endmenu
index f68465dee02651211452e7786e983447826d872a..e2bc385adb6b9b3ebb941702be4ea378586413c8 100644 (file)
@@ -35,6 +35,21 @@ extern unsigned int cpu_last_asid;
 void __init_new_context(struct task_struct *tsk, struct mm_struct *mm);
 void __new_context(struct mm_struct *mm);
 
+#ifdef CONFIG_PID_IN_CONTEXTIDR
+static inline void contextidr_thread_switch(struct task_struct *next)
+{
+       asm(
+       "       msr     contextidr_el1, %0\n"
+       "       isb"
+       :
+       : "r" (task_pid_nr(next)));
+}
+#else
+static inline void contextidr_thread_switch(struct task_struct *next)
+{
+}
+#endif
+
 /*
  * Set TTBR0 to empty_zero_page. No translations will be possible via TTBR0.
  */
index cb0956bc96edfe15333b0aee0012a15dcb730d13..a8fbd7eaa2ed85b23abbdd3a507f494eb803cf5c 100644 (file)
 
 #include <asm/compat.h>
 #include <asm/cacheflush.h>
+#include <asm/fpsimd.h>
+#include <asm/mmu_context.h>
 #include <asm/processor.h>
 #include <asm/stacktrace.h>
-#include <asm/fpsimd.h>
 
 static void setup_restart(void)
 {
@@ -319,6 +320,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
        /* the actual thread switch */
        last = cpu_switch_to(prev, next);
 
+       contextidr_thread_switch(next);
        return last;
 }