Re: s390 user_enable_single_step() (Was: odd utrace testing results on s390x)

2010-01-26 Thread Martin Schwidefsky
On Thu, 21 Jan 2010 21:51:13 +0100
Oleg Nesterov o...@redhat.com wrote:

 On 01/07, Roland McGrath wrote:
 
   I am confused as well. Yes, I thought about regs-psw.mask change too,
   but I don't understand why it helps..
  [...]
   But. Acoording to the testing I did (unless I did something wrong
   again) this patch doesn't make any difference in this particular
   case. 6580807da14c423f0d0a708108e6df6ebc8bc83d does.
 
  Those results are quite mysterious to me.
  I think we'll have to get Martin to sort it out definitively.

Finally nailed that one. Grrmpf.. the special case in the program check
handler for single stepped svcs clobbers the argument registers. With our
test case this affects the clone() system call. Funny things happen when
the clone_flags argument is more or less random ..
The following patch fixes the problem for me.

--
Subject: [PATCH] fix single stepped svcs with TRACE_IRQFLAGS=y

From: Martin Schwidefsky schwidef...@de.ibm.com

If irq flags tracing is enabled the TRACE_IRQS_ON macros expands to
a function call which clobbers registers %r0-%r5. The macro is used
in the code path for single stepped system calls. The argument
registers %r2-%r6 need to be restored from the stack before the system
call function is called.

Cc: sta...@kernel.org
Signed-off-by: Martin Schwidefsky schwidef...@de.ibm.com
---

 arch/s390/kernel/entry.S   |1 +
 arch/s390/kernel/entry64.S |1 +
 2 files changed, 2 insertions(+)

diff -urpN linux-2.6/arch/s390/kernel/entry64.S 
linux-2.6-patched/arch/s390/kernel/entry64.S
--- linux-2.6/arch/s390/kernel/entry64.S2009-12-03 04:51:21.0 
+0100
+++ linux-2.6-patched/arch/s390/kernel/entry64.S2010-01-26 
14:04:58.0 +0100
@@ -549,6 +549,7 @@ pgm_svcper:
mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
oi  __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
TRACE_IRQS_ON
+   lmg %r2,%r6,SP_R2(%r15) # load svc arguments
stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
j   sysc_do_svc
 
diff -urpN linux-2.6/arch/s390/kernel/entry.S 
linux-2.6-patched/arch/s390/kernel/entry.S
--- linux-2.6/arch/s390/kernel/entry.S  2009-12-03 04:51:21.0 +0100
+++ linux-2.6-patched/arch/s390/kernel/entry.S  2010-01-26 14:04:58.0 
+0100
@@ -571,6 +571,7 @@ pgm_svcper:
mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
oi  __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
TRACE_IRQS_ON
+   lm  %r2,%r6,SP_R2(%r15) # load svc arguments
stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
b   BASED(sysc_do_svc)
 
-- 
blue skies,
   Martin.

Reality continues to ruin my life. - Calvin.



Re: s390 user_enable_single_step() (Was: odd utrace testing results on s390x)

2010-01-08 Thread Martin Schwidefsky
On Thu,  7 Jan 2010 13:46:42 -0800 (PST)
Roland McGrath rol...@redhat.com wrote:

  Clear the TIF_SINGLE_STEP bit in copy_thread. If the new process is
  not auto-attached by the tracer it is wrong to delivere SIGTRAP to
  the new process.
 
 The change is right, but this log entry is confusing.  auto-attached has
 nothing to do with it, nor does anything about tracing the new process or
 not.  The new process has not experienced a PER trap of its own, so it is
 wrong to deliver a SIGTRAP that is meant for its creator.

Ok, I changed the wording slightly:

Clear the TIF_SINGLE_STEP bit in copy_thread. The new process did not get
a PER event of its own. It is wrong deliver a SIGTRAP that was meant for
the parent process.

-- 
blue skies,
   Martin.

Reality continues to ruin my life. - Calvin.



Re: s390 user_enable_single_step() (Was: odd utrace testing results on s390x)

2010-01-05 Thread Martin Schwidefsky
On Mon, 4 Jan 2010 19:14:12 +0100
Oleg Nesterov o...@redhat.com wrote:

 On 01/04, Martin Schwidefsky wrote:
  Subject: [PATCH] fix loading of PER control registers for utrace.
 
  From: Martin Schwidefsky schwidef...@de.ibm.com
 
  If the current task enables / disables PER tracing for itself the
  PER control registers need to be loaded in FixPerRegisters.
 
  Signed-off-by: Martin Schwidefsky schwidef...@de.ibm.com
  ---
   arch/s390/kernel/ptrace.c |3 +++
   1 file changed, 3 insertions(+)
 
  --- a/arch/s390/kernel/ptrace.c
  +++ b/arch/s390/kernel/ptrace.c
  @@ -98,6 +98,9 @@ FixPerRegisters(struct task_struct *task
  per_info-control_regs.bits.storage_alt_space_ctl = 1;
  else
  per_info-control_regs.bits.storage_alt_space_ctl = 0;
  +
  +   if (task == current)
  +   __ctl_load(per_info-control_regs.words, 9, 11);
   }
 
 Yes it does fix the problem! Thanks a lot Martin.

