mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-04-08 12:02:33 +02:00
Xtensa has two-argument MAKE_PC_FROM_RA macro to convert a0 to an actual
return address because when windowed ABI is used call{,x}{4,8,12}
opcodes stuff encoded window size into the top 2 bits of the register
that becomes a return address in the called function. Second argument of
that macro is supposed to be an address having these 2 topmost bits set
correctly, but the comment suggested that that could be the stack
address. However the stack doesn't have to be in the same 1GByte region
as the code, especially in noMMU XIP configurations.
Fix the comment and use either _text or regs->pc as the second argument
for the MAKE_PC_FROM_RA macro.
Cc: stable@vger.kernel.org
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
120 lines
3.3 KiB
C
120 lines
3.3 KiB
C
/*
|
|
* include/asm-xtensa/ptrace.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) 2001 - 2005 Tensilica Inc.
|
|
*/
|
|
#ifndef _XTENSA_PTRACE_H
|
|
#define _XTENSA_PTRACE_H
|
|
|
|
#include <asm/kmem_layout.h>
|
|
#include <uapi/asm/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 NO_SYSCALL (-1)
|
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
#include <asm/coprocessor.h>
|
|
#include <asm/core.h>
|
|
|
|
/*
|
|
* This struct defines the way the registers are stored on the
|
|
* kernel stack during a system call or other kernel entry.
|
|
*/
|
|
struct pt_regs {
|
|
unsigned long pc; /* 4 */
|
|
unsigned long ps; /* 8 */
|
|
unsigned long depc; /* 12 */
|
|
unsigned long exccause; /* 16 */
|
|
unsigned long excvaddr; /* 20 */
|
|
unsigned long debugcause; /* 24 */
|
|
unsigned long wmask; /* 28 */
|
|
unsigned long lbeg; /* 32 */
|
|
unsigned long lend; /* 36 */
|
|
unsigned long lcount; /* 40 */
|
|
unsigned long sar; /* 44 */
|
|
unsigned long windowbase; /* 48 */
|
|
unsigned long windowstart; /* 52 */
|
|
unsigned long syscall; /* 56 */
|
|
unsigned long icountlevel; /* 60 */
|
|
unsigned long scompare1; /* 64 */
|
|
unsigned long threadptr; /* 68 */
|
|
|
|
/* Additional configurable registers that are used by the compiler. */
|
|
xtregs_opt_t xtregs_opt;
|
|
|
|
/* Make sure the areg field is 16 bytes aligned. */
|
|
int align[0] __attribute__ ((aligned(16)));
|
|
|
|
/* current register frame.
|
|
* Note: The ESF for kernel exceptions ends after 16 registers!
|
|
*/
|
|
unsigned long areg[XCHAL_NUM_AREGS];
|
|
};
|
|
|
|
# define arch_has_single_step() (1)
|
|
# define task_pt_regs(tsk) ((struct pt_regs*) \
|
|
(task_stack_page(tsk) + KERNEL_STACK_SIZE) - 1)
|
|
# define user_mode(regs) (((regs)->ps & 0x00000020)!=0)
|
|
# define instruction_pointer(regs) ((regs)->pc)
|
|
# define return_pointer(regs) (MAKE_PC_FROM_RA((regs)->areg[0], \
|
|
(regs)->pc))
|
|
|
|
# ifndef CONFIG_SMP
|
|
# define profile_pc(regs) instruction_pointer(regs)
|
|
# else
|
|
# define profile_pc(regs) \
|
|
({ \
|
|
in_lock_functions(instruction_pointer(regs)) ? \
|
|
return_pointer(regs) : instruction_pointer(regs); \
|
|
})
|
|
# endif
|
|
|
|
#define user_stack_pointer(regs) ((regs)->areg[1])
|
|
|
|
static inline unsigned long regs_return_value(struct pt_regs *regs)
|
|
{
|
|
return regs->areg[2];
|
|
}
|
|
|
|
int do_syscall_trace_enter(struct pt_regs *regs);
|
|
void do_syscall_trace_leave(struct pt_regs *regs);
|
|
|
|
#else /* __ASSEMBLY__ */
|
|
|
|
# include <asm/asm-offsets.h>
|
|
#define PT_REGS_OFFSET (KERNEL_STACK_SIZE - PT_USER_SIZE)
|
|
|
|
#endif /* !__ASSEMBLY__ */
|
|
|
|
#endif /* _XTENSA_PTRACE_H */
|