Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b0a779de authored by Paul Mackerras's avatar Paul Mackerras
Browse files

[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: default avatarPaul Mackerras <paulus@samba.org>
parent 035223fb
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -489,6 +489,10 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
	andi.	r0,r3,MSR_RI
	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

	/*
+19 −9
Original line number Diff line number Diff line
@@ -961,10 +961,18 @@ bad_stack:
 * any task or sent any task a signal, you should use
 * 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
fast_exception_return:
	ld	r12,_MSR(r1)
	ld	r11,_NIP(r1)
1:	ld	r11,_NIP(r1)
	andi.	r3,r12,MSR_RI		/* check if RI is set */
	beq-	unrecov_fer

@@ -1361,6 +1369,16 @@ BEGIN_FW_FTR_SECTION
	 * interrupts if necessary.
	 */
	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 */
	ble-	12f

@@ -1372,14 +1390,6 @@ BEGIN_FW_FTR_SECTION
	ld	r3,SOFTE(r1)
	bl	.local_irq_restore
	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. */
_GLOBAL(handle_page_fault)