Skip to content

Commit 0e60f0b

Browse files
committed
xtensa: fix MAKE_PC_FROM_RA second argument
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: [email protected] Signed-off-by: Max Filippov <[email protected]>
1 parent e8f897f commit 0e60f0b

File tree

4 files changed

+10
-8
lines changed

4 files changed

+10
-8
lines changed

arch/xtensa/include/asm/processor.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,9 @@
115115
#define MAKE_RA_FOR_CALL(ra,ws) (((ra) & 0x3fffffff) | (ws) << 30)
116116

117117
/* Convert return address to a valid pc
118-
* Note: We assume that the stack pointer is in the same 1GB ranges as the ra
118+
* Note: 'text' is the address within the same 1GB range as the ra
119119
*/
120-
#define MAKE_PC_FROM_RA(ra,sp) (((ra) & 0x3fffffff) | ((sp) & 0xc0000000))
120+
#define MAKE_PC_FROM_RA(ra, text) (((ra) & 0x3fffffff) | ((unsigned long)(text) & 0xc0000000))
121121

122122
#elif defined(__XTENSA_CALL0_ABI__)
123123

@@ -127,9 +127,9 @@
127127
#define MAKE_RA_FOR_CALL(ra, ws) (ra)
128128

129129
/* Convert return address to a valid pc
130-
* Note: We assume that the stack pointer is in the same 1GB ranges as the ra
130+
* Note: 'text' is not used as 'ra' is always the full address
131131
*/
132-
#define MAKE_PC_FROM_RA(ra, sp) (ra)
132+
#define MAKE_PC_FROM_RA(ra, text) (ra)
133133

134134
#else
135135
#error Unsupported Xtensa ABI

arch/xtensa/include/asm/ptrace.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ struct pt_regs {
8787
# define user_mode(regs) (((regs)->ps & 0x00000020)!=0)
8888
# define instruction_pointer(regs) ((regs)->pc)
8989
# define return_pointer(regs) (MAKE_PC_FROM_RA((regs)->areg[0], \
90-
(regs)->areg[1]))
90+
(regs)->pc))
9191

9292
# ifndef CONFIG_SMP
9393
# define profile_pc(regs) instruction_pointer(regs)

arch/xtensa/kernel/process.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include <asm/asm-offsets.h>
4848
#include <asm/regs.h>
4949
#include <asm/hw_breakpoint.h>
50+
#include <asm/sections.h>
5051
#include <asm/traps.h>
5152

5253
extern void ret_from_fork(void);
@@ -380,7 +381,7 @@ unsigned long __get_wchan(struct task_struct *p)
380381
int count = 0;
381382

382383
sp = p->thread.sp;
383-
pc = MAKE_PC_FROM_RA(p->thread.ra, p->thread.sp);
384+
pc = MAKE_PC_FROM_RA(p->thread.ra, _text);
384385

385386
do {
386387
if (sp < stack_page + sizeof(struct task_struct) ||
@@ -392,7 +393,7 @@ unsigned long __get_wchan(struct task_struct *p)
392393

393394
/* Stack layout: sp-4: ra, sp-3: sp' */
394395

395-
pc = MAKE_PC_FROM_RA(SPILL_SLOT(sp, 0), sp);
396+
pc = MAKE_PC_FROM_RA(SPILL_SLOT(sp, 0), _text);
396397
sp = SPILL_SLOT(sp, 1);
397398
} while (count++ < 16);
398399
return 0;

arch/xtensa/kernel/stacktrace.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <linux/stacktrace.h>
1414

1515
#include <asm/ftrace.h>
16+
#include <asm/sections.h>
1617
#include <asm/stacktrace.h>
1718
#include <asm/traps.h>
1819
#include <linux/uaccess.h>
@@ -189,7 +190,7 @@ void walk_stackframe(unsigned long *sp,
189190
if (a1 <= (unsigned long)sp)
190191
break;
191192

192-
frame.pc = MAKE_PC_FROM_RA(a0, a1);
193+
frame.pc = MAKE_PC_FROM_RA(a0, _text);
193194
frame.sp = a1;
194195

195196
if (fn(&frame, data))

0 commit comments

Comments
 (0)