]> nv-tegra.nvidia Code Review - linux-2.6.git/commitdiff
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
authorLinus Torvalds <torvalds@g5.osdl.org>
Sat, 21 Oct 2006 20:40:29 +0000 (13:40 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Sat, 21 Oct 2006 20:40:29 +0000 (13:40 -0700)
* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6: (22 commits)
  [PATCH] ibmveth: Fix index increment calculation
  [PATCH] Fix timer race
  [PATCH] Remove useless comment from sb1250
  [PATCH] ucc_geth: changes to ucc_geth driver as a result of qe_lib changes and bugfixes
  [PATCH] sky2: 88E803X transmit lockup
  [PATCH] e1000: Reset all functions after a PCI error
  [PATCH] WAN/pc300: handle, propagate minor errors
  [PATCH] Update smc91x driver with ARM Versatile board info
  [PATCH] wireless: WE-20 compatibility for ESSID and NICKN ioctls
  [PATCH] zd1211rw: fix build-break caused by association race fix
  [PATCH] sotftmac: fix a slab corruption in WEP restricted key association
  [PATCH] airo: check if need to freeze
  [PATCH] wireless: More WE-21 potential overflows...
  [PATCH] zd1201: Possible NULL dereference
  [PATCH] orinoco: fix WE-21 buffer overflow
  [PATCH] airo.c: check returned values
  [PATCH] bcm43xx-softmac: Fix system hang for x86-64 with >1GB RAM
  [PATCH] bcm43xx-softmac: check returned value from pci_enable_device
  [PATCH] softmac: Fix WX and association related races
  [PATCH] bcm43xx: fix race condition in periodic work handler
  ...

48 files changed:
Makefile
arch/i386/Makefile
arch/i386/defconfig
arch/i386/kernel/head.S
arch/i386/kernel/nmi.c
arch/i386/kernel/process.c
arch/powerpc/Kconfig
arch/powerpc/configs/pseries_defconfig
arch/x86_64/Makefile
arch/x86_64/defconfig
arch/x86_64/kernel/e820.c
arch/x86_64/kernel/early-quirks.c
arch/x86_64/kernel/entry.S
arch/x86_64/kernel/genapic_flat.c
arch/x86_64/kernel/io_apic.c
arch/x86_64/kernel/vmlinux.lds.S
arch/x86_64/mm/srat.c
arch/x86_64/pci/Makefile
drivers/block/cciss.c
drivers/char/agp/uninorth-agp.c
drivers/char/moxa.c
drivers/char/rio/host.h
drivers/char/rio/rio_linux.c
drivers/clocksource/acpi_pm.c
drivers/firmware/dmi_scan.c
drivers/ide/pci/generic.c
drivers/md/bitmap.c
drivers/md/md.c
drivers/md/multipath.c
drivers/md/raid10.c
drivers/message/i2o/exec-osm.c
fs/dcache.c
fs/nfs/dir.c
include/asm-generic/vmlinux.lds.h
include/asm-x86_64/pgtable.h
include/asm-x86_64/proto.h
include/linux/compat_ioctl.h
include/linux/dmi.h
include/linux/mempolicy.h
include/linux/mmzone.h
include/linux/pci.h
include/linux/raid/bitmap.h
include/linux/raid/md_p.h
include/linux/unwind.h
init/main.c
kernel/unwind.c
mm/page_alloc.c
mm/slab.c

index 62a1343cf327c84e0afae0128b7d705c9330966b..389ff0cca9a7f3e0f3a5c8dba0c8f6539e79763c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -499,6 +499,7 @@ endif
 
 ifdef CONFIG_UNWIND_INFO
 CFLAGS         += -fasynchronous-unwind-tables
+LDFLAGS_vmlinux        += --eh-frame-hdr
 endif
 
 ifdef CONFIG_DEBUG_INFO
index 7cc0b189b82baa80d83d813a11ec256243a6cb0c..0677908dfa0600dd3f5cf9e315d4ad62154aca3f 100644 (file)
@@ -42,6 +42,10 @@ cflags-$(CONFIG_REGPARM) += -mregparm=3
 # temporary until string.h is fixed
 cflags-y += -ffreestanding
 
+# this works around some issues with generating unwind tables in older gccs
+# newer gccs do it by default
+cflags-y += -maccumulate-outgoing-args
+
 # Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use
 # a lot more stack due to the lack of sharing of stacklots:
 CFLAGS                         += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-option,-fno-unit-at-a-time); fi ;)
@@ -51,8 +55,8 @@ cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
 AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
 
 # is .cfi_signal_frame supported too?
-cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
-AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
+cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
+AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
 
 CFLAGS += $(cflags-y)
 
index 60c0c02574f08c7edad60a99e0125d5c96a8539a..97aacd6bd7d810a85c15f9d96811167b5b680165 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19-rc1
-# Thu Oct  5 13:04:53 2006
+# Linux kernel version: 2.6.19-rc2-git4
+# Sat Oct 21 03:38:56 2006
 #
 CONFIG_X86_32=y
 CONFIG_GENERIC_TIME=y
@@ -380,8 +380,8 @@ CONFIG_INET6_XFRM_MODE_TRANSPORT=y
 CONFIG_INET6_XFRM_MODE_TUNNEL=y
 # CONFIG_INET6_XFRM_MODE_BEET is not set
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
 # CONFIG_IPV6_TUNNEL is not set
-# CONFIG_IPV6_SUBTREES is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
@@ -482,6 +482,13 @@ CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
 
+#
+# Misc devices
+#
+# CONFIG_IBM_ASM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
 #
 # ATA/ATAPI/MFM/RLL support
 #
@@ -1024,6 +1031,7 @@ CONFIG_HANGCHECK_TIMER=y
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -1031,12 +1039,6 @@ CONFIG_HANGCHECK_TIMER=y
 # CONFIG_HWMON is not set
 # CONFIG_HWMON_VID is not set
 
-#
-# Misc devices
-#
-# CONFIG_IBM_ASM is not set
-# CONFIG_TIFM_CORE is not set
-
 #
 # Multimedia devices
 #
@@ -1169,7 +1171,6 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
 
 #
 # USB Imaging devices
@@ -1215,6 +1216,7 @@ CONFIG_USB_MON=y
 # CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -1284,6 +1286,7 @@ CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 # CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -1307,6 +1310,7 @@ CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 CONFIG_AUTOFS4_FS=y
 # CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -1384,7 +1388,6 @@ CONFIG_SUNRPC=y
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
 # CONFIG_9P_FS is not set
-CONFIG_GENERIC_ACL=y
 
 #
 # Partition Types
@@ -1436,10 +1439,6 @@ CONFIG_NLS_ISO8859_15=y
 # CONFIG_NLS_KOI8_U is not set
 CONFIG_NLS_UTF8=y
 
-#
-# Distributed Lock Manager
-#
-
 #
 # Instrumentation Support
 #
@@ -1480,6 +1479,7 @@ CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_UNWIND_INFO=y
 CONFIG_STACK_UNWIND=y
 # CONFIG_FORCED_INLINING is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_LKDTM is not set
 CONFIG_EARLY_PRINTK=y
index be9d883c62ce0302995b56c830530670902a7fe6..ca31f18d277c5487e3afab809783f9d79beb4fbe 100644 (file)
@@ -317,7 +317,7 @@ is386:      movl $2,%ecx            # set MP
        movl %eax,%gs
        lldt %ax
        cld                     # gcc2 wants the direction flag cleared at all times
-       pushl %eax              # fake return address
+       pushl $0                # fake return address for unwinder
 #ifdef CONFIG_SMP
        movb ready, %cl
        movb $1, ready
index 3e8e3adb04896243323922cc0dadf3b94429c0c1..eaafe233a5da83f4abbb2c17e670b8a46fa4edaa 100644 (file)
@@ -219,11 +219,11 @@ static int __init check_nmi_watchdog(void)
        int cpu;
 
        /* Enable NMI watchdog for newer systems.
-           Actually it should be safe for most systems before 2004 too except
-          for some IBM systems that corrupt registers when NMI happens
-          during SMM. Unfortunately we don't have more exact information
-          on these and use this coarse check. */
-       if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004)
+          Probably safe on most older systems too, but let's be careful.
+          IBM ThinkPads use INT10 inside SMM and that allows early NMI inside SMM
+          which hangs the system. Disable watchdog for all thinkpads */
+       if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004 &&
+               !dmi_name_in_vendors("ThinkPad"))
                nmi_watchdog = NMI_LOCAL_APIC;
 
        if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DEFAULT))
index 57d375900afb0643cf64f10b52ed49462131d001..1e1fa3e391a3889ec822c869c19bd9feb76e5e36 100644 (file)
@@ -336,7 +336,6 @@ extern void kernel_thread_helper(void);
 int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
 {
        struct pt_regs regs;
-       int err;
 
        memset(&regs, 0, sizeof(regs));
 
@@ -351,10 +350,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
        regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
 
        /* Ok, create the new process.. */
-       err = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
-       if (err == 0) /* terminate kernel stack */
-               task_pt_regs(current)->eip = 0;
-       return err;
+       return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
 }
 EXPORT_SYMBOL(kernel_thread);
 
index 8b6910465578b02cf8d00b9c9326f302d7ef5b5e..2bd9b7fb0f6c91cc7e35bdedf3bafed7f897e7a3 100644 (file)
@@ -751,6 +751,15 @@ config ARCH_MEMORY_PROBE
        def_bool y
        depends on MEMORY_HOTPLUG
 
+# 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 PPC_64K_PAGES
        bool "64k page size"
        depends on PPC64
