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 |
