From 3ced97305ded104e0c2814241952e261997dbb65 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 13 Mar 2017 10:28:33 -0700 Subject: xtensa: ISS: cleanup setup.c Drop commented out code, unused extern definition, extra blank lines. Rewrite iss_panic_block initialization in C99 style. Signed-off-by: Max Filippov --- arch/xtensa/platforms/iss/setup.c | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) (limited to 'arch/xtensa') diff --git a/arch/xtensa/platforms/iss/setup.c b/arch/xtensa/platforms/iss/setup.c index 379aeddcc638..3742ee63282f 100644 --- a/arch/xtensa/platforms/iss/setup.c +++ b/arch/xtensa/platforms/iss/setup.c @@ -31,13 +31,13 @@ #include #include +#include #include void __init platform_init(bp_tag_t* bootparam) { - } void platform_halt(void) @@ -59,26 +59,10 @@ void platform_restart(void) /* control never gets here */ } -extern void iss_net_poll(void); - -const char twirl[]="|/-\\|/-\\"; - void platform_heartbeat(void) { -#if 0 - static int i = 0, j = 0; - - if (--i < 0) { - i = 99; - printk("\r%c\r", twirl[j++]); - if (j == 8) - j = 0; - } -#endif } - - static int iss_panic_event(struct notifier_block *this, unsigned long event, void *ptr) { @@ -87,9 +71,7 @@ iss_panic_event(struct notifier_block *this, unsigned long event, void *ptr) } static struct notifier_block iss_panic_block = { - iss_panic_event, - NULL, - 0 + .notifier_call = iss_panic_event, }; void __init platform_setup(char **p_cmdline) -- cgit From e8cd8da934f29a0aca2c4bd96310a0b6ba6e31a7 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 13 Mar 2017 10:23:02 -0700 Subject: xtensa: ISS: add argc/argv simcall definitions There are three simcalls implemented by ISS and QEMU related to argc/argv processing: SYS_iss_argc (get number of command line arguments), SYS_iss_argv_size (get size of command line argument block) and SYS_iss_set_argv (copy command line arguments to virtual guest address). Add definitions for these calls to iss/include/platform/simcall.h Signed-off-by: Max Filippov --- arch/xtensa/platforms/iss/include/platform/simcall.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'arch/xtensa') diff --git a/arch/xtensa/platforms/iss/include/platform/simcall.h b/arch/xtensa/platforms/iss/include/platform/simcall.h index 27d7a528b41a..2ba45858e50a 100644 --- a/arch/xtensa/platforms/iss/include/platform/simcall.h +++ b/arch/xtensa/platforms/iss/include/platform/simcall.h @@ -6,6 +6,7 @@ * for more details. * * Copyright (C) 2001 Tensilica Inc. + * Copyright (C) 2017 Cadence Design Systems Inc. */ #ifndef _XTENSA_PLATFORM_ISS_SIMCALL_H @@ -49,6 +50,10 @@ #define SYS_bind 30 #define SYS_ioctl 31 +#define SYS_iss_argc 1000 /* returns value of argc */ +#define SYS_iss_argv_size 1001 /* bytes needed for argv & arg strings */ +#define SYS_iss_set_argv 1002 /* saves argv & arg strings at given addr */ + /* * SYS_select_one specifiers */ @@ -118,5 +123,20 @@ static inline int simc_lseek(int fd, uint32_t off, int whence) return __simc(SYS_lseek, fd, off, whence); } +static inline int simc_argc(void) +{ + return __simc(SYS_iss_argc, 0, 0, 0); +} + +static inline int simc_argv_size(void) +{ + return __simc(SYS_iss_argv_size, 0, 0, 0); +} + +static inline void simc_argv(void *buf) +{ + __simc(SYS_iss_set_argv, (int)buf, 0, 0); +} + #endif /* _XTENSA_PLATFORM_ISS_SIMCALL_H */ -- cgit From fbe22d280014e783fe2454db2a0ba44fc4f68a5a Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 13 Mar 2017 10:34:36 -0700 Subject: xtensa: ISS: update kernel command line in platform_setup Move platform_setup call higher in initialization sequence so that it could change kernel command line. Check command line passed to simulator in ISS platform_stup and update kernel command line if there's anything. Signed-off-by: Max Filippov --- arch/xtensa/kernel/setup.c | 5 ++--- arch/xtensa/platforms/iss/setup.c | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) (limited to 'arch/xtensa') diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 8fd4be610607..48ffc58ca38a 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -317,8 +317,9 @@ static inline int mem_reserve(unsigned long start, unsigned long end) void __init setup_arch(char **cmdline_p) { - strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); *cmdline_p = command_line; + platform_setup(cmdline_p); + strlcpy(boot_command_line, *cmdline_p, COMMAND_LINE_SIZE); /* Reserve some memory regions */ @@ -379,8 +380,6 @@ void __init setup_arch(char **cmdline_p) unflatten_and_copy_device_tree(); - platform_setup(cmdline_p); - #ifdef CONFIG_SMP smp_init_cpus(); #endif diff --git a/arch/xtensa/platforms/iss/setup.c b/arch/xtensa/platforms/iss/setup.c index 3742ee63282f..f4bbb28026f8 100644 --- a/arch/xtensa/platforms/iss/setup.c +++ b/arch/xtensa/platforms/iss/setup.c @@ -8,6 +8,7 @@ * Joe Taylor * * Copyright 2001 - 2005 Tensilica Inc. + * Copyright 2017 Cadence Design Systems Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -15,6 +16,7 @@ * option) any later version. * */ +#include #include #include #include @@ -76,5 +78,24 @@ static struct notifier_block iss_panic_block = { void __init platform_setup(char **p_cmdline) { + int argc = simc_argc(); + int argv_size = simc_argv_size(); + + if (argc > 1) { + void **argv = alloc_bootmem(argv_size); + char *cmdline = alloc_bootmem(argv_size); + int i; + + cmdline[0] = 0; + simc_argv((void *)argv); + + for (i = 1; i < argc; ++i) { + if (i > 1) + strcat(cmdline, " "); + strcat(cmdline, argv[i]); + } + *p_cmdline = cmdline; + } + atomic_notifier_chain_register(&panic_notifier_list, &iss_panic_block); } -- cgit From 60e22cffb53804e5331df4fa3892dacb6f57eb7a Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Wed, 29 Mar 2017 19:53:49 -0700 Subject: xtensa: use ITLB_HIT_BIT instead of hardcoded number There is ITLB_HIT_BIT macro, no need to use 0x8 to check for TLB hit. Signed-off-by: Max Filippov --- arch/xtensa/kernel/setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/xtensa') diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 197e75b400b1..fd33920e1a19 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -453,9 +453,9 @@ void cpu_reset(void) tmpaddr += SZ_512M; /* Invalidate mapping in the selected temporary area */ - if (itlb_probe(tmpaddr) & 0x8) + if (itlb_probe(tmpaddr) & BIT(ITLB_HIT_BIT)) invalidate_itlb_entry(itlb_probe(tmpaddr)); - if (itlb_probe(tmpaddr + PAGE_SIZE) & 0x8) + if (itlb_probe(tmpaddr + PAGE_SIZE) & BIT(ITLB_HIT_BIT)) invalidate_itlb_entry(itlb_probe(tmpaddr + PAGE_SIZE)); /* -- cgit From d9c7710db90c0069ca5eebc060d4571aabea8f74 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Tue, 27 Jan 2015 00:27:05 +0300 Subject: xtensa: drop unused fast_io_protect function fast_io_protect is not used anywhere, drop its definition. Signed-off-by: Max Filippov --- arch/xtensa/kernel/coprocessor.S | 24 ------------------------ 1 file changed, 24 deletions(-) (limited to 'arch/xtensa') diff --git a/arch/xtensa/kernel/coprocessor.S b/arch/xtensa/kernel/coprocessor.S index 6911e384f608..3a98503ad11a 100644 --- a/arch/xtensa/kernel/coprocessor.S +++ b/arch/xtensa/kernel/coprocessor.S @@ -26,30 +26,6 @@ #include #include -/* - * Entry condition: - * - * a0: trashed, original value saved on stack (PT_AREG0) - * a1: a1 - * a2: new stack pointer, original in DEPC - * a3: a3 - * depc: a2, original value saved on stack (PT_DEPC) - * excsave_1: dispatch table - * - * PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC - * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception - */ - -/* IO protection is currently unsupported. */ - -ENTRY(fast_io_protect) - - wsr a0, excsave1 - movi a0, unrecoverable_exception - callx0 a0 - -ENDPROC(fast_io_protect) - #if XTENSA_HAVE_COPROCESSORS /* -- cgit From 1b47a683a04a93ad32786a23b7f88990b980346a Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Tue, 27 Jan 2015 03:12:50 +0300 Subject: xtensa: clean up xtensa/kernel/ptrace.c - make locally-used functions static; - drop meaningless comments and commented out code; - fix code style and alignment. Signed-off-by: Max Filippov --- arch/xtensa/kernel/ptrace.c | 144 ++++++++++++++++++++++---------------------- 1 file changed, 71 insertions(+), 73 deletions(-) (limited to 'arch/xtensa') diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c index e0f583fed06a..ae7985ec7b8e 100644 --- a/arch/xtensa/kernel/ptrace.c +++ b/arch/xtensa/kernel/ptrace.c @@ -1,4 +1,3 @@ -// TODO some minor issues /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -24,13 +23,13 @@ #include #include #include +#include #include #include #include #include #include -#include void user_enable_single_step(struct task_struct *child) @@ -52,7 +51,7 @@ void ptrace_disable(struct task_struct *child) /* Nothing to do.. */ } -int ptrace_getregs(struct task_struct *child, void __user *uregs) +static int ptrace_getregs(struct task_struct *child, void __user *uregs) { struct pt_regs *regs = task_pt_regs(child); xtensa_gregset_t __user *gregset = uregs; @@ -73,12 +72,12 @@ int ptrace_getregs(struct task_struct *child, void __user *uregs) for (i = 0; i < XCHAL_NUM_AREGS; i++) __put_user(regs->areg[i], - gregset->a + ((wb * 4 + i) % XCHAL_NUM_AREGS)); + gregset->a + ((wb * 4 + i) % XCHAL_NUM_AREGS)); return 0; } -int ptrace_setregs(struct task_struct *child, void __user *uregs) +static int ptrace_setregs(struct task_struct *child, void __user *uregs) { struct pt_regs *regs = task_pt_regs(child); xtensa_gregset_t *gregset = uregs; @@ -107,7 +106,7 @@ int ptrace_setregs(struct task_struct *child, void __user *uregs) unsigned long rotws, wmask; rotws = (((ws | (ws << WSBITS)) >> wb) & - ((1 << WSBITS) - 1)) & ~1; + ((1 << WSBITS) - 1)) & ~1; wmask = ((rotws ? WSBITS + 1 - ffs(rotws) : 0) << 4) | (rotws & 0xF) | 1; regs->windowbase = wb; @@ -115,19 +114,19 @@ int ptrace_setregs(struct task_struct *child, void __user *uregs) regs->wmask = wmask; } - if (wb != 0 && __copy_from_user(regs->areg + XCHAL_NUM_AREGS - wb * 4, - gregset->a, wb * 16)) + if (wb != 0 && __copy_from_user(regs->areg + XCHAL_NUM_AREGS - wb * 4, + gregset->a, wb * 16)) return -EFAULT; if (__copy_from_user(regs->areg, gregset->a + wb * 4, - (WSBITS - wb) * 16)) + (WSBITS - wb) * 16)) return -EFAULT; return 0; } -int ptrace_getxregs(struct task_struct *child, void __user *uregs) +static int ptrace_getxregs(struct task_struct *child, void __user *uregs) { struct pt_regs *regs = task_pt_regs(child); struct thread_info *ti = task_thread_info(child); @@ -151,7 +150,7 @@ int ptrace_getxregs(struct task_struct *child, void __user *uregs) return ret ? -EFAULT : 0; } -int ptrace_setxregs(struct task_struct *child, void __user *uregs) +static int ptrace_setxregs(struct task_struct *child, void __user *uregs) { struct thread_info *ti = task_thread_info(child); struct pt_regs *regs = task_pt_regs(child); @@ -177,7 +176,8 @@ int ptrace_setxregs(struct task_struct *child, void __user *uregs) return ret ? -EFAULT : 0; } -int ptrace_peekusr(struct task_struct *child, long regno, long __user *ret) +static int ptrace_peekusr(struct task_struct *child, long regno, + long __user *ret) { struct pt_regs *regs; unsigned long tmp; @@ -186,86 +186,87 @@ int ptrace_peekusr(struct task_struct *child, long regno, long __user *ret) tmp = 0; /* Default return value. */ switch(regno) { + case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1: + tmp = regs->areg[regno - REG_AR_BASE]; + break; - case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1: - tmp = regs->areg[regno - REG_AR_BASE]; - break; - - case REG_A_BASE ... REG_A_BASE + 15: - tmp = regs->areg[regno - REG_A_BASE]; - break; + case REG_A_BASE ... REG_A_BASE + 15: + tmp = regs->areg[regno - REG_A_BASE]; + break; - case REG_PC: - tmp = regs->pc; - break; + case REG_PC: + tmp = regs->pc; + break; - case REG_PS: - /* Note: PS.EXCM is not set while user task is running; - * its being set in regs is for exception handling - * convenience. */ - tmp = (regs->ps & ~(1 << PS_EXCM_BIT)); - break; + case REG_PS: + /* Note: PS.EXCM is not set while user task is running; + * its being set in regs is for exception handling + * convenience. + */ + tmp = (regs->ps & ~(1 << PS_EXCM_BIT)); + break; - case REG_WB: - break; /* tmp = 0 */ + case REG_WB: + break; /* tmp = 0 */ - case REG_WS: + case REG_WS: { unsigned long wb = regs->windowbase; unsigned long ws = regs->windowstart; - tmp = ((ws>>wb) | (ws<<(WSBITS-wb))) & ((1<> wb) | (ws << (WSBITS - wb))) & + ((1 << WSBITS) - 1); break; } - case REG_LBEG: - tmp = regs->lbeg; - break; + case REG_LBEG: + tmp = regs->lbeg; + break; - case REG_LEND: - tmp = regs->lend; - break; + case REG_LEND: + tmp = regs->lend; + break; - case REG_LCOUNT: - tmp = regs->lcount; - break; + case REG_LCOUNT: + tmp = regs->lcount; + break; - case REG_SAR: - tmp = regs->sar; - break; + case REG_SAR: + tmp = regs->sar; + break; - case SYSCALL_NR: - tmp = regs->syscall; - break; + case SYSCALL_NR: + tmp = regs->syscall; + break; - default: - return -EIO; + default: + return -EIO; } return put_user(tmp, ret); } -int ptrace_pokeusr(struct task_struct *child, long regno, long val) +static int ptrace_pokeusr(struct task_struct *child, long regno, long val) { struct pt_regs *regs; regs = task_pt_regs(child); switch (regno) { - case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1: - regs->areg[regno - REG_AR_BASE] = val; - break; + case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1: + regs->areg[regno - REG_AR_BASE] = val; + break; - case REG_A_BASE ... REG_A_BASE + 15: - regs->areg[regno - REG_A_BASE] = val; - break; + case REG_A_BASE ... REG_A_BASE + 15: + regs->areg[regno - REG_A_BASE] = val; + break; - case REG_PC: - regs->pc = val; - break; + case REG_PC: + regs->pc = val; + break; - case SYSCALL_NR: - regs->syscall = val; - break; + case SYSCALL_NR: + regs->syscall = val; + break; - default: - return -EIO; + default: + return -EIO; } return 0; } @@ -473,7 +474,8 @@ void do_syscall_trace(void) * The 0x80 provides a way for the tracing parent to distinguish * between a syscall stop and SIGTRAP delivery */ - ptrace_notify(SIGTRAP|((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); + ptrace_notify(SIGTRAP | + ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); /* * this isn't the same as continuing with a signal, but it will do @@ -488,18 +490,14 @@ void do_syscall_trace(void) void do_syscall_trace_enter(struct pt_regs *regs) { - if (test_thread_flag(TIF_SYSCALL_TRACE) - && (current->ptrace & PT_PTRACED)) + if (test_thread_flag(TIF_SYSCALL_TRACE) && + (current->ptrace & PT_PTRACED)) do_syscall_trace(); - -#if 0 - audit_syscall_entry(...); -#endif } void do_syscall_trace_leave(struct pt_regs *regs) { - if ((test_thread_flag(TIF_SYSCALL_TRACE)) - && (current->ptrace & PT_PTRACED)) + if (test_thread_flag(TIF_SYSCALL_TRACE) && + (current->ptrace & PT_PTRACED)) do_syscall_trace(); } -- cgit From 0700ed072feffd65212e6a03840d19c4988d6820 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Tue, 27 Jan 2015 00:43:14 +0300 Subject: xtensa: move internal ptrace definitions from uapi/asm to asm Stack frame layout diagram, kernel stack size and exception_handlers offsets are used by the kernel and are not supposed to be accessible to userspace. Move these definitions from uapi/asm/ptrace.h to asm/ptrace.h Signed-off-by: Max Filippov --- arch/xtensa/include/asm/ptrace.h | 39 ++++++++++++++++++++++++++++++++++ arch/xtensa/include/uapi/asm/ptrace.h | 40 ----------------------------------- 2 files changed, 39 insertions(+), 40 deletions(-) (limited to 'arch/xtensa') diff --git a/arch/xtensa/include/asm/ptrace.h b/arch/xtensa/include/asm/ptrace.h index 598e752dcbcd..e2d9c5eb10bd 100644 --- a/arch/xtensa/include/asm/ptrace.h +++ b/arch/xtensa/include/asm/ptrace.h @@ -12,6 +12,45 @@ #include +/* + * Kernel stack + * + * +-----------------------+ -------- STACK_SIZE + * | register file | | + * +-----------------------+ | + * | struct pt_regs | | + * +-----------------------+ | ------ PT_REGS_OFFSET + * double : 16 bytes spill area : | ^ + * excetion :- - - - - - - - - - - -: | | + * frame : struct pt_regs : | | + * :- - - - - - - - - - - -: | | + * | | | | + * | memory stack | | | + * | | | | + * ~ ~ ~ ~ + * ~ ~ ~ ~ + * | | | | + * | | | | + * +-----------------------+ | | --- STACK_BIAS + * | struct task_struct | | | ^ + * current --> +-----------------------+ | | | + * | struct thread_info | | | | + * +-----------------------+ -------- + */ + +#define KERNEL_STACK_SIZE (2 * PAGE_SIZE) + +/* Offsets for exception_handlers[] (3 x 64-entries x 4-byte tables). */ + +#define EXC_TABLE_KSTK 0x004 /* Kernel Stack */ +#define EXC_TABLE_DOUBLE_SAVE 0x008 /* Double exception save area for a0 */ +#define EXC_TABLE_FIXUP 0x00c /* Fixup handler */ +#define EXC_TABLE_PARAM 0x010 /* For passing a parameter to fixup */ +#define EXC_TABLE_SYSCALL_SAVE 0x014 /* For fast syscall handler */ +#define EXC_TABLE_FAST_USER 0x100 /* Fast user exception handler */ +#define EXC_TABLE_FAST_KERNEL 0x200 /* Fast kernel exception handler */ +#define EXC_TABLE_DEFAULT 0x300 /* Default C-Handler */ +#define EXC_TABLE_SIZE 0x400 #ifndef __ASSEMBLY__ diff --git a/arch/xtensa/include/uapi/asm/ptrace.h b/arch/xtensa/include/uapi/asm/ptrace.h index 6ccbd9e38e35..8853a0d544c8 100644 --- a/arch/xtensa/include/uapi/asm/ptrace.h +++ b/arch/xtensa/include/uapi/asm/ptrace.h @@ -11,46 +11,6 @@ #ifndef _UAPI_XTENSA_PTRACE_H #define _UAPI_XTENSA_PTRACE_H -/* - * Kernel stack - * - * +-----------------------+ -------- STACK_SIZE - * | register file | | - * +-----------------------+ | - * | struct pt_regs | | - * +-----------------------+ | ------ PT_REGS_OFFSET - * double : 16 bytes spill area : | ^ - * excetion :- - - - - - - - - - - -: | | - * frame : struct pt_regs : | | - * :- - - - - - - - - - - -: | | - * | | | | - * | memory stack | | | - * | | | | - * ~ ~ ~ ~ - * ~ ~ ~ ~ - * | | | | - * | | | | - * +-----------------------+ | | --- STACK_BIAS - * | struct task_struct | | | ^ - * current --> +-----------------------+ | | | - * | struct thread_info | | | | - * +-----------------------+ -------- - */ - -#define KERNEL_STACK_SIZE (2 * PAGE_SIZE) - -/* Offsets for exception_handlers[] (3 x 64-entries x 4-byte tables). */ - -#define EXC_TABLE_KSTK 0x004 /* Kernel Stack */ -#define EXC_TABLE_DOUBLE_SAVE 0x008 /* Double exception save area for a0 */ -#define EXC_TABLE_FIXUP 0x00c /* Fixup handler */ -#define EXC_TABLE_PARAM 0x010 /* For passing a parameter to fixup */ -#define EXC_TABLE_SYSCALL_SAVE 0x014 /* For fast syscall handler */ -#define EXC_TABLE_FAST_USER 0x100 /* Fast user exception handler */ -#define EXC_TABLE_FAST_KERNEL 0x200 /* Fast kernel exception handler */ -#define EXC_TABLE_DEFAULT 0x300 /* Default C-Handler */ -#define EXC_TABLE_SIZE 0x400 - /* Registers used by strace */ #define REG_A_BASE 0x0000 -- cgit From f984409a00e7d9aa40af64d7c9619e5de3d980bf Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 16 Mar 2015 14:40:14 +0300 Subject: xtensa: use generic tracehooks Use tracehook_report_syscall_{entry,exit} instead of a local copy of it in do_syscall_trace. Allow tracehook to cancel syscall by returning invalid syscall number to the system_call function. Signed-off-by: Max Filippov --- arch/xtensa/kernel/entry.S | 3 ++- arch/xtensa/kernel/ptrace.c | 38 ++++++++++++-------------------------- 2 files changed, 14 insertions(+), 27 deletions(-) (limited to 'arch/xtensa') diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index f5ef3cc0497c..37a239556889 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S @@ -1899,10 +1899,11 @@ ENTRY(system_call) movi a4, do_syscall_trace_enter s32i a3, a2, PT_SYSCALL callx4 a4 + mov a3, a6 /* syscall = sys_call_table[syscall_nr] */ - movi a4, sys_call_table; + movi a4, sys_call_table movi a5, __NR_syscall_count movi a6, -ENOSYS bgeu a3, a5, 1f diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c index ae7985ec7b8e..e2461968efb2 100644 --- a/arch/xtensa/kernel/ptrace.c +++ b/arch/xtensa/kernel/ptrace.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -468,36 +469,21 @@ long arch_ptrace(struct task_struct *child, long request, return ret; } -void do_syscall_trace(void) -{ - /* - * The 0x80 provides a way for the tracing parent to distinguish - * between a syscall stop and SIGTRAP delivery - */ - ptrace_notify(SIGTRAP | - ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); - - /* - * this isn't the same as continuing with a signal, but it will do - * for normal use. strace only continues with a signal if the - * stopping signal is not SIGTRAP. -brl - */ - if (current->exit_code) { - send_sig(current->exit_code, current, 1); - current->exit_code = 0; - } -} - -void do_syscall_trace_enter(struct pt_regs *regs) +unsigned long do_syscall_trace_enter(struct pt_regs *regs) { if (test_thread_flag(TIF_SYSCALL_TRACE) && - (current->ptrace & PT_PTRACED)) - do_syscall_trace(); + tracehook_report_syscall_entry(regs)) + return -1; + + return regs->areg[2]; } void do_syscall_trace_leave(struct pt_regs *regs) { - if (test_thread_flag(TIF_SYSCALL_TRACE) && - (current->ptrace & PT_PTRACED)) - do_syscall_trace(); + int step; + + step = test_thread_flag(TIF_SINGLESTEP); + + if (step || test_thread_flag(TIF_SYSCALL_TRACE)) + tracehook_report_syscall_exit(regs, step); } -- cgit From 062b1c19b879e7831cbceb599ab1d758f87eda40 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Tue, 27 Jan 2015 01:15:10 +0300 Subject: xtensa: clean up access to spilled registers locations Define macros SPILL_SLOT* that return a reference to the stack location of the spill slot for specific register and use them instead of opencoded address calculations. Signed-off-by: Max Filippov --- arch/xtensa/include/asm/processor.h | 15 +++++++++++++++ arch/xtensa/kernel/process.c | 8 ++++---- arch/xtensa/kernel/signal.c | 10 +++++----- arch/xtensa/kernel/stacktrace.c | 35 ++++++++--------------------------- 4 files changed, 32 insertions(+), 36 deletions(-) (limited to 'arch/xtensa') diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h index 86ffcd68e496..003eeee3fbc6 100644 --- a/arch/xtensa/include/asm/processor.h +++ b/arch/xtensa/include/asm/processor.h @@ -113,6 +113,21 @@ */ #define MAKE_PC_FROM_RA(ra,sp) (((ra) & 0x3fffffff) | ((sp) & 0xc0000000)) +/* Spill slot location for the register reg in the spill area under the stack + * pointer sp. reg must be in the range [0..4). + */ +#define SPILL_SLOT(sp, reg) (*(((unsigned long *)(sp)) - 4 + (reg))) + +/* Spill slot location for the register reg in the spill area under the stack + * pointer sp for the call8. reg must be in the range [4..8). + */ +#define SPILL_SLOT_CALL8(sp, reg) (*(((unsigned long *)(sp)) - 12 + (reg))) + +/* Spill slot location for the register reg in the spill area under the stack + * pointer sp for the call12. reg must be in the range [4..12). + */ +#define SPILL_SLOT_CALL12(sp, reg) (*(((unsigned long *)(sp)) - 16 + (reg))) + typedef struct { unsigned long seg; } mm_segment_t; diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index 58f96d1230d4..ff4f0ecb03dd 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c @@ -204,8 +204,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn, #endif /* Create a call4 dummy-frame: a0 = 0, a1 = childregs. */ - *((int*)childregs - 3) = (unsigned long)childregs; - *((int*)childregs - 4) = 0; + SPILL_SLOT(childregs, 1) = (unsigned long)childregs; + SPILL_SLOT(childregs, 0) = 0; p->thread.sp = (unsigned long)childregs; @@ -266,8 +266,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn, /* pass parameters to ret_from_kernel_thread: * a2 = thread_fn, a3 = thread_fn arg */ - *((int *)childregs - 1) = thread_fn_arg; - *((int *)childregs - 2) = usp_thread_fn; + SPILL_SLOT(childregs, 3) = thread_fn_arg; + SPILL_SLOT(childregs, 2) = usp_thread_fn; /* Childregs are only used when we're going to userspace * in which case start_thread will set them up. diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c index 70a131945443..d427e784ab44 100644 --- a/arch/xtensa/kernel/signal.c +++ b/arch/xtensa/kernel/signal.c @@ -91,14 +91,14 @@ flush_window_regs_user(struct pt_regs *regs) inc = 1; } else if (m & 4) { /* call8 */ - if (copy_to_user((void*)(sp - 32), - ®s->areg[(base + 1) * 4], 16)) + if (copy_to_user(&SPILL_SLOT_CALL8(sp, 4), + ®s->areg[(base + 1) * 4], 16)) goto errout; inc = 2; } else if (m & 8) { /* call12 */ - if (copy_to_user((void*)(sp - 48), - ®s->areg[(base + 1) * 4], 32)) + if (copy_to_user(&SPILL_SLOT_CALL12(sp, 4), + ®s->areg[(base + 1) * 4], 32)) goto errout; inc = 3; } @@ -106,7 +106,7 @@ flush_window_regs_user(struct pt_regs *regs) /* Save current frame a0..a3 under next SP */ sp = regs->areg[((base + inc) * 4 + 1) % XCHAL_NUM_AREGS]; - if (copy_to_user((void*)(sp - 16), ®s->areg[base * 4], 16)) + if (copy_to_user(&SPILL_SLOT(sp, 0), ®s->areg[base * 4], 16)) goto errout; /* Get current stack pointer for next loop iteration. */ diff --git a/arch/xtensa/kernel/stacktrace.c b/arch/xtensa/kernel/stacktrace.c index e7d30ee0fd48..0df4080fa20f 100644 --- a/arch/xtensa/kernel/stacktrace.c +++ b/arch/xtensa/kernel/stacktrace.c @@ -23,14 +23,6 @@ */ extern int common_exception_return; -/* A struct that maps to the part of the frame containing the a0 and - * a1 registers. - */ -struct frame_start { - unsigned long a0; - unsigned long a1; -}; - void xtensa_backtrace_user(struct pt_regs *regs, unsigned int depth, int (*ufn)(struct stackframe *frame, void *data), void *data) @@ -96,26 +88,16 @@ void xtensa_backtrace_user(struct pt_regs *regs, unsigned int depth, /* Start from the a1 register. */ /* a1 = regs->areg[1]; */ while (a0 != 0 && depth--) { - struct frame_start frame_start; - /* Get the location for a1, a0 for the - * previous frame from the current a1. - */ - unsigned long *psp = (unsigned long *)a1; - - psp -= 4; + pc = MAKE_PC_FROM_RA(a0, pc); /* Check if the region is OK to access. */ - if (!access_ok(VERIFY_READ, psp, sizeof(frame_start))) + if (!access_ok(VERIFY_READ, &SPILL_SLOT(a1, 0), 8)) return; /* Copy a1, a0 from user space stack frame. */ - if (__copy_from_user_inatomic(&frame_start, psp, - sizeof(frame_start))) + if (__get_user(a0, &SPILL_SLOT(a1, 0)) || + __get_user(a1, &SPILL_SLOT(a1, 1))) return; - pc = MAKE_PC_FROM_RA(a0, pc); - a0 = frame_start.a0; - a1 = frame_start.a1; - frame.pc = pc; frame.sp = a1; @@ -147,7 +129,6 @@ void xtensa_backtrace_kernel(struct pt_regs *regs, unsigned int depth, */ while (a1 > sp_start && a1 < sp_end && depth--) { struct stackframe frame; - unsigned long *psp = (unsigned long *)a1; frame.pc = pc; frame.sp = a1; @@ -171,8 +152,8 @@ void xtensa_backtrace_kernel(struct pt_regs *regs, unsigned int depth, sp_start = a1; pc = MAKE_PC_FROM_RA(a0, pc); - a0 = *(psp - 4); - a1 = *(psp - 3); + a0 = SPILL_SLOT(a1, 0); + a1 = SPILL_SLOT(a1, 1); } } EXPORT_SYMBOL(xtensa_backtrace_kernel); @@ -196,8 +177,8 @@ void walk_stackframe(unsigned long *sp, sp = (unsigned long *)a1; - a0 = *(sp - 4); - a1 = *(sp - 3); + a0 = SPILL_SLOT(a1, 0); + a1 = SPILL_SLOT(a1, 1); if (a1 <= (unsigned long)sp) break; -- cgit