aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-05-08 20:57:57 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-05-08 20:57:57 -0400
commitea4e89afedc7fc64078076eacbcffaaa742baf0d (patch)
tree1e4a14dd1ada2eff8d1cb4d76bf9e337e079845e /arch/powerpc/kernel
parent43671cc96e58458b2711f1e97ff24a4c0e7cd1ac (diff)
parenta3512b2dd57cb653bb33645ca9c934436e547e3c (diff)
Merge branch 'merge' into next
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/entry_64.S18
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S2
-rw-r--r--arch/powerpc/kernel/irq.c14
-rw-r--r--arch/powerpc/kernel/machine_kexec.c7
-rw-r--r--arch/powerpc/kernel/traps.c10
5 files changed, 19 insertions, 32 deletions
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index fd4604674468..29f13570214d 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -763,16 +763,6 @@ do_work:
763 SOFT_DISABLE_INTS(r3,r4) 763 SOFT_DISABLE_INTS(r3,r4)
7641: bl .preempt_schedule_irq 7641: bl .preempt_schedule_irq
765 765
766 /* Hard-disable interrupts again (and update PACA) */
767#ifdef CONFIG_PPC_BOOK3E
768 wrteei 0
769#else
770 ld r10,PACAKMSR(r13) /* Get kernel MSR without EE */
771 mtmsrd r10,1
772#endif /* CONFIG_PPC_BOOK3E */
773 li r0,PACA_IRQ_HARD_DIS
774 stb r0,PACAIRQHAPPENED(r13)
775
776 /* Re-test flags and eventually loop */ 766 /* Re-test flags and eventually loop */
777 clrrdi r9,r1,THREAD_SHIFT 767 clrrdi r9,r1,THREAD_SHIFT
778 ld r4,TI_FLAGS(r9) 768 ld r4,TI_FLAGS(r9)
@@ -783,14 +773,6 @@ do_work:
783user_work: 773user_work:
784#endif /* CONFIG_PREEMPT */ 774#endif /* CONFIG_PREEMPT */
785 775
786 /* Enable interrupts */
787#ifdef CONFIG_PPC_BOOK3E
788 wrteei 1
789#else
790 ori r10,r10,MSR_EE
791 mtmsrd r10,1
792#endif /* CONFIG_PPC_BOOK3E */
793
794 andi. r0,r4,_TIF_NEED_RESCHED 776 andi. r0,r4,_TIF_NEED_RESCHED
795 beq 1f 777 beq 1f
796 bl .restore_interrupts 778 bl .restore_interrupts
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index e0537693d660..f7bed44ee165 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -764,8 +764,8 @@ alignment_common:
764 std r3,_DAR(r1) 764 std r3,_DAR(r1)
765 std r4,_DSISR(r1) 765 std r4,_DSISR(r1)
766 bl .save_nvgprs 766 bl .save_nvgprs
767 DISABLE_INTS
767 addi r3,r1,STACK_FRAME_OVERHEAD 768 addi r3,r1,STACK_FRAME_OVERHEAD
768 ENABLE_INTS
769 bl .alignment_exception 769 bl .alignment_exception
770 b .ret_from_except 770 b .ret_from_except
771 771
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 5ec1b2354ca6..c6c6f3b7f8cd 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -260,11 +260,17 @@ EXPORT_SYMBOL(arch_local_irq_restore);
260 * if they are currently disabled. This is typically called before 260 * if they are currently disabled. This is typically called before
261 * schedule() or do_signal() when returning to userspace. We do it 261 * schedule() or do_signal() when returning to userspace. We do it
262 * in C to avoid the burden of dealing with lockdep etc... 262 * in C to avoid the burden of dealing with lockdep etc...
263 *
264 * NOTE: This is called with interrupts hard disabled but not marked
265 * as such in paca->irq_happened, so we need to resync this.
263 */ 266 */
264void restore_interrupts(void) 267void restore_interrupts(void)
265{ 268{
266 if (irqs_disabled()) 269 if (irqs_disabled()) {
270 local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
267 local_irq_enable(); 271 local_irq_enable();
272 } else
273 __hard_irq_enable();
268} 274}
269 275
270#endif /* CONFIG_PPC64 */ 276#endif /* CONFIG_PPC64 */
@@ -330,14 +336,10 @@ void migrate_irqs(void)
330 336
331 alloc_cpumask_var(&mask, GFP_KERNEL); 337 alloc_cpumask_var(&mask, GFP_KERNEL);
332 338
333 for_each_irq(irq) { 339 for_each_irq_desc(irq, desc) {
334 struct irq_data *data; 340 struct irq_data *data;
335 struct irq_chip *chip; 341 struct irq_chip *chip;
336 342
337 desc = irq_to_desc(irq);
338 if (!desc)
339 continue;
340
341 data = irq_desc_get_irq_data(desc); 343 data = irq_desc_get_irq_data(desc);
342 if (irqd_is_per_cpu(data)) 344 if (irqd_is_per_cpu(data))
343 continue; 345 continue;
diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c
index c957b1202bdc..5df777794403 100644
--- a/arch/powerpc/kernel/machine_kexec.c
+++ b/arch/powerpc/kernel/machine_kexec.c
@@ -23,14 +23,11 @@
23 23
24void machine_kexec_mask_interrupts(void) { 24void machine_kexec_mask_interrupts(void) {
25 unsigned int i; 25 unsigned int i;
26 struct irq_desc *desc;
26 27
27 for_each_irq(i) { 28 for_each_irq_desc(i, desc) {
28 struct irq_desc *desc = irq_to_desc(i);
29 struct irq_chip *chip; 29 struct irq_chip *chip;
30 30
31 if (!desc)
32 continue;
33
34 chip = irq_desc_get_chip(desc); 31 chip = irq_desc_get_chip(desc);
35 if (!chip) 32 if (!chip)
36 continue; 33 continue;
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 6aa0c663e247..158972341a2d 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -248,7 +248,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
248 addr, regs->nip, regs->link, code); 248 addr, regs->nip, regs->link, code);
249 } 249 }
250 250
251 if (!arch_irq_disabled_regs(regs)) 251 if (arch_irqs_disabled() && !arch_irq_disabled_regs(regs))
252 local_irq_enable(); 252 local_irq_enable();
253 253
254 memset(&info, 0, sizeof(info)); 254 memset(&info, 0, sizeof(info));
@@ -1019,7 +1019,9 @@ void __kprobes program_check_exception(struct pt_regs *regs)
1019 return; 1019 return;
1020 } 1020 }
1021 1021
1022 local_irq_enable(); 1022 /* We restore the interrupt state now */
1023 if (!arch_irq_disabled_regs(regs))
1024 local_irq_enable();
1023 1025
1024#ifdef CONFIG_MATH_EMULATION 1026#ifdef CONFIG_MATH_EMULATION
1025 /* (reason & REASON_ILLEGAL) would be the obvious thing here, 1027 /* (reason & REASON_ILLEGAL) would be the obvious thing here,
@@ -1069,6 +1071,10 @@ void alignment_exception(struct pt_regs *regs)
1069{ 1071{
1070 int sig, code, fixed = 0; 1072 int sig, code, fixed = 0;
1071 1073
1074 /* We restore the interrupt state now */
1075 if (!arch_irq_disabled_regs(regs))
1076 local_irq_enable();
1077
1072 /* we don't implement logging of alignment exceptions */ 1078 /* we don't implement logging of alignment exceptions */
1073 if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS)) 1079 if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS))
1074 fixed = fix_alignment(regs); 1080 fixed = fix_alignment(regs);