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:
jhibbits 2017-11-08 01:23:37 +00:00
parent 7a4fdbc7ad
commit e56e8de02d
2 changed files with 8 additions and 8 deletions

View File

@ -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)

View File

@ -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: