diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-24 08:37:29 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-24 08:37:29 -0700 |
commit | e270b51df657011983241ec61a1fc7de186e16cd (patch) | |
tree | 3397be4cbf31676ca6ebb187903e8cfc2218f223 /arch | |
parent | 8fa82790fb9dfe57aeafc8de6b6a5c1df63efa06 (diff) | |
parent | 227739bf4c110bbd02d0c0f13b272c32de406e4c (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6: (23 commits)
sparc: sunzilog uart order
[SPARC64]: Detect trap frames in stack backtraces.
[SPARC64]: %l6 trap return handling no longer necessary.
[SPARC64]: Use trap type stored in pt_regs to handle syscall restart.
[SPARC64]: Store magic cookie and trap type in pt_regs.
[SPARC64]: PROM debug console can be CON_ANYTIME.
sparc64: cleanup after SunOS/Solaris binary emulation removal
sparc: cleanup after SunOS binary emulation removal
[SPARC64]: Add NUMA support.
[SPARC64]: Allocate TSB node-local.
[SPARC64]: NUMA device infrastructure.
[SPARC64]: Kill pci_iommu_table_init() declaration.
[SPARC64]: Once we have the boot cmdline, call parse_early_param()
[SPARC64]: Remove unused asm-sparc64/numnodes.h
[SPARC64]: Decrease SECTION_SIZE_BITS to 30.
[SPARC64]: Initialize MDESC earlier and use lmb_alloc()
[SPARC64]: Use lmb_alloc() for PROM device tree.
[SPARC64]: Call real_setup_per_cpu_areas() earlier and use lmb_alloc().
[SPARC64]: Fully use LMB information in bootmem_init().
[SPARC64]: Start using LMB information in bootmem_init().
...
Diffstat (limited to 'arch')
37 files changed, 1020 insertions, 450 deletions
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index 135644f8add..484c83d23ee 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S @@ -1409,7 +1409,6 @@ syscall_is_too_hard: st %o0, [%sp + STACKFRAME_SZ + PT_I0] - .globl ret_sys_call ret_sys_call: ld [%curptr + TI_FLAGS], %l6 cmp %o0, -ERESTART_RESTARTBLOCK diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c index 1f730619a24..3e849e8e348 100644 --- a/arch/sparc/kernel/signal.c +++ b/arch/sparc/kernel/signal.c @@ -105,11 +105,6 @@ static int _sigpause_common(old_sigset_t set) return -ERESTARTNOHAND; } -asmlinkage int sys_sigpause(unsigned int set) -{ - return _sigpause_common(set); -} - asmlinkage int sys_sigsuspend(old_sigset_t set) { return _sigpause_common(set); diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index df3eacb5ca1..8acc5cc3862 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -250,6 +250,26 @@ endchoice endmenu +config NUMA + bool "NUMA support" + +config NODES_SHIFT + int + default "4" + depends on NEED_MULTIPLE_NODES + +# Some NUMA nodes have memory ranges that span +# other nodes. Even though a pfn is valid and +# between a node's start and end pfns, it may not +# reside on that node. See memmap_init_zone() +# for details. +config NODES_SPAN_OTHER_NODES + def_bool y + depends on NEED_MULTIPLE_NODES + +config ARCH_POPULATES_NODE_MAP + def_bool y + config ARCH_SELECT_MEMORY_MODEL def_bool y diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index e1835868ad3..92f79680f70 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.25 -# Sun Apr 20 01:33:21 2008 +# Linux kernel version: 2.6.25-numa +# Wed Apr 23 04:49:08 2008 # CONFIG_SPARC=y CONFIG_SPARC64=y @@ -152,6 +152,8 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_HUGETLB_PAGE_SIZE_4MB=y # CONFIG_HUGETLB_PAGE_SIZE_512K is not set # CONFIG_HUGETLB_PAGE_SIZE_64K is not set +# CONFIG_NUMA is not set +CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_DEFAULT=y @@ -787,7 +789,6 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_SENSORS_PCF8574 is not set # CONFIG_PCF8575 is not set # CONFIG_SENSORS_PCF8591 is not set -# CONFIG_TPS65010 is not set # CONFIG_SENSORS_MAX6875 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set @@ -869,6 +870,7 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set # # Multimedia devices @@ -1219,10 +1221,6 @@ CONFIG_USB_STORAGE=m # CONFIG_NEW_LEDS is not set # CONFIG_INFINIBAND is not set # CONFIG_RTC_CLASS is not set - -# -# Userspace I/O -# # CONFIG_UIO is not set # @@ -1399,6 +1397,7 @@ CONFIG_SCHEDSTATS=y CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set # CONFIG_BOOT_PRINTK_DELAY is not set @@ -1425,53 +1424,82 @@ CONFIG_ASYNC_CORE=m CONFIG_ASYNC_MEMCPY=m CONFIG_ASYNC_XOR=m CONFIG_CRYPTO=y + +# +# Crypto core or helper +# CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_AEAD=y CONFIG_CRYPTO_BLKCIPHER=y -# CONFIG_CRYPTO_SEQIV is not set CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_NULL=m +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_AUTHENC=y +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m + +# +# Hash modes +# CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=y -CONFIG_CRYPTO_NULL=m + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=m CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_SHA1=y CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_GF128MUL=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_XTS=m -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_CRYPTD is not set -CONFIG_CRYPTO_DES=y -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m -CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_SEED=m # CONFIG_CRYPTO_SALSA20 is not set +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_CRC32C=m -CONFIG_CRYPTO_CAMELLIA=m -CONFIG_CRYPTO_TEST=m -CONFIG_CRYPTO_AUTHENC=y # CONFIG_CRYPTO_LZO is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set @@ -1492,3 +1520,4 @@ CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_HAVE_LMB=y diff --git a/arch/sparc64/kernel/ebus.c b/arch/sparc64/kernel/ebus.c index 04ab81cb4f4..bc263227484 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 sd->op = &dev->ofdev; sd->iommu = dev->bus->ofdev.dev.parent->archdata.iommu; sd->stc = dev->bus->ofdev.dev.parent->archdata.stc; + sd->numa_node = dev->bus->ofdev.dev.parent->archdata.numa_node; dev->ofdev.node = dp; dev->ofdev.dev.parent = &dev->bus->ofdev.dev; diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index fb43c76bdc2..fd06e937ae1 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -47,7 +47,7 @@ do_fpdis: ba,pt %xcc, etrap 109: or %g7, %lo(109b), %g7 add %g0, %g0, %g0 - ba,a,pt %xcc, rtrap_clr_l6 + ba,a,pt %xcc, rtrap 1: TRAP_LOAD_THREAD_REG(%g6, %g1) ldub [%g6 + TI_FPSAVED], %g5 @@ -226,7 +226,7 @@ fp_other_bounce: call do_fpother add %sp, PTREGS_OFF, %o0 ba,pt %xcc, rtrap - clr %l6 + nop .globl do_fpother_check_fitos .align 32 @@ -489,7 +489,7 @@ utrap_trap: /* %g3=handler,%g4=level */ call bad_trap add %sp, PTREGS_OFF, %o0 ba,pt %xcc, rtrap - clr %l6 + nop invoke_utrap: sllx %g3, 3, %g3 @@ -607,7 +607,7 @@ __spitfire_cee_trap_continue: call spitfire_access_error add %sp, PTREGS_OFF, %o0 ba,pt %xcc, rtrap - clr %l6 + nop /* This is the trap handler entry point for ECC correctable * errors. They are corrected, but we listen for the trap @@ -686,7 +686,7 @@ __spitfire_data_access_exception_tl1: call spitfire_data_access_exception_tl1 add %sp, PTREGS_OFF, %o0 ba,pt %xcc, rtrap - clr %l6 + nop __spitfire_data_access_exception: rdpr %pstate, %g4 @@ -705,7 +705,7 @@ __spitfire_data_access_exception: call spitfire_data_access_exception add %sp, PTREGS_OFF, %o0 ba,pt %xcc, rtrap - clr %l6 + nop .globl __spitfire_insn_access_exception .globl __spitfire_insn_access_exception_tl1 @@ -725,7 +725,7 @@ __spitfire_insn_access_exception_tl1: call spitfire_insn_access_exception_tl1 add %sp, PTREGS_OFF, %o0 ba,pt %xcc, rtrap - clr %l6 + nop __spitfire_insn_access_exception: rdpr %pstate, %g4 @@ -743,7 +743,7 @@ __spitfire_insn_access_exception: call spitfire_insn_access_exception add %sp, PTREGS_OFF, %o0 ba,pt %xcc, rtrap - clr %l6 + nop /* These get patched into the trap table at boot time * once we know we have a cheetah processor. @@ -937,7 +937,7 @@ do_dcpe_tl1_fatal: call cheetah_plus_parity_error add %sp, PTREGS_OFF, %o1 ba,pt %xcc, rtrap - clr %l6 + nop do_icpe_tl1: rdpr %tl, %g1 ! Save original trap level @@ -979,7 +979,7 @@ do_icpe_tl1_fatal: call cheetah_plus_parity_error add %sp, PTREGS_OFF, %o1 ba,pt %xcc, rtrap - clr %l6 + nop dcpe_icpe_tl1_common: /* Flush D-cache, re-enable D/I caches in DCU and finally @@ -1281,7 +1281,7 @@ __do_privact: call do_privact add %sp, PTREGS_OFF, %o0 ba,pt %xcc, rtrap - clr %l6 + nop .globl do_mna do_mna: @@ -1308,7 +1308,7 @@ do_mna: call mem_address_unaligned add %sp, PTREGS_OFF, %o0 ba,pt %xcc, rtrap - clr %l6 + nop .globl do_lddfmna do_lddfmna: @@ -1326,7 +1326,7 @@ do_lddfmna: call handle_lddfmna add %sp, PTREGS_OFF, %o0 ba,pt %xcc, rtrap - clr %l6 + nop .globl do_stdfmna do_stdfmna: @@ -1344,7 +1344,7 @@ do_stdfmna: call handle_stdfmna add %sp, PTREGS_OFF, %o0 ba,pt %xcc, rtrap - clr %l6 + nop .globl breakpoint_trap breakpoint_trap: @@ -1424,13 +1424,13 @@ sys32_rt_sigreturn: 1: ldx [%curptr + TI_FLAGS], %l5 andcc %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0 be,pt %icc, rtrap - clr %l6 + nop add %sp, PTREGS_OFF, %o0 call syscall_trace mov 1, %o1 ba,pt %xcc, rtrap - clr %l6 + nop /* This is how fork() was meant to be done, 8 instruction entry. * @@ -1559,7 +1559,7 @@ linux_sparc_syscall32: /* Linux native system calls enter here... */ .align 32 - .globl linux_sparc_syscall, ret_sys_call + .globl linux_sparc_syscall linux_sparc_syscall: /* Direct access to user regs, much faster. */ cmp %g1, NR_SYSCALLS ! IEU1 Group @@ -1605,7 +1605,7 @@ ret_sys_call: bne,pn %icc, linux_syscall_trace2 add %l1, 0x4, %l2 ! npc = npc+4 stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] - ba,pt %xcc, rtrap_clr_l6 + ba,pt %xcc, rtrap stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] 1: @@ -1616,7 +1616,6 @@ ret_sys_call: sub %g0, %o0, %o0 or %g3, %g2, %g3 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] - mov 1, %l6 stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE] bne,pn %icc, linux_syscall_trace2 add %l1, 0x4, %l2 ! npc = npc+4 diff --git a/arch/sparc64/kernel/entry.h b/arch/sparc64/kernel/entry.h index 4a91e9c6d31..32fbab62085 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); extern void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, - int restart_syscall, unsigned long thread_info_flags); extern asmlinkage void syscall_trace(struct pt_regs *regs, diff --git a/arch/sparc64/kernel/etrap.S b/arch/sparc64/kernel/etrap.S index 4b2bf9eb447..b49d3b60bc0 100644 --- a/arch/sparc64/kernel/etrap.S +++ b/arch/sparc64/kernel/etrap.S @@ -53,7 +53,11 @@ etrap_irq: stx %g3, [%g2 + STACKFRAME_SZ + PT_V9_TPC] rd %y, %g3 stx %g1, [%g2 + STACKFRAME_SZ + PT_V9_TNPC] + rdpr %tt, %g1 st %g3, [%g2 + STACKFRAME_SZ + PT_V9_Y] + sethi %hi(PT_REGS_MAGIC), %g3 + or %g3, %g1, %g1 + st %g1, [%g2 + STACKFRAME_SZ + PT_V9_MAGIC] rdpr %cansave, %g1 brnz,pt %g1, etrap_save diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c index 756fa24eeef..2a37a6ca2a1 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 } int iommu_table_init(struct iommu *iommu, int tsbsize, - u32 dma_offset, u32 dma_addr_mask) + u32 dma_offset, u32 dma_addr_mask, + int numa_node) { - unsigned long i, tsbbase, order, sz, num_tsb_entries; + unsigned long i, order, sz, num_tsb_entries; + struct page *page; num_tsb_entries = tsbsize / sizeof(iopte_t); @@ -188,11 +190,12 @@ int iommu_table_init(struct iommu *iommu, int tsbsize, /* Allocate and initialize the free area map. */ sz = num_tsb_entries / 8; sz = (sz + 7UL) & ~7UL; - iommu->arena.map = kzalloc(sz, GFP_KERNEL); + iommu->arena.map = kmalloc_node(sz, GFP_KERNEL, numa_node); if (!iommu->arena.map) { printk(KERN_ERR "IOMMU: Error, kmalloc(arena.map) failed.\n"); return -ENOMEM; } + memset(iommu->arena.map, 0, sz); iommu->arena.limit = num_tsb_entries; if (tlb_type != hypervisor) @@ -201,21 +204,23 @@ int iommu_table_init(struct iommu *iommu, int tsbsize, /* Allocate and initialize the dummy page which we * set inactive IO PTEs to point to. */ - iommu->dummy_page = get_zeroed_page(GFP_KERNEL); - if (!iommu->dummy_page) { + page = alloc_pages_node(numa_node, GFP_KERNEL, 0); + if (!page) { printk(KERN_ERR "IOMMU: Error, gfp(dummy_page) failed.\n"); goto out_free_map; } + iommu->dummy_page = (unsigned long) page_address(page); + memset((void *)iommu->dummy_page, 0, PAGE_SIZE); iommu->dummy_page_pa = (unsigned long) __pa(iommu->dummy_page); /* Now allocate and setup the IOMMU page table itself. */ order = get_order(tsbsize); - tsbbase = __get_free_pages(GFP_KERNEL, order); - if (!tsbbase) { + page = alloc_pages_node(numa_node, GFP_KERNEL, order); + if (!page) { printk(KERN_ERR "IOMMU: Error, gfp(tsb) failed.\n"); goto out_free_dummy_page; } - iommu->page_table = (iopte_t *)tsbbase; + iommu->page_table = (iopte_t *)page_address(page); for (i = 0; i < num_tsb_entries; i++) iopte_make_dummy(iommu, &iommu->page_table[i]); @@ -276,20 +281,24 @@ static inline void iommu_free_ctx(struct iommu *iommu, int ctx) static void *dma_4u_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addrp, gfp_t gfp) { + unsigned long flags, order, first_page; struct iommu *iommu; + struct page *page; + int npages, nid; iopte_t *iopte; - unsigned long flags, order, first_page; void *ret; - int npages; size = IO_PAGE_ALIGN(size); order = get_order(size); if (order >= 10) return NULL; - first_page = __get_free_pages(gfp, order); - if (first_page == 0UL) + nid = dev->archdata.numa_node; + page = alloc_pages_node(nid, gfp, order); + if (unlikely(!page)) return NULL; + + first_page = (unsigned long) page_address(page); memset((char *)first_page, 0, PAGE_SIZE << order); iommu = dev->archdata.iommu; diff --git a/arch/sparc64/kernel/isa.c b/arch/sparc64/kernel/isa.c index b5f7b354084..a2af5ed784c 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) sd->op = &isa_dev->ofdev; sd->iommu = isa_br->ofdev.dev.parent->archdata.iommu; sd->stc = isa_br->ofdev.dev.parent->archdata.stc; + sd->numa_node = isa_br->ofdev.dev.parent->archdata.numa_node; isa_dev->ofdev.node = dp; isa_dev->ofdev.dev.parent = &isa_br->ofdev.dev; diff --git a/arch/sparc64/kernel/mdesc.c b/arch/sparc64/kernel/mdesc.c index 91008358956..dde52bcf5c6 100644 --- a/arch/sparc64/kernel/mdesc.c +++ b/arch/sparc64/kernel/mdesc.c @@ -1,10 +1,10 @@ /* mdesc.c: Sun4V machine description handling. * - * Copyright (C) 2007 David S. Miller <davem@davemloft.net> + * Copyright (C) 2007, 2008 David S. Miller <davem@davemloft.net> */ #include <linux/kernel.h> #include <linux/types.h> -#include <linux/bootmem.h> +#include <linux/lmb.h> #include <linux/log2.h> #include <linux/list.h> #include <linux/slab.h> @@ -84,24 +84,28 @@ static void mdesc_handle_init(struct mdesc_handle *hp, hp->handle_size = handle_size; } -static struct mdesc_handle * __init mdesc_bootmem_alloc(unsigned int mdesc_size) +static struct mdesc_handle * __init mdesc_lmb_alloc(unsigned int mdesc_size) { - struct mdesc_handle *hp; unsigned int handle_size, alloc_size; + struct mdesc_handle *hp; + unsigned long paddr; handle_size = (sizeof(struct mdesc_handle) - sizeof(struct mdesc_hdr) + mdesc_size); alloc_size = PAGE_ALIGN(handle_size); - hp = __alloc_bootmem(alloc_size, PAGE_SIZE, 0UL); - if (hp) - mdesc_handle_init(hp, handle_size, hp); + paddr = lmb_alloc(alloc_size, PAGE_SIZE); + hp = NULL; + if (paddr) { + hp = __va(paddr); + mdesc_handle_init(hp, handle_size, hp); + } return hp; } -static void mdesc_bootmem_free(struct mdesc_handle *hp) +static void mdesc_lmb_free(struct mdesc_handle *hp) { unsigned int alloc_size, handle_size = hp->handle_size; unsigned long start, end; @@ -124,9 +128,9 @@ static void mdesc_bootmem_free(struct mdesc_handle *hp) } } -static struct mdesc_mem_ops bootmem_mdesc_ops = { - .alloc = mdesc_bootmem_alloc, - .free = mdesc_bootmem_free, +static struct mdesc_mem_ops lmb_mdesc_ops = { + .alloc = mdesc_lmb_alloc, + .free = mdesc_lmb_free, }; static struct mdesc_handle *mdesc_kmalloc(unsigned int mdesc_size) @@ -888,7 +892,7 @@ void __init sun4v_mdesc_init(void) printk("MDESC: Size is %lu bytes.\n", len); - hp = mdesc_alloc(len, &bootmem_mdesc_ops); + hp = mdesc_alloc(len, &lmb_mdesc_ops); if (hp == NULL) { prom_printf("MDESC: alloc of %lu bytes failed.\n", len); prom_halt(); diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index 0fd9db95b89..9e58e8cba1c 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c @@ -6,6 +6,7 @@ #include <linux/mod_devicetable.h> #include <linux/slab.h> #include <linux/errno.h> +#include <linux/irq.h> #include <linux/of_device.h> #include <linux/of_platform.h> @@ -660,6 +661,7 @@ static unsigned int __init build_one_device_irq(struct of_device *op, struct device_node *dp = op->node; struct device_node *pp, *ip; unsigned int orig_irq = irq; + int nid; if (irq == 0xffffffff) return irq; @@ -672,7 +674,7 @@ static unsigned int __init build_one_device_irq(struct of_device *op, printk("%s: direct translate %x --> %x\n", dp->full_name, orig_irq, irq); - return irq; + goto out; } /* 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, printk("%s: Apply IRQ trans [%s] %x --> %x\n", op->node->full_name, ip->full_name, orig_irq, irq); +out: + nid = of_node_to_nid(dp); + if (nid != -1) { + cpumask_t numa_mask = node_to_cpumask(nid); + + irq_set_affinity(irq, numa_mask); + } + return irq; } diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 545356b00e2..49f91276651 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, sd->host_controller = pbm; sd->prom_node = node; sd->op = of_find_device_by_node(node); + sd->numa_node = pbm->numa_node; sd = &sd->op->dev.archdata; sd->iommu = pbm->iommu; sd->stc = &pbm->stc; + sd->numa_node = pbm->numa_node; type = of_get_property(node, "device_type", NULL); if (type == NULL) @@ -1159,6 +1161,16 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, return 0; } +#ifdef CONFIG_NUMA +int pcibus_to_node(struct pci_bus *pbus) +{ + struct pci_pbm_info *pbm = pbus->sysdata; + + return pbm->numa_node; +} +EXPORT_SYMBOL(pcibus_to_node); +#endif + /* Return the domain nuber for this pci bus */ 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 7571ed56314..d23bb6f53cd 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) */ fire_write(iommu->iommu_flushinv, ~(u64)0); - err = iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask); + err = iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask, + pbm->numa_node); if (err) return err; @@ -449,6 +450,8 @@ static int __init pci_fire_pbm_init(struct pci_controller_info *p, pbm->next = pci_pbm_root; pci_pbm_root = pbm; + pbm->numa_node = -1; + pbm->scan_bus = pci_fire_scan_bus; pbm->pci_ops = &sun4u_pci_ops; pbm->config_space_reg_bits = 12; diff --git a/arch/sparc64/kernel/pci_impl.h b/arch/sparc64/kernel/pci_impl.h index 4a50da13ce4..218bac4ff79 100644 --- a/arch/sparc64/kernel/pci_impl.h +++ b/arch/sparc64/kernel/pci_impl.h @@ -148,6 +148,8 @@ struct pci_pbm_info { struct pci_bus *pci_bus; void (*scan_bus)(struct pci_pbm_info *); struct pci_ops *pci_ops; + + int numa_node; }; struct pci_controller_info { @@ -161,8 +163,6 @@ extern struct pci_pbm_info *pci_pbm_root; extern int pci_num_pbms; /* PCI bus scanning and fixup support. */ -extern void pci_iommu_table_init(struct iommu *iommu, int tsbsize, - u32 dma_offset, u32 dma_addr_mask); extern void pci_get_pbm_props(struct pci_pbm_info *pbm); extern struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm); 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 d6d64b44af6..db5e8fd8f67 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, unsigned long devino) { int irq = ops->msiq_build_irq(pbm, msiqid, devino); - int err; + int err, nid; if (irq < 0) return irq; + nid = pbm->numa_node; + if (nid != -1) { + cpumask_t numa_mask = node_to_cpumask(nid); + + irq_set_affinity(irq, numa_mask); + } err = request_irq(irq, sparc64_msiq_interrupt, 0, "MSIQ", &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 0bad96e5d18..994dbe0603d 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) /* Leave diag mode enabled for full-flushing done * in pci_iommu.c */ - err = iommu_table_init |