From 9f24f3c1067c8e4ffbbcd759180b422c9a761b1b Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Fri, 9 Nov 2018 15:45:53 -0800 Subject: xtensa: implement tracehook functions and enable HAVE_ARCH_TRACEHOOK Implement syscall_get_nr, syscall_rollback, syscall_get_error, syscall_{get,set}_return_value and syscall_{get,set}_arguments. Select HAVE_ARCH_TRACEHOOK as Xtensa now has all support for that. Signed-off-by: Max Filippov --- arch/xtensa/Kconfig | 1 + arch/xtensa/include/asm/syscall.h | 80 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 80 insertions(+), 1 deletion(-) (limited to 'arch/xtensa') diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index d29b7365da8d..55d13b589ff3 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -18,6 +18,7 @@ config XTENSA select GENERIC_SCHED_CLOCK select GENERIC_STRNCPY_FROM_USER if KASAN select HAVE_ARCH_KASAN if MMU + select HAVE_ARCH_TRACEHOOK select HAVE_DEBUG_KMEMLEAK select HAVE_DMA_CONTIGUOUS select HAVE_EXIT_THREAD diff --git a/arch/xtensa/include/asm/syscall.h b/arch/xtensa/include/asm/syscall.h index 6969956d3f93..e47470ec8ea8 100644 --- a/arch/xtensa/include/asm/syscall.h +++ b/arch/xtensa/include/asm/syscall.h @@ -10,6 +10,8 @@ #ifndef _ASM_SYSCALL_H #define _ASM_SYSCALL_H +#include +#include #include static inline int syscall_get_arch(void) @@ -17,7 +19,83 @@ static inline int syscall_get_arch(void) return AUDIT_ARCH_XTENSA; } -struct pt_regs; +static inline long syscall_get_nr(struct task_struct *task, + struct pt_regs *regs) +{ + return regs->syscall; +} + +static inline void syscall_rollback(struct task_struct *task, + struct pt_regs *regs) +{ + /* Do nothing. */ +} + +static inline long syscall_get_error(struct task_struct *task, + struct pt_regs *regs) +{ + /* 0 if syscall succeeded, otherwise -Errorcode */ + return IS_ERR_VALUE(regs->areg[2]) ? regs->areg[2] : 0; +} + +static inline long syscall_get_return_value(struct task_struct *task, + struct pt_regs *regs) +{ + return regs->areg[2]; +} + +static inline void syscall_set_return_value(struct task_struct *task, + struct pt_regs *regs, + int error, long val) +{ + regs->areg[0] = (long) error ? error : val; +} + +#define SYSCALL_MAX_ARGS 6 +#define XTENSA_SYSCALL_ARGUMENT_REGS {6, 3, 4, 5, 8, 9} + +static inline void syscall_get_arguments(struct task_struct *task, + struct pt_regs *regs, + unsigned int i, unsigned int n, + unsigned long *args) +{ + static const unsigned int reg[] = XTENSA_SYSCALL_ARGUMENT_REGS; + unsigned int j; + + if (n == 0) + return; + + WARN_ON_ONCE(i + n > SYSCALL_MAX_ARGS); + + for (j = 0; j < n; ++j) { + if (i + j < SYSCALL_MAX_ARGS) + args[j] = regs->areg[reg[i + j]]; + else + args[j] = 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) +{ + static const unsigned int reg[] = XTENSA_SYSCALL_ARGUMENT_REGS; + unsigned int j; + + if (n == 0) + return; + + if (WARN_ON_ONCE(i + n > SYSCALL_MAX_ARGS)) { + if (i < SYSCALL_MAX_ARGS) + n = SYSCALL_MAX_ARGS - i; + else + return; + } + + for (j = 0; j < n; ++j) + regs->areg[reg[i + j]] = args[j]; +} asmlinkage long xtensa_rt_sigreturn(struct pt_regs*); asmlinkage long xtensa_shmat(int, char __user *, int); -- cgit v1.2.3-59-g8ed1b