Commit b7f3a209e9b09b3110ea084836c75f2cd26b29f2
Exists in
master
and in
7 other branches
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6: sparc: Support show_unhandled_signals. sparc: use __ratelimit sunxvr500: Additional PCI id for sunxvr500 driver sparc: use asm-generic/scatterlist.h sparc64: If 'slot-names' property exist, create sysfs PCI slot information. sparc: remove trailing space in messages sparc: remove redundant return statements
Showing 23 changed files Side-by-side Diff
- arch/sparc/include/asm/scatterlist.h
- arch/sparc/kernel/devices.c
- arch/sparc/kernel/leon_kernel.c
- arch/sparc/kernel/leon_smp.c
- arch/sparc/kernel/pci.c
- arch/sparc/kernel/pcic.c
- arch/sparc/kernel/setup_32.c
- arch/sparc/kernel/sun4d_smp.c
- arch/sparc/kernel/unaligned_64.c
- arch/sparc/mm/fault_32.c
- arch/sparc/mm/fault_64.c
- arch/sparc/prom/console_32.c
- arch/sparc/prom/console_64.c
- arch/sparc/prom/devmap.c
- arch/sparc/prom/devops_32.c
- arch/sparc/prom/init_32.c
- arch/sparc/prom/palloc.c
- arch/sparc/prom/ranges.c
- arch/sparc/prom/segment.c
- arch/sparc/prom/tree_32.c
- arch/sparc/prom/tree_64.c
- drivers/video/sunxvr500.c
- kernel/sysctl.c
arch/sparc/include/asm/scatterlist.h
1 | 1 | #ifndef _SPARC_SCATTERLIST_H |
2 | 2 | #define _SPARC_SCATTERLIST_H |
3 | 3 | |
4 | -#include <asm/page.h> | |
5 | -#include <asm/types.h> | |
6 | - | |
7 | -struct scatterlist { | |
8 | -#ifdef CONFIG_DEBUG_SG | |
9 | - unsigned long sg_magic; | |
10 | -#endif | |
11 | - unsigned long page_link; | |
12 | - unsigned int offset; | |
13 | - | |
14 | - unsigned int length; | |
15 | - | |
16 | - dma_addr_t dma_address; | |
17 | - __u32 dma_length; | |
18 | -}; | |
19 | - | |
20 | -#define sg_dma_address(sg) ((sg)->dma_address) | |
21 | 4 | #define sg_dma_len(sg) ((sg)->dma_length) |
22 | 5 | |
23 | -#define ISA_DMA_THRESHOLD (~0UL) | |
24 | - | |
25 | -#define ARCH_HAS_SG_CHAIN | |
6 | +#include <asm-generic/scatterlist.h> | |
26 | 7 | |
27 | 8 | #endif /* !(_SPARC_SCATTERLIST_H) */ |
arch/sparc/kernel/devices.c
arch/sparc/kernel/leon_kernel.c
... | ... | @@ -124,7 +124,7 @@ |
124 | 124 | |
125 | 125 | if (!(LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->config) & |
126 | 126 | (1<<LEON3_GPTIMER_SEPIRQ))) { |
127 | - prom_printf("irq timer not configured with seperate irqs \n"); | |
127 | + prom_printf("irq timer not configured with separate irqs\n"); | |
128 | 128 | BUG(); |
129 | 129 | } |
130 | 130 |
arch/sparc/kernel/leon_smp.c
... | ... | @@ -177,7 +177,7 @@ |
177 | 177 | int nrcpu = leon_smp_nrcpus(); |
178 | 178 | int me = smp_processor_id(); |
179 | 179 | |
180 | - printk(KERN_INFO "%d:(%d:%d) cpus mpirq at 0x%x \n", (unsigned int)me, | |
180 | + printk(KERN_INFO "%d:(%d:%d) cpus mpirq at 0x%x\n", (unsigned int)me, | |
181 | 181 | (unsigned int)nrcpu, (unsigned int)NR_CPUS, |
182 | 182 | (unsigned int)&(leon3_irqctrl_regs->mpstatus)); |
183 | 183 | |
... | ... | @@ -226,7 +226,7 @@ |
226 | 226 | break; |
227 | 227 | udelay(200); |
228 | 228 | } |
229 | - printk(KERN_INFO "Started CPU %d \n", (unsigned int)i); | |
229 | + printk(KERN_INFO "Started CPU %d\n", (unsigned int)i); | |
230 | 230 | |
231 | 231 | if (!(cpu_callin_map[i])) { |
232 | 232 | printk(KERN_ERR "Processor %d is stuck.\n", i); |
arch/sparc/kernel/pci.c
... | ... | @@ -1095,4 +1095,79 @@ |
1095 | 1095 | return 0; |
1096 | 1096 | } |
1097 | 1097 | subsys_initcall(pcibios_init); |
1098 | + | |
1099 | +#ifdef CONFIG_SYSFS | |
1100 | +static void __devinit pci_bus_slot_names(struct device_node *node, | |
1101 | + struct pci_bus *bus) | |
1102 | +{ | |
1103 | + const struct pci_slot_names { | |
1104 | + u32 slot_mask; | |
1105 | + char names[0]; | |
1106 | + } *prop; | |
1107 | + const char *sp; | |
1108 | + int len, i; | |
1109 | + u32 mask; | |
1110 | + | |
1111 | + prop = of_get_property(node, "slot-names", &len); | |
1112 | + if (!prop) | |
1113 | + return; | |
1114 | + | |
1115 | + mask = prop->slot_mask; | |
1116 | + sp = prop->names; | |
1117 | + | |
1118 | + if (ofpci_verbose) | |
1119 | + printk("PCI: Making slots for [%s] mask[0x%02x]\n", | |
1120 | + node->full_name, mask); | |
1121 | + | |
1122 | + i = 0; | |
1123 | + while (mask) { | |
1124 | + struct pci_slot *pci_slot; | |
1125 | + u32 this_bit = 1 << i; | |
1126 | + | |
1127 | + if (!(mask & this_bit)) { | |
1128 | + i++; | |
1129 | + continue; | |
1130 | + } | |
1131 | + | |
1132 | + if (ofpci_verbose) | |
1133 | + printk("PCI: Making slot [%s]\n", sp); | |
1134 | + | |
1135 | + pci_slot = pci_create_slot(bus, i, sp, NULL); | |
1136 | + if (IS_ERR(pci_slot)) | |
1137 | + printk(KERN_ERR "PCI: pci_create_slot returned %ld\n", | |
1138 | + PTR_ERR(pci_slot)); | |
1139 | + | |
1140 | + sp += strlen(sp) + 1; | |
1141 | + mask &= ~this_bit; | |
1142 | + i++; | |
1143 | + } | |
1144 | +} | |
1145 | + | |
1146 | +static int __init of_pci_slot_init(void) | |
1147 | +{ | |
1148 | + struct pci_bus *pbus = NULL; | |
1149 | + | |
1150 | + while ((pbus = pci_find_next_bus(pbus)) != NULL) { | |
1151 | + struct device_node *node; | |
1152 | + | |
1153 | + if (pbus->self) { | |
1154 | + struct dev_archdata *sd = pbus->self->sysdata; | |
1155 | + | |
1156 | + /* PCI->PCI bridge */ | |
1157 | + node = sd->prom_node; | |
1158 | + } else { | |
1159 | + struct pci_pbm_info *pbm = pbus->sysdata; | |
1160 | + | |
1161 | + /* Host PCI controller */ | |
1162 | + node = pbm->op->node; | |
1163 | + } | |
1164 | + | |
1165 | + pci_bus_slot_names(node, pbus); | |
1166 | + } | |
1167 | + | |
1168 | + return 0; | |
1169 | +} | |
1170 | + | |
1171 | +module_init(of_pci_slot_init); | |
1172 | +#endif |
arch/sparc/kernel/pcic.c
arch/sparc/kernel/setup_32.c
arch/sparc/kernel/sun4d_smp.c
... | ... | @@ -194,7 +194,7 @@ |
194 | 194 | smp_penguin_ctable.reg_size = 0; |
195 | 195 | |
196 | 196 | /* whirrr, whirrr, whirrrrrrrrr... */ |
197 | - SMP_PRINTK(("Starting CPU %d at %p \n", i, entry)); | |
197 | + SMP_PRINTK(("Starting CPU %d at %p\n", i, entry)); | |
198 | 198 | local_flush_cache_all(); |
199 | 199 | prom_startcpu(cpu_node, |
200 | 200 | &smp_penguin_ctable, 0, (char *)entry); |
arch/sparc/kernel/unaligned_64.c
... | ... | @@ -21,6 +21,7 @@ |
21 | 21 | #include <linux/smp.h> |
22 | 22 | #include <linux/bitops.h> |
23 | 23 | #include <linux/perf_event.h> |
24 | +#include <linux/ratelimit.h> | |
24 | 25 | #include <asm/fpumacro.h> |
25 | 26 | |
26 | 27 | enum direction { |
27 | 28 | |
... | ... | @@ -274,13 +275,9 @@ |
274 | 275 | |
275 | 276 | static void log_unaligned(struct pt_regs *regs) |
276 | 277 | { |
277 | - static unsigned long count, last_time; | |
278 | + static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 5); | |
278 | 279 | |
279 | - if (time_after(jiffies, last_time + 5 * HZ)) | |
280 | - count = 0; | |
281 | - if (count < 5) { | |
282 | - last_time = jiffies; | |
283 | - count++; | |
280 | + if (__ratelimit(&ratelimit)) { | |
284 | 281 | printk("Kernel unaligned access at TPC[%lx] %pS\n", |
285 | 282 | regs->tpc, (void *) regs->tpc); |
286 | 283 | } |
... | ... | @@ -636,7 +633,6 @@ |
636 | 633 | return; |
637 | 634 | } |
638 | 635 | advance(regs); |
639 | - return; | |
640 | 636 | } |
641 | 637 | |
642 | 638 | void handle_stdfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr) |
... | ... | @@ -685,6 +681,5 @@ |
685 | 681 | return; |
686 | 682 | } |
687 | 683 | advance(regs); |
688 | - return; | |
689 | 684 | } |
arch/sparc/mm/fault_32.c
... | ... | @@ -35,6 +35,8 @@ |
35 | 35 | |
36 | 36 | extern int prom_node_root; |
37 | 37 | |
38 | +int show_unhandled_signals = 1; | |
39 | + | |
38 | 40 | /* At boot time we determine these two values necessary for setting |
39 | 41 | * up the segment maps and page table entries (pte's). |
40 | 42 | */ |
... | ... | @@ -149,6 +151,45 @@ |
149 | 151 | return 0; |
150 | 152 | } |
151 | 153 | |
154 | +static inline void | |
155 | +show_signal_msg(struct pt_regs *regs, int sig, int code, | |
156 | + unsigned long address, struct task_struct *tsk) | |
157 | +{ | |
158 | + if (!unhandled_signal(tsk, sig)) | |
159 | + return; | |
160 | + | |
161 | + if (!printk_ratelimit()) | |
162 | + return; | |
163 | + | |
164 | + printk("%s%s[%d]: segfault at %lx ip %p (rpc %p) sp %p error %x", | |
165 | + task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, | |
166 | + tsk->comm, task_pid_nr(tsk), address, | |
167 | + (void *)regs->pc, (void *)regs->u_regs[UREG_I7], | |
168 | + (void *)regs->u_regs[UREG_FP], code); | |
169 | + | |
170 | + print_vma_addr(KERN_CONT " in ", regs->pc); | |
171 | + | |
172 | + printk(KERN_CONT "\n"); | |
173 | +} | |
174 | + | |
175 | +static void __do_fault_siginfo(int code, int sig, struct pt_regs *regs, | |
176 | + unsigned long addr) | |
177 | +{ | |
178 | + siginfo_t info; | |
179 | + | |
180 | + info.si_signo = sig; | |
181 | + info.si_code = code; | |
182 | + info.si_errno = 0; | |
183 | + info.si_addr = (void __user *) addr; | |
184 | + info.si_trapno = 0; | |
185 | + | |
186 | + if (unlikely(show_unhandled_signals)) | |
187 | + show_signal_msg(regs, sig, info.si_code, | |
188 | + addr, current); | |
189 | + | |
190 | + force_sig_info (sig, &info, current); | |
191 | +} | |
192 | + | |
152 | 193 | extern unsigned long safe_compute_effective_address(struct pt_regs *, |
153 | 194 | unsigned int); |
154 | 195 | |
... | ... | @@ -168,6 +209,14 @@ |
168 | 209 | return safe_compute_effective_address(regs, insn); |
169 | 210 | } |
170 | 211 | |
212 | +static noinline void do_fault_siginfo(int code, int sig, struct pt_regs *regs, | |
213 | + int text_fault) | |
214 | +{ | |
215 | + unsigned long addr = compute_si_addr(regs, text_fault); | |
216 | + | |
217 | + __do_fault_siginfo(code, sig, regs, addr); | |
218 | +} | |
219 | + | |
171 | 220 | asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, |
172 | 221 | unsigned long address) |
173 | 222 | { |
174 | 223 | |
... | ... | @@ -176,9 +225,8 @@ |
176 | 225 | struct mm_struct *mm = tsk->mm; |
177 | 226 | unsigned int fixup; |
178 | 227 | unsigned long g2; |
179 | - siginfo_t info; | |
180 | 228 | int from_user = !(regs->psr & PSR_PS); |
181 | - int fault; | |
229 | + int fault, code; | |
182 | 230 | |
183 | 231 | if(text_fault) |
184 | 232 | address = regs->pc; |
... | ... | @@ -195,7 +243,7 @@ |
195 | 243 | if (!ARCH_SUN4C && address >= TASK_SIZE) |
196 | 244 | goto vmalloc_fault; |
197 | 245 | |
198 | - info.si_code = SEGV_MAPERR; | |
246 | + code = SEGV_MAPERR; | |
199 | 247 | |
200 | 248 | /* |
201 | 249 | * If we're in an interrupt or have no user |
... | ... | @@ -229,7 +277,7 @@ |
229 | 277 | * we can handle it.. |
230 | 278 | */ |
231 | 279 | good_area: |
232 | - info.si_code = SEGV_ACCERR; | |
280 | + code = SEGV_ACCERR; | |
233 | 281 | if(write) { |
234 | 282 | if(!(vma->vm_flags & VM_WRITE)) |
235 | 283 | goto bad_area; |
... | ... | @@ -273,18 +321,8 @@ |
273 | 321 | |
274 | 322 | bad_area_nosemaphore: |
275 | 323 | /* User mode accesses just cause a SIGSEGV */ |
276 | - if(from_user) { | |
277 | -#if 0 | |
278 | - printk("Fault whee %s [%d]: segfaults at %08lx pc=%08lx\n", | |
279 | - tsk->comm, tsk->pid, address, regs->pc); | |
280 | -#endif | |
281 | - info.si_signo = SIGSEGV; | |
282 | - info.si_errno = 0; | |
283 | - /* info.si_code set above to make clear whether | |
284 | - this was a SEGV_MAPERR or SEGV_ACCERR fault. */ | |
285 | - info.si_addr = (void __user *)compute_si_addr(regs, text_fault); | |
286 | - info.si_trapno = 0; | |
287 | - force_sig_info (SIGSEGV, &info, tsk); | |
324 | + if (from_user) { | |
325 | + do_fault_siginfo(code, SIGSEGV, regs, text_fault); | |
288 | 326 | return; |
289 | 327 | } |
290 | 328 | |
... | ... | @@ -335,12 +373,7 @@ |
335 | 373 | |
336 | 374 | do_sigbus: |
337 | 375 | up_read(&mm->mmap_sem); |
338 | - info.si_signo = SIGBUS; | |
339 | - info.si_errno = 0; | |
340 | - info.si_code = BUS_ADRERR; | |
341 | - info.si_addr = (void __user *) compute_si_addr(regs, text_fault); | |
342 | - info.si_trapno = 0; | |
343 | - force_sig_info (SIGBUS, &info, tsk); | |
376 | + do_fault_siginfo(BUS_ADRERR, SIGBUS, regs, text_fault); | |
344 | 377 | if (!from_user) |
345 | 378 | goto no_context; |
346 | 379 | |
347 | 380 | |
348 | 381 | |
... | ... | @@ -466,14 +499,10 @@ |
466 | 499 | struct vm_area_struct *vma; |
467 | 500 | struct task_struct *tsk = current; |
468 | 501 | struct mm_struct *mm = tsk->mm; |
469 | - siginfo_t info; | |
502 | + int code; | |
470 | 503 | |
471 | - info.si_code = SEGV_MAPERR; | |
504 | + code = SEGV_MAPERR; | |
472 | 505 | |
473 | -#if 0 | |
474 | - printk("wf<pid=%d,wr=%d,addr=%08lx>\n", | |
475 | - tsk->pid, write, address); | |
476 | -#endif | |
477 | 506 | down_read(&mm->mmap_sem); |
478 | 507 | vma = find_vma(mm, address); |
479 | 508 | if(!vma) |
... | ... | @@ -485,7 +514,7 @@ |
485 | 514 | if(expand_stack(vma, address)) |
486 | 515 | goto bad_area; |
487 | 516 | good_area: |
488 | - info.si_code = SEGV_ACCERR; | |
517 | + code = SEGV_ACCERR; | |
489 | 518 | if(write) { |
490 | 519 | if(!(vma->vm_flags & VM_WRITE)) |
491 | 520 | goto bad_area; |
492 | 521 | |
... | ... | @@ -502,27 +531,12 @@ |
502 | 531 | return; |
503 | 532 | bad_area: |
504 | 533 | up_read(&mm->mmap_sem); |
505 | -#if 0 | |
506 | - printk("Window whee %s [%d]: segfaults at %08lx\n", | |
507 | - tsk->comm, tsk->pid, address); | |
508 | -#endif | |
509 | - info.si_signo = SIGSEGV; | |
510 | - info.si_errno = 0; | |
511 | - /* info.si_code set above to make clear whether | |
512 | - this was a SEGV_MAPERR or SEGV_ACCERR fault. */ | |
513 | - info.si_addr = (void __user *) address; | |
514 | - info.si_trapno = 0; | |
515 | - force_sig_info (SIGSEGV, &info, tsk); | |
534 | + __do_fault_siginfo(code, SIGSEGV, tsk->thread.kregs, address); | |
516 | 535 | return; |
517 | 536 | |
518 | 537 | do_sigbus: |
519 | 538 | up_read(&mm->mmap_sem); |
520 | - info.si_signo = SIGBUS; | |
521 | - info.si_errno = 0; | |
522 | - info.si_code = BUS_ADRERR; | |
523 | - info.si_addr = (void __user *) address; | |
524 | - info.si_trapno = 0; | |
525 | - force_sig_info (SIGBUS, &info, tsk); | |
539 | + __do_fault_siginfo(BUS_ADRERR, SIGBUS, tsk->thread.kregs, address); | |
526 | 540 | } |
527 | 541 | |
528 | 542 | void window_overflow_fault(void) |
arch/sparc/mm/fault_64.c
... | ... | @@ -32,6 +32,8 @@ |
32 | 32 | #include <asm/sections.h> |
33 | 33 | #include <asm/mmu_context.h> |
34 | 34 | |
35 | +int show_unhandled_signals = 1; | |
36 | + | |
35 | 37 | static inline __kprobes int notify_page_fault(struct pt_regs *regs) |
36 | 38 | { |
37 | 39 | int ret = 0; |
38 | 40 | |
39 | 41 | |
40 | 42 | |
41 | 43 | |
... | ... | @@ -128,22 +130,48 @@ |
128 | 130 | return insn; |
129 | 131 | } |
130 | 132 | |
133 | +static inline void | |
134 | +show_signal_msg(struct pt_regs *regs, int sig, int code, | |
135 | + unsigned long address, struct task_struct *tsk) | |
136 | +{ | |
137 | + if (!unhandled_signal(tsk, sig)) | |
138 | + return; | |
139 | + | |
140 | + if (!printk_ratelimit()) | |
141 | + return; | |
142 | + | |
143 | + printk("%s%s[%d]: segfault at %lx ip %p (rpc %p) sp %p error %x", | |
144 | + task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, | |
145 | + tsk->comm, task_pid_nr(tsk), address, | |
146 | + (void *)regs->tpc, (void *)regs->u_regs[UREG_I7], | |
147 | + (void *)regs->u_regs[UREG_FP], code); | |
148 | + | |
149 | + print_vma_addr(KERN_CONT " in ", regs->tpc); | |
150 | + | |
151 | + printk(KERN_CONT "\n"); | |
152 | +} | |
153 | + | |
131 | 154 | extern unsigned long compute_effective_address(struct pt_regs *, unsigned int, unsigned int); |
132 | 155 | |
133 | 156 | static void do_fault_siginfo(int code, int sig, struct pt_regs *regs, |
134 | 157 | unsigned int insn, int fault_code) |
135 | 158 | { |
159 | + unsigned long addr; | |
136 | 160 | siginfo_t info; |
137 | 161 | |
138 | 162 | info.si_code = code; |
139 | 163 | info.si_signo = sig; |
140 | 164 | info.si_errno = 0; |
141 | 165 | if (fault_code & FAULT_CODE_ITLB) |
142 | - info.si_addr = (void __user *) regs->tpc; | |
166 | + addr = regs->tpc; | |
143 | 167 | else |
144 | - info.si_addr = (void __user *) | |
145 | - compute_effective_address(regs, insn, 0); | |
168 | + addr = compute_effective_address(regs, insn, 0); | |
169 | + info.si_addr = (void __user *) addr; | |
146 | 170 | info.si_trapno = 0; |
171 | + | |
172 | + if (unlikely(show_unhandled_signals)) | |
173 | + show_signal_msg(regs, sig, code, addr, current); | |
174 | + | |
147 | 175 | force_sig_info(sig, &info, current); |
148 | 176 | } |
149 | 177 |
arch/sparc/prom/console_32.c
arch/sparc/prom/console_64.c
arch/sparc/prom/devmap.c
arch/sparc/prom/devops_32.c
arch/sparc/prom/init_32.c
arch/sparc/prom/palloc.c
arch/sparc/prom/ranges.c
arch/sparc/prom/segment.c
arch/sparc/prom/tree_32.c
arch/sparc/prom/tree_64.c
drivers/video/sunxvr500.c
... | ... | @@ -400,6 +400,7 @@ |
400 | 400 | |
401 | 401 | static struct pci_device_id e3d_pci_table[] = { |
402 | 402 | { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x7a0), }, |
403 | + { PCI_DEVICE(0x1091, 0x7a0), }, | |
403 | 404 | { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x7a2), }, |
404 | 405 | { .vendor = PCI_VENDOR_ID_3DLABS, |
405 | 406 | .device = PCI_ANY_ID, |
kernel/sysctl.c
... | ... | @@ -1441,7 +1441,7 @@ |
1441 | 1441 | }; |
1442 | 1442 | |
1443 | 1443 | static struct ctl_table debug_table[] = { |
1444 | -#if defined(CONFIG_X86) || defined(CONFIG_PPC) | |
1444 | +#if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) | |
1445 | 1445 | { |
1446 | 1446 | .procname = "exception-trace", |
1447 | 1447 | .data = &show_unhandled_signals, |