|
@@ -47,29 +47,31 @@ enum s390_regset {
|
|
|
|
|
|
void update_per_regs(struct task_struct *task)
|
|
|
{
|
|
|
- static const struct per_regs per_single_step = {
|
|
|
- .control = PER_EVENT_IFETCH,
|
|
|
- .start = 0,
|
|
|
- .end = PSW_ADDR_INSN,
|
|
|
- };
|
|
|
struct pt_regs *regs = task_pt_regs(task);
|
|
|
struct thread_struct *thread = &task->thread;
|
|
|
- const struct per_regs *new;
|
|
|
- struct per_regs old;
|
|
|
-
|
|
|
- /* TIF_SINGLE_STEP overrides the user specified PER registers. */
|
|
|
- new = test_tsk_thread_flag(task, TIF_SINGLE_STEP) ?
|
|
|
- &per_single_step : &thread->per_user;
|
|
|
+ struct per_regs old, new;
|
|
|
+
|
|
|
+ /* Copy user specified PER registers */
|
|
|
+ new.control = thread->per_user.control;
|
|
|
+ new.start = thread->per_user.start;
|
|
|
+ new.end = thread->per_user.end;
|
|
|
+
|
|
|
+ /* merge TIF_SINGLE_STEP into user specified PER registers. */
|
|
|
+ if (test_tsk_thread_flag(task, TIF_SINGLE_STEP)) {
|
|
|
+ new.control |= PER_EVENT_IFETCH;
|
|
|
+ new.start = 0;
|
|
|
+ new.end = PSW_ADDR_INSN;
|
|
|
+ }
|
|
|
|
|
|
/* Take care of the PER enablement bit in the PSW. */
|
|
|
- if (!(new->control & PER_EVENT_MASK)) {
|
|
|
+ if (!(new.control & PER_EVENT_MASK)) {
|
|
|
regs->psw.mask &= ~PSW_MASK_PER;
|
|
|
return;
|
|
|
}
|
|
|
regs->psw.mask |= PSW_MASK_PER;
|
|
|
__ctl_store(old, 9, 11);
|
|
|
- if (memcmp(new, &old, sizeof(struct per_regs)) != 0)
|
|
|
- __ctl_load(*new, 9, 11);
|
|
|
+ if (memcmp(&new, &old, sizeof(struct per_regs)) != 0)
|
|
|
+ __ctl_load(new, 9, 11);
|
|
|
}
|
|
|
|
|
|
void user_enable_single_step(struct task_struct *task)
|