index 9828663652e9eb8eaa79d6983b7ad233550e6bb0..d2833c1a1f3d784f7b0b37302fb9728a64516dea 100644 (file)
@@ -184,6 +184,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
 CONFIG_RESOURCES_64BIT=y
 CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
+CONFIG_NODES_SPAN_OTHER_NODES=y
 # CONFIG_PPC_64K_PAGES is not set
 CONFIG_SCHED_SMT=y
 CONFIG_PROC_DEVICETREE=y
index 1c0f18d4f887a574734df7b6302ef8c362b8533d..13972148058dac9cae6c7e2829bf4c5b73b78bd9 100644 (file)
@@ -54,6 +54,10 @@ endif
 cflags-y += $(call cc-option,-funit-at-a-time)
 # prevent gcc from generating any FP code by mistake
 cflags-y += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,)
+# this works around some issues with generating unwind tables in older gccs
+# newer gccs do it by default
+cflags-y += -maccumulate-outgoing-args
+
 # do binutils support CFI?
 cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
 AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
index 47bfba6e9dc4d3d93ce8110d2eb13bf8b984eecb..0f5d44e86be56d8b3f61a2f204d24a720b6ef92d 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19-rc1
-# Thu Oct  5 13:04:43 2006
+# Linux kernel version: 2.6.19-rc2-git4
+# Sat Oct 21 03:38:52 2006
 #
 CONFIG_X86_64=y
 CONFIG_64BIT=y
@@ -335,8 +335,8 @@ CONFIG_IPV6=y
 # CONFIG_INET6_XFRM_MODE_TUNNEL is not set
 # CONFIG_INET6_XFRM_MODE_BEET is not set
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
 # CONFIG_IPV6_TUNNEL is not set
-# CONFIG_IPV6_SUBTREES is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
@@ -437,6 +437,13 @@ CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
 
+#
+# Misc devices
+#
+# CONFIG_IBM_ASM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
 #
 # ATA/ATAPI/MFM/RLL support
 #
@@ -1008,6 +1015,7 @@ CONFIG_I2C_ISA=m
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -1058,12 +1066,6 @@ CONFIG_SENSORS_SMSC47B397=m
 # CONFIG_SENSORS_HDAPS is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
-#
-# Misc devices
-#
-# CONFIG_IBM_ASM is not set
-# CONFIG_TIFM_CORE is not set
-
 #
 # Multimedia devices
 #
@@ -1196,7 +1198,6 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
 
 #
 # USB Imaging devices
@@ -1242,6 +1243,7 @@ CONFIG_USB_MON=y
 # CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -1318,6 +1320,7 @@ CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 # CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -1341,6 +1344,7 @@ CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 CONFIG_AUTOFS4_FS=y
 # CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -1418,7 +1422,6 @@ CONFIG_SUNRPC=y
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
 # CONFIG_9P_FS is not set
-CONFIG_GENERIC_ACL=y
 
 #
 # Partition Types
@@ -1470,10 +1473,6 @@ CONFIG_NLS_ISO8859_15=y
 # CONFIG_NLS_KOI8_U is not set
 CONFIG_NLS_UTF8=y
 
-#
-# Distributed Lock Manager
-#
-
 #
 # Instrumentation Support
 #
@@ -1512,6 +1511,7 @@ CONFIG_DEBUG_FS=y
 CONFIG_UNWIND_INFO=y
 CONFIG_STACK_UNWIND=y
 # CONFIG_FORCED_INLINING is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_LKDTM is not set
 # CONFIG_DEBUG_RODATA is not set
index b3f0908668ece23c11fc4d42675f011aab808821..a75c829c2b02b16bf23ea495a326d0307cd9685b 100644 (file)
@@ -54,13 +54,13 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size)
 
        /* various gunk below that needed for SMP startup */
        if (addr < 0x8000) { 
-               *addrp = 0x8000;
+               *addrp = PAGE_ALIGN(0x8000);
                return 1; 
        }
 
        /* direct mapping tables of the kernel */
        if (last >= table_start<<PAGE_SHIFT && addr < table_end<<PAGE_SHIFT) { 
-               *addrp = table_end << PAGE_SHIFT; 
+               *addrp = PAGE_ALIGN(table_end << PAGE_SHIFT);
                return 1;
        } 
 
@@ -68,18 +68,18 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size)
 #ifdef CONFIG_BLK_DEV_INITRD
        if (LOADER_TYPE && INITRD_START && last >= INITRD_START && 
            addr < INITRD_START+INITRD_SIZE) { 
-               *addrp = INITRD_START + INITRD_SIZE; 
+               *addrp = PAGE_ALIGN(INITRD_START + INITRD_SIZE);
                return 1;
        } 
 #endif
        /* kernel code */
