diff options
author | Jack Miller <jack@codezen.org> | 2016-06-08 22:31:09 -0400 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2016-06-21 01:30:50 -0400 |
commit | bd3ea317fddfd0f2044f94bed294b90c4bc8e69e (patch) | |
tree | 051da254ea09ce51759123472fbcc52002c0ad53 /arch/powerpc/kernel/process.c | |
parent | b57bd2de8c6c9aa03f1b899edd6f5582cc8b5b08 (diff) |
powerpc: Load Monitor Register Support
This enables new registers, LMRR and LMSER, that can trigger an EBB in
userspace code when a monitored load (via the new ldmx instruction)
loads memory from a monitored space. This facility is controlled by a
new FSCR bit, LM.
This patch disables the FSCR LM control bit on task init and enables
that bit when a load monitor facility unavailable exception is taken
for using it. On context switch, this bit is then used to determine
whether the two relevant registers are saved and restored. This is
done lazily for performance reasons.
Signed-off-by: Jack Miller <jack@codezen.org>
Signed-off-by: Michael Neuling <mikey@neuling.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/kernel/process.c')
-rw-r--r-- | arch/powerpc/kernel/process.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 6d0a831bc7d8..ddceeb96e8fb 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
@@ -1017,6 +1017,14 @@ static inline void save_sprs(struct thread_struct *t) | |||
1017 | */ | 1017 | */ |
1018 | t->tar = mfspr(SPRN_TAR); | 1018 | t->tar = mfspr(SPRN_TAR); |
1019 | } | 1019 | } |
1020 | |||
1021 | if (cpu_has_feature(CPU_FTR_ARCH_300)) { | ||
1022 | /* Conditionally save Load Monitor registers, if enabled */ | ||
1023 | if (t->fscr & FSCR_LM) { | ||
1024 | t->lmrr = mfspr(SPRN_LMRR); | ||
1025 | t->lmser = mfspr(SPRN_LMSER); | ||
1026 | } | ||
1027 | } | ||
1020 | #endif | 1028 | #endif |
1021 | } | 1029 | } |
1022 | 1030 | ||
@@ -1052,6 +1060,16 @@ static inline void restore_sprs(struct thread_struct *old_thread, | |||
1052 | if (old_thread->tar != new_thread->tar) | 1060 | if (old_thread->tar != new_thread->tar) |
1053 | mtspr(SPRN_TAR, new_thread->tar); | 1061 | mtspr(SPRN_TAR, new_thread->tar); |
1054 | } | 1062 | } |
1063 | |||
1064 | if (cpu_has_feature(CPU_FTR_ARCH_300)) { | ||
1065 | /* Conditionally restore Load Monitor registers, if enabled */ | ||
1066 | if (new_thread->fscr & FSCR_LM) { | ||
1067 | if (old_thread->lmrr != new_thread->lmrr) | ||
1068 | mtspr(SPRN_LMRR, new_thread->lmrr); | ||
1069 | if (old_thread->lmser != new_thread->lmser) | ||
1070 | mtspr(SPRN_LMSER, new_thread->lmser); | ||
1071 | } | ||
1072 | } | ||
1055 | #endif | 1073 | #endif |
1056 | } | 1074 | } |
1057 | 1075 | ||