diff options
Diffstat (limited to 'arch/sparc64/kernel')
30 files changed, 220 insertions, 129 deletions
diff --git a/arch/sparc64/kernel/ebus.c b/arch/sparc64/kernel/ebus.c index 04ab81cb4f48..bc2632274840 100644 --- a/arch/sparc64/kernel/ebus.c +++ b/arch/sparc64/kernel/ebus.c | |||
@@ -396,6 +396,7 @@ static void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_de | |||
396 | sd->op = &dev->ofdev; | 396 | sd->op = &dev->ofdev; |
397 | sd->iommu = dev->bus->ofdev.dev.parent->archdata.iommu; | 397 | sd->iommu = dev->bus->ofdev.dev.parent->archdata.iommu; |
398 | sd->stc = dev->bus->ofdev.dev.parent->archdata.stc; | 398 | sd->stc = dev->bus->ofdev.dev.parent->archdata.stc; |
399 | sd->numa_node = dev->bus->ofdev.dev.parent->archdata.numa_node; | ||
399 | 400 | ||
400 | dev->ofdev.node = dp; | 401 | dev->ofdev.node = dp; |
401 | dev->ofdev.dev.parent = &dev->bus->ofdev.dev; | 402 | dev->ofdev.dev.parent = &dev->bus->ofdev.dev; |
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index fb43c76bdc26..fd06e937ae1e 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S | |||
@@ -47,7 +47,7 @@ do_fpdis: | |||
47 | ba,pt %xcc, etrap | 47 | ba,pt %xcc, etrap |
48 | 109: or %g7, %lo(109b), %g7 | 48 | 109: or %g7, %lo(109b), %g7 |
49 | add %g0, %g0, %g0 | 49 | add %g0, %g0, %g0 |
50 | ba,a,pt %xcc, rtrap_clr_l6 | 50 | ba,a,pt %xcc, rtrap |
51 | 51 | ||
52 | 1: TRAP_LOAD_THREAD_REG(%g6, %g1) | 52 | 1: TRAP_LOAD_THREAD_REG(%g6, %g1) |
53 | ldub [%g6 + TI_FPSAVED], %g5 | 53 | ldub [%g6 + TI_FPSAVED], %g5 |
@@ -226,7 +226,7 @@ fp_other_bounce: | |||
226 | call do_fpother | 226 | call do_fpother |
227 | add %sp, PTREGS_OFF, %o0 | 227 | add %sp, PTREGS_OFF, %o0 |
228 | ba,pt %xcc, rtrap | 228 | ba,pt %xcc, rtrap |
229 | clr %l6 | 229 | nop |
230 | 230 | ||
231 | .globl do_fpother_check_fitos | 231 | .globl do_fpother_check_fitos |
232 | .align 32 | 232 | .align 32 |
@@ -489,7 +489,7 @@ utrap_trap: /* %g3=handler,%g4=level */ | |||
489 | call bad_trap | 489 | call bad_trap |
490 | add %sp, PTREGS_OFF, %o0 | 490 | add %sp, PTREGS_OFF, %o0 |
491 | ba,pt %xcc, rtrap | 491 | ba,pt %xcc, rtrap |
492 | clr %l6 | 492 | nop |
493 | 493 | ||
494 | invoke_utrap: | 494 | invoke_utrap: |
495 | sllx %g3, 3, %g3 | 495 | sllx %g3, 3, %g3 |
@@ -607,7 +607,7 @@ __spitfire_cee_trap_continue: | |||
607 | call spitfire_access_error | 607 | call spitfire_access_error |
608 | add %sp, PTREGS_OFF, %o0 | 608 | add %sp, PTREGS_OFF, %o0 |
609 | ba,pt %xcc, rtrap | 609 | ba,pt %xcc, rtrap |
610 | clr %l6 | 610 | nop |
611 | 611 | ||
612 | /* This is the trap handler entry point for ECC correctable | 612 | /* This is the trap handler entry point for ECC correctable |
613 | * errors. They are corrected, but we listen for the trap | 613 | * errors. They are corrected, but we listen for the trap |
@@ -686,7 +686,7 @@ __spitfire_data_access_exception_tl1: | |||
686 | call spitfire_data_access_exception_tl1 | 686 | call spitfire_data_access_exception_tl1 |
687 | add %sp, PTREGS_OFF, %o0 | 687 | add %sp, PTREGS_OFF, %o0 |
688 | ba,pt %xcc, rtrap | 688 | ba,pt %xcc, rtrap |
689 | clr %l6 | 689 | nop |
690 | 690 | ||
691 | __spitfire_data_access_exception: | 691 | __spitfire_data_access_exception: |
692 | rdpr %pstate, %g4 | 692 | rdpr %pstate, %g4 |
@@ -705,7 +705,7 @@ __spitfire_data_access_exception: | |||
705 | call spitfire_data_access_exception | 705 | call spitfire_data_access_exception |
706 | add %sp, PTREGS_OFF, %o0 | 706 | add %sp, PTREGS_OFF, %o0 |
707 | ba,pt %xcc, rtrap | 707 | ba,pt %xcc, rtrap |
708 | clr %l6 | 708 | nop |
709 | 709 | ||
710 | .globl __spitfire_insn_access_exception | 710 | .globl __spitfire_insn_access_exception |
711 | .globl __spitfire_insn_access_exception_tl1 | 711 | .globl __spitfire_insn_access_exception_tl1 |
@@ -725,7 +725,7 @@ __spitfire_insn_access_exception_tl1: | |||
725 | call spitfire_insn_access_exception_tl1 | 725 | call spitfire_insn_access_exception_tl1 |
726 | add %sp, PTREGS_OFF, %o0 | 726 | add %sp, PTREGS_OFF, %o0 |
727 | ba,pt %xcc, rtrap | 727 | ba,pt %xcc, rtrap |
728 | clr %l6 | 728 | nop |
729 | 729 | ||
730 | __spitfire_insn_access_exception: | 730 | __spitfire_insn_access_exception: |
731 | rdpr %pstate, %g4 | 731 | rdpr %pstate, %g4 |
@@ -743,7 +743,7 @@ __spitfire_insn_access_exception: | |||
743 | call spitfire_insn_access_exception | 743 | call spitfire_insn_access_exception |
744 | add %sp, PTREGS_OFF, %o0 | 744 | add %sp, PTREGS_OFF, %o0 |
745 | ba,pt %xcc, rtrap | 745 | ba,pt %xcc, rtrap |
746 | clr %l6 | 746 | nop |
747 | 747 | ||
748 | /* These get patched into the trap table at boot time | 748 | /* These get patched into the trap table at boot time |
749 | * once we know we have a cheetah processor. | 749 | * once we know we have a cheetah processor. |
@@ -937,7 +937,7 @@ do_dcpe_tl1_fatal: | |||
937 | call cheetah_plus_parity_error | 937 | call cheetah_plus_parity_error |
938 | add %sp, PTREGS_OFF, %o1 | 938 | add %sp, PTREGS_OFF, %o1 |
939 | ba,pt %xcc, rtrap | 939 | ba,pt %xcc, rtrap |
940 | clr %l6 | 940 | nop |
941 | 941 | ||
942 | do_icpe_tl1: | 942 | do_icpe_tl1: |
943 | rdpr %tl, %g1 ! Save original trap level | 943 | rdpr %tl, %g1 ! Save original trap level |
@@ -979,7 +979,7 @@ do_icpe_tl1_fatal: | |||
979 | call cheetah_plus_parity_error | 979 | call cheetah_plus_parity_error |
980 | add %sp, PTREGS_OFF, %o1 | 980 | add %sp, PTREGS_OFF, %o1 |
981 | ba,pt %xcc, rtrap | 981 | ba,pt %xcc, rtrap |
982 | clr %l6 | 982 | nop |
983 | 983 | ||
984 | dcpe_icpe_tl1_common: | 984 | dcpe_icpe_tl1_common: |
985 | /* Flush D-cache, re-enable D/I caches in DCU and finally | 985 | /* Flush D-cache, re-enable D/I caches in DCU and finally |
@@ -1281,7 +1281,7 @@ __do_privact: | |||
1281 | call do_privact | 1281 | call do_privact |
1282 | add %sp, PTREGS_OFF, %o0 | 1282 | add %sp, PTREGS_OFF, %o0 |
1283 | ba,pt %xcc, rtrap | 1283 | ba,pt %xcc, rtrap |
1284 | clr %l6 | 1284 | nop |
1285 | 1285 | ||
1286 | .globl do_mna | 1286 | .globl do_mna |
1287 | do_mna: | 1287 | do_mna: |
@@ -1308,7 +1308,7 @@ do_mna: | |||
1308 | call mem_address_unaligned | 1308 | call mem_address_unaligned |
1309 | add %sp, PTREGS_OFF, %o0 | 1309 | add %sp, PTREGS_OFF, %o0 |
1310 | ba,pt %xcc, rtrap | 1310 | ba,pt %xcc, rtrap |
1311 | clr %l6 | 1311 | nop |
1312 | 1312 | ||
1313 | .globl do_lddfmna | 1313 | .globl do_lddfmna |
1314 | do_lddfmna: | 1314 | do_lddfmna: |
@@ -1326,7 +1326,7 @@ do_lddfmna: | |||
1326 | call handle_lddfmna | 1326 | call handle_lddfmna |
1327 | add %sp, PTREGS_OFF, %o0 | 1327 | add %sp, PTREGS_OFF, %o0 |
1328 | ba,pt %xcc, rtrap | 1328 | ba,pt %xcc, rtrap |
1329 | clr %l6 | 1329 | nop |
1330 | 1330 | ||
1331 | .globl do_stdfmna | 1331 | .globl do_stdfmna |
1332 | do_stdfmna: | 1332 | do_stdfmna: |
@@ -1344,7 +1344,7 @@ do_stdfmna: | |||
1344 | call handle_stdfmna | 1344 | call handle_stdfmna |
1345 | add %sp, PTREGS_OFF, %o0 | 1345 | add %sp, PTREGS_OFF, %o0 |
1346 | ba,pt %xcc, rtrap | 1346 | ba,pt %xcc, rtrap |
1347 | clr %l6 | 1347 | nop |
1348 | 1348 | ||
1349 | .globl breakpoint_trap | 1349 | .globl breakpoint_trap |
1350 | breakpoint_trap: | 1350 | breakpoint_trap: |
@@ -1424,13 +1424,13 @@ sys32_rt_sigreturn: | |||
1424 | 1: ldx [%curptr + TI_FLAGS], %l5 | 1424 | 1: ldx [%curptr + TI_FLAGS], %l5 |
1425 | andcc %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0 | 1425 | andcc %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0 |
1426 | be,pt %icc, rtrap | 1426 | be,pt %icc, rtrap |
1427 | clr %l6 | 1427 | nop |
1428 | add %sp, PTREGS_OFF, %o0 | 1428 | add %sp, PTREGS_OFF, %o0 |
1429 | call syscall_trace | 1429 | call syscall_trace |
1430 | mov 1, %o1 | 1430 | mov 1, %o1 |
1431 | 1431 | ||
1432 | ba,pt %xcc, rtrap | 1432 | ba,pt %xcc, rtrap |
1433 | clr %l6 | 1433 | nop |
1434 | 1434 | ||
1435 | /* This is how fork() was meant to be done, 8 instruction entry. | 1435 | /* This is how fork() was meant to be done, 8 instruction entry. |
1436 | * | 1436 | * |
@@ -1559,7 +1559,7 @@ linux_sparc_syscall32: | |||
1559 | 1559 | ||
1560 | /* Linux native system calls enter here... */ | 1560 | /* Linux native system calls enter here... */ |
1561 | .align 32 | 1561 | .align 32 |
1562 | .globl linux_sparc_syscall, ret_sys_call | 1562 | .globl linux_sparc_syscall |
1563 | linux_sparc_syscall: | 1563 | linux_sparc_syscall: |
1564 | /* Direct access to user regs, much faster. */ | 1564 | /* Direct access to user regs, much faster. */ |
1565 | cmp %g1, NR_SYSCALLS ! IEU1 Group | 1565 | cmp %g1, NR_SYSCALLS ! IEU1 Group |
@@ -1605,7 +1605,7 @@ ret_sys_call: | |||
1605 | bne,pn %icc, linux_syscall_trace2 | 1605 | bne,pn %icc, linux_syscall_trace2 |
1606 | add %l1, 0x4, %l2 ! npc = npc+4 | 1606 | add %l1, 0x4, %l2 ! npc = npc+4 |
1607 | stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] | 1607 | stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] |
1608 | ba,pt %xcc, rtrap_clr_l6 | 1608 | ba,pt %xcc, rtrap |
1609 | stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] | 1609 | stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] |
1610 | 1610 | ||
1611 | 1: | 1611 | 1: |
@@ -1616,7 +1616,6 @@ ret_sys_call: | |||
1616 | sub %g0, %o0, %o0 | 1616 | sub %g0, %o0, %o0 |
1617 | or %g3, %g2, %g3 | 1617 | or %g3, %g2, %g3 |
1618 | stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] | 1618 | stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] |
1619 | mov 1, %l6 | ||
1620 | stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE] | 1619 | stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE] |
1621 | bne,pn %icc, linux_syscall_trace2 | 1620 | bne,pn %icc, linux_syscall_trace2 |
1622 | add %l1, 0x4, %l2 ! npc = npc+4 | 1621 | add %l1, 0x4, %l2 ! npc = npc+4 |
diff --git a/arch/sparc64/kernel/entry.h b/arch/sparc64/kernel/entry.h index 4a91e9c6d31b..32fbab620852 100644 --- a/arch/sparc64/kernel/entry.h +++ b/arch/sparc64/kernel/entry.h | |||
@@ -20,7 +20,6 @@ extern void timer_interrupt(int irq, struct pt_regs *regs); | |||
20 | 20 | ||
21 | extern void do_notify_resume(struct pt_regs *regs, | 21 | extern void do_notify_resume(struct pt_regs *regs, |
22 | unsigned long orig_i0, | 22 | unsigned long orig_i0, |
23 | int restart_syscall, | ||
24 | unsigned long thread_info_flags); | 23 | unsigned long thread_info_flags); |
25 | 24 | ||
26 | extern asmlinkage void syscall_trace(struct pt_regs *regs, | 25 | extern asmlinkage void syscall_trace(struct pt_regs *regs, |
diff --git a/arch/sparc64/kernel/etrap.S b/arch/sparc64/kernel/etrap.S index 4b2bf9eb447a..b49d3b60bc0c 100644 --- a/arch/sparc64/kernel/etrap.S +++ b/arch/sparc64/kernel/etrap.S | |||
@@ -53,7 +53,11 @@ etrap_irq: | |||
53 | stx %g3, [%g2 + STACKFRAME_SZ + PT_V9_TPC] | 53 | stx %g3, [%g2 + STACKFRAME_SZ + PT_V9_TPC] |
54 | rd %y, %g3 | 54 | rd %y, %g3 |
55 | stx %g1, [%g2 + STACKFRAME_SZ + PT_V9_TNPC] | 55 | stx %g1, [%g2 + STACKFRAME_SZ + PT_V9_TNPC] |
56 | rdpr %tt, %g1 | ||
56 | st %g3, [%g2 + STACKFRAME_SZ + PT_V9_Y] | 57 | st %g3, [%g2 + STACKFRAME_SZ + PT_V9_Y] |
58 | sethi %hi(PT_REGS_MAGIC), %g3 | ||
59 | or %g3, %g1, %g1 | ||
60 | st %g1, [%g2 + STACKFRAME_SZ + PT_V9_MAGIC] | ||
57 | 61 | ||
58 | rdpr %cansave, %g1 | 62 | rdpr %cansave, %g1 |
59 | brnz,pt %g1, etrap_save | 63 | brnz,pt %g1, etrap_save |
diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c index 756fa24eeefa..2a37a6ca2a16 100644 --- a/arch/sparc64/kernel/iommu.c +++ b/arch/sparc64/kernel/iommu.c | |||
@@ -173,9 +173,11 @@ void iommu_range_free(struct iommu *iommu, dma_addr_t dma_addr, unsigned long np | |||
173 | } | 173 | } |
174 | 174 | ||
175 | int iommu_table_init(struct iommu *iommu, int tsbsize, | 175 | int iommu_table_init(struct iommu *iommu, int tsbsize, |
176 | u32 dma_offset, u32 dma_addr_mask) | 176 | u32 dma_offset, u32 dma_addr_mask, |
177 | int numa_node) | ||
177 | { | 178 | { |
178 | unsigned long i, tsbbase, order, sz, num_tsb_entries; | 179 | unsigned long i, order, sz, num_tsb_entries; |
180 | struct page *page; | ||
179 | 181 | ||
180 | num_tsb_entries = tsbsize / sizeof(iopte_t); | 182 | num_tsb_entries = tsbsize / sizeof(iopte_t); |
181 | 183 | ||
@@ -188,11 +190,12 @@ int iommu_table_init(struct iommu *iommu, int tsbsize, | |||
188 | /* Allocate and initialize the free area map. */ | 190 | /* Allocate and initialize the free area map. */ |
189 | sz = num_tsb_entries / 8; | 191 | sz = num_tsb_entries / 8; |
190 | sz = (sz + 7UL) & ~7UL; | 192 | sz = (sz + 7UL) & ~7UL; |
191 | iommu->arena.map = kzalloc(sz, GFP_KERNEL); | 193 | iommu->arena.map = kmalloc_node(sz, GFP_KERNEL, numa_node); |
192 | if (!iommu->arena.map) { | 194 | if (!iommu->arena.map) { |
193 | printk(KERN_ERR "IOMMU: Error, kmalloc(arena.map) failed.\n"); | 195 | printk(KERN_ERR "IOMMU: Error, kmalloc(arena.map) failed.\n"); |
194 | return -ENOMEM; | 196 | return -ENOMEM; |
195 | } | 197 | } |
198 | memset(iommu->arena.map, 0, sz); | ||
196 | iommu->arena.limit = num_tsb_entries; | 199 | iommu->arena.limit = num_tsb_entries; |
197 | 200 | ||
198 | if (tlb_type != hypervisor) | 201 | if (tlb_type != hypervisor) |
@@ -201,21 +204,23 @@ int iommu_table_init(struct iommu *iommu, int tsbsize, | |||
201 | /* Allocate and initialize the dummy page which we | 204 | /* Allocate and initialize the dummy page which we |
202 | * set inactive IO PTEs to point to. | 205 | * set inactive IO PTEs to point to. |
203 | */ | 206 | */ |
204 | iommu->dummy_page = get_zeroed_page(GFP_KERNEL); | 207 | page = alloc_pages_node(numa_node, GFP_KERNEL, 0); |
205 | if (!iommu->dummy_page) { | 208 | if (!page) { |
206 | printk(KERN_ERR "IOMMU: Error, gfp(dummy_page) failed.\n"); | 209 | printk(KERN_ERR "IOMMU: Error, gfp(dummy_page) failed.\n"); |
207 | goto out_free_map; | 210 | goto out_free_map; |
208 | } | 211 | } |
212 | iommu->dummy_page = (unsigned long) page_address(page); | ||
213 | memset((void *)iommu->dummy_page, 0, PAGE_SIZE); | ||
209 | iommu->dummy_page_pa = (unsigned long) __pa(iommu->dummy_page); | 214 | iommu->dummy_page_pa = (unsigned long) __pa(iommu->dummy_page); |
210 | 215 | ||
211 | /* Now allocate and setup the IOMMU page table itself. */ | 216 | /* Now allocate and setup the IOMMU page table itself. */ |
212 | order = get_order(tsbsize); | 217 | order = get_order(tsbsize); |
213 | tsbbase = __get_free_pages(GFP_KERNEL, order); | 218 | page = alloc_pages_node(numa_node, GFP_KERNEL, order); |
214 | if (!tsbbase) { | 219 | if (!page) { |
215 | printk(KERN_ERR "IOMMU: Error, gfp(tsb) failed.\n"); | 220 | printk(KERN_ERR "IOMMU: Error, gfp(tsb) failed.\n"); |
216 | goto out_free_dummy_page; | 221 | goto out_free_dummy_page; |
217 | } | 222 | } |
218 | iommu->page_table = (iopte_t *)tsbbase; | 223 | iommu->page_table = (iopte_t *)page_address(page); |
219 | 224 | ||
220 | for (i = 0; i < num_tsb_entries; i++) | 225 | for (i = 0; i < num_tsb_entries; i++) |
221 | iopte_make_dummy(iommu, &iommu->page_table[i]); | 226 | iopte_make_dummy(iommu, &iommu->page_table[i]); |
@@ -276,20 +281,24 @@ static inline void iommu_free_ctx(struct iommu *iommu, int ctx) | |||
276 | static void *dma_4u_alloc_coherent(struct device *dev, size_t size, | 281 | static void *dma_4u_alloc_coherent(struct device *dev, size_t size, |
277 | dma_addr_t *dma_addrp, gfp_t gfp) | 282 | dma_addr_t *dma_addrp, gfp_t gfp) |
278 | { | 283 | { |
284 | unsigned long flags, order, first_page; | ||
279 | struct iommu *iommu; | 285 | struct iommu *iommu; |
286 | struct page *page; | ||
287 | int npages, nid; | ||
280 | iopte_t *iopte; | 288 | iopte_t *iopte; |
281 | unsigned long flags, order, first_page; | ||
282 | void *ret; | 289 | void *ret; |
283 | int npages; | ||
284 | 290 | ||
285 | size = IO_PAGE_ALIGN(size); | 291 | size = IO_PAGE_ALIGN(size); |
286 | order = get_order(size); | 292 | order = get_order(size); |
287 | if (order >= 10) | 293 | if (order >= 10) |
288 | return NULL; | 294 | return NULL; |
289 | 295 | ||
290 | first_page = __get_free_pages(gfp, order); | 296 | nid = dev->archdata.numa_node; |
291 | if (first_page == 0UL) | 297 | page = alloc_pages_node(nid, gfp, order); |
298 | if (unlikely(!page)) | ||
292 | return NULL; | 299 | return NULL; |
300 | |||
301 | first_page = (unsigned long) page_address(page); | ||
293 | memset((char *)first_page, 0, PAGE_SIZE << order); | 302 | memset((char *)first_page, 0, PAGE_SIZE << order); |
294 | 303 | ||
295 | iommu = dev->archdata.iommu; | 304 | iommu = dev->archdata.iommu; |
diff --git a/arch/sparc64/kernel/isa.c b/arch/sparc64/kernel/isa.c index b5f7b354084f..a2af5ed784c9 100644 --- a/arch/sparc64/kernel/isa.c +++ b/arch/sparc64/kernel/isa.c | |||
@@ -92,6 +92,7 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br) | |||
92 | sd->op = &isa_dev->ofdev; | 92 | sd->op = &isa_dev->ofdev; |
93 | sd->iommu = isa_br->ofdev.dev.parent->archdata.iommu; | 93 | sd->iommu = isa_br->ofdev.dev.parent->archdata.iommu; |
94 | sd->stc = isa_br->ofdev.dev.parent->archdata.stc; | 94 | sd->stc = isa_br->ofdev.dev.parent->archdata.stc; |
95 | sd->numa_node = isa_br->ofdev.dev.parent->archdata.numa_node; | ||
95 | 96 | ||
96 | isa_dev->ofdev.node = dp; | 97 | isa_dev->ofdev.node = dp; |
97 | isa_dev->ofdev.dev.parent = &isa_br->ofdev.dev; | 98 | isa_dev->ofdev.dev.parent = &isa_br->ofdev.dev; |
diff --git a/arch/sparc64/kernel/mdesc.c b/arch/sparc64/kernel/mdesc.c index 910083589569..dde52bcf5c64 100644 --- a/arch/sparc64/kernel/mdesc.c +++ b/arch/sparc64/kernel/mdesc.c | |||
@@ -1,10 +1,10 @@ | |||
1 | /* mdesc.c: Sun4V machine description handling. | 1 | /* mdesc.c: Sun4V machine description handling. |
2 | * | 2 | * |
3 | * Copyright (C) 2007 David S. Miller <davem@davemloft.net> | 3 | * Copyright (C) 2007, 2008 David S. Miller <davem@davemloft.net> |
4 | */ | 4 | */ |
5 | #include <linux/kernel.h> | 5 | #include <linux/kernel.h> |
6 | #include <linux/types.h> | 6 | #include <linux/types.h> |
7 | #include <linux/bootmem.h> | 7 | #include <linux/lmb.h> |
8 | #include <linux/log2.h> | 8 | #include <linux/log2.h> |
9 | #include <linux/list.h> | 9 | #include <linux/list.h> |
10 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
@@ -84,24 +84,28 @@ static void mdesc_handle_init(struct mdesc_handle *hp, | |||
84 | hp->handle_size = handle_size; | 84 | hp->handle_size = handle_size; |
85 | } | 85 | } |
86 | 86 | ||
87 | static struct mdesc_handle * __init mdesc_bootmem_alloc(unsigned int mdesc_size) | 87 | static struct mdesc_handle * __init mdesc_lmb_alloc(unsigned int mdesc_size) |
88 | { | 88 | { |
89 | struct mdesc_handle *hp; | ||
90 | unsigned int handle_size, alloc_size; | 89 | unsigned int handle_size, alloc_size; |
90 | struct mdesc_handle *hp; | ||
91 | unsigned long paddr; | ||
91 | 92 | ||
92 | handle_size = (sizeof(struct mdesc_handle) - | 93 | handle_size = (sizeof(struct mdesc_handle) - |
93 | sizeof(struct mdesc_hdr) + | 94 | sizeof(struct mdesc_hdr) + |
94 | mdesc_size); | 95 | mdesc_size); |
95 | alloc_size = PAGE_ALIGN(handle_size); | 96 | alloc_size = PAGE_ALIGN(handle_size); |
96 | 97 | ||
97 | hp = __alloc_bootmem(alloc_size, PAGE_SIZE, 0UL); | 98 | paddr = lmb_alloc(alloc_size, PAGE_SIZE); |
98 | if (hp) | ||
99 | mdesc_handle_init(hp, handle_size, hp); | ||
100 | 99 | ||
100 | hp = NULL; | ||
101 | if (paddr) { | ||
102 | hp = __va(paddr); | ||
103 | mdesc_handle_init(hp, handle_size, hp); | ||
104 | } | ||
101 | return hp; | 105 | return hp; |
102 | } | 106 | } |
103 | 107 | ||
104 | static void mdesc_bootmem_free(struct mdesc_handle *hp) | 108 | static void mdesc_lmb_free(struct mdesc_handle *hp) |
105 | { | 109 | { |
106 | unsigned int alloc_size, handle_size = hp->handle_size; | 110 | unsigned int alloc_size, handle_size = hp->handle_size; |
107 | unsigned long start, end; | 111 | unsigned long start, end; |
@@ -124,9 +128,9 @@ static void mdesc_bootmem_free(struct mdesc_handle *hp) | |||
124 | } | 128 | } |
125 | } | 129 | } |
126 | 130 | ||
127 | static struct mdesc_mem_ops bootmem_mdesc_ops = { | 131 | static struct mdesc_mem_ops lmb_mdesc_ops = { |
128 | .alloc = mdesc_bootmem_alloc, | 132 | .alloc = mdesc_lmb_alloc, |
129 | .free = mdesc_bootmem_free, | 133 | .free = mdesc_lmb_free, |
130 | }; | 134 | }; |
131 | 135 | ||
132 | static struct mdesc_handle *mdesc_kmalloc(unsigned int mdesc_size) | 136 | static struct mdesc_handle *mdesc_kmalloc(unsigned int mdesc_size) |
@@ -888,7 +892,7 @@ void __init sun4v_mdesc_init(void) | |||
888 | 892 | ||
889 | printk("MDESC: Size is %lu bytes.\n", len); | 893 | printk("MDESC: Size is %lu bytes.\n", len); |
890 | 894 | ||
891 | hp = mdesc_alloc(len, &bootmem_mdesc_ops); | 895 | hp = mdesc_alloc(len, &lmb_mdesc_ops); |
892 | if (hp == NULL) { | 896 | if (hp == NULL) { |
893 | prom_printf("MDESC: alloc of %lu bytes failed.\n", len); | 897 | prom_printf("MDESC: alloc of %lu bytes failed.\n", len); |
894 | prom_halt(); | 898 | prom_halt(); |
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index 0fd9db95b896..9e58e8cba1c3 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <linux/mod_devicetable.h> | 6 | #include <linux/mod_devicetable.h> |
7 | #include <linux/slab.h> | 7 | #include <linux/slab.h> |
8 | #include <linux/errno.h> | 8 | #include <linux/errno.h> |
9 | #include <linux/irq.h> | ||
9 | #include <linux/of_device.h> | 10 | #include <linux/of_device.h> |
10 | #include <linux/of_platform.h> | 11 | #include <linux/of_platform.h> |
11 | 12 | ||
@@ -660,6 +661,7 @@ static unsigned int __init build_one_device_irq(struct of_device *op, | |||
660 | struct device_node *dp = op->node; | 661 | struct device_node *dp = op->node; |
661 | struct device_node *pp, *ip; | 662 | struct device_node *pp, *ip; |
662 | unsigned int orig_irq = irq; | 663 | unsigned int orig_irq = irq; |
664 | int nid; | ||
663 | 665 | ||
664 | if (irq == 0xffffffff) | 666 | if (irq == 0xffffffff) |
665 | return irq; | 667 | return irq; |
@@ -672,7 +674,7 @@ static unsigned int __init build_one_device_irq(struct of_device *op, | |||
672 | printk("%s: direct translate %x --> %x\n", | 674 | printk("%s: direct translate %x --> %x\n", |
673 | dp->full_name, orig_irq, irq); | 675 | dp->full_name, orig_irq, irq); |
674 | 676 | ||
675 | return irq; | 677 | goto out; |
676 | } | 678 | } |
677 | 679 | ||
678 | /* Something more complicated. Walk up to the root, applying | 680 | /* Something more complicated. Walk up to the root, applying |
@@ -744,6 +746,14 @@ static unsigned int __init build_one_device_irq(struct of_device *op, | |||
744 | printk("%s: Apply IRQ trans [%s] %x --> %x\n", | 746 | printk("%s: Apply IRQ trans [%s] %x --> %x\n", |
745 | op->node->full_name, ip->full_name, orig_irq, irq); | 747 | op->node->full_name, ip->full_name, orig_irq, irq); |
746 | 748 | ||
749 | out: | ||
750 | nid = of_node_to_nid(dp); | ||
751 | if (nid != -1) { | ||
752 | cpumask_t numa_mask = node_to_cpumask(nid); | ||
753 | |||
754 | irq_set_affinity(irq, numa_mask); | ||
755 | } | ||
756 | |||
747 | return irq; | 757 | return irq; |
748 | } | 758 | } |
749 | 759 | ||
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 545356b00e2e..49f912766519 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c | |||
@@ -369,10 +369,12 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, | |||
369 | sd->host_controller = pbm; | 369 | sd->host_controller = pbm; |
370 | sd->prom_node = node; | 370 | sd->prom_node = node; |
371 | sd->op = of_find_device_by_node(node); | 371 | sd->op = of_find_device_by_node(node); |
372 | sd->numa_node = pbm->numa_node; | ||
372 | 373 | ||
373 | sd = &sd->op->dev.archdata; | 374 | sd = &sd->op->dev.archdata; |
374 | sd->iommu = pbm->iommu; | 375 | sd->iommu = pbm->iommu; |
375 | sd->stc = &pbm->stc; | 376 | sd->stc = &pbm->stc; |
377 | sd->numa_node = pbm->numa_node; | ||
376 | 378 | ||
377 | type = of_get_property(node, "device_type", NULL); | 379 | type = of_get_property(node, "device_type", NULL); |
378 | if (type == NULL) | 380 | if (type == NULL) |
@@ -1159,6 +1161,16 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |||
1159 | return 0; | 1161 | return 0; |
1160 | } | 1162 | } |
1161 | 1163 | ||
1164 | #ifdef CONFIG_NUMA | ||
1165 | int pcibus_to_node(struct pci_bus *pbus) | ||
1166 | { | ||
1167 | struct pci_pbm_info *pbm = pbus->sysdata; | ||
1168 | |||
1169 | return pbm->numa_node; | ||
1170 | } | ||
1171 | EXPORT_SYMBOL(pcibus_to_node); | ||
1172 | #endif | ||
1173 | |||
1162 | /* Return the domain nuber for this pci bus */ | 1174 | /* Return the domain nuber for this pci bus */ |
1163 | 1175 | ||
1164 | int pci_domain_nr(struct pci_bus *pbus) | 1176 | int pci_domain_nr(struct pci_bus *pbus) |
diff --git a/arch/sparc64/kernel/pci_fire.c b/arch/sparc64/kernel/pci_fire.c index 7571ed563147..d23bb6f53cda 100644 --- a/arch/sparc64/kernel/pci_fire.c +++ b/arch/sparc64/kernel/pci_fire.c | |||
@@ -71,7 +71,8 @@ static int pci_fire_pbm_iommu_init(struct pci_pbm_info *pbm) | |||
71 | */ | 71 | */ |
72 | fire_write(iommu->iommu_flushinv, ~(u64)0); | 72 | fire_write(iommu->iommu_flushinv, ~(u64)0); |
73 | 73 | ||
74 | err = iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask); | 74 | err = iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask, |
75 | pbm->numa_node); | ||
75 | if (err) | 76 | if (err) |
76 | return err; | 77 | return err; |
77 | 78 | ||
@@ -449,6 +450,8 @@ static int __init pci_fire_pbm_init(struct pci_controller_info *p, | |||
449 | pbm->next = pci_pbm_root; | 450 | pbm->next = pci_pbm_root; |
450 | pci_pbm_root = pbm; | 451 | pci_pbm_root = pbm; |
451 | 452 | ||
453 | pbm->numa_node = -1; | ||
454 | |||
452 | pbm->scan_bus = pci_fire_scan_bus; | 455 | pbm->scan_bus = pci_fire_scan_bus; |
453 | pbm->pci_ops = &sun4u_pci_ops; | 456 | pbm->pci_ops = &sun4u_pci_ops; |
454 | pbm->config_space_reg_bits = 12; | 457 | pbm->config_space_reg_bits = 12; |
diff --git a/arch/sparc64/kernel/pci_impl.h b/arch/sparc64/kernel/pci_impl.h index 4a50da13ce48..218bac4ff79b 100644 --- a/arch/sparc64/kernel/pci_impl.h +++ b/arch/sparc64/kernel/pci_impl.h | |||
@@ -148,6 +148,8 @@ struct pci_pbm_info { | |||
148 | struct pci_bus *pci_bus; | 148 | struct pci_bus *pci_bus; |
149 | void (*scan_bus)(struct pci_pbm_info *); | 149 | void (*scan_bus)(struct pci_pbm_info *); |
150 | struct pci_ops *pci_ops; | 150 | struct pci_ops *pci_ops; |
151 | |||
152 | int numa_node; | ||
151 | }; | 153 | }; |
152 | 154 | ||
153 | struct pci_controller_info { | 155 | struct pci_controller_info { |
@@ -161,8 +163,6 @@ extern struct pci_pbm_info *pci_pbm_root; | |||
161 | extern int pci_num_pbms; | 163 | extern int pci_num_pbms; |
162 | 164 | ||
163 | /* PCI bus scanning and fixup support. */ | 165 | /* PCI bus scanning and fixup support. */ |
164 | extern void pci_iommu_table_init(struct iommu *iommu, int tsbsize, | ||
165 | u32 dma_offset, u32 dma_addr_mask); | ||
166 | extern void pci_get_pbm_props(struct pci_pbm_info *pbm); | 166 | extern void pci_get_pbm_props(struct pci_pbm_info *pbm); |
167 | extern struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm); | 167 | extern struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm); |
168 | extern void pci_determine_mem_io_space(struct pci_pbm_info *pbm); | 168 | extern void pci_determine_mem_io_space(struct pci_pbm_info *pbm); |
diff --git a/arch/sparc64/kernel/pci_msi.c b/arch/sparc64/kernel/pci_msi.c index d6d64b44af63..db5e8fd8f674 100644 --- a/arch/sparc64/kernel/pci_msi.c +++ b/arch/sparc64/kernel/pci_msi.c | |||
@@ -279,11 +279,17 @@ static int bringup_one_msi_queue(struct pci_pbm_info *pbm, | |||
279 | unsigned long devino) | 279 | unsigned long devino) |
280 | { | 280 | { |
281 | int irq = ops->msiq_build_irq(pbm, msiqid, devino); | 281 | int irq = ops->msiq_build_irq(pbm, msiqid, devino); |
282 | int err; | 282 | int err, nid; |
283 | 283 | ||
284 | if (irq < 0) | 284 | if (irq < 0) |
285 | return irq; | 285 | return irq; |
286 | 286 | ||
287 | nid = pbm->numa_node; | ||
288 | if (nid != -1) { | ||
289 | cpumask_t numa_mask = node_to_cpumask(nid); | ||
290 | |||
291 | irq_set_affinity(irq, numa_mask); | ||
292 | } | ||
287 | err = request_irq(irq, sparc64_msiq_interrupt, 0, | 293 | err = request_irq(irq, sparc64_msiq_interrupt, 0, |
288 | "MSIQ", | 294 | "MSIQ", |
289 | &pbm->msiq_irq_cookies[msiqid - pbm->msiq_first]); | 295 | &pbm->msiq_irq_cookies[msiqid - pbm->msiq_first]); |
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 0bad96e5d184..994dbe0603da 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c | |||
@@ -848,7 +848,8 @@ static int psycho_iommu_init(struct pci_pbm_info *pbm) | |||
848 | /* Leave diag mode enabled for full-flushing done | 848 | /* Leave diag mode enabled for full-flushing done |
849 | * in pci_iommu.c | 849 | * in pci_iommu.c |
850 | */ | 850 | */ |
851 | err = iommu_table_init(iommu, IO_TSB_SIZE, 0xc0000000, 0xffffffff); | 851 | err = iommu_table_init(iommu, IO_TSB_SIZE, 0xc0000000, 0xffffffff, |
852 | pbm->numa_node); | ||
852 | if (err) | 853 | if (err) |
853 | return err; | 854 | return err; |
854 | 855 | ||
@@ -979,6 +980,8 @@ static void __init psycho_pbm_init(struct pci_controller_info *p, | |||
979 | pbm->next = pci_pbm_root; | 980 | pbm->next = pci_pbm_root; |
980 | pci_pbm_root = pbm; | 981 | pci_pbm_root = pbm; |
981 | 982 | ||
983 | pbm->numa_node = -1; | ||
984 | |||
982 | pbm->scan_bus = psycho_scan_bus; | 985 | pbm->scan_bus = psycho_scan_bus; |
983 | pbm->pci_ops = &sun4u_pci_ops; | 986 | pbm->pci_ops = &sun4u_pci_ops; |
984 | pbm->config_space_reg_bits = 8; | 987 | pbm->config_space_reg_bits = 8; |
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index 1c5f5fa2339f..4c34195baf37 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c | |||
@@ -704,7 +704,7 @@ static int sabre_iommu_init(struct pci_pbm_info *pbm, | |||
704 | * in pci_iommu.c | 704 | * in pci_iommu.c |
705 | */ | 705 | */ |
706 | err = iommu_table_init(iommu, tsbsize * 1024 * 8, | 706 | err = iommu_table_init(iommu, tsbsize * 1024 * 8, |
707 | dvma_offset, dma_mask); | 707 | dvma_offset, dma_mask, pbm->numa_node); |
708 | if (err) | 708 | if (err) |
709 | return err; | 709 | return err; |
710 | 710 | ||
@@ -737,6 +737,8 @@ static void __init sabre_pbm_init(struct pci_controller_info *p, | |||
737 | pbm->name = dp->full_name; | 737 | pbm->name = dp->full_name; |
738 | printk("%s: SABRE PCI Bus Module\n", pbm->name); | 738 | printk("%s: SABRE PCI Bus Module\n", pbm->name); |
739 | 739 | ||
740 | pbm->numa_node = -1; | ||
741 | |||
740 | pbm->scan_bus = sabre_scan_bus; | 742 | pbm->scan_bus = sabre_scan_bus; |
741 | pbm->pci_ops = &sun4u_pci_ops; | 743 | pbm->pci_ops = &sun4u_pci_ops; |
742 | pbm->config_space_reg_bits = 8; | 744 | pbm->config_space_reg_bits = 8; |
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index e30609362322..615edd9c8e2a 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c | |||
@@ -1220,7 +1220,8 @@ static int schizo_pbm_iommu_init(struct pci_pbm_info *pbm) | |||
1220 | /* Leave diag mode enabled for full-flushing done | 1220 | /* Leave diag mode enabled for full-flushing done |
1221 | * in pci_iommu.c | 1221 | * in pci_iommu.c |
1222 | */ | 1222 | */ |
1223 | err = iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask); | 1223 | err = iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask, |
1224 | pbm->numa_node); | ||
1224 | if (err) | 1225 | if (err) |
1225 | return err; | 1226 | return err; |
1226 | 1227 | ||
@@ -1379,6 +1380,8 @@ static int __init schizo_pbm_init(struct pci_controller_info *p, | |||
1379 | pbm->next = pci_pbm_root; | 1380 | pbm->next = pci_pbm_root; |
1380 | pci_pbm_root = pbm; | 1381 | pci_pbm_root = pbm; |
1381 | 1382 | ||
1383 | pbm->numa_node = -1; | ||
1384 | |||
1382 | pbm->scan_bus = schizo_scan_bus; | 1385 | pbm->scan_bus = schizo_scan_bus; |
1383 | pbm->pci_ops = &sun4u_pci_ops; | 1386 | pbm->pci_ops = &sun4u_pci_ops; |
1384 | pbm->config_space_reg_bits = 8; | 1387 | pbm->config_space_reg_bits = 8; |
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 01839706bd52..e2bb9790039c 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c | |||
@@ -127,10 +127,12 @@ static inline long iommu_batch_end(void) | |||
127 | static void *dma_4v_alloc_coherent(struct device *dev, size_t size, | 127 | static void *dma_4v_alloc_coherent(struct device *dev, size_t size, |
128 | dma_addr_t *dma_addrp, gfp_t gfp) | 128 | dma_addr_t *dma_addrp, gfp_t gfp) |
129 | { | 129 | { |
130 | struct iommu *iommu; | ||
131 | unsigned long flags, order, first_page, npages, n; | 130 | unsigned long flags, order, first_page, npages, n; |
131 | struct iommu *iommu; | ||
132 | struct page *page; | ||
132 | void *ret; | 133 | void *ret; |
133 | long entry; | 134 | long entry; |
135 | int nid; | ||
134 | 136 | ||
135 | size = IO_PAGE_ALIGN(size); | 137 | size = IO_PAGE_ALIGN(size); |
136 | order = get_order(size); | 138 | order = get_order(size); |
@@ -139,10 +141,12 @@ static void *dma_4v_alloc_coherent(struct device *dev, size_t size, | |||
139 | 141 | ||
140 | npages = size >> IO_PAGE_SHIFT; | 142 | npages = size >> IO_PAGE_SHIFT; |
141 | 143 | ||
142 | first_page = __get_free_pages(gfp, order); | 144 | nid = dev->archdata.numa_node; |
143 | if (unlikely(first_page == 0UL)) | 145 | page = alloc_pages_node(nid, gfp, order); |
146 | if (unlikely(!page)) | ||
144 | return NULL; | 147 | return NULL; |
145 | 148 | ||
149 | first_page = (unsigned long) page_address(page); | ||
146 | memset((char *)first_page, 0, PAGE_SIZE << order); | 150 | memset((char *)first_page, 0, PAGE_SIZE << order); |
147 | 151 | ||
148 | iommu = dev->archdata.iommu; | 152 | iommu = dev->archdata.iommu; |
@@ -899,6 +903,8 @@ static void __init pci_sun4v_pbm_init(struct pci_controller_info *p, | |||
899 | pbm->next = pci_pbm_root; | 903 | pbm->next = pci_pbm_root; |
900 | pci_pbm_root = pbm; | 904 | pci_pbm_root = pbm; |
901 | 905 | ||
906 | pbm->numa_node = of_node_to_nid(dp); | ||
907 | |||
902 | pbm->scan_bus = pci_sun4v_scan_bus; | 908 | pbm->scan_bus = pci_sun4v_scan_bus; |
903 | pbm->pci_ops = &sun4v_pci_ops; | 909 | pbm->pci_ops = &sun4v_pci_ops; |
904 | pbm->config_space_reg_bits = 12; | 910 | pbm->config_space_reg_bits = 12; |
@@ -913,6 +919,7 @@ static void __init pci_sun4v_pbm_init(struct pci_controller_info *p, | |||
913 | pbm->name = dp->full_name; | 919 | pbm->name = dp->full_name; |
914 | 920 | ||
915 | printk("%s: SUN4V PCI Bus Module\n", pbm->name); | 921 | printk("%s: SUN4V PCI Bus Module\n", pbm->name); |
922 | printk("%s: On NUMA node %d\n", pbm->name, pbm->numa_node); | ||
916 | 923 | ||
917 | pci_determine_mem_io_space(pbm); | 924 | pci_determine_mem_io_space(pbm); |
918 | 925 | ||
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c index 68964ddcde1e..ed03a18d3b36 100644 --- a/arch/sparc64/kernel/prom.c +++ b/arch/sparc64/kernel/prom.c | |||
@@ -19,8 +19,8 @@ | |||
19 | #include <linux/types.h> | 19 | #include <linux/types.h> |
20 | #include <linux/string.h> | 20 | #include <linux/string.h> |
21 | #include <linux/mm.h> | 21 | #include <linux/mm.h> |
22 | #include <linux/bootmem.h> | ||
23 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/lmb.h> | ||
24 | 24 | ||
25 | #include <asm/prom.h> | 25 | #include <asm/prom.h> |
26 | #include <asm/of_device.h> | 26 | #include <asm/of_device.h> |
@@ -122,16 +122,20 @@ int of_find_in_proplist(const char *list, const char *match, int len) | |||
122 | } | 122 | } |
123 | EXPORT_SYMBOL(of_find_in_proplist); | 123 | EXPORT_SYMBOL(of_find_in_proplist); |
124 | 124 | ||
125 | static unsigned int prom_early_allocated; | 125 | static unsigned int prom_early_allocated __initdata; |
126 | 126 | ||
127 | static void * __init prom_early_alloc(unsigned long size) | 127 | static void * __init prom_early_alloc(unsigned long size) |
128 | { | 128 | { |
129 | unsigned long paddr = lmb_alloc(size, SMP_CACHE_BYTES); | ||
129 | void *ret; | 130 | void *ret; |
130 | 131 | ||
131 | ret = __alloc_bootmem(size, SMP_CACHE_BYTES, 0UL); | 132 | if (!paddr) { |
132 | if (ret != NULL) | 133 | prom_printf("prom_early_alloc(%lu) failed\n"); |
133 | memset(ret, 0, size); | 134 | prom_halt(); |
135 | } | ||
134 | 136 | ||
137 | ret = __va(paddr); | ||
138 | memset(ret, 0, size); | ||
135 | prom_early_allocated += size; | 139 | prom_early_allocated += size; |
136 | 140 | ||
137 | return ret; | 141 | return ret; |
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S index 079d18a11d24..ecf6753b204a 100644 --- a/arch/sparc64/kernel/rtrap.S +++ b/arch/sparc64/kernel/rtrap.S | |||
@@ -18,12 +18,6 @@ | |||
18 | #define RTRAP_PSTATE_IRQOFF (PSTATE_RMO|PSTATE_PEF|PSTATE_PRIV) | 18 | #define RTRAP_PSTATE_IRQOFF (PSTATE_RMO|PSTATE_PEF|PSTATE_PRIV) |
19 | #define RTRAP_PSTATE_AG_IRQOFF (PSTATE_RMO|PSTATE_PEF|PSTATE_PRIV|PSTATE_AG) | 19 | #define RTRAP_PSTATE_AG_IRQOFF (PSTATE_RMO|PSTATE_PEF|PSTATE_PRIV|PSTATE_AG) |
20 | 20 | ||
21 | /* Register %l6 keeps track of whether we are returning | ||
22 | * from a system call or not. It is cleared if we call | ||
23 | * do_notify_resume, and it must not be otherwise modified | ||
24 | * until we fully commit to returning to userspace. | ||
25 | */ | ||
26 | |||
27 | .text | 21 | .text |
28 | .align 32 | 22 | .align 32 |
29 | __handle_softirq: | 23 | __handle_softirq: |
@@ -56,14 +50,12 @@ __handle_user_windows: | |||
56 | be,pt %xcc, __handle_user_windows_continue | 50 | be,pt %xcc, __handle_user_windows_continue |
57 | nop | 51 | nop |
58 | mov %l5, %o1 | 52 | mov %l5, %o1 |
59 | mov %l6, %o2 | ||
60 | add %sp, PTREGS_OFF, %o0 | 53 | add %sp, PTREGS_OFF, %o0 |
61 | mov %l0, %o3 | 54 | mov %l0, %o2 |
62 | 55 | ||
63 | call do_notify_resume | 56 | call do_notify_resume |
64 | wrpr %g0, RTRAP_PSTATE, %pstate | 57 | wrpr %g0, RTRAP_PSTATE, %pstate |
65 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate | 58 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate |
66 | clr %l6 | ||
67 | /* Signal delivery can modify pt_regs tstate, so we must | 59 | /* Signal delivery can modify pt_regs tstate, so we must |
68 | * reload it. | 60 | * reload it. |
69 | */ | 61 | */ |
@@ -99,14 +91,12 @@ __handle_perfctrs: | |||
99 | be,pt %xcc, __handle_perfctrs_continue | 91 | be,pt %xcc, __handle_perfctrs_continue |
100 | sethi %hi(TSTATE_PEF), %o0 | 92 | sethi %hi(TSTATE_PEF), %o0 |
101 | mov %l5, %o1 | 93 | mov %l5, %o1 |
102 | mov %l6, %o2 | ||
103 | add %sp, PTREGS_OFF, %o0 | 94 | add %sp, PTREGS_OFF, %o0 |
104 | mov %l0, %o3 | 95 | mov %l0, %o2 |
105 | call do_notify_resume | 96 | call do_notify_resume |
106 | 97 | ||
107 | wrpr %g0, RTRAP_PSTATE, %pstate | 98 | wrpr %g0, RTRAP_PSTATE, %pstate |
108 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate | 99 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate |
109 | clr %l6 | ||
110 | /* Signal delivery can modify pt_regs tstate, so we must | 100 | /* Signal delivery can modify pt_regs tstate, so we must |
111 | * reload it. | 101 | * reload it. |
112 | */ | 102 | */ |
@@ -127,13 +117,11 @@ __handle_userfpu: | |||
127 | 117 | ||
128 | __handle_signal: | 118 | __handle_signal: |
129 | mov %l5, %o1 | 119 | mov %l5, %o1 |
130 | mov %l6, %o2 | ||
131 | add %sp, PTREGS_OFF, %o0 | 120 | add %sp, PTREGS_OFF, %o0 |
132 | mov %l0, %o3 | 121 | mov %l0, %o2 |
133 | call do_notify_resume | 122 | call do_notify_resume |
134 | wrpr %g0, RTRAP_PSTATE, %pstate | 123 | wrpr %g0, RTRAP_PSTATE, %pstate |
135 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate | 124 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate |
136 | clr %l6 | ||
137 | 125 | ||
138 | /* Signal delivery can modify pt_regs tstate, so we must | 126 | /* Signal delivery can modify pt_regs tstate, so we must |
139 | * reload it. | 127 | * reload it. |
@@ -145,9 +133,8 @@ __handle_signal: | |||
145 | andn %l1, %l4, %l1 | 133 | andn %l1, %l4, %l1 |
146 | 134 | ||
147 | .align 64 | 135 | .align 64 |
148 | .globl rtrap_irq, rtrap_clr_l6, rtrap, irqsz_patchme, rtrap_xcall | 136 | .globl rtrap_irq, rtrap, irqsz_patchme, rtrap_xcall |
149 | rtrap_irq: | 137 | rtrap_irq: |
150 | rtrap_clr_l6: clr %l6 | ||
151 | rtrap: | 138 | rtrap: |
152 | #ifndef CONFIG_SMP | 139 | #ifndef CONFIG_SMP |
153 | sethi %hi(per_cpu____cpu_data), %l0 | 140 | sethi %hi(per_cpu____cpu_data), %l0 |
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c index d1fb13ba02b5..fa2827c4a3ad 100644 --- a/arch/sparc64/kernel/sbus.c +++ b/arch/sparc64/kernel/sbus.c | |||
@@ -544,6 +544,7 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus) | |||
544 | 544 | ||
545 | sbus->ofdev.dev.archdata.iommu = iommu; | 545 | sbus->ofdev.dev.archdata.iommu = iommu; |
546 | sbus->ofdev.dev.archdata.stc = strbuf; | 546 | sbus->ofdev.dev.archdata.stc = strbuf; |
547 | sbus->ofdev.dev.archdata.numa_node = -1; | ||
547 | 548 | ||
548 | reg_base = regs + SYSIO_IOMMUREG_BASE; | 549 | reg_base = regs + SYSIO_IOMMUREG_BASE; |
549 | iommu->iommu_control = reg_base + IOMMU_CONTROL; | 550 | iommu->iommu_control = reg_base + IOMMU_CONTROL; |
@@ -575,7 +576,7 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus) | |||
575 | sbus->portid, regs); | 576 | sbus->portid, regs); |
576 | 577 | ||
577 | /* Setup for TSB_SIZE=7, TBW_SIZE=0, MMU_DE=1, MMU_EN=1 */ | 578 | /* Setup for TSB_SIZE=7, TBW_SIZE=0, MMU_DE=1, MMU_EN=1 */ |
578 | if (iommu_table_init(iommu, IO_TSB_SIZE, MAP_BASE, 0xffffffff)) | 579 | if (iommu_table_init(iommu, IO_TSB_SIZE, MAP_BASE, 0xffffffff, -1)) |
579 | goto fatal_memory_error; | 580 | goto fatal_memory_error; |
580 | 581 | ||
581 | control = upa_readq(iommu->iommu_control); | 582 | control = upa_readq(iommu->iommu_control); |
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index 6acb4c51cfe4..da5e6ee0c661 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c | |||
@@ -82,7 +82,7 @@ unsigned long cmdline_memory_size = 0; | |||
82 | static struct console prom_early_console = { | 82 | static struct console prom_early_console = { |
83 | .name = "earlyprom", | 83 | .name = "earlyprom", |
84 | .write = prom_console_write, | 84 | .write = prom_console_write, |
85 | .flags = CON_PRINTBUFFER | CON_BOOT, | 85 | .flags = CON_PRINTBUFFER | CON_BOOT | CON_ANYTIME, |
86 | .index = -1, | 86 | .index = -1, |
87 | }; | 87 | }; |
88 | 88 | ||
@@ -281,6 +281,7 @@ void __init setup_arch(char **cmdline_p) | |||
281 | /* Initialize PROM console and command line. */ | 281 | /* Initialize PROM console and command line. */ |
282 | *cmdline_p = prom_getbootargs(); | 282 | *cmdline_p = prom_getbootargs(); |
283 | strcpy(boot_command_line, *cmdline_p); | 283 | strcpy(boot_command_line, *cmdline_p); |
284 | parse_early_param(); | ||
284 | 285 | ||
285 | boot_flags_init(*cmdline_p); | 286 | boot_flags_init(*cmdline_p); |
286 | register_console(&prom_early_console); | 287 | register_console(&prom_early_console); |
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c index 1c47009eb5ec..77a3e8592cbc 100644 --- a/arch/sparc64/kernel/signal.c +++ b/arch/sparc64/kernel/signal.c | |||
@@ -510,15 +510,20 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, | |||
510 | * want to handle. Thus you cannot kill init even with a SIGKILL even by | 510 | * want to handle. Thus you cannot kill init even with a SIGKILL even by |
511 | * mistake. | 511 | * mistake. |
512 | */ | 512 | */ |
513 | static void do_signal(struct pt_regs *regs, unsigned long orig_i0, int restart_syscall) | 513 | static void do_signal(struct pt_regs *regs, unsigned long orig_i0) |
514 | { | 514 | { |
515 | siginfo_t info; | ||
516 | struct signal_deliver_cookie cookie; | 515 | struct signal_deliver_cookie cookie; |
517 | struct k_sigaction ka; | 516 | struct k_sigaction ka; |
518 | int signr; | ||
519 | sigset_t *oldset; | 517 | sigset_t *oldset; |
518 | siginfo_t info; | ||
519 | int signr, tt; | ||
520 | 520 | ||
521 | cookie.restart_syscall = restart_syscall; | 521 | tt = regs->magic & 0x1ff; |
522 | if (tt == 0x110 || tt == 0x111 || tt == 0x16d) { | ||
523 | regs->magic &= ~0x1ff; | ||
524 | cookie.restart_syscall = 1; | ||
525 | } else | ||
526 | cookie.restart_syscall = 0; | ||
522 | cookie.orig_i0 = orig_i0; | 527 | cookie.orig_i0 = orig_i0; |
523 | 528 | ||
524 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | 529 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) |
@@ -529,9 +534,8 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0, int restart_s | |||
529 | #ifdef CONFIG_SPARC32_COMPAT | 534 | #ifdef CONFIG_SPARC32_COMPAT |
530 | if (test_thread_flag(TIF_32BIT)) { | 535 | if (test_thread_flag(TIF_32BIT)) { |
531 | extern void do_signal32(sigset_t *, struct pt_regs *, | 536 | extern void do_signal32(sigset_t *, struct pt_regs *, |
532 | unsigned long, int); | 537 | struct signal_deliver_cookie *); |
533 | do_signal32(oldset, regs, orig_i0, | 538 | do_signal32(oldset, regs, &cookie); |
534 | cookie.restart_syscall); | ||
535 | return; | 539 | return; |
536 | } | 540 | } |
537 | #endif | 541 | #endif |
@@ -539,7 +543,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0, int restart_s | |||
539 | signr = get_signal_to_deliver(&info, &ka, regs, &cookie); | 543 | signr = get_signal_to_deliver(&info, &ka, regs, &cookie); |
540 | if (signr > 0) { | 544 | if (signr > 0) { |
541 | if (cookie.restart_syscall) | 545 | if (cookie.restart_syscall) |
542 | syscall_restart(orig_i0, regs, &ka.sa); | 546 | syscall_restart(cookie.orig_i0, regs, &ka.sa); |
543 | handle_signal(signr, &ka, &info, oldset, regs); | 547 | handle_signal(signr, &ka, &info, oldset, regs); |
544 | 548 | ||
545 | /* a signal was successfully delivered; the saved | 549 | /* a signal was successfully delivered; the saved |
@@ -576,11 +580,10 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0, int restart_s | |||
576 | } | 580 | } |
577 | } | 581 | } |
578 | 582 | ||
579 | void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, int restart_syscall, | 583 | void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags) |
580 | unsigned long thread_info_flags) | ||
581 | { | 584 | { |
582 | if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) | 585 | if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) |
583 | do_signal(regs, orig_i0, restart_syscall); | 586 | do_signal(regs, orig_i0); |
584 | } | 587 | } |
585 | 588 | ||
586 | void ptrace_signal_deliver(struct pt_regs *regs, void *cookie) | 589 | void ptrace_signal_deliver(struct pt_regs *regs, void *cookie) |
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index 74e0512f135c..43cdec64d9c9 100644 --- a/arch/sparc64/kernel/signal32.c +++ b/arch/sparc64/kernel/signal32.c | |||
@@ -982,20 +982,16 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs | |||
982 | * mistake. | 982 | * mistake. |
983 | */ | 983 | */ |
984 | void do_signal32(sigset_t *oldset, struct pt_regs * regs, | 984 | void do_signal32(sigset_t *oldset, struct pt_regs * regs, |
985 | unsigned long orig_i0, int restart_syscall) | 985 | struct signal_deliver_cookie *cookie) |
986 | { | 986 | { |
987 | siginfo_t info; | ||
988 | struct signal_deliver_cookie cookie; | ||
989 | struct k_sigaction ka; | 987 | struct k_sigaction ka; |
988 | siginfo_t info; | ||
990 | int signr; | 989 | int signr; |
991 | 990 | ||
992 | cookie.restart_syscall = restart_syscall; | 991 | signr = get_signal_to_deliver(&info, &ka, regs, cookie); |
993 | cookie.orig_i0 = orig_i0; | ||
994 | |||
995 | signr = get_signal_to_deliver(&info, &ka, regs, &cookie); | ||
996 | if (signr > 0) { | 992 | if (signr > 0) { |
997 | if (cookie.restart_syscall) | 993 | if (cookie->restart_syscall) |
998 | syscall_restart32(orig_i0, regs, &ka.sa); | 994 | syscall_restart32(cookie->orig_i0, regs, &ka.sa); |
999 | handle_signal32(signr, &ka, &info, oldset, regs); | 995 | handle_signal32(signr, &ka, &info, oldset, regs); |
1000 | 996 | ||
1001 | /* a signal was successfully delivered; the saved | 997 | /* a signal was successfully delivered; the saved |
@@ -1007,16 +1003,16 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs, | |||
1007 | clear_thread_flag(TIF_RESTORE_SIGMASK); | 1003 | clear_thread_flag(TIF_RESTORE_SIGMASK); |
1008 | return; | 1004 | return; |
1009 | } | 1005 | } |
1010 | if (cookie.restart_syscall && | 1006 | if (cookie->restart_syscall && |
1011 | (regs->u_regs[UREG_I0] == ERESTARTNOHAND || | 1007 | (regs->u_regs[UREG_I0] == ERESTARTNOHAND || |
1012 | regs->u_regs[UREG_I0] == ERESTARTSYS || | 1008 | regs->u_regs[UREG_I0] == ERESTARTSYS || |
1013 | regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { | 1009 | regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { |
1014 | /* replay the system call when we are done */ | 1010 | /* replay the system call when we are done */ |
1015 | regs->u_regs[UREG_I0] = cookie.orig_i0; | 1011 | regs->u_regs[UREG_I0] = cookie->orig_i0; |
1016 | regs->tpc -= 4; | 1012 | regs->tpc -= 4; |
1017 | regs->tnpc -= 4; | 1013 | regs->tnpc -= 4; |
1018 | } | 1014 | } |
1019 | if (cookie.restart_syscall && | 1015 | if (cookie->restart_syscall && |
1020 | regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { | 1016 | regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { |
1021 | regs->u_regs[UREG_G1] = __NR_restart_syscall; | 1017 | regs->u_regs[UREG_G1] = __NR_restart_syscall; |
1022 | regs->tpc -= 4; | 1018 | regs->tpc -= 4; |
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 59f020d69d4c..524b88920947 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/cache.h> | 20 | #include <linux/cache.h> |
21 | #include <linux/jiffies.h> | 21 | #include <linux/jiffies.h> |
22 | #include <linux/profile.h> | 22 | #include <linux/profile.h> |
23 | #include <linux/bootmem.h> | 23 | #include <linux/lmb.h> |
24 | 24 | ||
25 | #include <asm/head.h> | 25 | #include <asm/head.h> |
26 | #include <asm/ptrace.h> | 26 | #include <asm/ptrace.h> |
@@ -1431,7 +1431,7 @@ EXPORT_SYMBOL(__per_cpu_shift); | |||
1431 | 1431 | ||
1432 | void __init real_setup_per_cpu_areas(void) | 1432 | void __init real_setup_per_cpu_areas(void) |
1433 | { | 1433 | { |
1434 | unsigned long goal, size, i; | 1434 | unsigned long paddr, goal, size, i; |
1435 | char *ptr; | 1435 | char *ptr; |
1436 | 1436 | ||
1437 | /* Copy section for each CPU (we discard the original) */ | 1437 | /* Copy section for each CPU (we discard the original) */ |
@@ -1441,8 +1441,13 @@ void __init real_setup_per_cpu_areas(void) | |||
1441 | for (size = PAGE_SIZE; size < goal; size <<= 1UL) | 1441 | for (size = PAGE_SIZE; size < goal; size <<= 1UL) |
1442 | __per_cpu_shift++; | 1442 | __per_cpu_shift++; |
1443 | 1443 | ||
1444 | ptr = alloc_bootmem_pages(size * NR_CPUS); | 1444 | paddr = lmb_alloc(size * NR_CPUS, PAGE_SIZE); |
1445 | if (!paddr) { | ||
1446 | prom_printf("Cannot allocate per-cpu memory.\n"); | ||
1447 | prom_halt(); | ||
1448 | } | ||
1445 | 1449 | ||
1450 | ptr = __va(paddr); | ||
1446 | __per_cpu_base = ptr - __per_cpu_start; | 1451 | __per_cpu_base = ptr - __per_cpu_start; |
1447 | 1452 | ||
1448 | for (i = 0; i < NR_CPUS; i++, ptr += size) | 1453 | for (i = 0; i < NR_CPUS; i++, ptr += size) |
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 38736460b8db..66336590e830 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c | |||
@@ -68,8 +68,6 @@ extern void *__memscan_zero(void *, size_t); | |||
68 | extern void *__memscan_generic(void *, int, size_t); | 68 | extern void *__memscan_generic(void *, int, size_t); |
69 | extern int __memcmp(const void *, const void *, __kernel_size_t); | 69 | extern int __memcmp(const void *, const void *, __kernel_size_t); |
70 | extern __kernel_size_t strlen(const char *); | 70 | extern __kernel_size_t strlen(const char *); |
71 | extern void linux_sparc_syscall(void); | ||
72 | extern void rtrap(void); | ||
73 | extern void show_regs(struct pt_regs *); | 71 | extern void show_regs(struct pt_regs *); |
74 | extern void syscall_trace(struct pt_regs *, int); | 72 | extern void syscall_trace(struct pt_regs *, int); |
75 | extern void sys_sigsuspend(void); | 73 | extern void sys_sigsuspend(void); |
diff --git a/arch/sparc64/kernel/stacktrace.c b/arch/sparc64/kernel/stacktrace.c index 84d39e873e88..01b52f561af4 100644 --- a/arch/sparc64/kernel/stacktrace.c +++ b/arch/sparc64/kernel/stacktrace.c | |||
@@ -20,6 +20,8 @@ void save_stack_trace(struct stack_trace *trace) | |||
20 | thread_base = (unsigned long) tp; | 20 | thread_base = (unsigned long) tp; |
21 | do { | 21 | do { |
22 | struct reg_window *rw; | 22 | struct reg_window *rw; |
23 | struct pt_regs *regs; | ||
24 | unsigned long pc; | ||
23 | 25 | ||
24 | /* Bogus frame pointer? */ | 26 | /* Bogus frame pointer? */ |
25 | if (fp < (thread_base + sizeof(struct thread_info)) || | 27 | if (fp < (thread_base + sizeof(struct thread_info)) || |
@@ -27,11 +29,19 @@ void save_stack_trace(struct stack_trace *trace) | |||
27 | break; | 29 | break; |
28 | 30 | ||
29 | rw = (struct reg_window *) fp; | 31 | rw = (struct reg_window *) fp; |
32 | regs = (struct pt_regs *) (rw + 1); | ||
33 | |||
34 | if ((regs->magic & ~0x1ff) == PT_REGS_MAGIC) { | ||
35 | pc = regs->tpc; | ||
36 | fp = regs->u_regs[UREG_I6] + STACK_BIAS; | ||
37 | } else { | ||
38 | pc = rw->ins[7]; | ||
39 | fp = rw->ins[6] + STACK_BIAS; | ||
40 | } | ||
41 | |||
30 | if (trace->skip > 0) | 42 | if (trace->skip > 0) |
31 | trace->skip--; | 43 | trace->skip--; |
32 | else | 44 | else |
33 | trace->entries[trace->nr_entries++] = rw->ins[7]; | 45 | trace->entries[trace->nr_entries++] = pc; |
34 | |||
35 | fp = rw->ins[6] + STACK_BIAS; | ||
36 | } while (trace->nr_entries < trace->max_entries); | 46 | } while (trace->nr_entries < trace->max_entries); |
37 | } | 47 | } |
diff --git a/arch/sparc64/kernel/sun4v_tlb_miss.S b/arch/sparc64/kernel/sun4v_tlb_miss.S index fd9430562e0b..e1fbf8c75787 100644 --- a/arch/sparc64/kernel/sun4v_tlb_miss.S +++ b/arch/sparc64/kernel/sun4v_tlb_miss.S | |||
@@ -262,7 +262,7 @@ sun4v_iacc: | |||
262 | mov %l5, %o2 | 262 | mov %l5, %o2 |
263 | call sun4v_insn_access_exception | 263 | call sun4v_insn_access_exception |
264 | add %sp, PTREGS_OFF, %o0 | 264 | add %sp, PTREGS_OFF, %o0 |
265 | ba,a,pt %xcc, rtrap_clr_l6 | 265 | ba,a,pt %xcc, rtrap |
266 | 266 | ||
267 | /* Instruction Access Exception, tl1. */ | 267 | /* Instruction Access Exception, tl1. */ |
268 | sun4v_iacc_tl1: | 268 | sun4v_iacc_tl1: |
@@ -278,7 +278,7 @@ sun4v_iacc_tl1: | |||
278 | mov %l5, %o2 | 278 | mov %l5, %o2 |
279 | call sun4v_insn_access_exception_tl1 | 279 | call sun4v_insn_access_exception_tl1 |
280 | add %sp, PTREGS_OFF, %o0 | 280 | add %sp, PTREGS_OFF, %o0 |
281 | ba,a,pt %xcc, rtrap_clr_l6 | 281 | ba,a,pt %xcc, rtrap |
282 | 282 | ||
283 | /* Data Access Exception, tl0. */ | 283 | /* Data Access Exception, tl0. */ |
284 | sun4v_dacc: | 284 | sun4v_dacc: |
@@ -294,7 +294,7 @@ sun4v_dacc: | |||
294 | mov %l5, %o2 | 294 | mov %l5, %o2 |
295 | call sun4v_data_access_exception | 295 | call sun4v_data_access_exception |
296 | add %sp, PTREGS_OFF, %o0 | 296 | add %sp, PTREGS_OFF, %o0 |
297 | ba,a,pt %xcc, rtrap_clr_l6 | 297 | ba,a,pt %xcc, rtrap |
298 | 298 | ||
299 | /* Data Access Exception, tl1. */ | 299 | /* Data Access Exception, tl1. */ |
300 | sun4v_dacc_tl1: | 300 | sun4v_dacc_tl1: |
@@ -310,7 +310,7 @@ sun4v_dacc_tl1: | |||
310 | mov %l5, %o2 | 310 | mov %l5, %o2 |
311 | call sun4v_data_access_exception_tl1 | 311 | call sun4v_data_access_exception_tl1 |
312 | add %sp, PTREGS_OFF, %o0 | 312 | add %sp, PTREGS_OFF, %o0 |
313 | ba,a,pt %xcc, rtrap_clr_l6 | 313 | ba,a,pt %xcc, rtrap |
314 | 314 | ||
315 | /* Memory Address Unaligned. */ | 315 | /* Memory Address Unaligned. */ |
316 | sun4v_mna: | 316 | sun4v_mna: |
@@ -344,7 +344,7 @@ sun4v_mna: | |||
344 | mov %l5, %o2 | 344 | mov %l5, %o2 |
345 | call sun4v_do_mna | 345 | call sun4v_do_mna |
346 | add %sp, PTREGS_OFF, %o0 | 346 | add %sp, PTREGS_OFF, %o0 |
347 | ba,a,pt %xcc, rtrap_clr_l6 | 347 | ba,a,pt %xcc, rtrap |
348 | 348 | ||
349 | /* Privileged Action. */ | 349 | /* Privileged Action. */ |
350 | sun4v_privact: | 350 | sun4v_privact: |
@@ -352,7 +352,7 @@ sun4v_privact: | |||
352 | rd %pc, %g7 | 352 | rd %pc, %g7 |
353 | call do_privact | 353 | call do_privact |
354 | add %sp, PTREGS_OFF, %o0 | 354 | add %sp, PTREGS_OFF, %o0 |
355 | ba,a,pt %xcc, rtrap_clr_l6 | 355 | ba,a,pt %xcc, rtrap |
356 | 356 | ||
357 | /* Unaligned ldd float, tl0. */ | 357 | /* Unaligned ldd float, tl0. */ |
358 | sun4v_lddfmna: | 358 | sun4v_lddfmna: |
@@ -368,7 +368,7 @@ sun4v_lddfmna: | |||
368 | mov %l5, %o2 | 368 | mov %l5, %o2 |
369 | call handle_lddfmna | 369 | call handle_lddfmna |
370 | add %sp, PTREGS_OFF, %o0 | 370 | add %sp, PTREGS_OFF, %o0 |
371 | ba,a,pt %xcc, rtrap_clr_l6 | 371 | ba,a,pt %xcc, rtrap |
372 | 372 | ||
373 | /* Unaligned std float, tl0. */ | 373 | /* Unaligned std float, tl0. */ |
374 | sun4v_stdfmna: | 374 | sun4v_stdfmna: |
@@ -384,7 +384,7 @@ sun4v_stdfmna: | |||
384 | mov %l5, %o2 | 384 | mov %l5, %o2 |
385 | call handle_stdfmna | 385 | call handle_stdfmna |
386 | add %sp, PTREGS_OFF, %o0 | 386 | add %sp, PTREGS_OFF, %o0 |
387 | ba,a,pt %xcc, rtrap_clr_l6 | 387 | ba,a,pt %xcc, rtrap |
388 | 388 | ||
389 | #define BRANCH_ALWAYS 0x10680000 | 389 | #define BRANCH_ALWAYS 0x10680000 |
390 | #define NOP 0x01000000 | 390 | #define NOP 0x01000000 |
diff --git a/arch/sparc64/kernel/sysfs.c b/arch/sparc64/kernel/sysfs.c index 52816c7be0b9..e885034a6b73 100644 --- a/arch/sparc64/kernel/sysfs.c +++ b/arch/sparc64/kernel/sysfs.c | |||
@@ -273,10 +273,22 @@ static void __init check_mmu_stats(void) | |||
273 | mmu_stats_supported = 1; | 273 | mmu_stats_supported = 1; |
274 | } | 274 | } |
275 | 275 | ||
276 | static void register_nodes(void) | ||
277 | { | ||
278 | #ifdef CONFIG_NUMA | ||
279 | int i; | ||
280 | |||
281 | for (i = 0; i < MAX_NUMNODES; i++) | ||
282 | register_one_node(i); | ||
283 | #endif | ||
284 | } | ||
285 | |||
276 | static int __init topology_init(void) | 286 | static int __init topology_init(void) |
277 | { | 287 | { |
278 | int cpu; | 288 | int cpu; |
279 | 289 | ||
290 | register_nodes(); | ||
291 | |||
280 | check_mmu_stats(); | 292 | check_mmu_stats(); |
281 | 293 | ||
282 | register_cpu_notifier(&sysfs_cpu_nb); | 294 | register_cpu_notifier(&sysfs_cpu_nb); |
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index 96da847023f3..d9b8d46707d1 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c | |||
@@ -2091,9 +2091,8 @@ static void user_instruction_dump(unsigned int __user *pc) | |||
2091 | 2091 | ||
2092 | void show_stack(struct task_struct *tsk, unsigned long *_ksp) | 2092 | void show_stack(struct task_struct *tsk, unsigned long *_ksp) |
2093 | { | 2093 | { |
2094 | unsigned long pc, fp, thread_base, ksp; | 2094 | unsigned long fp, thread_base, ksp; |
2095 | struct thread_info *tp; | 2095 | struct thread_info *tp; |
2096 | struct reg_window *rw; | ||
2097 | int count = 0; | 2096 | int count = 0; |
2098 | 2097 | ||
2099 | ksp = (unsigned long) _ksp; | 2098 | ksp = (unsigned long) _ksp; |
@@ -2117,15 +2116,27 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp) | |||
2117 | printk("\n"); | 2116 | printk("\n"); |
2118 | #endif | 2117 | #endif |
2119 | do { | 2118 | do { |
2119 | struct reg_window *rw; | ||
2120 | struct pt_regs *regs; | ||
2121 | unsigned long pc; | ||
2122 | |||
2120 | /* Bogus frame pointer? */ | 2123 | /* Bogus frame pointer? */ |
2121 | if (fp < (thread_base + sizeof(struct thread_info)) || | 2124 | if (fp < (thread_base + sizeof(struct thread_info)) || |
2122 | fp >= (thread_base + THREAD_SIZE)) | 2125 | fp >= (thread_base + THREAD_SIZE)) |
2123 | break; | 2126 | break; |
2124 | rw = (struct reg_window *)fp; | 2127 | rw = (struct reg_window *)fp; |
2125 | pc = rw->ins[7]; | 2128 | regs = (struct pt_regs *) (rw + 1); |
2129 | |||
2130 | if ((regs->magic & ~0x1ff) == PT_REGS_MAGIC) { | ||
2131 | pc = regs->tpc; | ||
2132 | fp = regs->u_regs[UREG_I6] + STACK_BIAS; | ||
2133 | } else { | ||
2134 | pc = rw->ins[7]; | ||
2135 | fp = rw->ins[6] + STACK_BIAS; | ||
2136 | } | ||
2137 | |||
2126 | printk(" [%016lx] ", pc); | 2138 | printk(" [%016lx] ", pc); |
2127 | print_symbol("%s\n", pc); | 2139 | print_symbol("%s\n", pc); |
2128 | fp = rw->ins[6] + STACK_BIAS; | ||
2129 | } while (++count < 16); | 2140 | } while (++count < 16); |
2130 | #ifndef CONFIG_KALLSYMS | 2141 | #ifndef CONFIG_KALLSYMS |
2131 | printk("\n"); | 2142 | printk("\n"); |
diff --git a/arch/sparc64/kernel/tsb.S b/arch/sparc64/kernel/tsb.S index 10adb2fb8ffe..c499214b501d 100644 --- a/arch/sparc64/kernel/tsb.S +++ b/arch/sparc64/kernel/tsb.S | |||
@@ -275,7 +275,7 @@ sparc64_realfault_common: | |||
275 | stx %l5, [%g6 + TI_FAULT_ADDR] ! Save fault address | 275 | stx %l5, [%g6 + TI_FAULT_ADDR] ! Save fault address |
276 | call do_sparc64_fault ! Call fault handler | 276 | call do_sparc64_fault ! Call fault handler |
277 | add %sp, PTREGS_OFF, %o0 ! Compute pt_regs arg | 277 | add %sp, PTREGS_OFF, %o0 ! Compute pt_regs arg |
278 | ba,pt %xcc, rtrap_clr_l6 ! Restore cpu state | 278 | ba,pt %xcc, rtrap ! Restore cpu state |
279 | nop ! Delay slot (fill me) | 279 | nop ! Delay slot (fill me) |
280 | 280 | ||
281 | winfix_trampoline: | 281 | winfix_trampoline: |
diff --git a/arch/sparc64/kernel/winfixup.S b/arch/sparc64/kernel/winfixup.S index c4aa110a10e5..a6b0863c27df 100644 --- a/arch/sparc64/kernel/winfixup.S +++ b/arch/sparc64/kernel/winfixup.S | |||
@@ -32,7 +32,7 @@ fill_fixup: | |||
32 | rd %pc, %g7 | 32 | rd %pc, %g7 |
33 | call do_sparc64_fault | 33 | call do_sparc64_fault |
34 | add %sp, PTREGS_OFF, %o0 | 34 | add %sp, PTREGS_OFF, %o0 |
35 | ba,pt %xcc, rtrap_clr_l6 | 35 | ba,pt %xcc, rtrap |
36 | nop | 36 | nop |
37 | 37 | ||
38 | /* Be very careful about usage of the trap globals here. | 38 | /* Be very careful about usage of the trap globals here. |
@@ -100,7 +100,7 @@ spill_fixup_dax: | |||
100 | rd %pc, %g7 | 100 | rd %pc, %g7 |
101 | call do_sparc64_fault | 101 | call do_sparc64_fault |
102 | add %sp, PTREGS_OFF, %o0 | 102 | add %sp, PTREGS_OFF, %o0 |
103 | ba,a,pt %xcc, rtrap_clr_l6 | 103 | ba,a,pt %xcc, rtrap |
104 | 104 | ||
105 | winfix_mna: | 105 | winfix_mna: |
106 | andn %g3, 0x7f, %g3 | 106 | andn %g3, 0x7f, %g3 |
@@ -122,12 +122,12 @@ fill_fixup_mna: | |||
122 | mov %l4, %o2 | 122 | mov %l4, %o2 |
123 | call sun4v_do_mna | 123 | call sun4v_do_mna |
124 | mov %l5, %o1 | 124 | mov %l5, %o1 |
125 | ba,a,pt %xcc, rtrap_clr_l6 | 125 | ba,a,pt %xcc, rtrap |
126 | 1: mov %l4, %o1 | 126 | 1: mov %l4, %o1 |
127 | mov %l5, %o2 | 127 | mov %l5, %o2 |
128 | call mem_address_unaligned | 128 | call mem_address_unaligned |
129 | nop | 129 | nop |
130 | ba,a,pt %xcc, rtrap_clr_l6 | 130 | ba,a,pt %xcc, rtrap |
131 | 131 | ||
132 | winfix_dax: | 132 | winfix_dax: |
133 | andn %g3, 0x7f, %g3 | 133 | andn %g3, 0x7f, %g3 |
@@ -150,7 +150,7 @@ fill_fixup_dax: | |||
150 | add %sp, PTREGS_OFF, %o0 | 150 | add %sp, PTREGS_OFF, %o0 |
151 | call sun4v_data_access_exception | 151 | call sun4v_data_access_exception |
152 | nop | 152 | nop |
153 | ba,a,pt %xcc, rtrap_clr_l6 | 153 | ba,a,pt %xcc, rtrap |
154 | 1: call spitfire_data_access_exception | 154 | 1: call spitfire_data_access_exception |
155 | nop | 155 | nop |
156 | ba,a,pt %xcc, rtrap_clr_l6 | 156 | ba,a,pt %xcc, rtrap |