-       if (last >= __pa_symbol(&_text) && last < __pa_symbol(&_end)) {
-               *addrp = __pa_symbol(&_end);
+       if (last >= __pa_symbol(&_text) && addr < __pa_symbol(&_end)) {
+               *addrp = PAGE_ALIGN(__pa_symbol(&_end));
                return 1;
        }
 
        if (last >= ebda_addr && addr < ebda_addr + ebda_size) {
-               *addrp = ebda_addr + ebda_size;
+               *addrp = PAGE_ALIGN(ebda_addr + ebda_size);
                return 1;
        }
 
@@ -152,7 +152,7 @@ unsigned long __init find_e820_area(unsigned long start, unsigned long end, unsi
                        continue; 
                while (bad_addr(&addr, size) && addr+size <= ei->addr+ei->size)
                        ;
-               last = addr + size;
+               last = PAGE_ALIGN(addr) + size;
                if (last > ei->addr + ei->size)
                        continue;
                if (last > end) 
index 208e38a372c107f0704dd16e77f56437c404f1e4..2b1245d8625849de6033eda814ed72b860faf232 100644 (file)
@@ -61,10 +61,11 @@ static void nvidia_bugs(void)
 
 static void ati_bugs(void)
 {
-#if 1 /* for testing */
-       printk("ATI board detected\n");
-#endif
-       /* No bugs right now */
+       if (timer_over_8254 == 1) {
+               timer_over_8254 = 0;
+               printk(KERN_INFO
+               "ATI board detected. Disabling timer routing over 8254.\n");
+       }
 }
 
 struct chipset {
index 38a7b2d528e2e537b78d13bc83e36dbb25f79c10..7d401b00d8227dbd6182524259a402822a903db6 100644 (file)
@@ -315,6 +315,8 @@ tracesys:
        LOAD_ARGS ARGOFFSET  /* reload args from stack in case ptrace changed it */
        RESTORE_REST
        cmpq $__NR_syscall_max,%rax
+       movq $-ENOSYS,%rcx
+       cmova %rcx,%rax
        ja  1f
        movq %r10,%rcx  /* fixup for C */
        call *sys_call_table(,%rax,8)
@@ -535,8 +537,6 @@ END(stub_rt_sigreturn)
 1:     incl    %gs:pda_irqcount
        cmoveq %gs:pda_irqstackptr,%rsp
        push    %rbp                    # backlink for old unwinder
-       CFI_ADJUST_CFA_OFFSET 8
-       CFI_REL_OFFSET rbp,0
        /*
         * We entered an interrupt context - irqs are off:
         */
@@ -980,11 +980,6 @@ ENTRY(kernel_thread)
        call do_fork
        movq %rax,RAX(%rsp)
        xorl %edi,%edi
-       test %rax,%rax
-       jnz  1f
-       /* terminate stack in child */
-       movq %rdi,RIP(%rsp)
-1:
 
        /*
         * It isn't worth to check for reschedule here,
@@ -1176,7 +1171,6 @@ ENTRY(call_softirq)
        incl %gs:pda_irqcount
        cmove %gs:pda_irqstackptr,%rsp
        push  %rbp                      # backlink for old unwinder
-       CFI_ADJUST_CFA_OFFSET    8
        call __do_softirq
        leaveq
        CFI_DEF_CFA_REGISTER    rsp
index 0dfc223c1839c9bbd58473f108b63f517177d2a4..7c01db8fa9d122eaf2adcff1e0927ec98a2e17e3 100644 (file)
@@ -153,7 +153,7 @@ struct genapic apic_flat =  {
 
 static cpumask_t physflat_target_cpus(void)
 {
-       return cpumask_of_cpu(0);
+       return cpu_online_map;
 }
 
 static cpumask_t physflat_vector_allocation_domain(int cpu)
index 49e94f7994c54f29fcc067533ab41563213b00bb..b000017e4b5da80f336588e321982217599cf848 100644 (file)
@@ -57,7 +57,7 @@ static int no_timer_check;
 
 static int disable_timer_pin_1 __initdata;
 
-int timer_over_8254 __initdata = 0;
+int timer_over_8254 __initdata = 1;
 
 /* Where if anywhere is the i8259 connect in external int mode */
 static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
@@ -651,12 +651,12 @@ next:
                if (vector == IA32_SYSCALL_VECTOR)
                        goto next;
                for_each_cpu_mask(new_cpu, domain)
-                       if (per_cpu(vector_irq, cpu)[vector] != -1)
+                       if (per_cpu(vector_irq, new_cpu)[vector] != -1)
                                goto next;
                /* Found one! */
                for_each_cpu_mask(new_cpu, domain) {
-                       pos[cpu].vector = vector;
-                       pos[cpu].offset = offset;
+                       pos[new_cpu].vector = vector;
+                       pos[new_cpu].offset = offset;
                }
                if (old_vector >= 0) {
                        int old_cpu;
@@ -1255,12 +1255,15 @@ static int ioapic_retrigger_irq(unsigned int irq)
 {
        cpumask_t mask;
        unsigned vector;
+       unsigned long flags;
 
+       spin_lock_irqsave(&vector_lock, flags);
        vector = irq_vector[irq];
        cpus_clear(mask);
-       cpu_set(vector >> 8, mask);
+       cpu_set(first_cpu(irq_domain[irq]), mask);
 
-       send_IPI_mask(mask, vector & 0xff);
+       send_IPI_mask(mask, vector);
+       spin_unlock_irqrestore(&vector_lock, flags);
 
        return 1;
 }
index b9df2ab6529fc8286b00f41d2081d393bbb2b444..1283614c9b247674ee75fd865744c9a95d902379 100644 (file)
@@ -17,6 +17,7 @@ PHDRS {
        text PT_LOAD FLAGS(5);  /* R_E */
        data PT_LOAD FLAGS(7);  /* RWE */
        user PT_LOAD FLAGS(7);  /* RWE */
+       data.init PT_LOAD FLAGS(7);     /* RWE */
        note PT_NOTE FLAGS(4);  /* R__ */
 }
 SECTIONS
@@ -131,7 +132,7 @@ SECTIONS
   . = ALIGN(8192);             /* init_task */
   .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
        *(.data.init_task)
-  } :data
+  }:data.init
 
   . = ALIGN(4096);
   .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
index 3cc0544e25f5a8569af1a727c3f819b252fe3635..1087e150a21896d1abfaadfccfe7fc4de98728ef 100644 (file)
@@ -207,7 +207,7 @@ static inline int save_add_info(void)
        return hotadd_percent > 0;
 }
 #else
-int update_end_of_memory(unsigned long end) {return 0;}
+int update_end_of_memory(unsigned long end) {return -1;}
 static int hotadd_enough_memory(struct bootnode *nd) {return 1;}
 #ifdef CONFIG_MEMORY_HOTPLUG_SPARSE
 static inline int save_add_info(void) {return 1;}
@@ -337,7 +337,7 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
        push_node_boundaries(node, nd->start >> PAGE_SHIFT,
                                                nd->end >> PAGE_SHIFT);
 
-       if (ma->flags.hot_pluggable && !reserve_hotadd(node, start, end) < 0) {
+       if (ma->flags.hot_pluggable && (reserve_hotadd(node, start, end) < 0)) {
                /* Ignore hotadd region. Undo damage */
                printk(KERN_NOTICE "SRAT: Hotplug region ignored\n");
                *nd = oldnode;
index 1eb18f421edff11924187e8242781bd68116a168..149aba05a5b8e70c6abb22dd17e21b1f1994adf4 100644 (file)
@@ -3,7 +3,7 @@
 #
 # Reuse the i386 PCI subsystem
 #
-CFLAGS += -Iarch/i386/pci
+EXTRA_CFLAGS += -Iarch/i386/pci
 
 obj-y          := i386.o
 obj-$(CONFIG_PCI_DIRECT)+= direct.o
index dcccaf2782f350cd68efa6fd431a0dc90cd05289..bc6602606fb541726f1537f610cc4d80d340ca2d 100644 (file)
@@ -1923,7 +1923,6 @@ static void cciss_geometry_inquiry(int ctlr, int logvol,
 {
        int return_code;
        unsigned long t;
-       unsigned long rem;
 
        memset(inq_buff, 0, sizeof(InquiryData_struct));
        if (withirq)
@@ -1939,26 +1938,23 @@ static void cciss_geometry_inquiry(int ctlr, int logvol,
                        printk(KERN_WARNING
                               "cciss: reading geometry failed, volume "
                               "does not support reading geometry\n");
-                       drv->block_size = block_size;
-                       drv->nr_blocks = total_size;
                        drv->heads = 255;
                        drv->sectors = 32;      // Sectors per track
-                       t = drv->heads * drv->sectors;
-                       drv->cylinders = total_size;
-                       rem = do_div(drv->cylinders, t);
                } else {
-                       drv->block_size = block_size;
-                       drv->nr_blocks = total_size;
                        drv->heads = inq_buff->data_byte[6];
                        drv->sectors = inq_buff->data_byte[7];
                        drv->cylinders = (inq_buff->data_byte[4] & 0xff) << 8;
                        drv->cylinders += inq_buff->data_byte[5];
                        drv->raid_level = inq_buff->data_byte[8];
-                       t = drv->heads * drv->sectors;
-                       if (t > 1) {
-                               drv->cylinders = total_size;
-                               rem = do_div(drv->cylinders, t);
-                       }
+               }
+               drv->block_size = block_size;
+               drv->nr_blocks = total_size;
+               t = drv->heads * drv->sectors;
+               if (t > 1) {
+                       unsigned rem = sector_div(total_size, t);
+                       if (rem)
+                               total_size++;
+                       drv->cylinders = total_size;
                }
        } else {                /* Get geometry failed */
                printk(KERN_WARNING "cciss: reading geometry failed\n");
index 91b71e750ee15f16a0372a3f7d8559c4fa2d6d72..dffc19382f7eb828f73426e91b7524f5ffce3305 100644 (file)
 static int uninorth_rev;
 static int is_u3;
 
+static char __devinitdata *aperture = NULL;
 
 static int uninorth_fetch_size(void)
 {
-       int i;
-       u32 temp;
-       struct aper_size_info_32 *values;
-
-       pci_read_config_dword(agp_bridge->dev, UNI_N_CFG_GART_BASE, &temp);
-       temp &= ~(0xfffff000);
-       values = A_SIZE_32(agp_bridge->driver->aperture_sizes);
-
-       for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
-               if (temp == values[i].size_value) {
-                       agp_bridge->previous_size =
-                           agp_bridge->current_size = (void *) (values + i);
-                       agp_bridge->aperture_size_idx = i;
-                       return values[i].size;
+       int i, size = 0;
+       struct aper_size_info_32 *values =
+           A_SIZE_32(agp_bridge->driver->aperture_sizes);
+
+       if (aperture) {
+               char *save = aperture;
+
+               size = memparse(aperture, &aperture) >> 20;
+               aperture = save;
+
+               for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++)
+                       if (size == values[i].size)
+                               break;
+
+               if (i == agp_bridge->driver->num_aperture_sizes) {
+                       printk(KERN_ERR PFX "Invalid aperture size, using"
+                              " default\n");
+                       size = 0;
+                       aperture = NULL;
                }
        }
 
-       agp_bridge->previous_size =
-           agp_bridge->current_size = (void *) (values + 1);
-       agp_bridge->aperture_size_idx = 1;
-       return values[1].size;
+       if (!size) {
+               for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++)
+                       if (values[i].size == 32)
+                               break;
+       }
 
-       return 0;
+       agp_bridge->previous_size =
+           agp_bridge->current_size = (void *)(values + i);
+       agp_bridge->aperture_size_idx = i;
+       return values[i].size;
 }
 
 static void uninorth_tlbflush(struct agp_memory *mem)
@@ -683,5 +693,11 @@ static void __exit agp_uninorth_cleanup(void)
 module_init(agp_uninorth_init);
 module_exit(agp_uninorth_cleanup);
 
+module_param(aperture, charp, 0);
+MODULE_PARM_DESC(aperture,
+                "Aperture size, must be power of two between 4MB and an\n"
+                "\t\tupper limit specific to the UniNorth revision.\n"
+                "\t\tDefault: 32M");
+
 MODULE_AUTHOR("Ben Herrenschmidt & Paul Mackerras");
 MODULE_LICENSE("GPL");
index b401383808c26ac4c16ce38f15fc129b4dafd56a..96cb1f07332b68e5fb5b77dfb68a74d6356c6b64 100644 (file)
@@ -130,6 +130,7 @@ static moxa_isa_board_conf moxa_isa_boards[] =
 typedef struct _moxa_pci_devinfo {
        ushort busNum;
        ushort devNum;
+       struct pci_dev *pdev;
 } moxa_pci_devinfo;
 
 typedef struct _moxa_board_conf {
@@ -324,6 +325,9 @@ static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf
        board->busType = MOXA_BUS_TYPE_PCI;
        board->pciInfo.busNum = p->bus->number;
        board->pciInfo.devNum = p->devfn >> 3;
+       board->pciInfo.pdev = p;
+       /* don't lose the reference in the next pci_get_device iteration */
+       pci_dev_get(p);
 
        return (0);
 }
@@ -493,6 +497,11 @@ static void __exit moxa_exit(void)
        if (tty_unregister_driver(moxaDriver))
                printk("Couldn't unregister MOXA Intellio family serial driver\n");
        put_tty_driver(moxaDriver);
+
+       for (i = 0; i < MAX_BOARDS; i++)
+               if (moxa_boards[i].busType == MOXA_BUS_TYPE_PCI)
+                       pci_dev_put(moxa_boards[i].pciInfo.pdev);
+
        if (verbose)
                printk("Done\n");
 }
index ee2ddea7a63a838e084f1103f7df5147f2b417f0..23d0681fe491abffeb08795f4028cc017c297b16 100644 (file)
@@ -44,6 +44,7 @@
 **    the host.
 */
 struct Host {
+       struct pci_dev *pdev;
        unsigned char Type;             /* RIO_EISA, RIO_MCA, ... */
        unsigned char Ivec;             /* POLLED or ivec number */
        unsigned char Mode;             /* Control stuff */
index c382df0f82f60957efd73391cc69c17e1577e0b7..7ac68cb3beddfa61df80e8ca0cfb22a3b53cf70b 100644 (file)
@@ -1017,6 +1017,10 @@ static int __init rio_init(void)
                        rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum);
 
                        fix_rio_pci(pdev);
+
+                       p->RIOHosts[p->RIONumHosts].pdev = pdev;
+                       pci_dev_get(pdev);
+
                        p->RIOLastPCISearch = 0;
                        p->RIONumHosts++;
                        found++;
@@ -1066,6 +1070,9 @@ static int __init rio_init(void)
                            ((readb(&p->RIOHosts[p->RIONumHosts].Unique[1]) & 0xFF) << 8) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[2]) & 0xFF) << 16) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[3]) & 0xFF) << 24);
                        rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum);
 
+                       p->RIOHosts[p->RIONumHosts].pdev = pdev;
+                       pci_dev_get(pdev);
+
                        p->RIOLastPCISearch = 0;
                        p->RIONumHosts++;
                        found++;
@@ -1181,6 +1188,8 @@ static void __exit rio_exit(void)
                }
                /* It is safe/allowed to del_timer a non-active timer */
                del_timer(&hp->timer);
+               if (hp->Type == RIO_PCI)
+                       pci_dev_put(hp->pdev);
        }
 
        if (misc_deregister(&rio_fw_device) < 0) {
index 7ad3be8c0f49e4f0bfc1722418ba377e9712de74..7fcb77a9d0111855948d5a02003c2845e8f5a8b3 100644 (file)
@@ -54,8 +54,8 @@ static cycle_t acpi_pm_read_verified(void)
                v1 = read_pmtmr();
                v2 = read_pmtmr();
                v3 = read_pmtmr();
-       } while ((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1)
-                       || (v3 > v1 && v3 < v2));
+       } while (unlikely((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1)
+                         || (v3 > v1 && v3 < v2)));
 
        return (cycle_t)v2;
 }
@@ -138,6 +138,8 @@ static void __devinit acpi_pm_check_graylist(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,
                        acpi_pm_check_graylist);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_LE,
+                       acpi_pm_check_graylist);
 #endif
 
 
index b8b596d5778dbe03295395eccbad2176a25c3bfa..37deee6c0c1cc5aa4ca575797dea77d6ad792243 100644 (file)
@@ -326,6 +326,26 @@ char *dmi_get_system_info(int field)
 }
 EXPORT_SYMBOL(dmi_get_system_info);
 
+
+/**
+ *     dmi_name_in_vendors - Check if string is anywhere in the DMI vendor information.
+ *     @str:   Case sensitive Name
+ */
+int dmi_name_in_vendors(char *str)
+{
+       static int fields[] = { DMI_BIOS_VENDOR, DMI_BIOS_VERSION, DMI_SYS_VENDOR,
+                               DMI_PRODUCT_NAME, DMI_PRODUCT_VERSION, DMI_BOARD_VENDOR,
+                               DMI_BOARD_NAME, DMI_BOARD_VERSION, DMI_NONE };
+       int i;
+       for (i = 0; fields[i] != DMI_NONE; i++) {
+               int f = fields[i];
+               if (dmi_ident[f] && strstr(dmi_ident[f], str))
+                       return 1;
+       }
+       return 0;
+}
+EXPORT_SYMBOL(dmi_name_in_vendors);
+
 /**
  *     dmi_find_device - find onboard device by type/name
  *     @type: device type or %DMI_DEV_TYPE_ANY to match all device types
index 5b77a5bcbf0c113b7a95f8ffc04bfa302292677a..ad418ce882cae837a77537fc8e54f2b909bfac7f 100644 (file)
 
 static int ide_generic_all;            /* Set to claim all devices */
 
+/*
+ * the module_param_named() was added for the modular case
+ * the __setup() is left as compatibility for existing setups
+ */
+#ifndef MODULE
+static int __init ide_generic_all_on(char *unused)
+{
+       ide_generic_all = 1;
+       printk(KERN_INFO "IDE generic will claim all unknown PCI IDE storage controllers.");
+       return 1;
+}
+__setup("all-generic-ide", ide_generic_all_on);
+#endif
 module_param_named(all_generic_ide, ide_generic_all, bool, 0444);
 MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers.");
 
index d47d38ac71b16f31f530d1bfd9656eb0e288f401..d6f614738bbd732e24cd039af3a05ffb01e01373 100644 (file)
@@ -536,7 +536,7 @@ static int bitmap_read_sb(struct bitmap *bitmap)
                printk(KERN_INFO "%s: bitmap file is out of date (%llu < %llu) "
                        "-- forcing full recovery\n", bmname(bitmap), events,
                        (unsigned long long) bitmap->mddev->events);
-               sb->state |= BITMAP_STALE;
+               sb->state |= cpu_to_le32(BITMAP_STALE);
        }
 success:
        /* assign fields using values from superblock */
@@ -544,11 +544,11 @@ success:
        bitmap->daemon_sleep = daemon_sleep;
        bitmap->daemon_lastrun = jiffies;
        bitmap->max_write_behind = write_behind;
-       bitmap->flags |= sb->state;
+       bitmap->flags |= le32_to_cpu(sb->state);
        if (le32_to_cpu(sb->version) == BITMAP_MAJOR_HOSTENDIAN)
                bitmap->flags |= BITMAP_HOSTENDIAN;
        bitmap->events_cleared = le64_to_cpu(sb->events_cleared);
-       if (sb->state & BITMAP_STALE)
+       if (sb->state & cpu_to_le32(BITMAP_STALE))
                bitmap->events_cleared = bitmap->mddev->events;
        err = 0;
 out:
@@ -578,9 +578,9 @@ static void bitmap_mask_state(struct bitmap *bitmap, enum bitmap_state bits,
        spin_unlock_irqrestore(&bitmap->lock, flags);
        sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0);
        switch (op) {
-               case MASK_SET: sb->state |= bits;
+               case MASK_SET: sb->state |= cpu_to_le32(bits);
                                break;
-               case MASK_UNSET: sb->state &= ~bits;
+               case MASK_UNSET: sb->state &= cpu_to_le32(~bits);
                                break;
                default: BUG();
        }
index f7f19088f3be4f05aada21cd33873cda2d91d56b..7daa7b1e145f32d3736a48e7e9ee6e81f94c5bb8 100644 (file)
@@ -974,12 +974,13 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
  * version 1 superblock
  */
 
-static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
+static __le32 calc_sb_1_csum(struct mdp_superblock_1 * sb)
 {
-       unsigned int disk_csum, csum;
+       __le32 disk_csum;
+       u32 csum;
        unsigned long long newcsum;
        int size = 256 + le32_to_cpu(sb->max_dev)*2;
-       unsigned int *isuper = (unsigned int*)sb;
+       __le32 *isuper = (__le32*)sb;
        int i;
 
        disk_csum = sb->sb_csum;
@@ -989,7 +990,7 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
                newcsum += le32_to_cpu(*isuper++);
 
        if (size == 2)
-               newcsum += le16_to_cpu(*(unsigned short*) isuper);
+               newcsum += le16_to_cpu(*(__le16*) isuper);
 
        csum = (newcsum & 0xffffffff) + (newcsum >> 32);
        sb->sb_csum = disk_csum;
@@ -1106,7 +1107,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
        if (le32_to_cpu(sb->chunksize))
                rdev->size &= ~((sector_t)le32_to_cpu(sb->chunksize)/2 - 1);
 
-       if (le32_to_cpu(sb->size) > rdev->size*2)
+       if (le64_to_cpu(sb->size) > rdev->size*2)
                return -EINVAL;
        return ret;
 }
@@ -1228,7 +1229,7 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
        else
                sb->resync_offset = cpu_to_le64(0);
 
-       sb->cnt_corrected_read = atomic_read(&rdev->corrected_errors);
+       sb->cnt_corrected_read = cpu_to_le32(atomic_read(&rdev->corrected_errors));
 
        sb->raid_disks = cpu_to_le32(mddev->raid_disks);
        sb->size = cpu_to_le64(mddev->size<<1);
index 171ff41b52b053e7acdc2f6c78e0ef34ed2bd695..a6260f0e3b9e57bf756ac32c8e75f15c37d47f12 100644 (file)
@@ -501,7 +501,7 @@ static int multipath_run (mddev_t *mddev)
                        mdname(mddev));
                goto out_free_conf;
        }
-       mddev->degraded = conf->raid_disks = conf->working_disks;
+       mddev->degraded = conf->raid_disks - conf->working_disks;
 
        conf->pool = mempool_create_kzalloc_pool(NR_RESERVED_BUFS,
                                                 sizeof(struct multipath_bh));
index 1250f0eab4afaf7b2c946a3c3767c25efc062bfc..74f17a9a6ebb78cca440a4c08b317b3f74a414a3 100644 (file)
@@ -2079,7 +2079,7 @@ static int run(mddev_t *mddev)
                disk = conf->mirrors + i;
 
                if (!disk->rdev ||
-                   !test_bit(In_sync, &rdev->flags)) {
+                   !test_bit(In_sync, &disk->rdev->flags)) {
                        disk->head_position = 0;
                        mddev->degraded++;
                }
index 91f95d172ca54097a0b2b14d767b11aa179fed74..01a5a702b037e9c12e22fd1ef43ebd211b8f4204 100644 (file)
@@ -127,7 +127,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg,
        DECLARE_WAIT_QUEUE_HEAD(wq);
        struct i2o_exec_wait *wait;
        static u32 tcntxt = 0x80000000;
-       long flags;
+       unsigned long flags;
        int rc = 0;
 
        wait = i2o_exec_wait_alloc();
index 2bac4ba1d1d3755b70598e992847459dc889a962..a1ff91eef10810c50583962ae671f07e14737bf6 100644 (file)
@@ -1469,23 +1469,21 @@ static void switch_names(struct dentry *dentry, struct dentry *target)
  * deleted it.
  */
  
