diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/s390/kernel/ptrace.c | 30 |
1 files changed, 16 insertions, 14 deletions
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index ef86ad24398..ae0e14b8880 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
@@ -47,29 +47,31 @@ enum s390_regset { | |||
47 | 47 | ||
48 | void update_per_regs(struct task_struct *task) | 48 | void update_per_regs(struct task_struct *task) |
49 | { | 49 | { |
50 | static const struct per_regs per_single_step = { | ||
51 | .control = PER_EVENT_IFETCH, | ||
52 | .start = 0, | ||
53 | .end = PSW_ADDR_INSN, | ||
54 | }; | ||
55 | struct pt_regs *regs = task_pt_regs(task); | 50 | struct pt_regs *regs = task_pt_regs(task); |
56 | struct thread_struct *thread = &task->thread; | 51 | struct thread_struct *thread = &task->thread; |
57 | const struct per_regs *new; | 52 | struct per_regs old, new; |
58 | struct per_regs old; | 53 | |
59 | 54 | /* Copy user specified PER registers */ | |
60 | /* TIF_SINGLE_STEP overrides the user specified PER registers. */ | 55 | new.control = thread->per_user.control; |
61 | new = test_tsk_thread_flag(task, TIF_SINGLE_STEP) ? | 56 | new.start = thread->per_user.start; |
62 | &per_single_step : &thread->per_user; | 57 | new.end = thread->per_user.end; |
58 | |||
59 | /* merge TIF_SINGLE_STEP into user specified PER registers. */ | ||
60 | if (test_tsk_thread_flag(task, TIF_SINGLE_STEP)) { | ||
61 | new.control |= PER_EVENT_IFETCH; | ||
62 | new.start = 0; | ||
63 | new.end = PSW_ADDR_INSN; | ||
64 | } | ||
63 | 65 | ||
64 | /* Take care of the PER enablement bit in the PSW. */ | 66 | /* Take care of the PER enablement bit in the PSW. */ |
65 | if (!(new->control & PER_EVENT_MASK)) { | 67 | if (!(new.control & PER_EVENT_MASK)) { |
66 | regs->psw.mask &= ~PSW_MASK_PER; | 68 | regs->psw.mask &= ~PSW_MASK_PER; |
67 | return; | 69 | return; |
68 | } | 70 | } |
69 | regs->psw.mask |= PSW_MASK_PER; | 71 | regs->psw.mask |= PSW_MASK_PER; |
70 | __ctl_store(old, 9, 11); | 72 | __ctl_store(old, 9, 11); |
71 | if (memcmp(new, &old, sizeof(struct per_regs)) != 0) | 73 | if (memcmp(&new, &old, sizeof(struct per_regs)) != 0) |
72 | __ctl_load(*new, 9, 11); | 74 | __ctl_load(new, 9, 11); |
73 | } | 75 | } |
74 | 76 | ||
75 | void user_enable_single_step(struct task_struct *task) | 77 | void user_enable_single_step(struct task_struct *task) |