Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 753c4dd6 authored by Martin Schwidefsky's avatar Martin Schwidefsky
Browse files

[S390] ptrace changes



* System call parameter and result access functions
* Add tracehook calls
* Split syscall_trace into two functions do_syscall_trace_enter and
  do_syscall_trace_exit

Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent d86730bb
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ config S390
	select HAVE_KPROBES
	select HAVE_KRETPROBES
	select HAVE_KVM if 64BIT
	select HAVE_ARCH_TRACEHOOK

source "init/Kconfig"

+1 −0
Original line number Diff line number Diff line
@@ -490,6 +490,7 @@ extern void user_disable_single_step(struct task_struct *);

#define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
#define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN)
#define user_stack_pointer(regs)((regs)->gprs[15])
#define regs_return_value(regs)((regs)->gprs[2])
#define profile_pc(regs) instruction_pointer(regs)
extern void show_regs(struct pt_regs * regs);
+80 −0
Original line number Diff line number Diff line
/*
 * Access to user system call parameters and results
 *
 *  Copyright IBM Corp. 2008
 *  Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License (version 2 only)
 * as published by the Free Software Foundation.
 */

#ifndef _ASM_SYSCALL_H
#define _ASM_SYSCALL_H	1

#include <asm/ptrace.h>

static inline long syscall_get_nr(struct task_struct *task,
				  struct pt_regs *regs)
{
	if (regs->trap != __LC_SVC_OLD_PSW)
		return -1;
	return regs->gprs[2];
}

static inline void syscall_rollback(struct task_struct *task,
				    struct pt_regs *regs)
{
	regs->gprs[2] = regs->orig_gpr2;
}

static inline long syscall_get_error(struct task_struct *task,
				     struct pt_regs *regs)
{
	return (regs->gprs[2] >= -4096UL) ? -regs->gprs[2] : 0;
}

static inline long syscall_get_return_value(struct task_struct *task,
					    struct pt_regs *regs)
{
	return regs->gprs[2];
}

static inline void syscall_set_return_value(struct task_struct *task,
					    struct pt_regs *regs,
					    int error, long val)
{
	regs->gprs[2] = error ? -error : val;
}

static inline void syscall_get_arguments(struct task_struct *task,
					 struct pt_regs *regs,
					 unsigned int i, unsigned int n,
					 unsigned long *args)
{
	BUG_ON(i + n > 6);
#ifdef CONFIG_COMPAT
	if (test_tsk_thread_flag(task, TIF_31BIT)) {
		if (i + n == 6)
			args[--n] = (u32) regs->args[0];
		while (n-- > 0)
			args[n] = (u32) regs->gprs[2 + i + n];
	}
#endif
	if (i + n == 6)
		args[--n] = regs->args[0];
	memcpy(args, &regs->gprs[2 + i], n * sizeof(args[0]));
}

static inline void syscall_set_arguments(struct task_struct *task,
					 struct pt_regs *regs,
					 unsigned int i, unsigned int n,
					 const unsigned long *args)
{
	BUG_ON(i + n > 6);
	if (i + n == 6)
		regs->args[0] = args[--n];
	memcpy(&regs->gprs[2 + i], args, n * sizeof(args[0]));
}

#endif	/* _ASM_SYSCALL_H */
+2 −0
Original line number Diff line number Diff line
@@ -86,6 +86,7 @@ static inline struct thread_info *current_thread_info(void)
 * thread information flags bit numbers
 */
#define TIF_SYSCALL_TRACE	0	/* syscall trace active */
#define TIF_NOTIFY_RESUME	1	/* callback before returning to user */
#define TIF_SIGPENDING		2	/* signal pending */
#define TIF_NEED_RESCHED	3	/* rescheduling necessary */
#define TIF_RESTART_SVC		4	/* restart svc with new svc number */
@@ -100,6 +101,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_RESTORE_SIGMASK	20	/* restore signal mask in do_signal() */

#define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
#define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
+40 −10
Original line number Diff line number Diff line
@@ -49,9 +49,9 @@ SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC
SP_TRAP      =	STACK_FRAME_OVERHEAD + __PT_TRAP
SP_SIZE      =	STACK_FRAME_OVERHEAD + __PT_SIZE

_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
		 _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
		 _TIF_MCCK_PENDING)

STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
@@ -318,6 +318,8 @@ sysc_work:
	bo	BASED(sysc_reschedule)
	tm	__TI_flags+3(%r9),_TIF_SIGPENDING
	bnz	BASED(sysc_sigpending)
	tm	__TI_flags+3(%r9),_TIF_NOTIFY_RESUME
	bnz	BASED(sysc_notify_resume)
	tm	__TI_flags+3(%r9),_TIF_RESTART_SVC
	bo	BASED(sysc_restart)
	tm	__TI_flags+3(%r9),_TIF_SINGLE_STEP
@@ -355,6 +357,16 @@ sysc_sigpending:
	bo	BASED(sysc_singlestep)
	b	BASED(sysc_work_loop)

#
# _TIF_NOTIFY_RESUME is set, call do_notify_resume
#
sysc_notify_resume:
	la	%r2,SP_PTREGS(%r15)	# load pt_regs
	l	%r1,BASED(.Ldo_notify_resume)
	la	%r14,BASED(sysc_work_loop)
	br	%r1			# call do_notify_resume


#
# _TIF_RESTART_SVC is set, set up registers and restart svc
#
@@ -378,20 +390,21 @@ sysc_singlestep:
	br	%r1			# branch to do_single_step

#
# call trace before and after sys_call
# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before
# and after the system call
#
sysc_tracesys:
	l	%r1,BASED(.Ltrace)
	l	%r1,BASED(.Ltrace_entry)
	la	%r2,SP_PTREGS(%r15)	# load pt_regs
	la	%r3,0
	srl	%r7,2
	st	%r7,SP_R2(%r15)
	basr	%r14,%r1
	clc	SP_R2(4,%r15),BASED(.Lnr_syscalls)
	cl	%r2,BASED(.Lnr_syscalls)
	bnl	BASED(sysc_tracenogo)
	l	%r8,BASED(.Lsysc_table)
	l	%r7,SP_R2(%r15) 	# strace might have changed the
	sll	%r7,2			#  system call
	lr	%r7,%r2
	sll	%r7,2			# *4
	l	%r8,0(%r7,%r8)
sysc_tracego:
	lm	%r3,%r6,SP_R3(%r15)
@@ -401,9 +414,8 @@ sysc_tracego:
sysc_tracenogo:
	tm	__TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
	bz	BASED(sysc_return)
	l	%r1,BASED(.Ltrace)
	l	%r1,BASED(.Ltrace_exit)
	la	%r2,SP_PTREGS(%r15)	# load pt_regs
	la	%r3,1
	la	%r14,BASED(sysc_return)
	br	%r1

@@ -666,6 +678,8 @@ io_work_loop:
	bo	BASED(io_reschedule)
	tm	__TI_flags+3(%r9),_TIF_SIGPENDING
	bnz	BASED(io_sigpending)
	tm	__TI_flags+3(%r9),_TIF_NOTIFY_RESUME
	bnz	BASED(io_notify_resume)
	b	BASED(io_restore)
io_work_done:

@@ -704,6 +718,19 @@ io_sigpending:
	TRACE_IRQS_OFF
	b	BASED(io_work_loop)

#
# _TIF_SIGPENDING is set, call do_signal
#
io_notify_resume:
	TRACE_IRQS_ON
	stosm	__SF_EMPTY(%r15),0x03	# reenable interrupts
	la	%r2,SP_PTREGS(%r15)	# load pt_regs
	l	%r1,BASED(.Ldo_notify_resume)
	basr	%r14,%r1		# call do_signal
	stnsm	__SF_EMPTY(%r15),0xfc	# disable I/O and ext. interrupts
	TRACE_IRQS_OFF
	b	BASED(io_work_loop)

/*
 * External interrupt handler routine
 */
@@ -1070,6 +1097,8 @@ cleanup_io_leave_insn:
.Ldo_IRQ:	.long	do_IRQ
.Ldo_extint:	.long	do_extint
.Ldo_signal:	.long	do_signal
.Ldo_notify_resume:
		.long	do_notify_resume
.Lhandle_per:	.long	do_single_step
.Ldo_execve:	.long	do_execve
.Lexecve_tail:	.long	execve_tail
@@ -1079,7 +1108,8 @@ cleanup_io_leave_insn:
.Lpreempt_schedule_irq:
		.long	preempt_schedule_irq
#endif
.Ltrace:	.long	syscall_trace
.Ltrace_entry:	.long	do_syscall_trace_enter
.Ltrace_exit:	.long	do_syscall_trace_exit
.Lschedtail:	.long	schedule_tail
.Lsysc_table:	.long	sys_call_table
#ifdef CONFIG_TRACE_IRQFLAGS
Loading