Clear the WE bit in C code rather than the asm
According to EREF rlwinm is supposed to clear the upper 32 bits of the register of 64-bit cores. However, from experience it seems there's a bug in the e5500 which causes the result to be duplicated in the upper bits of the register. This causes problems when applied to stashed SRR1 accessed to retrieve context, as the upper bits are not masked out, so a set_mcontext() fails. This causes sigreturn() to in turn return with EINVAL, causing make(1) to exit with error. This bit is unused in e500mc derivatives (including e5500), so could just be conditional on non-powerpc64, but there may be other non-Freescale cores which do use it. This is also the same as the POW bit on Book-S, so could be cleared unconditionally with the only penalty being a few clock cycles for these two interrupts.
This commit is contained in:
parent
7a4fdbc7ad
commit
e56e8de02d
@ -567,7 +567,7 @@ INTERRUPT(int_external_input)
|
||||
addi %r3, %r1, CALLSIZE
|
||||
bl CNAME(powerpc_interrupt)
|
||||
TOC_RESTORE
|
||||
b clear_we
|
||||
b trapexit
|
||||
|
||||
|
||||
INTERRUPT(int_alignment)
|
||||
@ -607,7 +607,7 @@ INTERRUPT(int_decrementer)
|
||||
addi %r3, %r1, CALLSIZE
|
||||
bl CNAME(powerpc_interrupt)
|
||||
TOC_RESTORE
|
||||
b clear_we
|
||||
b trapexit
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
@ -1091,12 +1091,6 @@ dbleave:
|
||||
rfi
|
||||
#endif /* KDB */
|
||||
|
||||
clear_we:
|
||||
LOAD %r3, (FRAME_SRR1+CALLSIZE)(%r1)
|
||||
rlwinm %r3, %r3, 0, 14, 12
|
||||
STORE %r3, (FRAME_SRR1+CALLSIZE)(%r1)
|
||||
b trapexit
|
||||
|
||||
#ifdef SMP
|
||||
ENTRY(tlb_lock)
|
||||
GET_CPUINFO(%r5)
|
||||
|
@ -89,6 +89,9 @@ powerpc_interrupt(struct trapframe *framep)
|
||||
critical_enter();
|
||||
PIC_DISPATCH(root_pic, framep);
|
||||
critical_exit();
|
||||
#ifdef BOOKE
|
||||
framep->srr1 &= ~PSL_WE;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case EXC_DECR:
|
||||
@ -100,6 +103,9 @@ powerpc_interrupt(struct trapframe *framep)
|
||||
td->td_intr_frame = oldframe;
|
||||
atomic_subtract_int(&td->td_intr_nesting_level, 1);
|
||||
critical_exit();
|
||||
#ifdef BOOKE
|
||||
framep->srr1 &= ~PSL_WE;
|
||||
#endif
|
||||
break;
|
||||
#ifdef HWPMC_HOOKS
|
||||
case EXC_PERF:
|
||||
|
Loading…
x
Reference in New Issue
Block a user