summaryrefslogtreecommitdiff
path: root/arch/s390/kernel/traps.c
diff options
context:
space:
mode:
authorSven Schnelle <svens@linux.ibm.com>2021-04-07 09:20:17 +0200
committerVasily Gorbik <gor@linux.ibm.com>2021-10-26 15:21:29 +0200
commit3b051e89da70d464a036a86d70ce2ed61c73f792 (patch)
treead9a4dc6ce89d26aaf92d530d48df8e992c629e6 /arch/s390/kernel/traps.c
parent5d17d4ed7e892be3670de7189c76009e12397fe7 (diff)
s390: add support for BEAR enhancement facility
The Breaking-Event-Address-Register (BEAR) stores the address of the last breaking event instruction. Breaking events are usually instructions that change the program flow - for example branches, and instructions that modify the address in the PSW like lpswe. This is useful for debugging wild branches, because one could easily figure out where the wild branch was originating from. What is problematic is that lpswe is considered a breaking event, and therefore overwrites BEAR on kernel exit. The BEAR enhancement facility adds new instructions that allow to save/restore BEAR and also an lpswey instruction that doesn't cause a breaking event. So we can save BEAR on kernel entry and restore it on exit to user space. Signed-off-by: Sven Schnelle <svens@linux.ibm.com> Reviewed-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Diffstat (limited to 'arch/s390/kernel/traps.c')
-rw-r--r--arch/s390/kernel/traps.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index d32a6ee7b0dd..6c6f7dcce1a5 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -300,7 +300,6 @@ static void (*pgm_check_table[128])(struct pt_regs *regs);
void noinstr __do_pgm_check(struct pt_regs *regs)
{
- unsigned long last_break = S390_lowcore.pgm_last_break;
unsigned int trapnr;
irqentry_state_t state;
@@ -311,10 +310,11 @@ void noinstr __do_pgm_check(struct pt_regs *regs)
if (user_mode(regs)) {
update_timer_sys();
- if (last_break < 4096)
- last_break = 1;
- current->thread.last_break = last_break;
- regs->last_break = last_break;
+ if (!static_branch_likely(&cpu_has_bear)) {
+ if (regs->last_break < 4096)
+ regs->last_break = 1;
+ }
+ current->thread.last_break = regs->last_break;
}
if (S390_lowcore.pgm_code & 0x0200) {