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

Commit a3512b2d authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt
Browse files

powerpc/irq: Make alignment & program interrupt behave the same



Alignment was the last user of the ENABLE_INTS macro, which we can
now remove. All non-syscall exceptions now disable interrupts on
entry, they get re-enabled conditionally from C code. Don't
unconditionally re-enable in program check either, check the
original context.

Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 56dfa7fa
Loading
Loading
Loading
Loading
+0 −7
Original line number Diff line number Diff line
@@ -288,13 +288,6 @@ label##_hv: \
/* Exception addition: Hard disable interrupts */
#define DISABLE_INTS	SOFT_DISABLE_INTS(r10,r11)

/* Exception addition: Keep interrupt state */
#define ENABLE_INTS				\
	ld	r11,PACAKMSR(r13);		\
	ld	r12,_MSR(r1);			\
	rlwimi	r11,r12,0,MSR_EE;		\
	mtmsrd	r11,1

#define ADD_NVGPRS				\
	bl	.save_nvgprs

+1 −1
Original line number Diff line number Diff line
@@ -768,8 +768,8 @@ alignment_common:
	std	r3,_DAR(r1)
	std	r4,_DSISR(r1)
	bl	.save_nvgprs
	DISABLE_INTS
	addi	r3,r1,STACK_FRAME_OVERHEAD
	ENABLE_INTS
	bl	.alignment_exception
	b	.ret_from_except

+8 −2
Original line number Diff line number Diff line
@@ -248,7 +248,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
				   addr, regs->nip, regs->link, code);
	}

	if (!arch_irq_disabled_regs(regs))
	if (arch_irqs_disabled() && !arch_irq_disabled_regs(regs))
		local_irq_enable();

	memset(&info, 0, sizeof(info));
@@ -1019,6 +1019,8 @@ void __kprobes program_check_exception(struct pt_regs *regs)
		return;
	}

	/* We restore the interrupt state now */
	if (!arch_irq_disabled_regs(regs))
		local_irq_enable();

#ifdef CONFIG_MATH_EMULATION
@@ -1069,6 +1071,10 @@ void alignment_exception(struct pt_regs *regs)
{
	int sig, code, fixed = 0;

	/* We restore the interrupt state now */
	if (!arch_irq_disabled_regs(regs))
		local_irq_enable();

	/* we don't implement logging of alignment exceptions */
	if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS))
		fixed = fix_alignment(regs);