mirror of https://gitee.com/openkylin/linux.git
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
Pull powerpc fixes from Benjamin Herrenschmidt: "Here are a couple of last minute fixes for 3.4 for regressions introduced by my rewrite of the lazy irq masking code." * 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: powerpc/irq: Make alignment & program interrupt behave the same powerpc/irq: Fix bug with new lazy IRQ handling code
This commit is contained in:
commit
6a5beacca8
|
@ -288,13 +288,6 @@ label##_hv: \
|
||||||
/* Exception addition: Hard disable interrupts */
|
/* Exception addition: Hard disable interrupts */
|
||||||
#define DISABLE_INTS SOFT_DISABLE_INTS(r10,r11)
|
#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 \
|
#define ADD_NVGPRS \
|
||||||
bl .save_nvgprs
|
bl .save_nvgprs
|
||||||
|
|
||||||
|
|
|
@ -767,16 +767,6 @@ do_work:
|
||||||
SOFT_DISABLE_INTS(r3,r4)
|
SOFT_DISABLE_INTS(r3,r4)
|
||||||
1: bl .preempt_schedule_irq
|
1: bl .preempt_schedule_irq
|
||||||
|
|
||||||
/* Hard-disable interrupts again (and update PACA) */
|
|
||||||
#ifdef CONFIG_PPC_BOOK3E
|
|
||||||
wrteei 0
|
|
||||||
#else
|
|
||||||
ld r10,PACAKMSR(r13) /* Get kernel MSR without EE */
|
|
||||||
mtmsrd r10,1
|
|
||||||
#endif /* CONFIG_PPC_BOOK3E */
|
|
||||||
li r0,PACA_IRQ_HARD_DIS
|
|
||||||
stb r0,PACAIRQHAPPENED(r13)
|
|
||||||
|
|
||||||
/* Re-test flags and eventually loop */
|
/* Re-test flags and eventually loop */
|
||||||
clrrdi r9,r1,THREAD_SHIFT
|
clrrdi r9,r1,THREAD_SHIFT
|
||||||
ld r4,TI_FLAGS(r9)
|
ld r4,TI_FLAGS(r9)
|
||||||
|
@ -787,14 +777,6 @@ do_work:
|
||||||
user_work:
|
user_work:
|
||||||
#endif /* CONFIG_PREEMPT */
|
#endif /* CONFIG_PREEMPT */
|
||||||
|
|
||||||
/* Enable interrupts */
|
|
||||||
#ifdef CONFIG_PPC_BOOK3E
|
|
||||||
wrteei 1
|
|
||||||
#else
|
|
||||||
ori r10,r10,MSR_EE
|
|
||||||
mtmsrd r10,1
|
|
||||||
#endif /* CONFIG_PPC_BOOK3E */
|
|
||||||
|
|
||||||
andi. r0,r4,_TIF_NEED_RESCHED
|
andi. r0,r4,_TIF_NEED_RESCHED
|
||||||
beq 1f
|
beq 1f
|
||||||
bl .restore_interrupts
|
bl .restore_interrupts
|
||||||
|
|
|
@ -768,8 +768,8 @@ alignment_common:
|
||||||
std r3,_DAR(r1)
|
std r3,_DAR(r1)
|
||||||
std r4,_DSISR(r1)
|
std r4,_DSISR(r1)
|
||||||
bl .save_nvgprs
|
bl .save_nvgprs
|
||||||
|
DISABLE_INTS
|
||||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||||
ENABLE_INTS
|
|
||||||
bl .alignment_exception
|
bl .alignment_exception
|
||||||
b .ret_from_except
|
b .ret_from_except
|
||||||
|
|
||||||
|
|
|
@ -260,11 +260,17 @@ EXPORT_SYMBOL(arch_local_irq_restore);
|
||||||
* if they are currently disabled. This is typically called before
|
* if they are currently disabled. This is typically called before
|
||||||
* schedule() or do_signal() when returning to userspace. We do it
|
* schedule() or do_signal() when returning to userspace. We do it
|
||||||
* in C to avoid the burden of dealing with lockdep etc...
|
* in C to avoid the burden of dealing with lockdep etc...
|
||||||
|
*
|
||||||
|
* NOTE: This is called with interrupts hard disabled but not marked
|
||||||
|
* as such in paca->irq_happened, so we need to resync this.
|
||||||
*/
|
*/
|
||||||
void restore_interrupts(void)
|
void restore_interrupts(void)
|
||||||
{
|
{
|
||||||
if (irqs_disabled())
|
if (irqs_disabled()) {
|
||||||
|
local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
|
} else
|
||||||
|
__hard_irq_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_PPC64 */
|
#endif /* CONFIG_PPC64 */
|
||||||
|
|
|
@ -248,7 +248,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
|
||||||
addr, regs->nip, regs->link, code);
|
addr, regs->nip, regs->link, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!arch_irq_disabled_regs(regs))
|
if (arch_irqs_disabled() && !arch_irq_disabled_regs(regs))
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
|
|
||||||
memset(&info, 0, sizeof(info));
|
memset(&info, 0, sizeof(info));
|
||||||
|
@ -1019,6 +1019,8 @@ void __kprobes program_check_exception(struct pt_regs *regs)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We restore the interrupt state now */
|
||||||
|
if (!arch_irq_disabled_regs(regs))
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
|
|
||||||
#ifdef CONFIG_MATH_EMULATION
|
#ifdef CONFIG_MATH_EMULATION
|
||||||
|
@ -1069,6 +1071,10 @@ void alignment_exception(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
int sig, code, fixed = 0;
|
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 */
|
/* we don't implement logging of alignment exceptions */
|
||||||
if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS))
|
if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS))
|
||||||
fixed = fix_alignment(regs);
|
fixed = fix_alignment(regs);
|
||||||
|
|
Loading…
Reference in New Issue