[POWERPC] Make sure interrupt enable gets restored properly
The lazy IRQ disable patch missed a couple of places where the interrupt enable flags need to be restored correctly. First, we weren't restoring the paca->hard_enabled flag on interrupt exit. Instead of saving it on entry, we compute it from the MSR_EE bit in the MSR we are restoring at exit. Secondly, the MMU hash miss code was clearing both paca->soft_enabled and paca->hard_enabled but not restoring them in the case where hash_page was able to resolve the miss from the Linux page tables. Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
parent
035223fb28
commit
b0a779debd
@ -489,6 +489,10 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
|
|||||||
andi. r0,r3,MSR_RI
|
andi. r0,r3,MSR_RI
|
||||||
beq- unrecov_restore
|
beq- unrecov_restore
|
||||||
|
|
||||||
|
/* extract EE bit and use it to restore paca->hard_enabled */
|
||||||
|
rldicl r4,r3,49,63 /* r0 = (r3 >> 15) & 1 */
|
||||||
|
stb r4,PACAHARDIRQEN(r13)
|
||||||
|
|
||||||
andi. r0,r3,MSR_PR
|
andi. r0,r3,MSR_PR
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -961,10 +961,18 @@ bad_stack:
|
|||||||
* any task or sent any task a signal, you should use
|
* any task or sent any task a signal, you should use
|
||||||
* ret_from_except or ret_from_except_lite instead of this.
|
* ret_from_except or ret_from_except_lite instead of this.
|
||||||
*/
|
*/
|
||||||
|
fast_exc_return_irq: /* restores irq state too */
|
||||||
|
ld r3,SOFTE(r1)
|
||||||
|
ld r12,_MSR(r1)
|
||||||
|
stb r3,PACASOFTIRQEN(r13) /* restore paca->soft_enabled */
|
||||||
|
rldicl r4,r12,49,63 /* get MSR_EE to LSB */
|
||||||
|
stb r4,PACAHARDIRQEN(r13) /* restore paca->hard_enabled */
|
||||||
|
b 1f
|
||||||
|
|
||||||
.globl fast_exception_return
|
.globl fast_exception_return
|
||||||
fast_exception_return:
|
fast_exception_return:
|
||||||
ld r12,_MSR(r1)
|
ld r12,_MSR(r1)
|
||||||
ld r11,_NIP(r1)
|
1: ld r11,_NIP(r1)
|
||||||
andi. r3,r12,MSR_RI /* check if RI is set */
|
andi. r3,r12,MSR_RI /* check if RI is set */
|
||||||
beq- unrecov_fer
|
beq- unrecov_fer
|
||||||
|
|
||||||
@ -1361,6 +1369,16 @@ BEGIN_FW_FTR_SECTION
|
|||||||
* interrupts if necessary.
|
* interrupts if necessary.
|
||||||
*/
|
*/
|
||||||
beq .ret_from_except_lite
|
beq .ret_from_except_lite
|
||||||
|
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
|
||||||
|
#endif
|
||||||
|
BEGIN_FW_FTR_SECTION
|
||||||
|
/*
|
||||||
|
* Here we have interrupts hard-disabled, so it is sufficient
|
||||||
|
* to restore paca->{soft,hard}_enable and get out.
|
||||||
|
*/
|
||||||
|
beq fast_exc_return_irq /* Return from exception on success */
|
||||||
|
END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
|
||||||
|
|
||||||
/* For a hash failure, we don't bother re-enabling interrupts */
|
/* For a hash failure, we don't bother re-enabling interrupts */
|
||||||
ble- 12f
|
ble- 12f
|
||||||
|
|
||||||
@ -1372,14 +1390,6 @@ BEGIN_FW_FTR_SECTION
|
|||||||
ld r3,SOFTE(r1)
|
ld r3,SOFTE(r1)
|
||||||
bl .local_irq_restore
|
bl .local_irq_restore
|
||||||
b 11f
|
b 11f
|
||||||
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
|
|
||||||
#endif
|
|
||||||
BEGIN_FW_FTR_SECTION
|
|
||||||
beq fast_exception_return /* Return from exception on success */
|
|
||||||
ble- 12f /* Failure return from hash_page */
|
|
||||||
|
|
||||||
/* fall through */
|
|
||||||
END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
|
|
||||||
|
|
||||||
/* Here we have a page fault that hash_page can't handle. */
|
/* Here we have a page fault that hash_page can't handle. */
|
||||||
_GLOBAL(handle_page_fault)
|
_GLOBAL(handle_page_fault)
|
||||||
|
Loading…
Reference in New Issue
Block a user