Skip to content

Commit 5cc5f19

Browse files
committed
xtensa: improve call0 ABI probing
When call0 userspace ABI support by probing is enabled instructions that cause illegal instruction exception when PS.WOE is clear are retried with PS.WOE set before calling c-level exception handler. Record user pc at which PS.WOE was set in the fast exception handler and clear PS.WOE in the c-level exception handler if we get there from the same address. Signed-off-by: Max Filippov <[email protected]>
1 parent d748620 commit 5cc5f19

File tree

4 files changed

+24
-0
lines changed

4 files changed

+24
-0
lines changed

arch/xtensa/include/asm/thread_info.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ struct thread_info {
5656
/* result of the most recent exclusive store */
5757
unsigned long atomctl8;
5858
#endif
59+
#ifdef CONFIG_USER_ABI_CALL0_PROBE
60+
/* Address where PS.WOE was enabled by the ABI probing code */
61+
unsigned long ps_woe_fix_addr;
62+
#endif
5963

6064
/*
6165
* If i-th bit is set then coprocessor state is loaded into the

arch/xtensa/kernel/asm-offsets.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ int main(void)
8888
OFFSET(TI_STSTUS, thread_info, status);
8989
OFFSET(TI_CPU, thread_info, cpu);
9090
OFFSET(TI_PRE_COUNT, thread_info, preempt_count);
91+
#ifdef CONFIG_USER_ABI_CALL0_PROBE
92+
OFFSET(TI_PS_WOE_FIX_ADDR, thread_info, ps_woe_fix_addr);
93+
#endif
9194

9295
/* struct thread_info (offset from start_struct) */
9396
DEFINE(THREAD_RA, offsetof (struct task_struct, thread.ra));

arch/xtensa/kernel/entry.S

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,6 +1056,11 @@ ENTRY(fast_illegal_instruction_user)
10561056
movi a3, PS_WOE_MASK
10571057
or a0, a0, a3
10581058
wsr a0, ps
1059+
#ifdef CONFIG_USER_ABI_CALL0_PROBE
1060+
GET_THREAD_INFO(a3, a2)
1061+
rsr a0, epc1
1062+
s32i a0, a3, TI_PS_WOE_FIX_ADDR
1063+
#endif
10591064
l32i a3, a2, PT_AREG3
10601065
l32i a0, a2, PT_AREG0
10611066
rsr a2, depc

arch/xtensa/kernel/traps.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,18 @@ static bool check_div0(struct pt_regs *regs)
317317

318318
static void do_illegal_instruction(struct pt_regs *regs)
319319
{
320+
#ifdef CONFIG_USER_ABI_CALL0_PROBE
321+
/*
322+
* When call0 application encounters an illegal instruction fast
323+
* exception handler will attempt to set PS.WOE and retry failing
324+
* instruction.
325+
* If we get here we know that that instruction is also illegal
326+
* with PS.WOE set, so it's not related to the windowed option
327+
* hence PS.WOE may be cleared.
328+
*/
329+
if (regs->pc == current_thread_info()->ps_woe_fix_addr)
330+
regs->ps &= ~PS_WOE_MASK;
331+
#endif
320332
if (check_div0(regs)) {
321333
do_div0(regs);
322334
return;

0 commit comments

Comments
 (0)