aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/align.c12
-rw-r--r--arch/powerpc/kernel/entry_64.S45
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S3
-rw-r--r--arch/powerpc/kernel/irq.c6
-rw-r--r--arch/powerpc/kernel/pci_64.c2
-rw-r--r--arch/powerpc/kernel/perf_event.c19
-rw-r--r--arch/powerpc/kernel/power5+-pmu.c4
-rw-r--r--arch/powerpc/kernel/power5-pmu.c6
-rw-r--r--arch/powerpc/kernel/power6-pmu.c2
-rw-r--r--arch/powerpc/kernel/power7-pmu.c6
-rw-r--r--arch/powerpc/kernel/ppc970-pmu.c4
-rw-r--r--arch/powerpc/kernel/process.c2
-rw-r--r--arch/powerpc/kernel/setup-common.c1
-rw-r--r--arch/powerpc/kernel/setup_64.c1
-rw-r--r--arch/powerpc/kernel/time.c21
-rw-r--r--arch/powerpc/kernel/traps.c18
-rw-r--r--arch/powerpc/kernel/vdso.c11
-rw-r--r--arch/powerpc/kernel/vdso32/vdso32.lds.S4
18 files changed, 97 insertions, 70 deletions
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
index a5b632e52fae..3839839f83c7 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -732,7 +732,7 @@ int fix_alignment(struct pt_regs *regs)
732 732
733#ifdef CONFIG_SPE 733#ifdef CONFIG_SPE
734 if ((instr >> 26) == 0x4) { 734 if ((instr >> 26) == 0x4) {
735 PPC_WARN_EMULATED(spe); 735 PPC_WARN_ALIGNMENT(spe, regs);
736 return emulate_spe(regs, reg, instr); 736 return emulate_spe(regs, reg, instr);
737 } 737 }
738#endif 738#endif
@@ -786,7 +786,7 @@ int fix_alignment(struct pt_regs *regs)
786 flags |= SPLT; 786 flags |= SPLT;
787 nb = 8; 787 nb = 8;
788 } 788 }
789 PPC_WARN_EMULATED(vsx); 789 PPC_WARN_ALIGNMENT(vsx, regs);
790 return emulate_vsx(addr, reg, areg, regs, flags, nb); 790 return emulate_vsx(addr, reg, areg, regs, flags, nb);
791 } 791 }
792#endif 792#endif
@@ -794,7 +794,7 @@ int fix_alignment(struct pt_regs *regs)
794 * the exception of DCBZ which is handled as a special case here 794 * the exception of DCBZ which is handled as a special case here
795 */ 795 */
796 if (instr == DCBZ) { 796 if (instr == DCBZ) {
797 PPC_WARN_EMULATED(dcbz); 797 PPC_WARN_ALIGNMENT(dcbz, regs);
798 return emulate_dcbz(regs, addr); 798 return emulate_dcbz(regs, addr);
799 } 799 }
800 if (unlikely(nb == 0)) 800 if (unlikely(nb == 0))
@@ -804,7 +804,7 @@ int fix_alignment(struct pt_regs *regs)
804 * function 804 * function
805 */ 805 */
806 if (flags & M) { 806 if (flags & M) {
807 PPC_WARN_EMULATED(multiple); 807 PPC_WARN_ALIGNMENT(multiple, regs);
808 return emulate_multiple(regs, addr, reg, nb, 808 return emulate_multiple(regs, addr, reg, nb,
809 flags, instr, swiz); 809 flags, instr, swiz);
810 } 810 }
@@ -825,11 +825,11 @@ int fix_alignment(struct pt_regs *regs)
825 825
826 /* Special case for 16-byte FP loads and stores */ 826 /* Special case for 16-byte FP loads and stores */
827 if (nb == 16) { 827 if (nb == 16) {
828 PPC_WARN_EMULATED(fp_pair); 828 PPC_WARN_ALIGNMENT(fp_pair, regs);
829 return emulate_fp_pair(addr, reg, flags); 829 return emulate_fp_pair(addr, reg, flags);
830 } 830 }
831 831
832 PPC_WARN_EMULATED(unaligned); 832 PPC_WARN_ALIGNMENT(unaligned, regs);
833 833
834 /* If we are loading, get the data from user space, else 834 /* If we are loading, get the data from user space, else
835 * get it from register values 835 * get it from register values
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index f9fd54bfcc84..bdcb557d470a 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -551,7 +551,7 @@ restore:
551BEGIN_FW_FTR_SECTION 551BEGIN_FW_FTR_SECTION
552 ld r5,SOFTE(r1) 552 ld r5,SOFTE(r1)
553FW_FTR_SECTION_ELSE 553FW_FTR_SECTION_ELSE
554 b iseries_check_pending_irqs 554 b .Liseries_check_pending_irqs
555ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES) 555ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES)
5562: 5562:
557 TRACE_AND_RESTORE_IRQ(r5); 557 TRACE_AND_RESTORE_IRQ(r5);
@@ -623,7 +623,7 @@ ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES)
623 623
624#endif /* CONFIG_PPC_BOOK3E */ 624#endif /* CONFIG_PPC_BOOK3E */
625 625
626iseries_check_pending_irqs: 626.Liseries_check_pending_irqs:
627#ifdef CONFIG_PPC_ISERIES 627#ifdef CONFIG_PPC_ISERIES
628 ld r5,SOFTE(r1) 628 ld r5,SOFTE(r1)
629 cmpdi 0,r5,0 629 cmpdi 0,r5,0
@@ -658,42 +658,43 @@ do_work:
658 cmpdi r0,0 658 cmpdi r0,0
659 crandc eq,cr1*4+eq,eq 659 crandc eq,cr1*4+eq,eq
660 bne restore 660 bne restore
661 /* here we are preempting the current task */ 661
6621: 662 /* Here we are preempting the current task.
663#ifdef CONFIG_TRACE_IRQFLAGS 663 *
664 bl .trace_hardirqs_on 664 * Ensure interrupts are soft-disabled. We also properly mark
665 /* Note: we just clobbered r10 which used to contain the previous 665 * the PACA to reflect the fact that they are hard-disabled
666 * MSR before the hard-disabling done by the caller of do_work. 666 * and trace the change
667 * We don't have that value anymore, but it doesn't matter as
668 * we will hard-enable unconditionally, we can just reload the
669 * current MSR into r10
670 */ 667 */
671 mfmsr r10 668 li r0,0
672#endif /* CONFIG_TRACE_IRQFLAGS */
673 li r0,1
674 stb r0,PACASOFTIRQEN(r13) 669 stb r0,PACASOFTIRQEN(r13)
675 stb r0,PACAHARDIRQEN(r13) 670 stb r0,PACAHARDIRQEN(r13)
671 TRACE_DISABLE_INTS
672
673 /* Call the scheduler with soft IRQs off */
6741: bl .preempt_schedule_irq
675
676 /* Hard-disable interrupts again (and update PACA) */
676#ifdef CONFIG_PPC_BOOK3E 677#ifdef CONFIG_PPC_BOOK3E
677 wrteei 1
678 bl .preempt_schedule
679 wrteei 0 678 wrteei 0
680#else 679#else
681 ori r10,r10,MSR_EE
682 mtmsrd r10,1 /* reenable interrupts */
683 bl .preempt_schedule
684 mfmsr r10 680 mfmsr r10
685 clrrdi r9,r1,THREAD_SHIFT 681 rldicl r10,r10,48,1
686 rldicl r10,r10,48,1 /* disable interrupts again */
687 rotldi r10,r10,16 682 rotldi r10,r10,16
688 mtmsrd r10,1 683 mtmsrd r10,1
689#endif /* CONFIG_PPC_BOOK3E */ 684#endif /* CONFIG_PPC_BOOK3E */
685 li r0,0
686 stb r0,PACAHARDIRQEN(r13)
687
688 /* Re-test flags and eventually loop */
689 clrrdi r9,r1,THREAD_SHIFT
690 ld r4,TI_FLAGS(r9) 690 ld r4,TI_FLAGS(r9)
691 andi. r0,r4,_TIF_NEED_RESCHED 691 andi. r0,r4,_TIF_NEED_RESCHED
692 bne 1b 692 bne 1b
693 b restore 693 b restore
694 694
695user_work: 695user_work:
696#endif 696#endif /* CONFIG_PREEMPT */
697
697 /* Enable interrupts */ 698 /* Enable interrupts */
698#ifdef CONFIG_PPC_BOOK3E 699#ifdef CONFIG_PPC_BOOK3E
699 wrteei 1 700 wrteei 1
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 1808876edcc9..c7eb4e0eb86c 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -185,12 +185,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
185 * prolog code of the PerformanceMonitor one. A little 185 * prolog code of the PerformanceMonitor one. A little
186 * trickery is thus necessary 186 * trickery is thus necessary
187 */ 187 */
188performance_monitor_pSeries_1:
188 . = 0xf00 189 . = 0xf00
189 b performance_monitor_pSeries 190 b performance_monitor_pSeries
190 191
192altivec_unavailable_pSeries_1:
191 . = 0xf20 193 . = 0xf20
192 b altivec_unavailable_pSeries 194 b altivec_unavailable_pSeries
193 195
196vsx_unavailable_pSeries_1:
194 . = 0xf40 197 . = 0xf40
195 b vsx_unavailable_pSeries 198 b vsx_unavailable_pSeries
196 199
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index e5d121177984..02a334662cc0 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -70,6 +70,8 @@
70#include <asm/firmware.h> 70#include <asm/firmware.h>
71#include <asm/lv1call.h> 71#include <asm/lv1call.h>
72#endif 72#endif
73#define CREATE_TRACE_POINTS
74#include <asm/trace.h>
73 75
74int __irq_offset_value; 76int __irq_offset_value;
75static int ppc_spurious_interrupts; 77static int ppc_spurious_interrupts;
@@ -325,6 +327,8 @@ void do_IRQ(struct pt_regs *regs)
325 struct pt_regs *old_regs = set_irq_regs(regs); 327 struct pt_regs *old_regs = set_irq_regs(regs);
326 unsigned int irq; 328 unsigned int irq;
327 329
330 trace_irq_entry(regs);
331
328 irq_enter(); 332 irq_enter();
329 333
330 check_stack_overflow(); 334 check_stack_overflow();
@@ -348,6 +352,8 @@ void do_IRQ(struct pt_regs *regs)
348 timer_interrupt(regs); 352 timer_interrupt(regs);
349 } 353 }
350#endif 354#endif
355
356 trace_irq_exit(regs);
351} 357}
352 358
353void __init init_IRQ(void) 359void __init init_IRQ(void)
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index ba949a2c93ac..ccf56ac92de5 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -97,7 +97,9 @@ int pcibios_unmap_io_space(struct pci_bus *bus)
97 * to do an appropriate TLB flush here too 97 * to do an appropriate TLB flush here too
98 */ 98 */
99 if (bus->self) { 99 if (bus->self) {
100#ifdef CONFIG_PPC_STD_MMU_64
100 struct resource *res = bus->resource[0]; 101 struct resource *res = bus->resource[0];
102#endif
101 103
102 pr_debug("IO unmapping for PCI-PCI bridge %s\n", 104 pr_debug("IO unmapping for PCI-PCI bridge %s\n",
103 pci_name(bus->self)); 105 pci_name(bus->self));
diff --git a/arch/powerpc/kernel/perf_event.c b/arch/powerpc/kernel/perf_event.c
index bbcbae183e92..1eb85fbf53a5 100644
--- a/arch/powerpc/kernel/perf_event.c
+++ b/arch/powerpc/kernel/perf_event.c
@@ -116,20 +116,23 @@ static inline void perf_get_data_addr(struct pt_regs *regs, u64 *addrp)
116static inline u32 perf_get_misc_flags(struct pt_regs *regs) 116static inline u32 perf_get_misc_flags(struct pt_regs *regs)
117{ 117{
118 unsigned long mmcra = regs->dsisr; 118 unsigned long mmcra = regs->dsisr;
119 unsigned long sihv = MMCRA_SIHV;
120 unsigned long sipr = MMCRA_SIPR;
119 121
120 if (TRAP(regs) != 0xf00) 122 if (TRAP(regs) != 0xf00)
121 return 0; /* not a PMU interrupt */ 123 return 0; /* not a PMU interrupt */
122 124
123 if (ppmu->flags & PPMU_ALT_SIPR) { 125 if (ppmu->flags & PPMU_ALT_SIPR) {
124 if (mmcra & POWER6_MMCRA_SIHV) 126 sihv = POWER6_MMCRA_SIHV;
125 return PERF_RECORD_MISC_HYPERVISOR; 127 sipr = POWER6_MMCRA_SIPR;
126 return (mmcra & POWER6_MMCRA_SIPR) ?
127 PERF_RECORD_MISC_USER : PERF_RECORD_MISC_KERNEL;
128 } 128 }
129 if (mmcra & MMCRA_SIHV) 129
130 /* PR has priority over HV, so order below is important */
131 if (mmcra & sipr)
132 return PERF_RECORD_MISC_USER;
133 if ((mmcra & sihv) && (freeze_events_kernel != MMCR0_FCHV))
130 return PERF_RECORD_MISC_HYPERVISOR; 134 return PERF_RECORD_MISC_HYPERVISOR;
131 return (mmcra & MMCRA_SIPR) ? PERF_RECORD_MISC_USER : 135 return PERF_RECORD_MISC_KERNEL;
132 PERF_RECORD_MISC_KERNEL;
133} 136}
134 137
135/* 138/*
@@ -1162,7 +1165,7 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
1162 */ 1165 */
1163 if (record) { 1166 if (record) {
1164 struct perf_sample_data data = { 1167 struct perf_sample_data data = {
1165 .addr = 0, 1168 .addr = ~0ULL,
1166 .period = event->hw.last_period, 1169 .period = event->hw.last_period,
1167 }; 1170 };
1168 1171
diff --git a/arch/powerpc/kernel/power5+-pmu.c b/arch/powerpc/kernel/power5+-pmu.c
index 0f4c1c73a6ad..199de527d411 100644
--- a/arch/powerpc/kernel/power5+-pmu.c
+++ b/arch/powerpc/kernel/power5+-pmu.c
@@ -73,10 +73,6 @@
73#define MMCR1_PMCSEL_MSK 0x7f 73#define MMCR1_PMCSEL_MSK 0x7f
74 74
75/* 75/*
76 * Bits in MMCRA
77 */
78
79/*
80 * Layout of constraint bits: 76 * Layout of constraint bits:
81 * 6666555555555544444444443333333333222222222211111111110000000000 77 * 6666555555555544444444443333333333222222222211111111110000000000
82 * 3210987654321098765432109876543210987654321098765432109876543210 78 * 3210987654321098765432109876543210987654321098765432109876543210
diff --git a/arch/powerpc/kernel/power5-pmu.c b/arch/powerpc/kernel/power5-pmu.c
index c351b3a57fbb..98b6a729a9dd 100644
--- a/arch/powerpc/kernel/power5-pmu.c
+++ b/arch/powerpc/kernel/power5-pmu.c
@@ -73,10 +73,6 @@
73#define MMCR1_PMCSEL_MSK 0x7f 73#define MMCR1_PMCSEL_MSK 0x7f
74 74
75/* 75/*
76 * Bits in MMCRA
77 */
78
79/*
80 * Layout of constraint bits: 76 * Layout of constraint bits:
81 * 6666555555555544444444443333333333222222222211111111110000000000 77 * 6666555555555544444444443333333333222222222211111111110000000000
82 * 3210987654321098765432109876543210987654321098765432109876543210 78 * 3210987654321098765432109876543210987654321098765432109876543210
@@ -390,7 +386,7 @@ static int power5_compute_mmcr(u64 event[], int n_ev,
390 unsigned int hwc[], unsigned long mmcr[]) 386 unsigned int hwc[], unsigned long mmcr[])
391{ 387{
392 unsigned long mmcr1 = 0; 388 unsigned long mmcr1 = 0;
393 unsigned long mmcra = 0; 389 unsigned long mmcra = MMCRA_SDAR_DCACHE_MISS | MMCRA_SDAR_ERAT_MISS;
394 unsigned int pmc, unit, byte, psel; 390 unsigned int pmc, unit, byte, psel;
395 unsigned int ttm, grp; 391 unsigned int ttm, grp;
396 int i, isbus, bit, grsel; 392 int i, isbus, bit, grsel;
diff --git a/arch/powerpc/kernel/power6-pmu.c b/arch/powerpc/kernel/power6-pmu.c
index ca399ba5034c..84a607bda8fb 100644
--- a/arch/powerpc/kernel/power6-pmu.c
+++ b/arch/powerpc/kernel/power6-pmu.c
@@ -178,7 +178,7 @@ static int p6_compute_mmcr(u64 event[], int n_ev,
178 unsigned int hwc[], unsigned long mmcr[]) 178 unsigned int hwc[], unsigned long mmcr[])
179{ 179{
180 unsigned long mmcr1 = 0; 180 unsigned long mmcr1 = 0;
181 unsigned long mmcra = 0; 181 unsigned long mmcra = MMCRA_SDAR_DCACHE_MISS | MMCRA_SDAR_ERAT_MISS;
182 int i; 182 int i;
183 unsigned int pmc, ev, b, u, s, psel; 183 unsigned int pmc, ev, b, u, s, psel;
184 unsigned int ttmset = 0; 184 unsigned int ttmset = 0;
diff --git a/arch/powerpc/kernel/power7-pmu.c b/arch/powerpc/kernel/power7-pmu.c
index 28a4daacdc02..852f7b7f6b40 100644
--- a/arch/powerpc/kernel/power7-pmu.c
+++ b/arch/powerpc/kernel/power7-pmu.c
@@ -51,10 +51,6 @@
51#define MMCR1_PMCSEL_MSK 0xff 51#define MMCR1_PMCSEL_MSK 0xff
52 52
53/* 53/*
54 * Bits in MMCRA
55 */
56
57/*
58 * Layout of constraint bits: 54 * Layout of constraint bits:
59 * 6666555555555544444444443333333333222222222211111111110000000000 55 * 6666555555555544444444443333333333222222222211111111110000000000
60 * 3210987654321098765432109876543210987654321098765432109876543210 56 * 3210987654321098765432109876543210987654321098765432109876543210
@@ -230,7 +226,7 @@ static int power7_compute_mmcr(u64 event[], int n_ev,
230 unsigned int hwc[], unsigned long mmcr[]) 226 unsigned int hwc[], unsigned long mmcr[])
231{ 227{
232 unsigned long mmcr1 = 0; 228 unsigned long mmcr1 = 0;
233 unsigned long mmcra = 0; 229 unsigned long mmcra = MMCRA_SDAR_DCACHE_MISS | MMCRA_SDAR_ERAT_MISS;
234 unsigned int pmc, unit, combine, l2sel, psel; 230 unsigned int pmc, unit, combine, l2sel, psel;
235 unsigned int pmc_inuse = 0; 231 unsigned int pmc_inuse = 0;
236 int i; 232 int i;
diff --git a/arch/powerpc/kernel/ppc970-pmu.c b/arch/powerpc/kernel/ppc970-pmu.c
index 479574413a93..8eff48e20dba 100644
--- a/arch/powerpc/kernel/ppc970-pmu.c
+++ b/arch/powerpc/kernel/ppc970-pmu.c
@@ -84,10 +84,6 @@ static short mmcr1_adder_bits[8] = {
84}; 84};
85 85
86/* 86/*
87 * Bits in MMCRA
88 */
89
90/*
91 * Layout of constraint bits: 87 * Layout of constraint bits:
92 * 6666555555555544444444443333333333222222222211111111110000000000 88 * 6666555555555544444444443333333333222222222211111111110000000000
93 * 3210987654321098765432109876543210987654321098765432109876543210 89 * 3210987654321098765432109876543210987654321098765432109876543210
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 2ec1eaed19ca..c930ac38e59f 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1172,7 +1172,7 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
1172 unsigned long base = mm->brk; 1172 unsigned long base = mm->brk;
1173 unsigned long ret; 1173 unsigned long ret;
1174 1174
1175#ifdef CONFIG_PPC64 1175#ifdef CONFIG_PPC_STD_MMU_64
1176 /* 1176 /*
1177 * If we are using 1TB segments and we are allowed to randomise 1177 * If we are using 1TB segments and we are allowed to randomise
1178 * the heap, we can put it above 1TB so it is backed by a 1TB 1178 * the heap, we can put it above 1TB so it is backed by a 1TB
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 4271f7a655a3..845c72ab7357 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -660,6 +660,7 @@ late_initcall(check_cache_coherency);
660 660
661#ifdef CONFIG_DEBUG_FS 661#ifdef CONFIG_DEBUG_FS
662struct dentry *powerpc_debugfs_root; 662struct dentry *powerpc_debugfs_root;
663EXPORT_SYMBOL(powerpc_debugfs_root);
663 664
664static int powerpc_debugfs_init(void) 665static int powerpc_debugfs_init(void)
665{ 666{
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 797ea95aae2e..04f638d82fb3 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -57,7 +57,6 @@
57#include <asm/cache.h> 57#include <asm/cache.h>
58#include <asm/page.h> 58#include <asm/page.h>
59#include <asm/mmu.h> 59#include <asm/mmu.h>
60#include <asm/mmu-hash64.h>
61#include <asm/firmware.h> 60#include <asm/firmware.h>
62#include <asm/xmon.h> 61#include <asm/xmon.h>
63#include <asm/udbg.h> 62#include <asm/udbg.h>
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 92dc844299b6..36707dec94d7 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -54,6 +54,7 @@
54#include <linux/irq.h> 54#include <linux/irq.h>
55#include <linux/delay.h> 55#include <linux/delay.h>
56#include <linux/perf_event.h> 56#include <linux/perf_event.h>
57#include <asm/trace.h>
57 58
58#include <asm/io.h> 59#include <asm/io.h>
59#include <asm/processor.h> 60#include <asm/processor.h>
@@ -571,6 +572,8 @@ void timer_interrupt(struct pt_regs * regs)
571 struct clock_event_device *evt = &decrementer->event; 572 struct clock_event_device *evt = &decrementer->event;
572 u64 now; 573 u64 now;
573 574
575 trace_timer_interrupt_entry(regs);
576
574 /* Ensure a positive value is written to the decrementer, or else 577 /* Ensure a positive value is written to the decrementer, or else
575 * some CPUs will continuue to take decrementer exceptions */ 578 * some CPUs will continuue to take decrementer exceptions */
576 set_dec(DECREMENTER_MAX); 579 set_dec(DECREMENTER_MAX);
@@ -590,6 +593,7 @@ void timer_interrupt(struct pt_regs * regs)
590 now = decrementer->next_tb - now; 593 now = decrementer->next_tb - now;
591 if (now <= DECREMENTER_MAX) 594 if (now <= DECREMENTER_MAX)
592 set_dec((int)now); 595 set_dec((int)now);
596 trace_timer_interrupt_exit(regs);
593 return; 597 return;
594 } 598 }
595 old_regs = set_irq_regs(regs); 599 old_regs = set_irq_regs(regs);
@@ -620,6 +624,8 @@ void timer_interrupt(struct pt_regs * regs)
620 624
621 irq_exit(); 625 irq_exit();
622 set_irq_regs(old_regs); 626 set_irq_regs(old_regs);
627
628 trace_timer_interrupt_exit(regs);
623} 629}
624 630
625void wakeup_decrementer(void) 631void wakeup_decrementer(void)
@@ -777,7 +783,7 @@ int update_persistent_clock(struct timespec now)
777 return ppc_md.set_rtc_time(&tm); 783 return ppc_md.set_rtc_time(&tm);
778} 784}
779 785
780void read_persistent_clock(struct timespec *ts) 786static void __read_persistent_clock(struct timespec *ts)
781{ 787{
782 struct rtc_time tm; 788 struct rtc_time tm;
783 static int first = 1; 789 static int first = 1;
@@ -800,10 +806,23 @@ void read_persistent_clock(struct timespec *ts)
800 return; 806 return;
801 } 807 }
802 ppc_md.get_rtc_time(&tm); 808 ppc_md.get_rtc_time(&tm);
809
803 ts->tv_sec = mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, 810 ts->tv_sec = mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
804 tm.tm_hour, tm.tm_min, tm.tm_sec); 811 tm.tm_hour, tm.tm_min, tm.tm_sec);
805} 812}
806 813
814void read_persistent_clock(struct timespec *ts)
815{
816 __read_persistent_clock(ts);
817
818 /* Sanitize it in case real time clock is set below EPOCH */
819 if (ts->tv_sec < 0) {
820 ts->tv_sec = 0;
821 ts->tv_nsec = 0;
822 }
823
824}
825
807/* clocksource code */ 826/* clocksource code */
808static cycle_t rtc_read(struct clocksource *cs) 827static cycle_t rtc_read(struct clocksource *cs)
809{ 828{
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 6f0ae1a9bfae..9d1f9354d6ca 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -759,7 +759,7 @@ static int emulate_instruction(struct pt_regs *regs)
759 759
760 /* Emulate the mfspr rD, PVR. */ 760 /* Emulate the mfspr rD, PVR. */
761 if ((instword & PPC_INST_MFSPR_PVR_MASK) == PPC_INST_MFSPR_PVR) { 761 if ((instword & PPC_INST_MFSPR_PVR_MASK) == PPC_INST_MFSPR_PVR) {
762 PPC_WARN_EMULATED(mfpvr); 762 PPC_WARN_EMULATED(mfpvr, regs);
763 rd = (instword >> 21) & 0x1f; 763 rd = (instword >> 21) & 0x1f;
764 regs->gpr[rd] = mfspr(SPRN_PVR); 764 regs->gpr[rd] = mfspr(SPRN_PVR);
765 return 0; 765 return 0;
@@ -767,7 +767,7 @@ static int emulate_instruction(struct pt_regs *regs)
767 767
768 /* Emulating the dcba insn is just a no-op. */ 768 /* Emulating the dcba insn is just a no-op. */
769 if ((instword & PPC_INST_DCBA_MASK) == PPC_INST_DCBA) { 769 if ((instword & PPC_INST_DCBA_MASK) == PPC_INST_DCBA) {
770 PPC_WARN_EMULATED(dcba); 770 PPC_WARN_EMULATED(dcba, regs);
771 return 0; 771 return 0;
772 } 772 }
773 773
@@ -776,7 +776,7 @@ static int emulate_instruction(struct pt_regs *regs)
776 int shift = (instword >> 21) & 0x1c; 776 int shift = (instword >> 21) & 0x1c;
777 unsigned long msk = 0xf0000000UL >> shift; 777 unsigned long msk = 0xf0000000UL >> shift;
778 778
779 PPC_WARN_EMULATED(mcrxr); 779 PPC_WARN_EMULATED(mcrxr, regs);
780 regs->ccr = (regs->ccr & ~msk) | ((regs->xer >> shift) & msk); 780 regs->ccr = (regs->ccr & ~msk) | ((regs->xer >> shift) & msk);
781 regs->xer &= ~0xf0000000UL; 781 regs->xer &= ~0xf0000000UL;
782 return 0; 782 return 0;
@@ -784,19 +784,19 @@ static int emulate_instruction(struct pt_regs *regs)
784 784
785 /* Emulate load/store string insn. */ 785 /* Emulate load/store string insn. */
786 if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING) { 786 if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING) {
787 PPC_WARN_EMULATED(string); 787 PPC_WARN_EMULATED(string, regs);
788 return emulate_string_inst(regs, instword); 788 return emulate_string_inst(regs, instword);
789 } 789 }
790 790
791 /* Emulate the popcntb (Population Count Bytes) instruction. */ 791 /* Emulate the popcntb (Population Count Bytes) instruction. */
792 if ((instword & PPC_INST_POPCNTB_MASK) == PPC_INST_POPCNTB) { 792 if ((instword & PPC_INST_POPCNTB_MASK) == PPC_INST_POPCNTB) {
793 PPC_WARN_EMULATED(popcntb); 793 PPC_WARN_EMULATED(popcntb, regs);
794 return emulate_popcntb_inst(regs, instword); 794 return emulate_popcntb_inst(regs, instword);
795 } 795 }
796 796
797 /* Emulate isel (Integer Select) instruction */ 797 /* Emulate isel (Integer Select) instruction */
798 if ((instword & PPC_INST_ISEL_MASK) == PPC_INST_ISEL) { 798 if ((instword & PPC_INST_ISEL_MASK) == PPC_INST_ISEL) {
799 PPC_WARN_EMULATED(isel); 799 PPC_WARN_EMULATED(isel, regs);
800 return emulate_isel(regs, instword); 800 return emulate_isel(regs, instword);
801 } 801 }
802 802
@@ -995,7 +995,7 @@ void SoftwareEmulation(struct pt_regs *regs)
995#ifdef CONFIG_MATH_EMULATION 995#ifdef CONFIG_MATH_EMULATION
996 errcode = do_mathemu(regs); 996 errcode = do_mathemu(regs);
997 if (errcode >= 0) 997 if (errcode >= 0)
998 PPC_WARN_EMULATED(math); 998 PPC_WARN_EMULATED(math, regs);
999 999
1000 switch (errcode) { 1000 switch (errcode) {
1001 case 0: 1001 case 0:
@@ -1018,7 +1018,7 @@ void SoftwareEmulation(struct pt_regs *regs)
1018#elif defined(CONFIG_8XX_MINIMAL_FPEMU) 1018#elif defined(CONFIG_8XX_MINIMAL_FPEMU)
1019 errcode = Soft_emulate_8xx(regs); 1019 errcode = Soft_emulate_8xx(regs);
1020 if (errcode >= 0) 1020 if (errcode >= 0)
1021 PPC_WARN_EMULATED(8xx); 1021 PPC_WARN_EMULATED(8xx, regs);
1022 1022
1023 switch (errcode) { 1023 switch (errcode) {
1024 case 0: 1024 case 0:
@@ -1129,7 +1129,7 @@ void altivec_assist_exception(struct pt_regs *regs)
1129 1129
1130 flush_altivec_to_thread(current); 1130 flush_altivec_to_thread(current);
1131 1131
1132 PPC_WARN_EMULATED(altivec); 1132 PPC_WARN_EMULATED(altivec, regs);
1133 err = emulate_altivec(regs); 1133 err = emulate_altivec(regs);
1134 if (err == 0) { 1134 if (err == 0) {
1135 regs->nip += 4; /* skip emulated instruction */ 1135 regs->nip += 4; /* skip emulated instruction */
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index 94e2df3cae07..137dc22afa42 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -50,6 +50,9 @@
50/* Max supported size for symbol names */ 50/* Max supported size for symbol names */
51#define MAX_SYMNAME 64 51#define MAX_SYMNAME 64
52 52
53/* The alignment of the vDSO */
54#define VDSO_ALIGNMENT (1 << 16)
55
53extern char vdso32_start, vdso32_end; 56extern char vdso32_start, vdso32_end;
54static void *vdso32_kbase = &vdso32_start; 57static void *vdso32_kbase = &vdso32_start;
55static unsigned int vdso32_pages; 58static unsigned int vdso32_pages;
@@ -231,15 +234,21 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
231 * pick a base address for the vDSO in process space. We try to put it 234 * pick a base address for the vDSO in process space. We try to put it
232 * at vdso_base which is the "natural" base for it, but we might fail 235 * at vdso_base which is the "natural" base for it, but we might fail
233 * and end up putting it elsewhere. 236 * and end up putting it elsewhere.
237 * Add enough to the size so that the result can be aligned.
234 */ 238 */
235 down_write(&mm->mmap_sem); 239 down_write(&mm->mmap_sem);
236 vdso_base = get_unmapped_area(NULL, vdso_base, 240 vdso_base = get_unmapped_area(NULL, vdso_base,
237 vdso_pages << PAGE_SHIFT, 0, 0); 241 (vdso_pages << PAGE_SHIFT) +
242 ((VDSO_ALIGNMENT - 1) & PAGE_MASK),
243 0, 0);
238 if (IS_ERR_VALUE(vdso_base)) { 244 if (IS_ERR_VALUE(vdso_base)) {
239 rc = vdso_base; 245 rc = vdso_base;
240 goto fail_mmapsem; 246 goto fail_mmapsem;
241 } 247 }
242 248
249 /* Add required alignment. */
250 vdso_base = ALIGN(vdso_base, VDSO_ALIGNMENT);
251
243 /* 252 /*
244 * Put vDSO base into mm struct. We need to do this before calling 253 * Put vDSO base into mm struct. We need to do this before calling
245 * install_special_mapping or the perf counter mmap tracking code 254 * install_special_mapping or the perf counter mmap tracking code
diff --git a/arch/powerpc/kernel/vdso32/vdso32.lds.S b/arch/powerpc/kernel/vdso32/vdso32.lds.S
index 904ef1360dd7..0546bcd49cd0 100644
--- a/arch/powerpc/kernel/vdso32/vdso32.lds.S
+++ b/arch/powerpc/kernel/vdso32/vdso32.lds.S
@@ -25,7 +25,7 @@ SECTIONS
25 . = ALIGN(16); 25 . = ALIGN(16);
26 .text : { 26 .text : {
27 *(.text .stub .text.* .gnu.linkonce.t.* __ftr_alt_*) 27 *(.text .stub .text.* .gnu.linkonce.t.* __ftr_alt_*)
28 } 28 } :text
29 PROVIDE(__etext = .); 29 PROVIDE(__etext = .);
30 PROVIDE(_etext = .); 30 PROVIDE(_etext = .);
31 PROVIDE(etext = .); 31 PROVIDE(etext = .);
@@ -56,7 +56,7 @@ SECTIONS
56 .fixup : { *(.fixup) } 56 .fixup : { *(.fixup) }
57 57
58 .dynamic : { *(.dynamic) } :text :dynamic 58 .dynamic : { *(.dynamic) } :text :dynamic
59 .got : { *(.got) } 59 .got : { *(.got) } :text
60 .plt : { *(.plt) } 60 .plt : { *(.plt) }
61 61
62 _end = .; 62 _end = .;