-/**
- * d_move - move a dentry
+/*
+ * d_move_locked - move a dentry
  * @dentry: entry to move
  * @target: new dentry
  *
  * Update the dcache to reflect the move of a file name. Negative
  * dcache entries should not be moved in this way.
  */
-
-void d_move(struct dentry * dentry, struct dentry * target)
+static void d_move_locked(struct dentry * dentry, struct dentry * target)
 {
        struct hlist_head *list;
 
        if (!dentry->d_inode)
                printk(KERN_WARNING "VFS: moving negative dcache entry\n");
 
-       spin_lock(&dcache_lock);
        write_seqlock(&rename_lock);
        /*
         * XXXX: do we really need to take target->d_lock?
@@ -1536,9 +1534,83 @@ already_unhashed:
        fsnotify_d_move(dentry);
        spin_unlock(&dentry->d_lock);
        write_sequnlock(&rename_lock);
+}
+
+/**
+ * d_move - move a dentry
+ * @dentry: entry to move
+ * @target: new dentry
+ *
+ * Update the dcache to reflect the move of a file name. Negative
+ * dcache entries should not be moved in this way.
+ */
+
+void d_move(struct dentry * dentry, struct dentry * target)
+{
+       spin_lock(&dcache_lock);
+       d_move_locked(dentry, target);
        spin_unlock(&dcache_lock);
 }
 
+/*
+ * Helper that returns 1 if p1 is a parent of p2, else 0
+ */
+static int d_isparent(struct dentry *p1, struct dentry *p2)
+{
+       struct dentry *p;
+
+       for (p = p2; p->d_parent != p; p = p->d_parent) {
+               if (p->d_parent == p1)
+                       return 1;
+       }
+       return 0;
+}
+
+/*
+ * This helper attempts to cope with remotely renamed directories
+ *
+ * It assumes that the caller is already holding
+ * dentry->d_parent->d_inode->i_mutex and the dcache_lock
+ *
+ * Note: If ever the locking in lock_rename() changes, then please
+ * remember to update this too...
+ *
+ * On return, dcache_lock will have been unlocked.
+ */
+static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias)
+{
+       struct mutex *m1 = NULL, *m2 = NULL;
+       struct dentry *ret;
+
+       /* If alias and dentry share a parent, then no extra locks required */
+       if (alias->d_parent == dentry->d_parent)
+               goto out_unalias;
+
+       /* Check for loops */
+       ret = ERR_PTR(-ELOOP);
+       if (d_isparent(alias, dentry))
+               goto out_err;
+
+       /* See lock_rename() */
+       ret = ERR_PTR(-EBUSY);
+       if (!mutex_trylock(&dentry->d_sb->s_vfs_rename_mutex))
+               goto out_err;
+       m1 = &dentry->d_sb->s_vfs_rename_mutex;
+       if (!mutex_trylock(&alias->d_parent->d_inode->i_mutex))
+               goto out_err;
+       m2 = &alias->d_parent->d_inode->i_mutex;
+out_unalias:
+       d_move_locked(alias, dentry);
+       ret = alias;
+out_err:
+       spin_unlock(&dcache_lock);
+       if (m2)
+               mutex_unlock(m2);
+       if (m1)
+               mutex_unlock(m1);
+       return ret;
+}
+
 /*
  * Prepare an anonymous dentry for life in the superblock's dentry tree as a
  * named dentry in place of the dentry to be replaced.
@@ -1581,7 +1653,7 @@ static void __d_materialise_dentry(struct dentry *dentry, struct dentry *anon)
  */
 struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
 {
-       struct dentry *alias, *actual;
+       struct dentry *actual;
 
        BUG_ON(!d_unhashed(dentry));
 
@@ -1593,26 +1665,27 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
                goto found_lock;
        }
 
-       /* See if a disconnected directory already exists as an anonymous root
-        * that we should splice into the tree instead */
-       if (S_ISDIR(inode->i_mode) && (alias = __d_find_alias(inode, 1))) {
-               spin_lock(&alias->d_lock);
-
-               /* Is this a mountpoint that we could splice into our tree? */
-               if (IS_ROOT(alias))
-                       goto connect_mountpoint;
-
-               if (alias->d_name.len == dentry->d_name.len &&
-                   alias->d_parent == dentry->d_parent &&
-                   memcmp(alias->d_name.name,
-                          dentry->d_name.name,
-                          dentry->d_name.len) == 0)
-                       goto replace_with_alias;
-
-               spin_unlock(&alias->d_lock);
-
-               /* Doh! Seem to be aliasing directories for some reason... */
-               dput(alias);
+       if (S_ISDIR(inode->i_mode)) {
+               struct dentry *alias;
+
+               /* Does an aliased dentry already exist? */
+               alias = __d_find_alias(inode, 0);
+               if (alias) {
+                       actual = alias;
+                       /* Is this an anonymous mountpoint that we could splice
+                        * into our tree? */
+                       if (IS_ROOT(alias)) {
+                               spin_lock(&alias->d_lock);
+                               __d_materialise_dentry(dentry, alias);
+                               __d_drop(alias);
+                               goto found;
+                       }
+                       /* Nope, but we must(!) avoid directory aliasing */
+                       actual = __d_unalias(dentry, alias);
+                       if (IS_ERR(actual))
+                               dput(alias);
+                       goto out_nolock;
+               }
        }
 
        /* Add a unique reference */
@@ -1628,7 +1701,7 @@ found:
        _d_rehash(actual);
        spin_unlock(&actual->d_lock);
        spin_unlock(&dcache_lock);
-
+out_nolock:
        if (actual == dentry) {
                security_d_instantiate(dentry, inode);
                return NULL;
@@ -1637,16 +1710,6 @@ found:
        iput(inode);
        return actual;
 
-       /* Convert the anonymous/root alias into an ordinary dentry */
-connect_mountpoint:
-       __d_materialise_dentry(dentry, alias);
-
-       /* Replace the candidate dentry with the alias in the tree */
-replace_with_alias:
-       __d_drop(alias);
-       actual = alias;
-       goto found;
-
 shouldnt_be_hashed:
        spin_unlock(&dcache_lock);
        BUG();
index 4133ef5264e53c738c1c312da874bea25e3de1bf..b34cd16f472fef71c798c0470f98cbb33f6ea10c 100644 (file)
@@ -935,8 +935,17 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
 
 no_entry:
        res = d_materialise_unique(dentry, inode);
-       if (res != NULL)
+       if (res != NULL) {
+               struct dentry *parent;
+               if (IS_ERR(res))
+                       goto out_unlock;
+               /* Was a directory renamed! */
+               parent = dget_parent(res);
+               if (!IS_ROOT(parent))
+                       nfs_mark_for_revalidate(parent->d_inode);
+               dput(parent);
                dentry = res;
+       }
        nfs_renew_times(dentry);
        nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
 out_unlock:
@@ -1132,6 +1141,8 @@ static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc)
        alias = d_materialise_unique(dentry, inode);
        if (alias != NULL) {
                dput(dentry);
+               if (IS_ERR(alias))
+                       return NULL;
                dentry = alias;
        }
 
index 69240b52f8e17931d939c96c6c2901978717b9b9..9d0d11c180d958674922d37e2d36c757fcd6142a 100644 (file)
                *(__param)                                              \
                VMLINUX_SYMBOL(__stop___param) = .;                     \
        }                                                               \
+                                                                       \
+       /* Unwind data binary search table */                           \
+       EH_FRAME_HDR                                                    \
+                                                                       \
        __end_rodata = .;                                               \
        . = ALIGN(4096);
 
                *(.kprobes.text)                                        \
                VMLINUX_SYMBOL(__kprobes_text_end) = .;
 
+#ifdef CONFIG_STACK_UNWIND
+               /* Unwind data binary search table */
+#define EH_FRAME_HDR                                                   \
+               .eh_frame_hdr : AT(ADDR(.eh_frame_hdr) - LOAD_OFFSET) { \
+                       VMLINUX_SYMBOL(__start_unwind_hdr) = .;         \
+                       *(.eh_frame_hdr)                                \
+                       VMLINUX_SYMBOL(__end_unwind_hdr) = .;           \
+               }
+#else
+#define EH_FRAME_HDR
+#endif
+
                /* DWARF debug sections.
                Symbols in the DWARF debugging sections are relative to
                the beginning of the section so we begin them at 0.  */
index 6899e770b173e4a2cb75fdd5bc664359cdf0fa7b..0555c1c4d8fa9fcda13c280997c076decc85d708 100644 (file)
@@ -366,6 +366,7 @@ static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
 { 
        pte_t pte;
        pte_val(pte) = physpage | pgprot_val(pgprot); 
+       pte_val(pte) &= __supported_pte_mask;
        return pte; 
 }
  
index c181fef786e43adcd4b114fa9922aa6a725ff2b9..e72cfcdf53448d262ce0b549de267ae470f8ebe1 100644 (file)
@@ -122,6 +122,8 @@ extern int fix_aperture;
 extern int reboot_force;
 extern int notsc_setup(char *);
 
+extern int timer_over_8254;
+
 extern int gsi_irq_sharing(int gsi);
 
 extern void smp_local_timer_interrupt(void);
index cfdb4f6a89d4a0edd2aa5ec65cf88ec88787eb13..c26c3adcfacff0aa9231d527daf75d0f2fc09336 100644 (file)
@@ -131,6 +131,7 @@ COMPATIBLE_IOCTL(RUN_ARRAY)
 COMPATIBLE_IOCTL(STOP_ARRAY)
 COMPATIBLE_IOCTL(STOP_ARRAY_RO)
 COMPATIBLE_IOCTL(RESTART_ARRAY_RW)
