aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/asm-offsets.c1
-rw-r--r--arch/powerpc/kernel/dbell.c2
-rw-r--r--arch/powerpc/kernel/dma-iommu.c9
-rw-r--r--arch/powerpc/kernel/entry_64.S23
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S3
-rw-r--r--arch/powerpc/kernel/hw_breakpoint.c2
-rw-r--r--arch/powerpc/kernel/idle_power7.S2
-rw-r--r--arch/powerpc/kernel/kgdb.c27
-rw-r--r--arch/powerpc/kernel/process.c12
-rw-r--r--arch/powerpc/kernel/smp.c11
-rw-r--r--arch/powerpc/kernel/syscalls.c8
-rw-r--r--arch/powerpc/kernel/sysfs.c10
-rw-r--r--arch/powerpc/kernel/time.c9
-rw-r--r--arch/powerpc/kernel/traps.c3
14 files changed, 89 insertions, 33 deletions
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 85b05c463fae..e8995727b1c1 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -76,6 +76,7 @@ int main(void)
76 DEFINE(SIGSEGV, SIGSEGV); 76 DEFINE(SIGSEGV, SIGSEGV);
77 DEFINE(NMI_MASK, NMI_MASK); 77 DEFINE(NMI_MASK, NMI_MASK);
78 DEFINE(THREAD_DSCR, offsetof(struct thread_struct, dscr)); 78 DEFINE(THREAD_DSCR, offsetof(struct thread_struct, dscr));
79 DEFINE(THREAD_DSCR_INHERIT, offsetof(struct thread_struct, dscr_inherit));
79#else 80#else
80 DEFINE(THREAD_INFO, offsetof(struct task_struct, stack)); 81 DEFINE(THREAD_INFO, offsetof(struct task_struct, stack));
81#endif /* CONFIG_PPC64 */ 82#endif /* CONFIG_PPC64 */
diff --git a/arch/powerpc/kernel/dbell.c b/arch/powerpc/kernel/dbell.c
index 5b25c8060fd6..a892680668d8 100644
--- a/arch/powerpc/kernel/dbell.c
+++ b/arch/powerpc/kernel/dbell.c
@@ -28,6 +28,8 @@ void doorbell_setup_this_cpu(void)
28 28
29void doorbell_cause_ipi(int cpu, unsigned long data) 29void doorbell_cause_ipi(int cpu, unsigned long data)
30{ 30{
31 /* Order previous accesses vs. msgsnd, which is treated as a store */
32 mb();
31 ppc_msgsnd(PPC_DBELL, 0, data); 33 ppc_msgsnd(PPC_DBELL, 0, data);
32} 34}
33 35
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c
index 2d7bb8ced136..e4897523de41 100644
--- a/arch/powerpc/kernel/dma-iommu.c
+++ b/arch/powerpc/kernel/dma-iommu.c
@@ -83,11 +83,10 @@ static int dma_iommu_dma_supported(struct device *dev, u64 mask)
83 return 0; 83 return 0;
84 } 84 }
85 85
86 if ((tbl->it_offset + tbl->it_size) > (mask >> IOMMU_PAGE_SHIFT)) { 86 if (tbl->it_offset > (mask >> IOMMU_PAGE_SHIFT)) {
87 dev_info(dev, "Warning: IOMMU window too big for device mask\n"); 87 dev_info(dev, "Warning: IOMMU offset too big for device mask\n");
88 dev_info(dev, "mask: 0x%08llx, table end: 0x%08lx\n", 88 dev_info(dev, "mask: 0x%08llx, table offset: 0x%08lx\n",
89 mask, (tbl->it_offset + tbl->it_size) << 89 mask, tbl->it_offset << IOMMU_PAGE_SHIFT);
90 IOMMU_PAGE_SHIFT);
91 return 0; 90 return 0;
92 } else 91 } else
93 return 1; 92 return 1;
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 4b01a25e29ef..b40e0b4815b3 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -370,6 +370,12 @@ _GLOBAL(ret_from_fork)
370 li r3,0 370 li r3,0
371 b syscall_exit 371 b syscall_exit
372 372
373 .section ".toc","aw"
374DSCR_DEFAULT:
375 .tc dscr_default[TC],dscr_default
376
377 .section ".text"
378
373/* 379/*
374 * This routine switches between two different tasks. The process 380 * This routine switches between two different tasks. The process
375 * state of one is saved on its kernel stack. Then the state 381 * state of one is saved on its kernel stack. Then the state
@@ -509,9 +515,6 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
509 mr r1,r8 /* start using new stack pointer */ 515 mr r1,r8 /* start using new stack pointer */
510 std r7,PACAKSAVE(r13) 516 std r7,PACAKSAVE(r13)
511 517
512 ld r6,_CCR(r1)
513 mtcrf 0xFF,r6
514
515#ifdef CONFIG_ALTIVEC 518#ifdef CONFIG_ALTIVEC
516BEGIN_FTR_SECTION 519BEGIN_FTR_SECTION
517 ld r0,THREAD_VRSAVE(r4) 520 ld r0,THREAD_VRSAVE(r4)
@@ -520,14 +523,22 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
520#endif /* CONFIG_ALTIVEC */ 523#endif /* CONFIG_ALTIVEC */
521#ifdef CONFIG_PPC64 524#ifdef CONFIG_PPC64
522BEGIN_FTR_SECTION 525BEGIN_FTR_SECTION
526 lwz r6,THREAD_DSCR_INHERIT(r4)
527 ld r7,DSCR_DEFAULT@toc(2)
523 ld r0,THREAD_DSCR(r4) 528 ld r0,THREAD_DSCR(r4)
524 cmpd r0,r25 529 cmpwi r6,0
525 beq 1f 530 bne 1f
531 ld r0,0(r7)
5321: cmpd r0,r25
533 beq 2f
526 mtspr SPRN_DSCR,r0 534 mtspr SPRN_DSCR,r0
5271: 5352:
528END_FTR_SECTION_IFSET(CPU_FTR_DSCR) 536END_FTR_SECTION_IFSET(CPU_FTR_DSCR)
529#endif 537#endif
530 538
539 ld r6,_CCR(r1)
540 mtcrf 0xFF,r6
541
531 /* r3-r13 are destroyed -- Cort */ 542 /* r3-r13 are destroyed -- Cort */
532 REST_8GPRS(14, r1) 543 REST_8GPRS(14, r1)
533 REST_10GPRS(22, r1) 544 REST_10GPRS(22, r1)
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index e894515e77bb..39aa97d3ff88 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -186,7 +186,7 @@ hardware_interrupt_hv:
186 KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x800) 186 KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x800)
187 187
188 MASKABLE_EXCEPTION_PSERIES(0x900, 0x900, decrementer) 188 MASKABLE_EXCEPTION_PSERIES(0x900, 0x900, decrementer)
189 MASKABLE_EXCEPTION_HV(0x980, 0x982, decrementer) 189 STD_EXCEPTION_HV(0x980, 0x982, hdecrementer)
190 190
191 STD_EXCEPTION_PSERIES(0xa00, 0xa00, trap_0a) 191 STD_EXCEPTION_PSERIES(0xa00, 0xa00, trap_0a)
192 KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xa00) 192 KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xa00)
@@ -486,6 +486,7 @@ machine_check_common:
486 486
487 STD_EXCEPTION_COMMON_ASYNC(0x500, hardware_interrupt, do_IRQ) 487 STD_EXCEPTION_COMMON_ASYNC(0x500, hardware_interrupt, do_IRQ)
488 STD_EXCEPTION_COMMON_ASYNC(0x900, decrementer, .timer_interrupt) 488 STD_EXCEPTION_COMMON_ASYNC(0x900, decrementer, .timer_interrupt)
489 STD_EXCEPTION_COMMON(0x980, hdecrementer, .hdec_interrupt)
489 STD_EXCEPTION_COMMON(0xa00, trap_0a, .unknown_exception) 490 STD_EXCEPTION_COMMON(0xa00, trap_0a, .unknown_exception)
490 STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception) 491 STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)
491 STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception) 492 STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception)
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c
index f3a82dde61db..956a4c496de9 100644
--- a/arch/powerpc/kernel/hw_breakpoint.c
+++ b/arch/powerpc/kernel/hw_breakpoint.c
@@ -253,7 +253,7 @@ int __kprobes hw_breakpoint_handler(struct die_args *args)
253 253
254 /* Do not emulate user-space instructions, instead single-step them */ 254 /* Do not emulate user-space instructions, instead single-step them */
255 if (user_mode(regs)) { 255 if (user_mode(regs)) {
256 bp->ctx->task->thread.last_hit_ubp = bp; 256 current->thread.last_hit_ubp = bp;
257 regs->msr |= MSR_SE; 257 regs->msr |= MSR_SE;
258 goto out; 258 goto out;
259 } 259 }
diff --git a/arch/powerpc/kernel/idle_power7.S b/arch/powerpc/kernel/idle_power7.S
index 7140d838339e..e11863f4e595 100644
--- a/arch/powerpc/kernel/idle_power7.S
+++ b/arch/powerpc/kernel/idle_power7.S
@@ -28,7 +28,9 @@ _GLOBAL(power7_idle)
28 lwz r4,ADDROFF(powersave_nap)(r3) 28 lwz r4,ADDROFF(powersave_nap)(r3)
29 cmpwi 0,r4,0 29 cmpwi 0,r4,0
30 beqlr 30 beqlr
31 /* fall through */
31 32
33_GLOBAL(power7_nap)
32 /* NAP is a state loss, we create a regs frame on the 34 /* NAP is a state loss, we create a regs frame on the
33 * stack, fill it up with the state we care about and 35 * stack, fill it up with the state we care about and
34 * stick a pointer to it in PACAR1. We really only 36 * stick a pointer to it in PACAR1. We really only
diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c
index 782bd0a3c2f0..c470a40b29f5 100644
--- a/arch/powerpc/kernel/kgdb.c
+++ b/arch/powerpc/kernel/kgdb.c
@@ -25,6 +25,7 @@
25#include <asm/processor.h> 25#include <asm/processor.h>
26#include <asm/machdep.h> 26#include <asm/machdep.h>
27#include <asm/debug.h> 27#include <asm/debug.h>
28#include <linux/slab.h>
28 29
29/* 30/*
30 * This table contains the mapping between PowerPC hardware trap types, and 31 * This table contains the mapping between PowerPC hardware trap types, and
@@ -101,6 +102,21 @@ static int computeSignal(unsigned int tt)
101 return SIGHUP; /* default for things we don't know about */ 102 return SIGHUP; /* default for things we don't know about */
102} 103}
103 104
105/**
106 *
107 * kgdb_skipexception - Bail out of KGDB when we've been triggered.
108 * @exception: Exception vector number
109 * @regs: Current &struct pt_regs.
110 *
111 * On some architectures we need to skip a breakpoint exception when
112 * it occurs after a breakpoint has been removed.
113 *
114 */
115int kgdb_skipexception(int exception, struct pt_regs *regs)
116{
117 return kgdb_isremovedbreak(regs->nip);
118}
119
104static int kgdb_call_nmi_hook(struct pt_regs *regs) 120static int kgdb_call_nmi_hook(struct pt_regs *regs)
105{ 121{
106 kgdb_nmicallback(raw_smp_processor_id(), regs); 122 kgdb_nmicallback(raw_smp_processor_id(), regs);
@@ -138,6 +154,8 @@ static int kgdb_handle_breakpoint(struct pt_regs *regs)
138static int kgdb_singlestep(struct pt_regs *regs) 154static int kgdb_singlestep(struct pt_regs *regs)
139{ 155{
140 struct thread_info *thread_info, *exception_thread_info; 156 struct thread_info *thread_info, *exception_thread_info;
157 struct thread_info *backup_current_thread_info = \
158 (struct thread_info *)kmalloc(sizeof(struct thread_info), GFP_KERNEL);
141 159
142 if (user_mode(regs)) 160 if (user_mode(regs))
143 return 0; 161 return 0;
@@ -155,13 +173,17 @@ static int kgdb_singlestep(struct pt_regs *regs)
155 thread_info = (struct thread_info *)(regs->gpr[1] & ~(THREAD_SIZE-1)); 173 thread_info = (struct thread_info *)(regs->gpr[1] & ~(THREAD_SIZE-1));
156 exception_thread_info = current_thread_info(); 174 exception_thread_info = current_thread_info();
157 175
158 if (thread_info != exception_thread_info) 176 if (thread_info != exception_thread_info) {
177 /* Save the original current_thread_info. */
178 memcpy(backup_current_thread_info, exception_thread_info, sizeof *thread_info);
159 memcpy(exception_thread_info, thread_info, sizeof *thread_info); 179 memcpy(exception_thread_info, thread_info, sizeof *thread_info);
180 }
160 181
161 kgdb_handle_exception(0, SIGTRAP, 0, regs); 182 kgdb_handle_exception(0, SIGTRAP, 0, regs);
162 183
163 if (thread_info != exception_thread_info) 184 if (thread_info != exception_thread_info)
164 memcpy(thread_info, exception_thread_info, sizeof *thread_info); 185 /* Restore current_thread_info lastly. */
186 memcpy(exception_thread_info, backup_current_thread_info, sizeof *thread_info);
165 187
166 return 1; 188 return 1;
167} 189}
@@ -410,7 +432,6 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code,
410#else 432#else
411 linux_regs->msr |= MSR_SE; 433 linux_regs->msr |= MSR_SE;
412#endif 434#endif
413 kgdb_single_step = 1;
414 atomic_set(&kgdb_cpu_doing_single_step, 435 atomic_set(&kgdb_cpu_doing_single_step,
415 raw_smp_processor_id()); 436 raw_smp_processor_id());
416 } 437 }
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 710f400476de..1a1f2ddfb581 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -802,16 +802,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
802#endif /* CONFIG_PPC_STD_MMU_64 */ 802#endif /* CONFIG_PPC_STD_MMU_64 */
803#ifdef CONFIG_PPC64 803#ifdef CONFIG_PPC64
804 if (cpu_has_feature(CPU_FTR_DSCR)) { 804 if (cpu_has_feature(CPU_FTR_DSCR)) {
805 if (current->thread.dscr_inherit) { 805 p->thread.dscr_inherit = current->thread.dscr_inherit;
806 p->thread.dscr_inherit = 1; 806 p->thread.dscr = current->thread.dscr;
807 p->thread.dscr = current->thread.dscr;
808 } else if (0 != dscr_default) {
809 p->thread.dscr_inherit = 1;
810 p->thread.dscr = dscr_default;
811 } else {
812 p->thread.dscr_inherit = 0;
813 p->thread.dscr = 0;
814 }
815 } 807 }
816#endif 808#endif
817 809
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 0321007086f7..8d4214afc21d 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -198,8 +198,15 @@ void smp_muxed_ipi_message_pass(int cpu, int msg)
198 struct cpu_messages *info = &per_cpu(ipi_message, cpu); 198 struct cpu_messages *info = &per_cpu(ipi_message, cpu);
199 char *message = (char *)&info->messages; 199 char *message = (char *)&info->messages;
200 200
201 /*
202 * Order previous accesses before accesses in the IPI handler.
203 */
204 smp_mb();
201 message[msg] = 1; 205 message[msg] = 1;
202 mb(); 206 /*
207 * cause_ipi functions are required to include a full barrier
208 * before doing whatever causes the IPI.
209 */
203 smp_ops->cause_ipi(cpu, info->data); 210 smp_ops->cause_ipi(cpu, info->data);
204} 211}
205 212
@@ -211,7 +218,7 @@ irqreturn_t smp_ipi_demux(void)
211 mb(); /* order any irq clear */ 218 mb(); /* order any irq clear */
212 219
213 do { 220 do {
214 all = xchg_local(&info->messages, 0); 221 all = xchg(&info->messages, 0);
215 222
216#ifdef __BIG_ENDIAN 223#ifdef __BIG_ENDIAN
217 if (all & (1 << (24 - 8 * PPC_MSG_CALL_FUNCTION))) 224 if (all & (1 << (24 - 8 * PPC_MSG_CALL_FUNCTION)))
diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c
index f2496f2faecc..4e3cc47f26b9 100644
--- a/arch/powerpc/kernel/syscalls.c
+++ b/arch/powerpc/kernel/syscalls.c
@@ -107,11 +107,11 @@ long ppc64_personality(unsigned long personality)
107 long ret; 107 long ret;
108 108
109 if (personality(current->personality) == PER_LINUX32 109 if (personality(current->personality) == PER_LINUX32
110 && personality == PER_LINUX) 110 && personality(personality) == PER_LINUX)
111 personality = PER_LINUX32; 111 personality = (personality & ~PER_MASK) | PER_LINUX32;
112 ret = sys_personality(personality); 112 ret = sys_personality(personality);
113 if (ret == PER_LINUX32) 113 if (personality(ret) == PER_LINUX32)
114 ret = PER_LINUX; 114 ret = (ret & ~PER_MASK) | PER_LINUX;
115 return ret; 115 return ret;
116} 116}
117#endif 117#endif
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index 3529446c2abd..8302af649219 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -194,6 +194,14 @@ static ssize_t show_dscr_default(struct device *dev,
194 return sprintf(buf, "%lx\n", dscr_default); 194 return sprintf(buf, "%lx\n", dscr_default);
195} 195}
196 196
197static void update_dscr(void *dummy)
198{
199 if (!current->thread.dscr_inherit) {
200 current->thread.dscr = dscr_default;
201 mtspr(SPRN_DSCR, dscr_default);
202 }
203}
204
197static ssize_t __used store_dscr_default(struct device *dev, 205static ssize_t __used store_dscr_default(struct device *dev,
198 struct device_attribute *attr, const char *buf, 206 struct device_attribute *attr, const char *buf,
199 size_t count) 207 size_t count)
@@ -206,6 +214,8 @@ static ssize_t __used store_dscr_default(struct device *dev,
206 return -EINVAL; 214 return -EINVAL;
207 dscr_default = val; 215 dscr_default = val;
208 216
217 on_each_cpu(update_dscr, NULL, 1);
218
209 return count; 219 return count;
210} 220}
211 221
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index be171ee73bf8..e49e93191b69 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -535,6 +535,15 @@ void timer_interrupt(struct pt_regs * regs)
535 trace_timer_interrupt_exit(regs); 535 trace_timer_interrupt_exit(regs);
536} 536}
537 537
538/*
539 * Hypervisor decrementer interrupts shouldn't occur but are sometimes
540 * left pending on exit from a KVM guest. We don't need to do anything
541 * to clear them, as they are edge-triggered.
542 */
543void hdec_interrupt(struct pt_regs *regs)
544{
545}
546
538#ifdef CONFIG_SUSPEND 547#ifdef CONFIG_SUSPEND
539static void generic_suspend_disable_irqs(void) 548static void generic_suspend_disable_irqs(void)
540{ 549{
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 158972341a2d..ae0843fa7a61 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -972,8 +972,9 @@ static int emulate_instruction(struct pt_regs *regs)
972 cpu_has_feature(CPU_FTR_DSCR)) { 972 cpu_has_feature(CPU_FTR_DSCR)) {
973 PPC_WARN_EMULATED(mtdscr, regs); 973 PPC_WARN_EMULATED(mtdscr, regs);
974 rd = (instword >> 21) & 0x1f; 974 rd = (instword >> 21) & 0x1f;
975 mtspr(SPRN_DSCR, regs->gpr[rd]); 975 current->thread.dscr = regs->gpr[rd];
976 current->thread.dscr_inherit = 1; 976 current->thread.dscr_inherit = 1;
977 mtspr(SPRN_DSCR, current->thread.dscr);
977 return 0; 978 return 0;
978 } 979 }
979#endif 980#endif