diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2013-04-08 01:29:19 +0400 |
---|---|---|
committer | Chris Zankel <chris@zankel.net> | 2013-05-09 01:07:10 -0700 |
commit | 3ae908c99e944a7a5c4f4b2d8c603a6bc57b728b (patch) | |
tree | 10159f1a9c02b862957d7d196cb1da6bb762ad39 /arch/xtensa/include | |
parent | 3e4196a5cc9cff50900f3dc8acc3d41e5963fd50 (diff) | |
download | op-kernel-dev-3ae908c99e944a7a5c4f4b2d8c603a6bc57b728b.zip op-kernel-dev-3ae908c99e944a7a5c4f4b2d8c603a6bc57b728b.tar.gz |
xtensa: provide custom CALLER_ADDR* implementations
Definition of CALLER_ADDR* through __builtin_return_address makes
compiler insert calls to __xtensa_libgcc_window_spill, which in turn
makes fast_syscall_spill_registers syscall that clobbers registers when
called from the kernel mode, leading to invalid opcode exceptions on
return to userspace.
Provide definition for CALLER_ADDR0 as MAKE_PC_FROM_RA(a0, a1) and in
case CONFIG_FRAME_POINTER is enabled extract CALLER_ADDR{1-3} from
stack.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Chris Zankel <chris@zankel.net>
Diffstat (limited to 'arch/xtensa/include')
-rw-r--r-- | arch/xtensa/include/asm/ftrace.h | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/arch/xtensa/include/asm/ftrace.h b/arch/xtensa/include/asm/ftrace.h index 40a8c17..36dc7a6 100644 --- a/arch/xtensa/include/asm/ftrace.h +++ b/arch/xtensa/include/asm/ftrace.h @@ -1 +1,33 @@ -/* empty */ +/* + * arch/xtensa/include/asm/ftrace.h + * + * 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 + * for more details. + * + * Copyright (C) 2013 Tensilica Inc. + */ +#ifndef _XTENSA_FTRACE_H +#define _XTENSA_FTRACE_H + +#include <asm/processor.h> + +#define HAVE_ARCH_CALLER_ADDR +#define CALLER_ADDR0 ({ unsigned long a0, a1; \ + __asm__ __volatile__ ( \ + "mov %0, a0\n" \ + "mov %1, a1\n" \ + : "=r"(a0), "=r"(a1) : : ); \ + MAKE_PC_FROM_RA(a0, a1); }) +#ifdef CONFIG_FRAME_POINTER +extern unsigned long return_address(unsigned level); +#define CALLER_ADDR1 return_address(1) +#define CALLER_ADDR2 return_address(2) +#define CALLER_ADDR3 return_address(3) +#else +#define CALLER_ADDR1 (0) +#define CALLER_ADDR2 (0) +#define CALLER_ADDR3 (0) +#endif + +#endif /* _XTENSA_FTRACE_H */ |