+COMPATIBLE_IOCTL(GET_BITMAP_FILE)
 ULONG_IOCTL(SET_BITMAP_FILE)
 /* DM */
 COMPATIBLE_IOCTL(DM_VERSION_32)
index 38dc403be70b5bc4f49aee4132ba7ea85ca61399..904bf3d2d90bb068bc3837dfc40bf45e65cdddb6 100644 (file)
@@ -69,6 +69,7 @@ extern struct dmi_device * dmi_find_device(int type, const char *name,
        struct dmi_device *from);
 extern void dmi_scan_machine(void);
 extern int dmi_get_year(int field);
+extern int dmi_name_in_vendors(char *str);
 
 #else
 
@@ -77,6 +78,7 @@ static inline char * dmi_get_system_info(int field) { return NULL; }
 static inline struct dmi_device * dmi_find_device(int type, const char *name,
        struct dmi_device *from) { return NULL; }
 static inline int dmi_get_year(int year) { return 0; }
+static inline int dmi_name_in_vendors(char *s) { return 0; }
 
 #endif
 
index 09f0f575ddff947b32ac9cdef5e8f2b07b4dff87..daabb3aa1ec6b96b5078f6236d2df87fbfe710f6 100644 (file)
@@ -150,7 +150,7 @@ extern void mpol_rebind_mm(struct mm_struct *mm, nodemask_t *new);
 extern void mpol_fix_fork_child_flag(struct task_struct *p);
 #define set_cpuset_being_rebound(x) (cpuset_being_rebound = (x))
 
-#ifdef CONFIG_CPUSET
+#ifdef CONFIG_CPUSETS
 #define current_cpuset_is_being_rebound() \
                                (cpuset_being_rebound == current->cpuset)
 #else
index 59855b8718a0a4b993a39cb825034ad081dd09cd..ed0762b283a9fd725b08a10fd2e194f89fcba3c0 100644 (file)
@@ -674,6 +674,12 @@ void sparse_init(void);
 #define sparse_index_init(_sec, _nid)  do {} while (0)
 #endif /* CONFIG_SPARSEMEM */
 
+#ifdef CONFIG_NODES_SPAN_OTHER_NODES
+#define early_pfn_in_nid(pfn, nid)     (early_pfn_to_nid(pfn) == (nid))
+#else
+#define early_pfn_in_nid(pfn, nid)     (1)
+#endif
+
 #ifndef early_pfn_valid
 #define early_pfn_valid(pfn)   (1)
 #endif
index 4689e2a699c001b797db97888f183be3b9dd396c..09be0f81b27ba37d4125f4dfa7fa2de601858b37 100644 (file)
@@ -455,7 +455,11 @@ int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap);
 int pci_find_ext_capability (struct pci_dev *dev, int cap);
 struct pci_bus *pci_find_next_bus(const struct pci_bus *from);
 
-struct pci_dev *pci_get_device (unsigned int vendor, unsigned int device, struct pci_dev *from);
+struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device,
+                               struct pci_dev *from);
+struct pci_dev *pci_get_device_reverse(unsigned int vendor, unsigned int device,
+                               struct pci_dev *from);
+
 struct pci_dev *pci_get_subsys (unsigned int vendor, unsigned int device,
                                unsigned int ss_vendor, unsigned int ss_device,
                                struct pci_dev *from);