Ok, I will add that patch to the git390 queue.

 However. Could you please look at 6580807da14c423f0d0a708108e6df6ebc8bc83d ?
 I am worried, perhaps this commit is not enough for s390. OK, do_single_step()
 tracehook_consider_fatal_signal(), this means the forked thread will not
 be killed by SIGTRAP if it is not auto-attached, but still this may be
 wrong.
 
 IOW. I think this problem is minor and probably can be ignored, but if
 I remove tracehook_consider_fatal_signal() check from do_single_step(),
 
 --- a/arch/s390/kernel/traps.c
 +++ b/arch/s390/kernel/traps.c
 @@ -382,8 +382,7 @@ void __kprobes do_single_step(struct pt_
   SIGTRAP) == NOTIFY_STOP){
   return;
   }
 - if (tracehook_consider_fatal_signal(current, SIGTRAP))
 - force_sig(SIGTRAP, current);
 + force_sig(SIGTRAP, current);
  }
 
  static void default_trap_handler(struct pt_regs * regs, long 
 interruption_code)
 ---
 
 then the test-case from 6580807da14c423f0d0a708108e6df6ebc8bc83d
 fails. This probably means that copy_process()-user_disable_single_step()
 is not enough to clear the this task wants single-stepping copied
 from parent.

user_disable_single_step() does not remove the TIF_SINGLE_STEP bit from the
forked task. Perhaps we should just clear the bit in the function.

-- 
blue skies,
   Martin.

Reality continues to ruin my life. - Calvin.



Re: s390 user_enable_single_step() (Was: odd utrace testing results on s390x)

2010-01-05 Thread Martin Schwidefsky
On Tue, 5 Jan 2010 16:36:33 +0100
Oleg Nesterov o...@redhat.com wrote:

 On 01/05, Martin Schwidefsky wrote:
 
  On Mon,  4 Jan 2010 13:11:47 -0800 (PST)
  Roland McGrath rol...@redhat.com wrote:
 
This probably means that copy_process()-user_disable_single_step()
is not enough to clear the this task wants single-stepping copied
from parent.
  
   I would suspect s390's TIF_SINGLE_STEP flag here.  That flag means a
   single-step trap occurred.  This is what causes do_single_step to be
   called before returning to user mode, rather than the machine trap doing 
   it
   directly as is done in the other arch implementations.
 
  Just my thinking as well.
 
 Oh, I am not sure. But I don't understand TIF_SINGLE_STEP on s390,
 absolutely.
 
 For example, why do_signal() sets TIF_SINGLE_STEP? Why can't we do
 
   --- a/arch/s390/kernel/signal.c
   +++ b/arch/s390/kernel/signal.c
   @@ -500,18 +500,10 @@ void do_signal(struct pt_regs *regs)
   clear_thread_flag(TIF_RESTORE_SIGMASK);

   /*
   -* If we would have taken a single-step trap
   -* for a normal instruction, act like we took
   -* one for the handler setup.
   -*/
   -   if (current-thread.per_info.single_step)
   -   set_thread_flag(TIF_SINGLE_STEP);
   -
   -   /*
* Let tracing know that we've done the handler 
 setup.
*/
   tracehook_signal_handler(signr, info, ka, 
 regs,
   -
 test_thread_flag(TIF_SINGLE_STEP));
   +   
 current-thread.per_info.single_step);
   }
   return;
   }
 
 ?

