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>
This commit is contained in:

committed by
Michael Ellerman

parent
b57bd2de8c
commit
bd3ea317fd
@@ -1017,6 +1017,14 @@ static inline void save_sprs(struct thread_struct *t)
|
||||
*/
|
||||
t->tar = mfspr(SPRN_TAR);
|
||||
}
|
||||
|
||||
if (cpu_has_feature(CPU_FTR_ARCH_300)) {
|
||||
/* Conditionally save Load Monitor registers, if enabled */
|
||||
if (t->fscr & FSCR_LM) {
|
||||
t->lmrr = mfspr(SPRN_LMRR);
|
||||
t->lmser = mfspr(SPRN_LMSER);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1052,6 +1060,16 @@ static inline void restore_sprs(struct thread_struct *old_thread,
|
||||
if (old_thread->tar != new_thread->tar)
|
||||
mtspr(SPRN_TAR, new_thread->tar);
|
||||
}
|
||||
|
||||
if (cpu_has_feature(CPU_FTR_ARCH_300)) {
|
||||
/* Conditionally restore Load Monitor registers, if enabled */
|
||||
if (new_thread->fscr & FSCR_LM) {
|
||||
if (old_thread->lmrr != new_thread->lmrr)
|
||||
mtspr(SPRN_LMRR, new_thread->lmrr);
|
||||
if (old_thread->lmser != new_thread->lmser)
|
||||
mtspr(SPRN_LMSER, new_thread->lmser);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -1377,6 +1377,7 @@ void facility_unavailable_exception(struct pt_regs *regs)
|
||||
[FSCR_TM_LG] = "TM",
|
||||
[FSCR_EBB_LG] = "EBB",
|
||||
[FSCR_TAR_LG] = "TAR",
|
||||
[FSCR_LM_LG] = "LM",
|
||||
};
|
||||
char *facility = "unknown";
|
||||
u64 value;
|
||||
@@ -1434,6 +1435,14 @@ void facility_unavailable_exception(struct pt_regs *regs)
|
||||
emulate_single_step(regs);
|
||||
}
|
||||
return;
|
||||
} else if ((status == FSCR_LM_LG) && cpu_has_feature(CPU_FTR_ARCH_300)) {
|
||||
/*
|
||||
* This process has touched LM, so turn it on forever
|
||||
* for this process
|
||||
*/
|
||||
current->thread.fscr |= FSCR_LM;
|
||||
mtspr(SPRN_FSCR, current->thread.fscr);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((status < ARRAY_SIZE(facility_strings)) &&
|
||||
|
Reference in New Issue
Block a user