@@ -660,7 +664,12 @@ static inline struct pci_dev *pci_find_device(unsigned int vendor, unsigned int
 static inline struct pci_dev *pci_find_slot(unsigned int bus, unsigned int devfn)
 { return NULL; }
 
-static inline struct pci_dev *pci_get_device (unsigned int vendor, unsigned int device, struct pci_dev *from)
+static inline struct pci_dev *pci_get_device(unsigned int vendor,
+                               unsigned int device, struct pci_dev *from)
+{ return NULL; }
+
+static inline struct pci_dev *pci_get_device_reverse(unsigned int vendor,
+                               unsigned int device, struct pci_dev *from)
 { return NULL; }
 
 static inline struct pci_dev *pci_get_subsys (unsigned int vendor, unsigned int device,
index 84d88775185556e4d2a8a6b0560bcfc9c202038a..ebd42a3710b4eefc44bec8a9880bd88af6472bcb 100644 (file)
@@ -146,16 +146,16 @@ enum bitmap_state {
 
 /* the superblock at the front of the bitmap file -- little endian */
 typedef struct bitmap_super_s {
-       __u32 magic;        /*  0  BITMAP_MAGIC */
-       __u32 version;      /*  4  the bitmap major for now, could change... */
-       __u8  uuid[16];     /*  8  128 bit uuid - must match md device uuid */
-       __u64 events;       /* 24  event counter for the bitmap (1)*/
-       __u64 events_cleared;/*32  event counter when last bit cleared (2) */
-       __u64 sync_size;    /* 40  the size of the md device's sync range(3) */
-       __u32 state;        /* 48  bitmap state information */
-       __u32 chunksize;    /* 52  the bitmap chunk size in bytes */
-       __u32 daemon_sleep; /* 56  seconds between disk flushes */
-       __u32 write_behind; /* 60  number of outstanding write-behind writes */
+       __le32 magic;        /*  0  BITMAP_MAGIC */
+       __le32 version;      /*  4  the bitmap major for now, could change... */
+       __u8  uuid[16];      /*  8  128 bit uuid - must match md device uuid */
+       __le64 events;       /* 24  event counter for the bitmap (1)*/
+       __le64 events_cleared;/*32  event counter when last bit cleared (2) */
+       __le64 sync_size;    /* 40  the size of the md device's sync range(3) */
+       __le32 state;        /* 48  bitmap state information */
+       __le32 chunksize;    /* 52  the bitmap chunk size in bytes */
+       __le32 daemon_sleep; /* 56  seconds between disk flushes */
+       __le32 write_behind; /* 60  number of outstanding write-behind writes */
 
        __u8  pad[256 - 64]; /* set to zero */
 } bitmap_super_t;
index b6ebc69bae54d7b22402732355279d474701f699..3f2cd98c508bfdff781b361b1b86886bd65ddda8 100644 (file)
@@ -206,52 +206,52 @@ static inline __u64 md_event(mdp_super_t *sb) {
  */
 struct mdp_superblock_1 {
        /* constant array information - 128 bytes */
-       __u32   magic;          /* MD_SB_MAGIC: 0xa92b4efc - little endian */
-       __u32   major_version;  /* 1 */
-       __u32   feature_map;    /* bit 0 set if 'bitmap_offset' is meaningful */
-       __u32   pad0;           /* always set to 0 when writing */
+       __le32  magic;          /* MD_SB_MAGIC: 0xa92b4efc - little endian */
+       __le32  major_version;  /* 1 */
+       __le32  feature_map;    /* bit 0 set if 'bitmap_offset' is meaningful */
+       __le32  pad0;           /* always set to 0 when writing */
 
        __u8    set_uuid[16];   /* user-space generated. */
        char    set_name[32];   /* set and interpreted by user-space */
 
-       __u64   ctime;          /* lo 40 bits are seconds, top 24 are microseconds or 0*/
-       __u32   level;          /* -4 (multipath), -1 (linear), 0,1,4,5 */
-       __u32   layout;         /* only for raid5 and raid10 currently */
-       __u64   size;           /* used size of component devices, in 512byte sectors */
+       __le64  ctime;          /* lo 40 bits are seconds, top 24 are microseconds or 0*/
+       __le32  level;          /* -4 (multipath), -1 (linear), 0,1,4,5 */
+       __le32  layout;         /* only for raid5 and raid10 currently */
+       __le64  size;           /* used size of component devices, in 512byte sectors */
 
-       __u32   chunksize;      /* in 512byte sectors */
-       __u32   raid_disks;
-       __u32   bitmap_offset;  /* sectors after start of superblock that bitmap starts
+       __le32  chunksize;      /* in 512byte sectors */
+       __le32  raid_disks;
+       __le32  bitmap_offset;  /* sectors after start of superblock that bitmap starts
                                 * NOTE: signed, so bitmap can be before superblock
                                 * only meaningful of feature_map[0] is set.
                                 */
 
        /* These are only valid with feature bit '4' */
-       __u32   new_level;      /* new level we are reshaping to                */
-       __u64   reshape_position;       /* next address in array-space for reshape */
-       __u32   delta_disks;    /* change in number of raid_disks               */
-       __u32   new_layout;     /* new layout                                   */
-       __u32   new_chunk;      /* new chunk size (bytes)                       */
+       __le32  new_level;      /* new level we are reshaping to                */
+       __le64  reshape_position;       /* next address in array-space for reshape */
+       __le32  delta_disks;    /* change in number of raid_disks               */
+       __le32  new_layout;     /* new layout                                   */
+       __le32  new_chunk;      /* new chunk size (bytes)                       */
        __u8    pad1[128-124];  /* set to 0 when written */
 
        /* constant this-device information - 64 bytes */
-       __u64   data_offset;    /* sector start of data, often 0 */
-       __u64   data_size;      /* sectors in this device that can be used for data */
-       __u64   super_offset;   /* sector start of this superblock */
-       __u64   recovery_offset;/* sectors before this offset (from data_offset) have been recovered */
-       __u32   dev_number;     /* permanent identifier of this  device - not role in raid */
-       __u32   cnt_corrected_read; /* number of read errors that were corrected by re-writing */
+       __le64  data_offset;    /* sector start of data, often 0 */
+       __le64  data_size;      /* sectors in this device that can be used for data */
+       __le64  super_offset;   /* sector start of this superblock */
+       __le64  recovery_offset;/* sectors before this offset (from data_offset) have been recovered */
+       __le32  dev_number;     /* permanent identifier of this  device - not role in raid */
+       __le32  cnt_corrected_read; /* number of read errors that were corrected by re-writing */
        __u8    device_uuid[16]; /* user-space setable, ignored by kernel */
        __u8    devflags;       /* per-device flags.  Only one defined...*/
 #define        WriteMostly1    1       /* mask for writemostly flag in above */
        __u8    pad2[64-57];    /* set to 0 when writing */
 
        /* array state information - 64 bytes */
-       __u64   utime;          /* 40 bits second, 24 btes microseconds */
-       __u64   events;         /* incremented when superblock updated */
-       __u64   resync_offset;  /* data before this offset (from data_offset) known to be in sync */
-       __u32   sb_csum;        /* checksum upto devs[max_dev] */
-       __u32   max_dev;        /* size of devs[] array to consider */
+       __le64  utime;          /* 40 bits second, 24 btes microseconds */
+       __le64  events;         /* incremented when superblock updated */
+       __le64  resync_offset;  /* data before this offset (from data_offset) known to be in sync */
+       __le32  sb_csum;        /* checksum upto devs[max_dev] */
+       __le32  max_dev;        /* size of devs[] array to consider */
        __u8    pad3[64-32];    /* set to 0 when writing */
 
        /* device state information. Indexed by dev_number.
@@ -260,7 +260,7 @@ struct mdp_superblock_1 {
         * into the 'roles' value.  If a device is spare or faulty, then it doesn't
         * have a meaningful role.
         */
-       __u16   dev_roles[0];   /* role in array, or 0xffff for a spare, or 0xfffe for faulty */
+       __le16  dev_roles[0];   /* role in array, or 0xffff for a spare, or 0xfffe for faulty */
 };
 
 /* feature_map bits */
index 73e1751d03dd18e2806d4a018c05f9cf05eaf942..749928c161fb24a6fbdcc95fc703c18d900f9494 100644 (file)
@@ -26,6 +26,7 @@ struct module;
  * Initialize unwind support.
  */
 extern void unwind_init(void);
+extern void unwind_setup(void);
 
 #ifdef CONFIG_MODULES
 
@@ -73,6 +74,7 @@ extern int unwind_to_user(struct unwind_frame_info *);
 struct unwind_frame_info {};
 
 static inline void unwind_init(void) {}
+static inline void unwind_setup(void) {}
 
 #ifdef CONFIG_MODULES
 
index ee123243fb530b4d4e589f731c5bfa4652148dc8..36f608a7cfbaf0fe1e2d3b1f37ff42e945bc100d 100644 (file)
@@ -503,6 +503,7 @@ asmlinkage void __init start_kernel(void)
        printk(KERN_NOTICE);
        printk(linux_banner);
        setup_arch(&command_line);
+       unwind_setup();
        setup_per_cpu_areas();
        smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */
 
index 2e2368607aab1a8293739315d832c608463d8d5f..f7e50d16dbf6b6ba55980dda3e0841d0a9d0d394 100644 (file)
 
 #include <linux/unwind.h>
 #include <linux/module.h>
-#include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/sort.h>
 #include <linux/stop_machine.h>
 #include <asm/sections.h>
 #include <asm/uaccess.h>
 #include <asm/unaligned.h>
 
 extern char __start_unwind[], __end_unwind[];
+extern const u8 __start_unwind_hdr[], __end_unwind_hdr[];
 
 #define MAX_STACK_DEPTH 8
 
@@ -100,6 +102,8 @@ static struct unwind_table {
        } core, init;
        const void *address;
        unsigned long size;
+       const unsigned char *header;
+       unsigned long hdrsz;
        struct unwind_table *link;
        const char *name;
 } root_table;
@@ -145,6 +149,10 @@ static struct unwind_table *find_table(unsigned long pc)
        return table;
 }
 
+static unsigned long read_pointer(const u8 **pLoc,
+                                  const void *end,
+                                  signed ptrType);
+
 static void init_unwind_table(struct unwind_table *table,
                               const char *name,
                               const void *core_start,
@@ -152,14 +160,30 @@ static void init_unwind_table(struct unwind_table *table,
                               const void *init_start,
                               unsigned long init_size,
                               const void *table_start,
-                              unsigned long table_size)
+                              unsigned long table_size,
+                              const u8 *header_start,
+                              unsigned long header_size)
 {
+       const u8 *ptr = header_start + 4;
+       const u8 *end = header_start + header_size;
+
        table->core.pc = (unsigned long)core_start;
        table->core.range = core_size;
        table->init.pc = (unsigned long)init_start;
        table->init.range = init_size;
        table->address = table_start;
        table->size = table_size;
+       /* See if the linker provided table looks valid. */
+       if (header_size <= 4
+           || header_start[0] != 1
+           || (void *)read_pointer(&ptr, end, header_start[1]) != table_start
+           || header_start[2] == DW_EH_PE_omit
+           || read_pointer(&ptr, end, header_start[2]) <= 0
+           || header_start[3] == DW_EH_PE_omit)
+               header_start = NULL;
+       table->hdrsz = header_size;
+       smp_wmb();
+       table->header = header_start;
        table->link = NULL;
        table->name = name;
 }
@@ -169,7 +193,143 @@ void __init unwind_init(void)
        init_unwind_table(&root_table, "kernel",
                          _text, _end - _text,
                          NULL, 0,
-                         __start_unwind, __end_unwind - __start_unwind);
+                         __start_unwind, __end_unwind - __start_unwind,
+                         __start_unwind_hdr, __end_unwind_hdr - __start_unwind_hdr);
+}
+
+static const u32 bad_cie, not_fde;
+static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *);
+static signed fde_pointer_type(const u32 *cie);
+
+struct eh_frame_hdr_table_entry {
+       unsigned long start, fde;
+};
+
+static int cmp_eh_frame_hdr_table_entries(const void *p1, const void *p2)
+{
+       const struct eh_frame_hdr_table_entry *e1 = p1;
+       const struct eh_frame_hdr_table_entry *e2 = p2;
+
+       return (e1->start > e2->start) - (e1->start < e2->start);
+}
+
+static void swap_eh_frame_hdr_table_entries(void *p1, void *p2, int size)
+{
+       struct eh_frame_hdr_table_entry *e1 = p1;
+       struct eh_frame_hdr_table_entry *e2 = p2;
+       unsigned long v;
+
+       v = e1->start;
+       e1->start = e2->start;
+       e2->start = v;
+       v = e1->fde;
+       e1->fde = e2->fde;
+       e2->fde = v;
+}
+
+static void __init setup_unwind_table(struct unwind_table *table,
+                                       void *(*alloc)(unsigned long))
+{
+       const u8 *ptr;
+       unsigned long tableSize = table->size, hdrSize;
+       unsigned n;
+       const u32 *fde;
+       struct {
+               u8 version;
+               u8 eh_frame_ptr_enc;
+               u8 fde_count_enc;
+               u8 table_enc;
+               unsigned long eh_frame_ptr;
+               unsigned int fde_count;
+               struct eh_frame_hdr_table_entry table[];
+       } __attribute__((__packed__)) *header;
+
+       if (table->header)
+               return;
+
+       if (table->hdrsz)
+               printk(KERN_WARNING ".eh_frame_hdr for '%s' present but unusable\n",
+                      table->name);
+
+       if (tableSize & (sizeof(*fde) - 1))
+               return;
+
+       for (fde = table->address, n = 0;
+            tableSize > sizeof(*fde) && tableSize - sizeof(*fde) >= *fde;
+            tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) {
+               const u32 *cie = cie_for_fde(fde, table);
+               signed ptrType;
+
+               if (cie == &not_fde)
+                       continue;
+               if (cie == NULL
+                   || cie == &bad_cie
+                   || (ptrType = fde_pointer_type(cie)) < 0)
+                       return;
+               ptr = (const u8 *)(fde + 2);
+               if (!read_pointer(&ptr,
+                                 (const u8 *)(fde + 1) + *fde,
+                                 ptrType))
+                       return;
+               ++n;
+       }
+
+       if (tableSize || !n)
+               return;
+
+       hdrSize = 4 + sizeof(unsigned long) + sizeof(unsigned int)
+               + 2 * n * sizeof(unsigned long);
+       header = alloc(hdrSize);
+       if (!header)
+               return;
+       header->version          = 1;
+       header->eh_frame_ptr_enc = DW_EH_PE_abs|DW_EH_PE_native;
+       header->fde_count_enc    = DW_EH_PE_abs|DW_EH_PE_data4;
+       header->table_enc        = DW_EH_PE_abs|DW_EH_PE_native;
+       put_unaligned((unsigned long)table->address, &header->eh_frame_ptr);
+       BUILD_BUG_ON(offsetof(typeof(*header), fde_count)
+                    % __alignof(typeof(header->fde_count)));
+       header->fde_count        = n;
+
+       BUILD_BUG_ON(offsetof(typeof(*header), table)
+                    % __alignof(typeof(*header->table)));
+       for (fde = table->address, tableSize = table->size, n = 0;
+            tableSize;
+            tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) {
+               const u32 *cie = fde + 1 - fde[1] / sizeof(*fde);
+
+               if (!fde[1])
+                       continue; /* this is a CIE */
+               ptr = (const u8 *)(fde + 2);
+               header->table[n].start = read_pointer(&ptr,
+                                                     (const u8 *)(fde + 1) + *fde,
+                                                     fde_pointer_type(cie));
+               header->table[n].fde = (unsigned long)fde;
+               ++n;
+       }
+       WARN_ON(n != header->fde_count);
+
+       sort(header->table,
+            n,
+            sizeof(*header->table),
+            cmp_eh_frame_hdr_table_entries,
+            swap_eh_frame_hdr_table_entries);
+
+       table->hdrsz = hdrSize;
+       smp_wmb();
+       table->header = (const void *)header;
+}
+
+static void *__init balloc(unsigned long sz)
+{
+       return __alloc_bootmem_nopanic(sz,
+                                      sizeof(unsigned int),
+                                      __pa(MAX_DMA_ADDRESS));
+}
+
+void __init unwind_setup(void)
+{
+       setup_unwind_table(&root_table, balloc);
 }
 
 #ifdef CONFIG_MODULES