The reason why we set the TIF_SINGLE_STEP bit in do_signal is that we
want to be able to stop the debugged program before the first
instruction of the signal handler has been executed. The PER single
step causes a trap after an instruction has been executed. That first
instruction can do bad things to the arguments of the signal handler..

 Apart from arch/s390/signal.c, TIF_SINGLE_STEP is used by entry.S
 but I don't understand this asm at all.
 
 Anyway. I modified the debugging patch a bit:
 
 --- K/arch/s390/kernel/traps.c~   2009-12-22 10:41:52.909174198 -0500
 +++ K/arch/s390/kernel/traps.c2010-01-05 09:49:19.541792379 -0500
 @@ -384,6 +384,8 @@ void __kprobes do_single_step(struct pt_
   }
   if (tracehook_consider_fatal_signal(current, SIGTRAP))
   force_sig(SIGTRAP, current);
 + else
 + printk(XXX: %d %d\n, current-pid, 
 test_thread_flag(TIF_SINGLE_STEP));
  }
 
  static void default_trap_handler(struct pt_regs * regs, long 
 interruption_code)
 ---
 
 Now, when I run this test-case
 
   #include stdio.h
   #include unistd.h
   #include signal.h
   #include sys/ptrace.h
   #include sys/wait.h
   #include assert.h
 
   int main(void)
   {
   int pid, status;
 
   if (!(pid = fork())) {
   assert(ptrace(PTRACE_TRACEME) == 0);
   kill(getpid(), SIGSTOP);
 
   if (!fork())
   return 43;
 
   wait(status);
   return WEXITSTATUS(status);
   }
 
 
   for (;;) {
   assert(pid == wait(status));
   if (WIFEXITED(status))
   break;
   assert(ptrace(PTRACE_SINGLESTEP, pid, 0,0) == 0);
   }
 
   assert(WEXITSTATUS(status) == 43);
   return 0;
   }
 
 dmesg shows 799 lines of
 
   XXX: 2389 0
 
 
 The kernel is 2.6.32.2 + utrace, but CONFIG_UTRACE is not set.

With or without my bug fix ?

-- 
blue skies,
   Martin.

Reality continues to ruin my life. - Calvin.



Re: s390 user_enable_single_step() (Was: odd utrace testing results on s390x)

2010-01-05 Thread Martin Schwidefsky
On Tue, 5 Jan 2010 16:47:25 +0100
Oleg Nesterov o...@redhat.com wrote:

 On 01/05, Oleg Nesterov wrote:
 
  Anyway. I modified the debugging patch a bit:
 
  --- K/arch/s390/kernel/traps.c~ 2009-12-22 10:41:52.909174198 -0500
  +++ K/arch/s390/kernel/traps.c  2010-01-05 09:49:19.541792379 -0500
  @@ -384,6 +384,8 @@ void __kprobes do_single_step(struct pt_
  }
  if (tracehook_consider_fatal_signal(current, SIGTRAP))
  force_sig(SIGTRAP, current);
  +   else
  +   printk(XXX: %d %d\n, current-pid, 
  test_thread_flag(TIF_SINGLE_STEP));
   }
 
   static void default_trap_handler(struct pt_regs * regs, long 
  interruption_code)
  ---
 
 Ah, please ignore. I guess TIF_SINGLE_STEP was already cleared by the caller
 in entry.S

Yes, TIF_SINGLE_STEP is checked in entry.S and cleared before do_signal
is called. That is the ni instruction at sysc_singlestep and
sysc_sigpending.

-- 
blue skies,
   Martin.

Reality continues to ruin my life. - Calvin.



Re: s390 user_enable_single_step() (Was: odd utrace testing results on s390x)

2010-01-04 Thread Martin Schwidefsky
On Mon, 4 Jan 2010 16:52:25 +0100
Oleg Nesterov o...@redhat.com wrote:

 Hi!
 
 We have some strange problems with utrace on s390, and so far this _looks_
 like a s390 problem.
 
 Looks like, on any CPU user_enable_single_step() does not work until at
 least one thread with per_info.single_step = 1 does the context switch.
 
 This doesn't matter with the old ptrace implementation, but with utrace
 the tracee itself does user_enable_single_step(current) and returns to
 user-mode. Until it does at least one context switch the single-stepping
 doesn't work, after that everything works fine till the next reboot.

The PER control registers only get reloaded on task switch. Can you test
if this patch fixes your problem?

--
Subject: [PATCH] fix loading of PER control registers for utrace.

From: Martin Schwidefsky schwidef...@de.ibm.com

If the current task enables / disables PER tracing for itself the
PER control registers need to be loaded in FixPerRegisters.

Signed-off-by: Martin Schwidefsky schwidef...@de.ibm.com
---
 arch/s390/kernel/ptrace.c |3 +++
 1 file changed, 3 insertions(+)

--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -98,6 +98,9 @@ FixPerRegisters(struct task_struct *task
per_info-control_regs.bits.storage_alt_space_ctl = 1;
else
per_info-control_regs.bits.storage_alt_space_ctl = 0;
+
+   if (task == current)
+   __ctl_load(per_info-control_regs.words, 9, 11);
 }
 
 void user_enable_single_step(struct task_struct *task)

-- 
blue skies,
   Martin.

Reality continues to ruin my life. - Calvin.