@@ -193,7 +353,8 @@ void *unwind_add_table(struct module *module,
        init_unwind_table(table, module->name,
                          module->module_core, module->core_size,
                          module->module_init, module->init_size,
-                         table_start, table_size);
+                         table_start, table_size,
+                         NULL, 0);
 
        if (last_table)
                last_table->link = table;
@@ -303,6 +464,26 @@ static sleb128_t get_sleb128(const u8 **pcur, const u8 *end)
        return value;
 }
 
+static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *table)
+{
+       const u32 *cie;
+
+       if (!*fde || (*fde & (sizeof(*fde) - 1)))
+               return &bad_cie;
+       if (!fde[1])
+               return &not_fde; /* this is a CIE */
+       if ((fde[1] & (sizeof(*fde) - 1))
+           || fde[1] > (unsigned long)(fde + 1) - (unsigned long)table->address)
+               return NULL; /* this is not a valid FDE */
+       cie = fde + 1 - fde[1] / sizeof(*fde);
+       if (*cie <= sizeof(*cie) + 4
+           || *cie >= fde[1] - sizeof(*fde)
+           || (*cie & (sizeof(*cie) - 1))
+           || cie[1])
+               return NULL; /* this is not a (valid) CIE */
+       return cie;
+}
+
 static unsigned long read_pointer(const u8 **pLoc,
                                   const void *end,
                                   signed ptrType)
@@ -610,49 +791,108 @@ int unwind(struct unwind_frame_info *frame)
        unsigned i;
        signed ptrType = -1;
        uleb128_t retAddrReg = 0;
-       struct unwind_table *table;
+       const struct unwind_table *table;
        struct unwind_state state;
 
        if (UNW_PC(frame) == 0)
                return -EINVAL;
        if ((table = find_table(pc)) != NULL
            && !(table->size & (sizeof(*fde) - 1))) {
-               unsigned long tableSize = table->size;
-
-               for (fde = table->address;
-                    tableSize > sizeof(*fde) && tableSize - sizeof(*fde) >= *fde;
-                    tableSize -= sizeof(*fde) + *fde,
-                    fde += 1 + *fde / sizeof(*fde)) {
-                       if (!*fde || (*fde & (sizeof(*fde) - 1)))
-                               break;
-                       if (!fde[1])
-                               continue; /* this is a CIE */
-                       if ((fde[1] & (sizeof(*fde) - 1))
-                           || fde[1] > (unsigned long)(fde + 1)
-                                       - (unsigned long)table->address)
-                               continue; /* this is not a valid FDE */
-                       cie = fde + 1 - fde[1] / sizeof(*fde);
-                       if (*cie <= sizeof(*cie) + 4
-                           || *cie >= fde[1] - sizeof(*fde)
-                           || (*cie & (sizeof(*cie) - 1))
-                           || cie[1]
-                           || (ptrType = fde_pointer_type(cie)) < 0) {
-                               cie = NULL; /* this is not a (valid) CIE */
-                               continue;
+               const u8 *hdr = table->header;
+               unsigned long tableSize;
+
+               smp_rmb();
+               if (hdr && hdr[0] == 1) {
+                       switch(hdr[3] & DW_EH_PE_FORM) {
+                       case DW_EH_PE_native: tableSize = sizeof(unsigned long); break;
+                       case DW_EH_PE_data2: tableSize = 2; break;
+                       case DW_EH_PE_data4: tableSize = 4; break;
+                       case DW_EH_PE_data8: tableSize = 8; break;
+                       default: tableSize = 0; break;
+                       }
+                       ptr = hdr + 4;
+                       end = hdr + table->hdrsz;
+                       if (tableSize
+                           && read_pointer(&ptr, end, hdr[1])
+                              == (unsigned long)table->address
+                           && (i = read_pointer(&ptr, end, hdr[2])) > 0
+                           && i == (end - ptr) / (2 * tableSize)
+                           && !((end - ptr) % (2 * tableSize))) {
+                               do {
+                                       const u8 *cur = ptr + (i / 2) * (2 * tableSize);
+
+                                       startLoc = read_pointer(&cur,
+                                                               cur + tableSize,
+                                                               hdr[3]);
+                                       if (pc < startLoc)
+                                               i /= 2;
+                                       else {
+                                               ptr = cur - tableSize;
+                                               i = (i + 1) / 2;
+                                       }
+                               } while (startLoc && i > 1);
+                               if (i == 1
+                                   && (startLoc = read_pointer(&ptr,
+                                                               ptr + tableSize,
+                                                               hdr[3])) != 0
+                                   && pc >= startLoc)
+                                       fde = (void *)read_pointer(&ptr,
+                                                                  ptr + tableSize,
+                                                                  hdr[3]);
                        }
+               }
+
+               if (fde != NULL) {
+                       cie = cie_for_fde(fde, table);
                        ptr = (const u8 *)(fde + 2);
-                       startLoc = read_pointer(&ptr,
-                                               (const u8 *)(fde + 1) + *fde,
-                                               ptrType);
-                       endLoc = startLoc
-                                + read_pointer(&ptr,
-                                               (const u8 *)(fde + 1) + *fde,
-                                               ptrType & DW_EH_PE_indirect
-                                               ? ptrType
-                                               : ptrType & (DW_EH_PE_FORM|DW_EH_PE_signed));
-                       if (pc >= startLoc && pc < endLoc)
-                               break;
-                       cie = NULL;
+                       if(cie != NULL
+                          && cie != &bad_cie
+                          && cie != &not_fde
+                          && (ptrType = fde_pointer_type(cie)) >= 0
+                          && read_pointer(&ptr,
+                                          (const u8 *)(fde + 1) + *fde,
+                                          ptrType) == startLoc) {
+                               if (!(ptrType & DW_EH_PE_indirect))
+                                       ptrType &= DW_EH_PE_FORM|DW_EH_PE_signed;
+                               endLoc = startLoc
+                                        + read_pointer(&ptr,
+                                                       (const u8 *)(fde + 1) + *fde,
+                                                       ptrType);
+                               if(pc >= endLoc)
+                                       fde = NULL;
+                       } else
+                               fde = NULL;
+               }
+               if (fde == NULL) {
+                       for (fde = table->address, tableSize = table->size;
+                            cie = NULL, tableSize > sizeof(*fde)
+                            && tableSize - sizeof(*fde) >= *fde;
+                            tableSize -= sizeof(*fde) + *fde,
+                            fde += 1 + *fde / sizeof(*fde)) {
+                               cie = cie_for_fde(fde, table);
+                               if (cie == &bad_cie) {
+                                       cie = NULL;
+                                       break;
+                               }
+                               if (cie == NULL
+                                   || cie == &not_fde
+                                   || (ptrType = fde_pointer_type(cie)) < 0)
+                                       continue;
+                               ptr = (const u8 *)(fde + 2);
+                               startLoc = read_pointer(&ptr,
+                                                       (const u8 *)(fde + 1) + *fde,
+                                                       ptrType);
+                               if (!startLoc)
+                                       continue;
+                               if (!(ptrType & DW_EH_PE_indirect))
+                                       ptrType &= DW_EH_PE_FORM|DW_EH_PE_signed;
+                               endLoc = startLoc
+                                        + read_pointer(&ptr,
+                                                       (const u8 *)(fde + 1) + *fde,
+                                                       ptrType);
+                               if (pc >= startLoc && pc < endLoc)
+                                       break;
+                       }
                }
        }
        if (cie != NULL) {
index ebd425c2e2a7fe8402733d1a5166ca2a69fa6678..f5fc45472d5ca77d3406b9ced195c45fde97ca78 100644 (file)
@@ -1689,6 +1689,8 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
        for (pfn = start_pfn; pfn < end_pfn; pfn++) {
                if (!early_pfn_valid(pfn))
                        continue;
+               if (!early_pfn_in_nid(pfn, nid))
+                       continue;
                page = pfn_to_page(pfn);
                set_page_links(page, zone, nid, pfn);
                init_page_count(page);
index 266449d604bd170c4c1656318c1ded64fcc5404a..84c631f30741016e0e73602129ed6c33d6ca88f9 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -3152,12 +3152,15 @@ void *fallback_alloc(struct kmem_cache *cache, gfp_t flags)
        struct zone **z;
        void *obj = NULL;
 
-       for (z = zonelist->zones; *z && !obj; z++)
+       for (z = zonelist->zones; *z && !obj; z++) {
+               int nid = zone_to_nid(*z);
+
                if (zone_idx(*z) <= ZONE_NORMAL &&
-                               cpuset_zone_allowed(*z, flags))
+                               cpuset_zone_allowed(*z, flags) &&
+                               cache->nodelists[nid])
                        obj = __cache_alloc_node(cache,
-                                       flags | __GFP_THISNODE,
-                                       zone_to_nid(*z));
+                                       flags | __GFP_THISNODE, nid);
+       }
        return obj;
 }