diff -Naur linux-2.6.16/arch/alpha/kernel/setup.c linux-2.6.16.16/arch/alpha/kernel/setup.c --- linux-2.6.16/arch/alpha/kernel/setup.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/arch/alpha/kernel/setup.c 2006-05-11 04:56:24.000000000 +0300 @@ -24,6 +24,7 @@ #include /* CONFIG_ALPHA_LCA etc */ #include #include +#include #include #include #include @@ -477,6 +478,22 @@ #undef PFN_PHYS #undef PFN_MAX +static int __init +register_cpus(void) +{ + int i; + + for_each_possible_cpu(i) { + struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL); + if (!p) + return -ENOMEM; + register_cpu(p, i, NULL); + } + return 0; +} + +arch_initcall(register_cpus); + void __init setup_arch(char **cmdline_p) { diff -Naur linux-2.6.16/arch/alpha/kernel/smp.c linux-2.6.16.16/arch/alpha/kernel/smp.c --- linux-2.6.16/arch/alpha/kernel/smp.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/arch/alpha/kernel/smp.c 2006-05-11 04:56:24.000000000 +0300 @@ -439,7 +439,7 @@ if ((cpu->flags & 0x1cc) == 0x1cc) { smp_num_probed++; /* Assume here that "whami" == index */ - cpu_set(i, cpu_possible_map); + cpu_set(i, cpu_present_mask); cpu->pal_revision = boot_cpu_palrev; } @@ -450,9 +450,8 @@ } } else { smp_num_probed = 1; - cpu_set(boot_cpuid, cpu_possible_map); + cpu_set(boot_cpuid, cpu_present_mask); } - cpu_present_mask = cpumask_of_cpu(boot_cpuid); printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n", smp_num_probed, cpu_possible_map.bits[0]); @@ -488,9 +487,8 @@ smp_prepare_boot_cpu(void) { /* - * Mark the boot cpu (current cpu) as both present and online + * Mark the boot cpu (current cpu) as online */ - cpu_set(smp_processor_id(), cpu_present_mask); cpu_set(smp_processor_id(), cpu_online_map); } diff -Naur linux-2.6.16/arch/alpha/lib/strncpy.S linux-2.6.16.16/arch/alpha/lib/strncpy.S --- linux-2.6.16/arch/alpha/lib/strncpy.S 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/arch/alpha/lib/strncpy.S 2006-05-11 04:56:24.000000000 +0300 @@ -43,8 +43,8 @@ .align 4 $multiword: - subq $24, 1, $2 # clear the final bits in the prev word - or $2, $24, $2 + subq $27, 1, $2 # clear the final bits in the prev word + or $2, $27, $2 zapnot $1, $2, $1 subq $18, 1, $18 @@ -70,8 +70,8 @@ bne $18, 0b 1: ldq_u $1, 0($16) # clear the leading bits in the final word - subq $27, 1, $2 - or $2, $27, $2 + subq $24, 1, $2 + or $2, $24, $2 zap $1, $2, $1 stq_u $1, 0($16) diff -Naur linux-2.6.16/arch/i386/kernel/apm.c linux-2.6.16.16/arch/i386/kernel/apm.c --- linux-2.6.16/arch/i386/kernel/apm.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/arch/i386/kernel/apm.c 2006-05-11 04:56:24.000000000 +0300 @@ -1081,7 +1081,7 @@ break; } - if (error == APM_NOT_ENGAGED && state != APM_STATE_READY) { + if (error == APM_NOT_ENGAGED) { static int tried; int eng_error; if (tried++ == 0) { diff -Naur linux-2.6.16/arch/i386/kernel/cpu/amd.c linux-2.6.16.16/arch/i386/kernel/cpu/amd.c --- linux-2.6.16/arch/i386/kernel/cpu/amd.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/arch/i386/kernel/cpu/amd.c 2006-05-11 04:56:24.000000000 +0300 @@ -207,6 +207,8 @@ set_bit(X86_FEATURE_K7, c->x86_capability); break; } + if (c->x86 >= 6) + set_bit(X86_FEATURE_FXSAVE_LEAK, c->x86_capability); display_cacheinfo(c); diff -Naur linux-2.6.16/arch/i386/kernel/cpu/cpufreq/Kconfig linux-2.6.16.16/arch/i386/kernel/cpu/cpufreq/Kconfig --- linux-2.6.16/arch/i386/kernel/cpu/cpufreq/Kconfig 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/arch/i386/kernel/cpu/cpufreq/Kconfig 2006-05-11 04:56:24.000000000 +0300 @@ -203,6 +203,7 @@ config X86_LONGHAUL tristate "VIA Cyrix III Longhaul" select CPU_FREQ_TABLE + depends on BROKEN help This adds the CPUFreq driver for VIA Samuel/CyrixIII, VIA Cyrix Samuel/C3, VIA Cyrix Ezra and VIA Cyrix Ezra-T diff -Naur linux-2.6.16/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c linux-2.6.16.16/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c --- linux-2.6.16/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c 2006-05-11 04:56:24.000000000 +0300 @@ -244,7 +244,7 @@ for (i=1; (p4clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) { if ((i<2) && (has_N44_O17_errata[policy->cpu])) p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID; - else if (has_N60_errata[policy->cpu] && p4clockmod_table[i].frequency < 2000000) + else if (has_N60_errata[policy->cpu] && ((stock_freq * i)/8) < 2000000) p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID; else p4clockmod_table[i].frequency = (stock_freq * i)/8; diff -Naur linux-2.6.16/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c linux-2.6.16.16/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c --- linux-2.6.16/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c 2006-05-11 04:56:24.000000000 +0300 @@ -75,7 +75,9 @@ __asm__ __volatile__( "out %%al, (%%dx)\n" : "=D" (result) - : "a" (command), "b" (function), "c" (0), "d" (smi_port), "D" (0), "S" (magic) + : "a" (command), "b" (function), "c" (0), "d" (smi_port), + "D" (0), "S" (magic) + : "memory" ); dprintk("result is %x\n", result); diff -Naur linux-2.6.16/arch/i386/kernel/dmi_scan.c linux-2.6.16.16/arch/i386/kernel/dmi_scan.c --- linux-2.6.16/arch/i386/kernel/dmi_scan.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/arch/i386/kernel/dmi_scan.c 2006-05-11 04:56:24.000000000 +0300 @@ -106,7 +106,7 @@ struct dmi_device *dev; for (i = 0; i < count; i++) { - char *d = ((char *) dm) + (i * 2); + char *d = (char *)(dm + 1) + (i * 2); /* Skip disabled device */ if ((*d & 0x80) == 0) diff -Naur linux-2.6.16/arch/i386/kernel/vm86.c linux-2.6.16.16/arch/i386/kernel/vm86.c --- linux-2.6.16/arch/i386/kernel/vm86.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/arch/i386/kernel/vm86.c 2006-05-11 04:56:24.000000000 +0300 @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -252,6 +253,7 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk) { struct tss_struct *tss; + long eax; /* * make sure the vm86() system call doesn't try to do anything silly */ @@ -305,13 +307,19 @@ tsk->thread.screen_bitmap = info->screen_bitmap; if (info->flags & VM86_SCREEN_BITMAP) mark_screen_rdonly(tsk->mm); + __asm__ __volatile__("xorl %eax,%eax; movl %eax,%fs; movl %eax,%gs\n\t"); + __asm__ __volatile__("movl %%eax, %0\n" :"=r"(eax)); + + /*call audit_syscall_exit since we do not exit via the normal paths */ + if (unlikely(current->audit_context)) + audit_syscall_exit(current, AUDITSC_RESULT(eax), eax); + __asm__ __volatile__( - "xorl %%eax,%%eax; movl %%eax,%%fs; movl %%eax,%%gs\n\t" "movl %0,%%esp\n\t" "movl %1,%%ebp\n\t" "jmp resume_userspace" : /* no outputs */ - :"r" (&info->regs), "r" (task_thread_info(tsk)) : "ax"); + :"r" (&info->regs), "r" (task_thread_info(tsk))); /* we never return here */ } diff -Naur linux-2.6.16/arch/m32r/kernel/m32r_ksyms.c linux-2.6.16.16/arch/m32r/kernel/m32r_ksyms.c --- linux-2.6.16/arch/m32r/kernel/m32r_ksyms.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/arch/m32r/kernel/m32r_ksyms.c 2006-05-11 04:56:24.000000000 +0300 @@ -38,10 +38,6 @@ EXPORT_SYMBOL(__delay); EXPORT_SYMBOL(__const_udelay); -EXPORT_SYMBOL(__get_user_1); -EXPORT_SYMBOL(__get_user_2); -EXPORT_SYMBOL(__get_user_4); - EXPORT_SYMBOL(strpbrk); EXPORT_SYMBOL(strstr); diff -Naur linux-2.6.16/arch/m32r/kernel/setup.c linux-2.6.16.16/arch/m32r/kernel/setup.c --- linux-2.6.16/arch/m32r/kernel/setup.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/arch/m32r/kernel/setup.c 2006-05-11 04:56:24.000000000 +0300 @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -218,8 +219,6 @@ extern unsigned long setup_memory(void); #endif /* CONFIG_DISCONTIGMEM */ -#define M32R_PCC_PCATCR 0x00ef7014 /* will move to m32r.h */ - void __init setup_arch(char **cmdline_p) { ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); @@ -268,15 +267,14 @@ paging_init(); } -static struct cpu cpu[NR_CPUS]; +static struct cpu cpu_devices[NR_CPUS]; static int __init topology_init(void) { - int cpu_id; + int i; - for (cpu_id = 0; cpu_id < NR_CPUS; cpu_id++) - if (cpu_possible(cpu_id)) - register_cpu(&cpu[cpu_id], cpu_id, NULL); + for_each_present_cpu(i) + register_cpu(&cpu_devices[i], i, NULL); return 0; } diff -Naur linux-2.6.16/arch/m32r/kernel/smpboot.c linux-2.6.16.16/arch/m32r/kernel/smpboot.c --- linux-2.6.16/arch/m32r/kernel/smpboot.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/arch/m32r/kernel/smpboot.c 2006-05-11 04:56:24.000000000 +0300 @@ -39,8 +39,10 @@ * Martin J. Bligh : Added support for multi-quad systems */ +#include #include #include +#include #include #include #include @@ -72,11 +74,15 @@ /* Bitmask of currently online CPUs */ cpumask_t cpu_online_map; +EXPORT_SYMBOL(cpu_online_map); cpumask_t cpu_bootout_map; cpumask_t cpu_bootin_map; -cpumask_t cpu_callout_map; static cpumask_t cpu_callin_map; +cpumask_t cpu_callout_map; +EXPORT_SYMBOL(cpu_callout_map); +cpumask_t cpu_possible_map = CPU_MASK_ALL; +EXPORT_SYMBOL(cpu_possible_map); /* Per CPU bogomips and other parameters */ struct cpuinfo_m32r cpu_data[NR_CPUS] __cacheline_aligned; @@ -110,7 +116,6 @@ void smp_prepare_boot_cpu(void); void smp_prepare_cpus(unsigned int); -static void smp_tune_scheduling(void); static void init_ipi_lock(void); static void do_boot_cpu(int); int __cpu_up(unsigned int); @@ -177,6 +182,9 @@ } for (phys_id = 0 ; phys_id < nr_cpu ; phys_id++) physid_set(phys_id, phys_cpu_present_map); +#ifndef CONFIG_HOTPLUG_CPU + cpu_present_map = cpu_possible_map; +#endif show_mp_info(nr_cpu); @@ -186,7 +194,6 @@ * Setup boot CPU information */ smp_store_cpu_info(0); /* Final full version of the data */ - smp_tune_scheduling(); /* * If SMP should be disabled, then really disable it! @@ -230,11 +237,6 @@ Dprintk("Boot done.\n"); } -static void __init smp_tune_scheduling(void) -{ - /* Nothing to do. */ -} - /* * init_ipi_lock : Initialize IPI locks. */ @@ -629,4 +631,3 @@ physid_2_cpu[phys_id] = -1; cpu_2_physid[cpu_id] = -1; } - diff -Naur linux-2.6.16/arch/m32r/lib/getuser.S linux-2.6.16.16/arch/m32r/lib/getuser.S --- linux-2.6.16/arch/m32r/lib/getuser.S 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/arch/m32r/lib/getuser.S 1970-01-01 02:00:00.000000000 +0200 @@ -1,88 +0,0 @@ -/* - * __get_user functions. - * - * (C) Copyright 2001 Hirokazu Takata - * - * These functions have a non-standard call interface - * to make them more efficient, especially as they - * return an error value in addition to the "real" - * return value. - */ - -#include - -/* - * __get_user_X - * - * Inputs: r0 contains the address - * - * Outputs: r0 is error code (0 or -EFAULT) - * r1 contains zero-extended value - * - * These functions should not modify any other registers, - * as they get called from within inline assembly. - */ - -#ifdef CONFIG_ISA_DUAL_ISSUE - - .text - .balign 4 - .globl __get_user_1 -__get_user_1: -1: ldub r1, @r0 || ldi r0, #0 - jmp r14 - - .balign 4 - .globl __get_user_2 -__get_user_2: -2: lduh r1, @r0 || ldi r0, #0 - jmp r14 - - .balign 4 - .globl __get_user_4 -__get_user_4: -3: ld r1, @r0 || ldi r0, #0 - jmp r14 - -bad_get_user: - ldi r1, #0 || ldi r0, #-14 - jmp r14 - -#else /* not CONFIG_ISA_DUAL_ISSUE */ - - .text - .balign 4 - .globl __get_user_1 -__get_user_1: -1: ldub r1, @r0 - ldi r0, #0 - jmp r14 - - .balign 4 - .globl __get_user_2 -__get_user_2: -2: lduh r1, @r0 - ldi r0, #0 - jmp r14 - - .balign 4 - .globl __get_user_4 -__get_user_4: -3: ld r1, @r0 - ldi r0, #0 - jmp r14 - -bad_get_user: - ldi r1, #0 - ldi r0, #-14 - jmp r14 - -#endif /* not CONFIG_ISA_DUAL_ISSUE */ - -.section __ex_table,"a" - .long 1b,bad_get_user - .long 2b,bad_get_user - .long 3b,bad_get_user -.previous - - .end diff -Naur linux-2.6.16/arch/m32r/lib/Makefile linux-2.6.16.16/arch/m32r/lib/Makefile --- linux-2.6.16/arch/m32r/lib/Makefile 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/arch/m32r/lib/Makefile 2006-05-11 04:56:24.000000000 +0300 @@ -2,6 +2,6 @@ # Makefile for M32R-specific library files.. # -lib-y := checksum.o ashxdi3.o memset.o memcpy.o getuser.o \ - putuser.o delay.o strlen.o usercopy.o csum_partial_copy.o +lib-y := checksum.o ashxdi3.o memset.o memcpy.o \ + delay.o strlen.o usercopy.o csum_partial_copy.o diff -Naur linux-2.6.16/arch/m32r/lib/putuser.S linux-2.6.16.16/arch/m32r/lib/putuser.S --- linux-2.6.16/arch/m32r/lib/putuser.S 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/arch/m32r/lib/putuser.S 1970-01-01 02:00:00.000000000 +0200 @@ -1,84 +0,0 @@ -/* - * __put_user functions. - * - * (C) Copyright 1998 Linus Torvalds - * (C) Copyright 2001 Hirokazu Takata - * - * These functions have a non-standard call interface - * to make them more efficient. - */ - -#include - -/* - * __put_user_X - * - * Inputs: r0 contains the address - * r1 contains the value - * - * Outputs: r0 is error code (0 or -EFAULT) - * r1 is corrupted (will contain "current_task"). - * - * These functions should not modify any other registers, - * as they get called from within inline assembly. - */ - -#ifdef CONFIG_ISA_DUAL_ISSUE - - .text - .balign 4 - .globl __put_user_1 -__put_user_1: -1: stb r1, @r0 || ldi r0, #0 - jmp r14 - - .balign 4 - .globl __put_user_2 -__put_user_2: -2: sth r1, @r0 || ldi r0, #0 - jmp r14 - - .balign 4 - .globl __put_user_4 -__put_user_4: -3: st r1, @r0 || ldi r0, #0 - jmp r14 - -bad_put_user: - ldi r0, #-14 || jmp r14 - -#else /* not CONFIG_ISA_DUAL_ISSUE */ - - .text - .balign 4 - .globl __put_user_1 -__put_user_1: -1: stb r1, @r0 - ldi r0, #0 - jmp r14 - - .balign 4 - .globl __put_user_2 -__put_user_2: -2: sth r1, @r0 - ldi r0, #0 - jmp r14 - - .balign 4 - .globl __put_user_4 -__put_user_4: -3: st r1, @r0 - ldi r0, #0 - jmp r14 - -bad_put_user: - ldi r0, #-14 - jmp r14 - -#endif /* not CONFIG_ISA_DUAL_ISSUE */ - -.section __ex_table,"a" - .long 1b,bad_put_user - .long 2b,bad_put_user - .long 3b,bad_put_user -.previous diff -Naur linux-2.6.16/arch/mips/kernel/branch.c linux-2.6.16.16/arch/mips/kernel/branch.c --- linux-2.6.16/arch/mips/kernel/branch.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/arch/mips/kernel/branch.c 2006-05-11 04:56:24.000000000 +0300 @@ -184,7 +184,7 @@ bit = (insn.i_format.rt >> 2); bit += (bit != 0); bit += 23; - switch (insn.i_format.rt) { + switch (insn.i_format.rt & 3) { case 0: /* bc1f */ case 2: /* bc1fl */ if (~fcr31 & (1 << bit)) diff -Naur linux-2.6.16/arch/mips/mm/c-r4k.c linux-2.6.16.16/arch/mips/mm/c-r4k.c --- linux-2.6.16/arch/mips/mm/c-r4k.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/arch/mips/mm/c-r4k.c 2006-05-11 04:56:24.000000000 +0300 @@ -154,7 +154,8 @@ static inline void tx49_blast_icache32_page_indexed(unsigned long page) { - unsigned long start = page; + unsigned long indexmask = current_cpu_data.icache.waysize - 1; + unsigned long start = INDEX_BASE + (page & indexmask); unsigned long end = start + PAGE_SIZE; unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; unsigned long ws_end = current_cpu_data.icache.ways << diff -Naur linux-2.6.16/arch/powerpc/kernel/pci_64.c linux-2.6.16.16/arch/powerpc/kernel/pci_64.c --- linux-2.6.16/arch/powerpc/kernel/pci_64.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/arch/powerpc/kernel/pci_64.c 2006-05-11 04:56:24.000000000 +0300 @@ -78,6 +78,7 @@ /* Cached ISA bridge dev. */ struct pci_dev *ppc64_isabridge_dev = NULL; +EXPORT_SYMBOL_GPL(ppc64_isabridge_dev); static void fixup_broken_pcnet32(struct pci_dev* dev) { diff -Naur linux-2.6.16/arch/powerpc/kernel/setup_64.c linux-2.6.16.16/arch/powerpc/kernel/setup_64.c --- linux-2.6.16/arch/powerpc/kernel/setup_64.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/arch/powerpc/kernel/setup_64.c 2006-05-11 04:56:24.000000000 +0300 @@ -256,12 +256,10 @@ /* * Initialize stab / SLB management except on iSeries */ - if (!firmware_has_feature(FW_FEATURE_ISERIES)) { - if (cpu_has_feature(CPU_FTR_SLB)) - slb_initialize(); - else - stab_initialize(lpaca->stab_real); - } + if (cpu_has_feature(CPU_FTR_SLB)) + slb_initialize(); + else if (!firmware_has_feature(FW_FEATURE_ISERIES)) + stab_initialize(lpaca->stab_real); DBG(" <- early_setup()\n"); } diff -Naur linux-2.6.16/arch/powerpc/kernel/signal_64.c linux-2.6.16.16/arch/powerpc/kernel/signal_64.c --- linux-2.6.16/arch/powerpc/kernel/signal_64.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/arch/powerpc/kernel/signal_64.c 2006-05-11 04:56:24.000000000 +0300 @@ -213,7 +213,7 @@ /* Default to using normal stack */ newsp = regs->gpr[1]; - if (ka->sa.sa_flags & SA_ONSTACK) { + if ((ka->sa.sa_flags & SA_ONSTACK) && current->sas_ss_size) { if (! on_sig_stack(regs->gpr[1])) newsp = (current->sas_ss_sp + current->sas_ss_size); } diff -Naur linux-2.6.16/arch/x86_64/ia32/Makefile linux-2.6.16.16/arch/x86_64/ia32/Makefile --- linux-2.6.16/arch/x86_64/ia32/Makefile 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/arch/x86_64/ia32/Makefile 2006-05-11 04:56:24.000000000 +0300 @@ -27,5 +27,5 @@ $(obj)/vsyscall-%.so: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE $(call if_changed,syscall) -AFLAGS_vsyscall-sysenter.o = -m32 -AFLAGS_vsyscall-syscall.o = -m32 +AFLAGS_vsyscall-sysenter.o = -m32 -Wa,-32 +AFLAGS_vsyscall-syscall.o = -m32 -Wa,-32 diff -Naur linux-2.6.16/arch/x86_64/kernel/entry.S linux-2.6.16.16/arch/x86_64/kernel/entry.S --- linux-2.6.16/arch/x86_64/kernel/entry.S 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/arch/x86_64/kernel/entry.S 2006-05-11 04:56:24.000000000 +0300 @@ -180,6 +180,10 @@ * * XXX if we had a free scratch register we could save the RSP into the stack frame * and report it properly in ps. Unfortunately we haven't. + * + * When user can change the frames always force IRET. That is because + * it deals with uncanonical addresses better. SYSRET has trouble + * with them due to bugs in both AMD and Intel CPUs. */ ENTRY(system_call) @@ -254,7 +258,10 @@ xorl %esi,%esi # oldset -> arg2 call ptregscall_common 1: movl $_TIF_NEED_RESCHED,%edi - jmp sysret_check + /* Use IRET because user could have changed frame. This + works because ptregscall_common has called FIXUP_TOP_OF_STACK. */ + cli + jmp int_with_check badsys: movq $-ENOSYS,RAX-ARGOFFSET(%rsp) @@ -280,7 +287,8 @@ call syscall_trace_leave RESTORE_TOP_OF_STACK %rbx RESTORE_REST - jmp ret_from_sys_call + /* Use IRET because user could have changed frame */ + jmp int_ret_from_sys_call CFI_ENDPROC /* @@ -408,25 +416,9 @@ CFI_ADJUST_CFA_OFFSET -8 CFI_REGISTER rip, r11 SAVE_REST - movq %r11, %r15 - CFI_REGISTER rip, r15 FIXUP_TOP_OF_STACK %r11 call sys_execve - GET_THREAD_INFO(%rcx) - bt $TIF_IA32,threadinfo_flags(%rcx) - CFI_REMEMBER_STATE - jc exec_32bit RESTORE_TOP_OF_STACK %r11 - movq %r15, %r11 - CFI_REGISTER rip, r11 - RESTORE_REST - pushq %r11 - CFI_ADJUST_CFA_OFFSET 8 - CFI_REL_OFFSET rip, 0 - ret - -exec_32bit: - CFI_RESTORE_STATE movq %rax,RAX(%rsp) RESTORE_REST jmp int_ret_from_sys_call diff -Naur linux-2.6.16/arch/x86_64/kernel/pci-gart.c linux-2.6.16.16/arch/x86_64/kernel/pci-gart.c --- linux-2.6.16/arch/x86_64/kernel/pci-gart.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/arch/x86_64/kernel/pci-gart.c 2006-05-11 04:56:24.000000000 +0300 @@ -114,10 +114,6 @@ static void free_iommu(unsigned long offset, int size) { unsigned long flags; - if (size == 1) { - clear_bit(offset, iommu_gart_bitmap); - return; - } spin_lock_irqsave(&iommu_bitmap_lock, flags); __clear_bit_string(iommu_gart_bitmap, offset, size); spin_unlock_irqrestore(&iommu_bitmap_lock, flags); diff -Naur linux-2.6.16/arch/x86_64/kernel/process.c linux-2.6.16.16/arch/x86_64/kernel/process.c --- linux-2.6.16/arch/x86_64/kernel/process.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/arch/x86_64/kernel/process.c 2006-05-11 04:56:24.000000000 +0300 @@ -527,8 +527,6 @@ int cpu = smp_processor_id(); struct tss_struct *tss = &per_cpu(init_tss, cpu); - unlazy_fpu(prev_p); - /* * Reload esp0, LDT and the page table pointer: */ @@ -591,6 +589,12 @@ prev->userrsp = read_pda(oldrsp); write_pda(oldrsp, next->userrsp); write_pda(pcurrent, next_p); + + /* This must be here to ensure both math_state_restore() and + kernel_fpu_begin() work consistently. + And the AMD workaround requires it to be after DS reload. */ + unlazy_fpu(prev_p); + write_pda(kernelstack, task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET); diff -Naur linux-2.6.16/arch/x86_64/kernel/setup.c linux-2.6.16.16/arch/x86_64/kernel/setup.c --- linux-2.6.16/arch/x86_64/kernel/setup.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/arch/x86_64/kernel/setup.c 2006-05-11 04:56:24.000000000 +0300 @@ -909,6 +909,10 @@ if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58)) set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability); + /* Enable workaround for FXSAVE leak */ + if (c->x86 >= 6) + set_bit(X86_FEATURE_FXSAVE_LEAK, &c->x86_capability); + r = get_model_name(c); if (!r) { switch (c->x86) { diff -Naur linux-2.6.16/block/genhd.c linux-2.6.16.16/block/genhd.c --- linux-2.6.16/block/genhd.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/block/genhd.c 2006-05-11 04:56:24.000000000 +0300 @@ -16,8 +16,6 @@ #include #include -#define MAX_PROBE_HASH 255 /* random */ - static struct subsystem block_subsys; static DECLARE_MUTEX(block_subsys_sem); @@ -30,108 +28,29 @@ struct blk_major_name *next; int major; char name[16]; -} *major_names[MAX_PROBE_HASH]; +} *major_names[BLKDEV_MAJOR_HASH_SIZE]; /* index in the above - for now: assume no multimajor ranges */ static inline int major_to_index(int major) { - return major % MAX_PROBE_HASH; -} - -struct blkdev_info { - int index; - struct blk_major_name *bd; -}; - -/* - * iterate over a list of blkdev_info structures. allows - * the major_names array to be iterated over from outside this file - * must be called with the block_subsys_sem held - */ -void *get_next_blkdev(void *dev) -{ - struct blkdev_info *info; - - if (dev == NULL) { - info = kmalloc(sizeof(*info), GFP_KERNEL); - if (!info) - goto out; - info->index=0; - info->bd = major_names[info->index]; - if (info->bd) - goto out; - } else { - info = dev; - } - - while (info->index < ARRAY_SIZE(major_names)) { - if (info->bd) - info->bd = info->bd->next; - if (info->bd) - goto out; - /* - * No devices on this chain, move to the next - */ - info->index++; - info->bd = (info->index < ARRAY_SIZE(major_names)) ? - major_names[info->index] : NULL; - if (info->bd) - goto out; - } - -out: - return info; -} - -void *acquire_blkdev_list(void) -{ - down(&block_subsys_sem); - return get_next_blkdev(NULL); -} - -void release_blkdev_list(void *dev) -{ - up(&block_subsys_sem); - kfree(dev); + return major % BLKDEV_MAJOR_HASH_SIZE; } +#ifdef CONFIG_PROC_FS -/* - * Count the number of records in the blkdev_list. - * must be called with the block_subsys_sem held - */ -int count_blkdev_list(void) +void blkdev_show(struct seq_file *f, off_t offset) { - struct blk_major_name *n; - int i, count; - - count = 0; + struct blk_major_name *dp; - for (i = 0; i < ARRAY_SIZE(major_names); i++) { - for (n = major_names[i]; n; n = n->next) - count++; + if (offset < BLKDEV_MAJOR_HASH_SIZE) { + down(&block_subsys_sem); + for (dp = major_names[offset]; dp; dp = dp->next) + seq_printf(f, "%3d %s\n", dp->major, dp->name); + up(&block_subsys_sem); } - - return count; -} - -/* - * extract the major and name values from a blkdev_info struct - * passed in as a void to *dev. Must be called with - * block_subsys_sem held - */ -int get_blkdev_info(void *dev, int *major, char **name) -{ - struct blkdev_info *info = dev; - - if (info->bd == NULL) - return 1; - - *major = info->bd->major; - *name = info->bd->name; - return 0; } +#endif /* CONFIG_PROC_FS */ int register_blkdev(unsigned int major, const char *name) { diff -Naur linux-2.6.16/Documentation/dvb/get_dvb_firmware linux-2.6.16.16/Documentation/dvb/get_dvb_firmware --- linux-2.6.16/Documentation/dvb/get_dvb_firmware 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/Documentation/dvb/get_dvb_firmware 2006-05-11 04:56:24.000000000 +0300 @@ -240,9 +240,9 @@ } sub nxt2002 { - my $sourcefile = "Broadband4PC_4_2_11.zip"; + my $sourcefile = "Technisat_DVB-PC_4_4_COMPACT.zip"; my $url = "http://www.bbti.us/download/windows/$sourcefile"; - my $hash = "c6d2ea47a8f456d887ada0cfb718ff2a"; + my $hash = "476befae8c7c1bb9648954060b1eec1f"; my $outfile = "dvb-fe-nxt2002.fw"; my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); @@ -250,8 +250,8 @@ wgetfile($sourcefile, $url); unzip($sourcefile, $tmpdir); - verify("$tmpdir/SkyNETU.sys", $hash); - extract("$tmpdir/SkyNETU.sys", 375832, 5908, $outfile); + verify("$tmpdir/SkyNET.sys", $hash); + extract("$tmpdir/SkyNET.sys", 331624, 5908, $outfile); $outfile; } diff -Naur linux-2.6.16/drivers/base/cpu.c linux-2.6.16.16/drivers/base/cpu.c --- linux-2.6.16/drivers/base/cpu.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/base/cpu.c 2006-05-11 04:56:24.000000000 +0300 @@ -141,7 +141,7 @@ return error; } -struct sys_device *get_cpu_sysdev(int cpu) +struct sys_device *get_cpu_sysdev(unsigned cpu) { if (cpu < NR_CPUS) return cpu_sys_devices[cpu]; diff -Naur linux-2.6.16/drivers/base/firmware_class.c linux-2.6.16.16/drivers/base/firmware_class.c --- linux-2.6.16/drivers/base/firmware_class.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/base/firmware_class.c 2006-05-11 04:56:24.000000000 +0300 @@ -211,18 +211,20 @@ fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size) { u8 *new_data; + int new_size = fw_priv->alloc_size; if (min_size <= fw_priv->alloc_size) return 0; - new_data = vmalloc(fw_priv->alloc_size + PAGE_SIZE); + new_size = ALIGN(min_size, PAGE_SIZE); + new_data = vmalloc(new_size); if (!new_data) { printk(KERN_ERR "%s: unable to alloc buffer\n", __FUNCTION__); /* Make sure that we don't keep incomplete data */ fw_load_abort(fw_priv); return -ENOMEM; } - fw_priv->alloc_size += PAGE_SIZE; + fw_priv->alloc_size = new_size; if (fw_priv->fw->data) { memcpy(new_data, fw_priv->fw->data, fw_priv->fw->size); vfree(fw_priv->fw->data); diff -Naur linux-2.6.16/drivers/base/node.c linux-2.6.16.16/drivers/base/node.c --- linux-2.6.16/drivers/base/node.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/base/node.c 2006-05-11 04:56:24.000000000 +0300 @@ -106,7 +106,7 @@ other_node = 0; for (i = 0; i < MAX_NR_ZONES; i++) { struct zone *z = &pg->node_zones[i]; - for (cpu = 0; cpu < NR_CPUS; cpu++) { + for_each_online_cpu(cpu) { struct per_cpu_pageset *ps = zone_pcp(z,cpu); numa_hit += ps->numa_hit; numa_miss += ps->numa_miss; diff -Naur linux-2.6.16/drivers/block/cciss.c linux-2.6.16.16/drivers/block/cciss.c --- linux-2.6.16/drivers/block/cciss.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/block/cciss.c 2006-05-11 04:56:24.000000000 +0300 @@ -1181,6 +1181,53 @@ return 0; } +static inline void complete_buffers(struct bio *bio, int status) +{ + while (bio) { + struct bio *xbh = bio->bi_next; + int nr_sectors = bio_sectors(bio); + + bio->bi_next = NULL; + blk_finished_io(len); + bio_endio(bio, nr_sectors << 9, status ? 0 : -EIO); + bio = xbh; + } + +} + +static void cciss_softirq_done(struct request *rq) +{ + CommandList_struct *cmd = rq->completion_data; + ctlr_info_t *h = hba[cmd->ctlr]; + unsigned long flags; + u64bit temp64; + int i, ddir; + + if (cmd->Request.Type.Direction == XFER_READ) + ddir = PCI_DMA_FROMDEVICE; + else + ddir = PCI_DMA_TODEVICE; + + /* command did not need to be retried */ + /* unmap the DMA mapping for all the scatter gather elements */ + for(i=0; iHeader.SGList; i++) { + temp64.val32.lower = cmd->SG[i].Addr.lower; + temp64.val32.upper = cmd->SG[i].Addr.upper; + pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir); + } + + complete_buffers(rq->bio, rq->errors); + +#ifdef CCISS_DEBUG + printk("Done with %p\n", rq); +#endif /* CCISS_DEBUG */ + + spin_lock_irqsave(&h->lock, flags); + end_that_request_last(rq, rq->errors); + cmd_free(h, cmd,1); + spin_unlock_irqrestore(&h->lock, flags); +} + /* This function will check the usage_count of the drive to be updated/added. * If the usage_count is zero then the drive information will be updated and * the disk will be re-registered with the kernel. If not then it will be @@ -1249,6 +1296,8 @@ blk_queue_max_sectors(disk->queue, 512); + blk_queue_softirq_done(disk->queue, cciss_softirq_done); + disk->queue->queuedata = hba[ctlr]; blk_queue_hardsect_size(disk->queue, @@ -2148,20 +2197,6 @@ addQ (&(h->cmpQ), c); } } - -static inline void complete_buffers(struct bio *bio, int status) -{ - while (bio) { - struct bio *xbh = bio->bi_next; - int nr_sectors = bio_sectors(bio); - - bio->bi_next = NULL; - blk_finished_io(len); - bio_endio(bio, nr_sectors << 9, status ? 0 : -EIO); - bio = xbh; - } - -} /* Assumes that CCISS_LOCK(h->ctlr) is held. */ /* Zeros out the error record and then resends the command back */ /* to the controller */ @@ -2179,39 +2214,6 @@ start_io(h); } -static void cciss_softirq_done(struct request *rq) -{ - CommandList_struct *cmd = rq->completion_data; - ctlr_info_t *h = hba[cmd->ctlr]; - unsigned long flags; - u64bit temp64; - int i, ddir; - - if (cmd->Request.Type.Direction == XFER_READ) - ddir = PCI_DMA_FROMDEVICE; - else - ddir = PCI_DMA_TODEVICE; - - /* command did not need to be retried */ - /* unmap the DMA mapping for all the scatter gather elements */ - for(i=0; iHeader.SGList; i++) { - temp64.val32.lower = cmd->SG[i].Addr.lower; - temp64.val32.upper = cmd->SG[i].Addr.upper; - pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir); - } - - complete_buffers(rq->bio, rq->errors); - -#ifdef CCISS_DEBUG - printk("Done with %p\n", rq); -#endif /* CCISS_DEBUG */ - - spin_lock_irqsave(&h->lock, flags); - end_that_request_last(rq, rq->errors); - cmd_free(h, cmd,1); - spin_unlock_irqrestore(&h->lock, flags); -} - /* checks the status of the job and calls complete buffers to mark all * buffers for the completed job. Note that this function does not need * to hold the hba/queue lock. @@ -3269,8 +3271,8 @@ unregister_blkdev(hba[i]->major, hba[i]->devname); clean1: release_io_mem(hba[i]); - free_hba(i); hba[i]->busy_initializing = 0; + free_hba(i); return(-1); } diff -Naur linux-2.6.16/drivers/char/agp/efficeon-agp.c linux-2.6.16.16/drivers/char/agp/efficeon-agp.c --- linux-2.6.16/drivers/char/agp/efficeon-agp.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/char/agp/efficeon-agp.c 2006-05-11 04:56:24.000000000 +0300 @@ -64,6 +64,12 @@ {.mask = 0x00000001, .type = 0} }; +/* This function does the same thing as mask_memory() for this chipset... */ +static inline unsigned long efficeon_mask_memory(unsigned long addr) +{ + return addr | 0x00000001; +} + static struct aper_size_info_lvl2 efficeon_generic_sizes[4] = { {256, 65536, 0}, @@ -251,7 +257,7 @@ last_page = NULL; for (i = 0; i < count; i++) { int index = pg_start + i; - unsigned long insert = mem->memory[i]; + unsigned long insert = efficeon_mask_memory(mem->memory[i]); page = (unsigned int *) efficeon_private.l1_table[index >> 10]; diff -Naur linux-2.6.16/drivers/char/cs5535_gpio.c linux-2.6.16.16/drivers/char/cs5535_gpio.c --- linux-2.6.16/drivers/char/cs5535_gpio.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/char/cs5535_gpio.c 2006-05-11 04:56:24.000000000 +0300 @@ -241,9 +241,10 @@ static void __exit cs5535_gpio_cleanup(void) { dev_t dev_id = MKDEV(major, 0); + + cdev_del(&cs5535_gpio_cdev); unregister_chrdev_region(dev_id, CS5535_GPIO_COUNT); - if (gpio_base != 0) - release_region(gpio_base, CS5535_GPIO_SIZE); + release_region(gpio_base, CS5535_GPIO_SIZE); } module_init(cs5535_gpio_init); diff -Naur linux-2.6.16/drivers/char/ipmi/ipmi_bt_sm.c linux-2.6.16.16/drivers/char/ipmi/ipmi_bt_sm.c --- linux-2.6.16/drivers/char/ipmi/ipmi_bt_sm.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/char/ipmi/ipmi_bt_sm.c 2006-05-11 04:56:24.000000000 +0300 @@ -165,7 +165,7 @@ { unsigned int i; - if ((size < 2) || (size > IPMI_MAX_MSG_LENGTH)) + if ((size < 2) || (size > (IPMI_MAX_MSG_LENGTH - 2))) return -1; if ((bt->state != BT_STATE_IDLE) && (bt->state != BT_STATE_HOSED)) diff -Naur linux-2.6.16/drivers/char/Kconfig linux-2.6.16.16/drivers/char/Kconfig --- linux-2.6.16/drivers/char/Kconfig 2006-05-18 01:12:22.000000000 +0300 +++ linux-2.6.16.16/drivers/char/Kconfig 2006-05-17 21:41:29.000000000 +0300 @@ -187,6 +187,7 @@ config ISI tristate "Multi-Tech multiport card support (EXPERIMENTAL)" depends on SERIAL_NONSTANDARD + select FW_LOADER help This is a driver for the Multi-Tech cards which provide several serial ports. The driver is experimental and can currently only be diff -Naur linux-2.6.16/drivers/char/snsc.c linux-2.6.16.16/drivers/char/snsc.c --- linux-2.6.16/drivers/char/snsc.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/char/snsc.c 2006-05-11 04:56:24.000000000 +0300 @@ -391,7 +391,8 @@ format_module_id(devnamep, geo_module(geoid), MODULE_FORMAT_BRIEF); devnamep = devname + strlen(devname); - sprintf(devnamep, "#%d", geo_slab(geoid)); + sprintf(devnamep, "^%d#%d", geo_slot(geoid), + geo_slab(geoid)); /* allocate sysctl device data */ scd = kmalloc(sizeof (struct sysctl_data_s), diff -Naur linux-2.6.16/drivers/char/sonypi.c linux-2.6.16.16/drivers/char/sonypi.c --- linux-2.6.16/drivers/char/sonypi.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/char/sonypi.c 2006-05-11 04:56:24.000000000 +0300 @@ -1341,6 +1341,9 @@ else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, NULL))) sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3; + else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_ICH7_1, NULL))) + sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3; else sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE2; diff -Naur linux-2.6.16/drivers/char/tipar.c linux-2.6.16.16/drivers/char/tipar.c --- linux-2.6.16/drivers/char/tipar.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/char/tipar.c 2006-05-11 04:56:24.000000000 +0300 @@ -515,7 +515,7 @@ err = PTR_ERR(tipar_class); goto out_chrdev; } - if (parport_register_driver(&tipar_driver) || tp_count == 0) { + if (parport_register_driver(&tipar_driver)) { printk(KERN_ERR "tipar: unable to register with parport\n"); err = -EIO; goto out_class; diff -Naur linux-2.6.16/drivers/char/tlclk.c linux-2.6.16.16/drivers/char/tlclk.c --- linux-2.6.16/drivers/char/tlclk.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/char/tlclk.c 2006-05-11 04:56:24.000000000 +0300 @@ -327,7 +327,7 @@ return strnlen(buf, count); } -static DEVICE_ATTR(received_ref_clk3a, S_IWUGO, NULL, +static DEVICE_ATTR(received_ref_clk3a, (S_IWUSR|S_IWGRP), NULL, store_received_ref_clk3a); @@ -349,7 +349,7 @@ return strnlen(buf, count); } -static DEVICE_ATTR(received_ref_clk3b, S_IWUGO, NULL, +static DEVICE_ATTR(received_ref_clk3b, (S_IWUSR|S_IWGRP), NULL, store_received_ref_clk3b); @@ -371,7 +371,7 @@ return strnlen(buf, count); } -static DEVICE_ATTR(enable_clk3b_output, S_IWUGO, NULL, +static DEVICE_ATTR(enable_clk3b_output, (S_IWUSR|S_IWGRP), NULL, store_enable_clk3b_output); static ssize_t store_enable_clk3a_output(struct device *d, @@ -392,7 +392,7 @@ return strnlen(buf, count); } -static DEVICE_ATTR(enable_clk3a_output, S_IWUGO, NULL, +static DEVICE_ATTR(enable_clk3a_output, (S_IWUSR|S_IWGRP), NULL, store_enable_clk3a_output); static ssize_t store_enable_clkb1_output(struct device *d, @@ -413,7 +413,7 @@ return strnlen(buf, count); } -static DEVICE_ATTR(enable_clkb1_output, S_IWUGO, NULL, +static DEVICE_ATTR(enable_clkb1_output, (S_IWUSR|S_IWGRP), NULL, store_enable_clkb1_output); @@ -435,7 +435,7 @@ return strnlen(buf, count); } -static DEVICE_ATTR(enable_clka1_output, S_IWUGO, NULL, +static DEVICE_ATTR(enable_clka1_output, (S_IWUSR|S_IWGRP), NULL, store_enable_clka1_output); static ssize_t store_enable_clkb0_output(struct device *d, @@ -456,7 +456,7 @@ return strnlen(buf, count); } -static DEVICE_ATTR(enable_clkb0_output, S_IWUGO, NULL, +static DEVICE_ATTR(enable_clkb0_output, (S_IWUSR|S_IWGRP), NULL, store_enable_clkb0_output); static ssize_t store_enable_clka0_output(struct device *d, @@ -477,7 +477,7 @@ return strnlen(buf, count); } -static DEVICE_ATTR(enable_clka0_output, S_IWUGO, NULL, +static DEVICE_ATTR(enable_clka0_output, (S_IWUSR|S_IWGRP), NULL, store_enable_clka0_output); static ssize_t store_select_amcb2_transmit_clock(struct device *d, @@ -519,7 +519,7 @@ return strnlen(buf, count); } -static DEVICE_ATTR(select_amcb2_transmit_clock, S_IWUGO, NULL, +static DEVICE_ATTR(select_amcb2_transmit_clock, (S_IWUSR|S_IWGRP), NULL, store_select_amcb2_transmit_clock); static ssize_t store_select_amcb1_transmit_clock(struct device *d, @@ -560,7 +560,7 @@ return strnlen(buf, count); } -static DEVICE_ATTR(select_amcb1_transmit_clock, S_IWUGO, NULL, +static DEVICE_ATTR(select_amcb1_transmit_clock, (S_IWUSR|S_IWGRP), NULL, store_select_amcb1_transmit_clock); static ssize_t store_select_redundant_clock(struct device *d, @@ -581,7 +581,7 @@ return strnlen(buf, count); } -static DEVICE_ATTR(select_redundant_clock, S_IWUGO, NULL, +static DEVICE_ATTR(select_redundant_clock, (S_IWUSR|S_IWGRP), NULL, store_select_redundant_clock); static ssize_t store_select_ref_frequency(struct device *d, @@ -602,7 +602,7 @@ return strnlen(buf, count); } -static DEVICE_ATTR(select_ref_frequency, S_IWUGO, NULL, +static DEVICE_ATTR(select_ref_frequency, (S_IWUSR|S_IWGRP), NULL, store_select_ref_frequency); static ssize_t store_filter_select(struct device *d, @@ -623,7 +623,7 @@ return strnlen(buf, count); } -static DEVICE_ATTR(filter_select, S_IWUGO, NULL, store_filter_select); +static DEVICE_ATTR(filter_select, (S_IWUSR|S_IWGRP), NULL, store_filter_select); static ssize_t store_hardware_switching_mode(struct device *d, struct device_attribute *attr, const char *buf, size_t count) @@ -643,7 +643,7 @@ return strnlen(buf, count); } -static DEVICE_ATTR(hardware_switching_mode, S_IWUGO, NULL, +static DEVICE_ATTR(hardware_switching_mode, (S_IWUSR|S_IWGRP), NULL, store_hardware_switching_mode); static ssize_t store_hardware_switching(struct device *d, @@ -664,7 +664,7 @@ return strnlen(buf, count); } -static DEVICE_ATTR(hardware_switching, S_IWUGO, NULL, +static DEVICE_ATTR(hardware_switching, (S_IWUSR|S_IWGRP), NULL, store_hardware_switching); static ssize_t store_refalign (struct device *d, @@ -684,7 +684,7 @@ return strnlen(buf, count); } -static DEVICE_ATTR(refalign, S_IWUGO, NULL, store_refalign); +static DEVICE_ATTR(refalign, (S_IWUSR|S_IWGRP), NULL, store_refalign); static ssize_t store_mode_select (struct device *d, struct device_attribute *attr, const char *buf, size_t count) @@ -704,7 +704,7 @@ return strnlen(buf, count); } -static DEVICE_ATTR(mode_select, S_IWUGO, NULL, store_mode_select); +static DEVICE_ATTR(mode_select, (S_IWUSR|S_IWGRP), NULL, store_mode_select); static ssize_t store_reset (struct device *d, struct device_attribute *attr, const char *buf, size_t count) @@ -724,7 +724,7 @@ return strnlen(buf, count); } -static DEVICE_ATTR(reset, S_IWUGO, NULL, store_reset); +static DEVICE_ATTR(reset, (S_IWUSR|S_IWGRP), NULL, store_reset); static struct attribute *tlclk_sysfs_entries[] = { &dev_attr_current_ref.attr, @@ -767,6 +767,7 @@ printk(KERN_ERR "tlclk: can't get major %d.\n", tlclk_major); return ret; } + tlclk_major = ret; alarm_events = kzalloc( sizeof(struct tlclk_alarms), GFP_KERNEL); if (!alarm_events) goto out1; diff -Naur linux-2.6.16/drivers/char/tty_io.c linux-2.6.16.16/drivers/char/tty_io.c --- linux-2.6.16/drivers/char/tty_io.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/char/tty_io.c 2006-05-11 04:56:24.000000000 +0300 @@ -2706,7 +2706,11 @@ } task_lock(p); if (p->files) { - rcu_read_lock(); + /* + * We don't take a ref to the file, so we must + * hold ->file_lock instead. + */ + spin_lock(&p->files->file_lock); fdt = files_fdtable(p->files); for (i=0; i < fdt->max_fds; i++) { filp = fcheck_files(p->files, i); @@ -2721,7 +2725,7 @@ break; } } - rcu_read_unlock(); + spin_unlock(&p->files->file_lock); } task_unlock(p); } while_each_task_pid(session, PIDTYPE_SID, p); diff -Naur linux-2.6.16/drivers/edac/Kconfig linux-2.6.16.16/drivers/edac/Kconfig --- linux-2.6.16/drivers/edac/Kconfig 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/edac/Kconfig 2006-05-11 04:56:24.000000000 +0300 @@ -71,7 +71,7 @@ config EDAC_E752X tristate "Intel e752x (e7520, e7525, e7320)" - depends on EDAC_MM_EDAC && PCI + depends on EDAC_MM_EDAC && PCI && HOTPLUG help Support for error detection and correction on the Intel E7520, E7525, E7320 server chipsets. diff -Naur linux-2.6.16/drivers/i2c/busses/i2c-i801.c linux-2.6.16.16/drivers/i2c/busses/i2c-i801.c --- linux-2.6.16/drivers/i2c/busses/i2c-i801.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/i2c/busses/i2c-i801.c 2006-05-11 04:56:24.000000000 +0300 @@ -478,6 +478,11 @@ ret = i801_transaction(); } + /* Some BIOSes don't like it when PEC is enabled at reboot or resume + time, so we forcibly disable it after every transaction. */ + if (hwpec) + outb_p(0, SMBAUXCTL); + if(block) return ret; if(ret) diff -Naur linux-2.6.16/drivers/i2c/chips/m41t00.c linux-2.6.16.16/drivers/i2c/chips/m41t00.c --- linux-2.6.16/drivers/i2c/chips/m41t00.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/i2c/chips/m41t00.c 2006-05-11 04:56:24.000000000 +0300 @@ -129,13 +129,13 @@ if ((i2c_smbus_write_byte_data(save_client, 0, tm.tm_sec & 0x7f) < 0) || (i2c_smbus_write_byte_data(save_client, 1, tm.tm_min & 0x7f) < 0) - || (i2c_smbus_write_byte_data(save_client, 2, tm.tm_hour & 0x7f) + || (i2c_smbus_write_byte_data(save_client, 2, tm.tm_hour & 0x3f) < 0) - || (i2c_smbus_write_byte_data(save_client, 4, tm.tm_mday & 0x7f) + || (i2c_smbus_write_byte_data(save_client, 4, tm.tm_mday & 0x3f) < 0) - || (i2c_smbus_write_byte_data(save_client, 5, tm.tm_mon & 0x7f) + || (i2c_smbus_write_byte_data(save_client, 5, tm.tm_mon & 0x1f) < 0) - || (i2c_smbus_write_byte_data(save_client, 6, tm.tm_year & 0x7f) + || (i2c_smbus_write_byte_data(save_client, 6, tm.tm_year & 0xff) < 0)) dev_warn(&save_client->dev,"m41t00: can't write to rtc chip\n"); diff -Naur linux-2.6.16/drivers/ide/pci/alim15x3.c linux-2.6.16.16/drivers/ide/pci/alim15x3.c --- linux-2.6.16/drivers/ide/pci/alim15x3.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/ide/pci/alim15x3.c 2006-05-11 04:56:24.000000000 +0300 @@ -731,6 +731,8 @@ if(m5229_revision <= 0x20) tmpbyte = (tmpbyte & (~0x02)) | 0x01; + else if (m5229_revision == 0xc7) + tmpbyte |= 0x03; else tmpbyte |= 0x01; diff -Naur linux-2.6.16/drivers/ieee1394/sbp2.c linux-2.6.16.16/drivers/ieee1394/sbp2.c --- linux-2.6.16/drivers/ieee1394/sbp2.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/ieee1394/sbp2.c 2006-05-11 04:56:24.000000000 +0300 @@ -495,22 +495,17 @@ /* * This function finds the sbp2_command for a given outstanding SCpnt. * Only looks at the inuse list. + * Must be called with scsi_id->sbp2_command_orb_lock held. */ -static struct sbp2_command_info *sbp2util_find_command_for_SCpnt(struct scsi_id_instance_data *scsi_id, void *SCpnt) +static struct sbp2_command_info *sbp2util_find_command_for_SCpnt( + struct scsi_id_instance_data *scsi_id, void *SCpnt) { struct sbp2_command_info *command; - unsigned long flags; - spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); - if (!list_empty(&scsi_id->sbp2_command_orb_inuse)) { - list_for_each_entry(command, &scsi_id->sbp2_command_orb_inuse, list) { - if (command->Current_SCpnt == SCpnt) { - spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); + if (!list_empty(&scsi_id->sbp2_command_orb_inuse)) + list_for_each_entry(command, &scsi_id->sbp2_command_orb_inuse, list) + if (command->Current_SCpnt == SCpnt) return command; - } - } - } - spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); return NULL; } @@ -579,17 +574,15 @@ /* * This function moves a command to the completed orb list. + * Must be called with scsi_id->sbp2_command_orb_lock held. */ -static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_id, - struct sbp2_command_info *command) +static void sbp2util_mark_command_completed( + struct scsi_id_instance_data *scsi_id, + struct sbp2_command_info *command) { - unsigned long flags; - - spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); list_del(&command->list); sbp2util_free_command_dma(command); list_add_tail(&command->list, &scsi_id->sbp2_command_orb_completed); - spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); } /* @@ -2177,7 +2170,9 @@ * Matched status with command, now grab scsi command pointers and check status */ SCpnt = command->Current_SCpnt; + spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); sbp2util_mark_command_completed(scsi_id, command); + spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); if (SCpnt) { @@ -2513,6 +2508,7 @@ (struct scsi_id_instance_data *)SCpnt->device->host->hostdata[0]; struct sbp2scsi_host_info *hi = scsi_id->hi; struct sbp2_command_info *command; + unsigned long flags; SBP2_ERR("aborting sbp2 command"); scsi_print_command(SCpnt); @@ -2523,6 +2519,7 @@ * Right now, just return any matching command structures * to the free pool. */ + spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); command = sbp2util_find_command_for_SCpnt(scsi_id, SCpnt); if (command) { SBP2_DEBUG("Found command to abort"); @@ -2540,6 +2537,7 @@ command->Current_done(command->Current_SCpnt); } } + spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); /* * Initiate a fetch agent reset. diff -Naur linux-2.6.16/drivers/macintosh/therm_adt746x.c linux-2.6.16.16/drivers/macintosh/therm_adt746x.c --- linux-2.6.16/drivers/macintosh/therm_adt746x.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/macintosh/therm_adt746x.c 2006-05-11 04:56:24.000000000 +0300 @@ -627,8 +627,8 @@ if(therm_type == ADT7460) device_create_file(&of_dev->dev, &dev_attr_sensor2_fan_speed); -#ifndef CONFIG_I2C_KEYWEST - request_module("i2c-keywest"); +#ifndef CONFIG_I2C_POWERMAC + request_module("i2c-powermac"); #endif return i2c_add_driver(&thermostat_driver); diff -Naur linux-2.6.16/drivers/md/dm.c linux-2.6.16.16/drivers/md/dm.c --- linux-2.6.16/drivers/md/dm.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/md/dm.c 2006-05-11 04:56:24.000000000 +0300 @@ -533,30 +533,35 @@ } else { /* - * Create two copy bios to deal with io that has - * been split across a target. + * Handle a bvec that must be split between two or more targets. */ struct bio_vec *bv = bio->bi_io_vec + ci->idx; + sector_t remaining = to_sector(bv->bv_len); + unsigned int offset = 0; - clone = split_bvec(bio, ci->sector, ci->idx, - bv->bv_offset, max); - __map_bio(ti, clone, tio); - - ci->sector += max; - ci->sector_count -= max; - ti = dm_table_find_target(ci->map, ci->sector); - - len = to_sector(bv->bv_len) - max; - clone = split_bvec(bio, ci->sector, ci->idx, - bv->bv_offset + to_bytes(max), len); - tio = alloc_tio(ci->md); - tio->io = ci->io; - tio->ti = ti; - memset(&tio->info, 0, sizeof(tio->info)); - __map_bio(ti, clone, tio); + do { + if (offset) { + ti = dm_table_find_target(ci->map, ci->sector); + max = max_io_len(ci->md, ci->sector, ti); + + tio = alloc_tio(ci->md); + tio->io = ci->io; + tio->ti = ti; + memset(&tio->info, 0, sizeof(tio->info)); + } + + len = min(remaining, max); + + clone = split_bvec(bio, ci->sector, ci->idx, + bv->bv_offset + offset, len); + + __map_bio(ti, clone, tio); + + ci->sector += len; + ci->sector_count -= len; + offset += to_bytes(len); + } while (remaining -= len); - ci->sector += len; - ci->sector_count -= len; ci->idx++; } } @@ -1093,6 +1098,7 @@ { struct dm_table *map = NULL; DECLARE_WAITQUEUE(wait, current); + struct bio *def; int r = -EINVAL; down(&md->suspend_lock); @@ -1152,9 +1158,11 @@ /* were we interrupted ? */ r = -EINTR; if (atomic_read(&md->pending)) { + clear_bit(DMF_BLOCK_IO, &md->flags); + def = bio_list_get(&md->deferred); + __flush_deferred_io(md, def); up_write(&md->io_lock); unlock_fs(md); - clear_bit(DMF_BLOCK_IO, &md->flags); goto out; } up_write(&md->io_lock); diff -Naur linux-2.6.16/drivers/md/dm-snap.c linux-2.6.16.16/drivers/md/dm-snap.c --- linux-2.6.16/drivers/md/dm-snap.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/md/dm-snap.c 2006-05-11 04:56:24.000000000 +0300 @@ -542,8 +542,12 @@ { struct dm_snapshot *s = (struct dm_snapshot *) ti->private; + /* Prevent further origin writes from using this snapshot. */ + /* After this returns there can be no new kcopyd jobs. */ unregister_snapshot(s); + kcopyd_client_destroy(s->kcopyd_client); + exit_exception_table(&s->pending, pending_cache); exit_exception_table(&s->complete, exception_cache); @@ -552,7 +556,7 @@ dm_put_device(ti, s->origin); dm_put_device(ti, s->cow); - kcopyd_client_destroy(s->kcopyd_client); + kfree(s); } diff -Naur linux-2.6.16/drivers/md/kcopyd.c linux-2.6.16.16/drivers/md/kcopyd.c --- linux-2.6.16/drivers/md/kcopyd.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/md/kcopyd.c 2006-05-11 04:56:24.000000000 +0300 @@ -44,6 +44,9 @@ struct page_list *pages; unsigned int nr_pages; unsigned int nr_free_pages; + + wait_queue_head_t destroyq; + atomic_t nr_jobs; }; static struct page_list *alloc_pl(void) @@ -293,10 +296,15 @@ int read_err = job->read_err; unsigned int write_err = job->write_err; kcopyd_notify_fn fn = job->fn; + struct kcopyd_client *kc = job->kc; - kcopyd_put_pages(job->kc, job->pages); + kcopyd_put_pages(kc, job->pages); mempool_free(job, _job_pool); fn(read_err, write_err, context); + + if (atomic_dec_and_test(&kc->nr_jobs)) + wake_up(&kc->destroyq); + return 0; } @@ -431,6 +439,7 @@ */ static void dispatch_job(struct kcopyd_job *job) { + atomic_inc(&job->kc->nr_jobs); push(&_pages_jobs, job); wake(); } @@ -670,6 +679,9 @@ return r; } + init_waitqueue_head(&kc->destroyq); + atomic_set(&kc->nr_jobs, 0); + client_add(kc); *result = kc; return 0; @@ -677,6 +689,9 @@ void kcopyd_client_destroy(struct kcopyd_client *kc) { + /* Wait for completion of all jobs submitted by this client. */ + wait_event(kc->destroyq, !atomic_read(&kc->nr_jobs)); + dm_io_put(kc->nr_pages); client_free_pages(kc); client_del(kc); diff -Naur linux-2.6.16/drivers/media/dvb/dvb-usb/cxusb.c linux-2.6.16.16/drivers/media/dvb/dvb-usb/cxusb.c --- linux-2.6.16/drivers/media/dvb/dvb-usb/cxusb.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/media/dvb/dvb-usb/cxusb.c 2006-05-11 04:56:24.000000000 +0300 @@ -149,6 +149,15 @@ return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0); } +static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff) +{ + u8 b = 0; + if (onoff) + return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0); + else + return 0; +} + static int cxusb_streaming_ctrl(struct dvb_usb_device *d, int onoff) { u8 buf[2] = { 0x03, 0x00 }; @@ -505,7 +514,7 @@ .size_of_priv = sizeof(struct cxusb_state), .streaming_ctrl = cxusb_streaming_ctrl, - .power_ctrl = cxusb_power_ctrl, + .power_ctrl = cxusb_bluebird_power_ctrl, .frontend_attach = cxusb_lgdt3303_frontend_attach, .tuner_attach = cxusb_lgh064f_tuner_attach, @@ -545,7 +554,7 @@ .size_of_priv = sizeof(struct cxusb_state), .streaming_ctrl = cxusb_streaming_ctrl, - .power_ctrl = cxusb_power_ctrl, + .power_ctrl = cxusb_bluebird_power_ctrl, .frontend_attach = cxusb_dee1601_frontend_attach, .tuner_attach = cxusb_dee1601_tuner_attach, @@ -594,7 +603,7 @@ .size_of_priv = sizeof(struct cxusb_state), .streaming_ctrl = cxusb_streaming_ctrl, - .power_ctrl = cxusb_power_ctrl, + .power_ctrl = cxusb_bluebird_power_ctrl, .frontend_attach = cxusb_mt352_frontend_attach, .tuner_attach = cxusb_lgz201_tuner_attach, @@ -634,7 +643,7 @@ .size_of_priv = sizeof(struct cxusb_state), .streaming_ctrl = cxusb_streaming_ctrl, - .power_ctrl = cxusb_power_ctrl, + .power_ctrl = cxusb_bluebird_power_ctrl, .frontend_attach = cxusb_mt352_frontend_attach, .tuner_attach = cxusb_dtt7579_tuner_attach, diff -Naur linux-2.6.16/drivers/media/video/Kconfig linux-2.6.16.16/drivers/media/video/Kconfig --- linux-2.6.16/drivers/media/video/Kconfig 2006-05-18 01:12:22.000000000 +0300 +++ linux-2.6.16.16/drivers/media/video/Kconfig 2006-05-17 21:41:30.000000000 +0300 @@ -349,6 +349,7 @@ config VIDEO_DECODER tristate "Add support for additional video chipsets" depends on VIDEO_DEV && I2C && EXPERIMENTAL + select FW_LOADER ---help--- Say Y here to compile drivers for SAA7115, SAA7127 and CX25840 video decoders. diff -Naur linux-2.6.16/drivers/media/video/saa7127.c linux-2.6.16.16/drivers/media/video/saa7127.c --- linux-2.6.16/drivers/media/video/saa7127.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/media/video/saa7127.c 2006-05-11 04:56:24.000000000 +0300 @@ -141,6 +141,7 @@ static const struct i2c_reg_value saa7129_init_config_extra[] = { { SAA7127_REG_OUTPUT_PORT_CONTROL, 0x38 }, { SAA7127_REG_VTRIG, 0xfa }, + { 0, 0 } }; static const struct i2c_reg_value saa7127_init_config_common[] = { diff -Naur linux-2.6.16/drivers/media/video/tuner-types.c linux-2.6.16.16/drivers/media/video/tuner-types.c --- linux-2.6.16/drivers/media/video/tuner-types.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/media/video/tuner-types.c 2006-05-11 04:56:24.000000000 +0300 @@ -1087,8 +1087,8 @@ /* ------------ TUNER_SAMSUNG_TCPN_2121P30A - Samsung NTSC ------------ */ static struct tuner_range tuner_samsung_tcpn_2121p30a_ntsc_ranges[] = { - { 16 * 175.75 /*MHz*/, 0x01, }, - { 16 * 410.25 /*MHz*/, 0x02, }, + { 16 * 130.00 /*MHz*/, 0x01, }, + { 16 * 364.50 /*MHz*/, 0x02, }, { 16 * 999.99 , 0x08, }, }; diff -Naur linux-2.6.16/drivers/mtd/nand/Kconfig linux-2.6.16.16/drivers/mtd/nand/Kconfig --- linux-2.6.16/drivers/mtd/nand/Kconfig 2006-05-18 01:12:23.000000000 +0300 +++ linux-2.6.16.16/drivers/mtd/nand/Kconfig 2006-05-17 22:32:57.000000000 +0300 @@ -184,15 +184,14 @@ Even if you leave this disabled, you can enable BBT writes at module load time (assuming you build diskonchip as a module) with the module parameter "inftl_bbt_write=1". - - config MTD_NAND_SHARPSL - bool "Support for NAND Flash on Sharp SL Series (C7xx + others)" - depends on MTD_NAND && ARCH_PXA - - config MTD_NAND_NANDSIM - bool "Support for NAND Flash Simulator" - depends on MTD_NAND && MTD_PARTITIONS +config MTD_NAND_SHARPSL + tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)" + depends on MTD_NAND && ARCH_PXA + +config MTD_NAND_NANDSIM + tristate "Support for NAND Flash Simulator" + depends on MTD_NAND && MTD_PARTITIONS help The simulator may simulate verious NAND flash chips for the MTD nand layer. @@ -200,7 +199,6 @@ config MTD_NAND_OMAP_HW bool "OMAP HW NAND Flash controller support" depends on ARM && ARCH_OMAP16XX && MTD_NAND - help Driver for TI OMAP16xx hardware NAND flash controller. diff -Naur linux-2.6.16/drivers/net/e1000/e1000_main.c linux-2.6.16.16/drivers/net/e1000/e1000_main.c --- linux-2.6.16/drivers/net/e1000/e1000_main.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/net/e1000/e1000_main.c 2006-05-11 04:56:24.000000000 +0300 @@ -3851,6 +3851,7 @@ skb_shinfo(skb)->nr_frags++; skb->len += length; skb->data_len += length; + skb->truesize += length; } e1000_rx_checksum(adapter, staterr, diff -Naur linux-2.6.16/drivers/net/irda/irda-usb.c linux-2.6.16.16/drivers/net/irda/irda-usb.c --- linux-2.6.16/drivers/net/irda/irda-usb.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/net/irda/irda-usb.c 2006-05-11 04:56:24.000000000 +0300 @@ -740,7 +740,7 @@ struct sk_buff *newskb; struct sk_buff *dataskb; struct urb *next_urb; - int docopy; + unsigned int len, docopy; IRDA_DEBUG(2, "%s(), len=%d\n", __FUNCTION__, urb->actual_length); @@ -851,10 +851,11 @@ dataskb->dev = self->netdev; dataskb->mac.raw = dataskb->data; dataskb->protocol = htons(ETH_P_IRDA); + len = dataskb->len; netif_rx(dataskb); /* Keep stats up to date */ - self->stats.rx_bytes += dataskb->len; + self->stats.rx_bytes += len; self->stats.rx_packets++; self->netdev->last_rx = jiffies; diff -Naur linux-2.6.16/drivers/net/sky2.c linux-2.6.16.16/drivers/net/sky2.c --- linux-2.6.16/drivers/net/sky2.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/net/sky2.c 2006-05-11 04:56:24.000000000 +0300 @@ -579,8 +579,8 @@ reg = gma_read16(hw, port, GM_PHY_ADDR); gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR); - for (i = 0; i < GM_MIB_CNT_SIZE; i++) - gma_read16(hw, port, GM_MIB_CNT_BASE + 8 * i); + for (i = GM_MIB_CNT_BASE; i <= GM_MIB_CNT_END; i += 4) + gma_read16(hw, port, i); gma_write16(hw, port, GM_PHY_ADDR, reg); /* transmit control */ diff -Naur linux-2.6.16/drivers/net/sky2.h linux-2.6.16.16/drivers/net/sky2.h --- linux-2.6.16/drivers/net/sky2.h 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/net/sky2.h 2006-05-11 04:56:24.000000000 +0300 @@ -1380,6 +1380,7 @@ /* MIB Counters */ #define GM_MIB_CNT_BASE 0x0100 /* Base Address of MIB Counters */ #define GM_MIB_CNT_SIZE 44 /* Number of MIB Counters */ +#define GM_MIB_CNT_END 0x025C /* Last MIB counter */ /* * MIB Counters base address definitions (low word) - diff -Naur linux-2.6.16/drivers/net/wireless/hostap/hostap_80211_tx.c linux-2.6.16.16/drivers/net/wireless/hostap/hostap_80211_tx.c --- linux-2.6.16/drivers/net/wireless/hostap/hostap_80211_tx.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/net/wireless/hostap/hostap_80211_tx.c 2006-05-11 04:56:24.000000000 +0300 @@ -469,7 +469,7 @@ } if (local->ieee_802_1x && meta->ethertype == ETH_P_PAE && tx.crypt && - !(fc & IEEE80211_FCTL_VERS)) { + !(fc & IEEE80211_FCTL_PROTECTED)) { no_encrypt = 1; PDEBUG(DEBUG_EXTRA2, "%s: TX: IEEE 802.1X - passing " "unencrypted EAPOL frame\n", dev->name); diff -Naur linux-2.6.16/drivers/net/wireless/ipw2200.c linux-2.6.16.16/drivers/net/wireless/ipw2200.c --- linux-2.6.16/drivers/net/wireless/ipw2200.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/net/wireless/ipw2200.c 2006-05-11 04:56:24.000000000 +0300 @@ -9956,9 +9956,8 @@ return -EINVAL; down(&p->sem); memcpy(&p->eeprom[eeprom->offset], bytes, eeprom->len); - for (i = IPW_EEPROM_DATA; - i < IPW_EEPROM_DATA + IPW_EEPROM_IMAGE_SIZE; i++) - ipw_write8(p, i, p->eeprom[i]); + for (i = 0; i < IPW_EEPROM_IMAGE_SIZE; i++) + ipw_write8(p, i + IPW_EEPROM_DATA, p->eeprom[i]); up(&p->sem); return 0; } diff -Naur linux-2.6.16/drivers/net/wireless/Kconfig linux-2.6.16.16/drivers/net/wireless/Kconfig --- linux-2.6.16/drivers/net/wireless/Kconfig 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/net/wireless/Kconfig 2006-05-11 04:56:24.000000000 +0300 @@ -239,7 +239,8 @@ config AIRO tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards" - depends on NET_RADIO && ISA_DMA_API && CRYPTO && (PCI || BROKEN) + depends on NET_RADIO && ISA_DMA_API && (PCI || BROKEN) + select CRYPTO ---help--- This is the standard Linux driver to support Cisco/Aironet ISA and PCI 802.11 wireless cards. @@ -374,6 +375,7 @@ config PCMCIA_SPECTRUM tristate "Symbol Spectrum24 Trilogy PCMCIA card support" depends on NET_RADIO && PCMCIA && HERMES + select FW_LOADER ---help--- This is a driver for 802.11b cards using RAM-loadable Symbol @@ -387,6 +389,7 @@ config AIRO_CS tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards" depends on NET_RADIO && PCMCIA && (BROKEN || !M32R) + select CRYPTO ---help--- This is the standard Linux driver to support Cisco/Aironet PCMCIA 802.11 wireless cards. This driver is the same as the Aironet diff -Naur linux-2.6.16/drivers/pcmcia/ds.c linux-2.6.16.16/drivers/pcmcia/ds.c --- linux-2.6.16/drivers/pcmcia/ds.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/pcmcia/ds.c 2006-05-11 04:56:24.000000000 +0300 @@ -546,7 +546,7 @@ tmp = vers1->str + vers1->ofs[i]; length = strlen(tmp) + 1; - if ((length < 3) || (length > 255)) + if ((length < 2) || (length > 255)) continue; p_dev->prod_id[i] = kmalloc(sizeof(char) * length, diff -Naur linux-2.6.16/drivers/scsi/3w-9xxx.c linux-2.6.16.16/drivers/scsi/3w-9xxx.c --- linux-2.6.16/drivers/scsi/3w-9xxx.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/scsi/3w-9xxx.c 2006-05-11 04:56:24.000000000 +0300 @@ -85,7 +85,7 @@ #include "3w-9xxx.h" /* Globals */ -#define TW_DRIVER_VERSION "2.26.02.005" +#define TW_DRIVER_VERSION "2.26.02.007" static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; static unsigned int twa_device_extension_count; static int twa_major = -1; @@ -1944,9 +1944,13 @@ } if (tw_dev->srb[request_id]->use_sg == 1) { struct scatterlist *sg = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer; - char *buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; + char *buf; + unsigned long flags = 0; + local_irq_save(flags); + buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; memcpy(buf, tw_dev->generic_buffer_virt[request_id], sg->length); kunmap_atomic(buf - sg->offset, KM_IRQ0); + local_irq_restore(flags); } } } /* End twa_scsiop_execute_scsi_complete() */ diff -Naur linux-2.6.16/drivers/scsi/3w-xxxx.c linux-2.6.16.16/drivers/scsi/3w-xxxx.c --- linux-2.6.16/drivers/scsi/3w-xxxx.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/scsi/3w-xxxx.c 2006-05-11 04:56:24.000000000 +0300 @@ -1508,10 +1508,12 @@ struct scsi_cmnd *cmd = tw_dev->srb[request_id]; void *buf; unsigned int transfer_len; + unsigned long flags = 0; if (cmd->use_sg) { struct scatterlist *sg = (struct scatterlist *)cmd->request_buffer; + local_irq_save(flags); buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; transfer_len = min(sg->length, len); } else { @@ -1526,6 +1528,7 @@ sg = (struct scatterlist *)cmd->request_buffer; kunmap_atomic(buf - sg->offset, KM_IRQ0); + local_irq_restore(flags); } } diff -Naur linux-2.6.16/drivers/scsi/sata_mv.c linux-2.6.16.16/drivers/scsi/sata_mv.c --- linux-2.6.16/drivers/scsi/sata_mv.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/scsi/sata_mv.c 2006-05-11 04:56:24.000000000 +0300 @@ -1102,6 +1102,7 @@ void __iomem *port_mmio = mv_ap_base(ap); struct mv_port_priv *pp = ap->private_data; u32 out_ptr; + u8 ata_status; out_ptr = readl(port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); @@ -1109,6 +1110,8 @@ assert(((out_ptr >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) == pp->rsp_consumer); + ata_status = pp->crpb[pp->rsp_consumer].flags >> CRPB_FLAG_STATUS_SHIFT; + /* increment our consumer index... */ pp->rsp_consumer = mv_inc_q_index(&pp->rsp_consumer); @@ -1123,7 +1126,7 @@ writelfl(out_ptr, port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); /* Return ATA status register for completed CRPB */ - return (pp->crpb[pp->rsp_consumer].flags >> CRPB_FLAG_STATUS_SHIFT); + return ata_status; } /** @@ -1192,7 +1195,6 @@ u32 hc_irq_cause; int shift, port, port0, hard_port, handled; unsigned int err_mask; - u8 ata_status = 0; if (hc == 0) { port0 = 0; @@ -1210,6 +1212,7 @@ hc,relevant,hc_irq_cause); for (port = port0; port < port0 + MV_PORTS_PER_HC; port++) { + u8 ata_status = 0; ap = host_set->ports[port]; hard_port = port & MV_PORT_MASK; /* range 0-3 */ handled = 0; /* ensure ata_status is set if handled++ */ diff -Naur linux-2.6.16/drivers/usb/core/message.c linux-2.6.16.16/drivers/usb/core/message.c --- linux-2.6.16/drivers/usb/core/message.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/usb/core/message.c 2006-05-11 04:56:24.000000000 +0300 @@ -1388,11 +1388,13 @@ if (dev->state != USB_STATE_ADDRESS) usb_disable_device (dev, 1); // Skip ep0 - i = dev->bus_mA - cp->desc.bMaxPower * 2; - if (i < 0) - dev_warn(&dev->dev, "new config #%d exceeds power " - "limit by %dmA\n", - configuration, -i); + if (cp) { + i = dev->bus_mA - cp->desc.bMaxPower * 2; + if (i < 0) + dev_warn(&dev->dev, "new config #%d exceeds power " + "limit by %dmA\n", + configuration, -i); + } if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_CONFIGURATION, 0, configuration, 0, diff -Naur linux-2.6.16/drivers/usb/host/ehci-sched.c linux-2.6.16.16/drivers/usb/host/ehci-sched.c --- linux-2.6.16/drivers/usb/host/ehci-sched.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/usb/host/ehci-sched.c 2006-05-11 04:56:24.000000000 +0300 @@ -707,6 +707,7 @@ } else { u32 addr; int think_time; + int hs_transfers; addr = dev->ttport << 24; if (!ehci_is_TDI(ehci) @@ -719,6 +720,7 @@ think_time = dev->tt ? dev->tt->think_time : 0; stream->tt_usecs = NS_TO_US (think_time + usb_calc_bus_time ( dev->speed, is_input, 1, maxp)); + hs_transfers = max (1u, (maxp + 187) / 188); if (is_input) { u32 tmp; @@ -727,12 +729,11 @@ stream->usecs = HS_USECS_ISO (1); stream->raw_mask = 1; - /* pessimistic c-mask */ - tmp = usb_calc_bus_time (USB_SPEED_FULL, 1, 0, maxp) - / (125 * 1000); - stream->raw_mask |= 3 << (tmp + 9); + /* c-mask as specified in USB 2.0 11.18.4 3.c */ + tmp = (1 << (hs_transfers + 2)) - 1; + stream->raw_mask |= tmp << (8 + 2); } else - stream->raw_mask = smask_out [maxp / 188]; + stream->raw_mask = smask_out [hs_transfers - 1]; bandwidth = stream->usecs + stream->c_usecs; bandwidth /= 1 << (interval + 2); diff -Naur linux-2.6.16/drivers/usb/serial/console.c linux-2.6.16.16/drivers/usb/serial/console.c --- linux-2.6.16/drivers/usb/serial/console.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/usb/serial/console.c 2006-05-11 04:56:24.000000000 +0300 @@ -54,7 +54,7 @@ * serial.c code, except that the specifier is "ttyUSB" instead * of "ttyS". */ -static int __init usb_console_setup(struct console *co, char *options) +static int usb_console_setup(struct console *co, char *options) { struct usbcons_info *info = &usbcons_info; int baud = 9600; diff -Naur linux-2.6.16/drivers/usb/serial/option.c linux-2.6.16.16/drivers/usb/serial/option.c --- linux-2.6.16/drivers/usb/serial/option.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/usb/serial/option.c 2006-05-11 04:56:24.000000000 +0300 @@ -582,14 +582,14 @@ portdata = usb_get_serial_port_data(port); /* Do indat endpoints first */ - for (j = 0; j <= N_IN_URB; ++j) { + for (j = 0; j < N_IN_URB; ++j) { portdata->in_urbs[j] = option_setup_urb (serial, port->bulk_in_endpointAddress, USB_DIR_IN, port, portdata->in_buffer[j], IN_BUFLEN, option_indat_callback); } /* outdat endpoints */ - for (j = 0; j <= N_OUT_URB; ++j) { + for (j = 0; j < N_OUT_URB; ++j) { portdata->out_urbs[j] = option_setup_urb (serial, port->bulk_out_endpointAddress, USB_DIR_OUT, port, portdata->out_buffer[j], OUT_BUFLEN, option_outdat_callback); diff -Naur linux-2.6.16/drivers/usb/storage/Kconfig linux-2.6.16.16/drivers/usb/storage/Kconfig --- linux-2.6.16/drivers/usb/storage/Kconfig 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/usb/storage/Kconfig 2006-05-11 04:56:24.000000000 +0300 @@ -48,7 +48,8 @@ config USB_STORAGE_ISD200 bool "ISD-200 USB/ATA Bridge support" - depends on USB_STORAGE && BLK_DEV_IDE + depends on USB_STORAGE + depends on BLK_DEV_IDE=y || BLK_DEV_IDE=USB_STORAGE ---help--- Say Y here if you want to use USB Mass Store devices based on the In-Systems Design ISD-200 USB/ATA bridge. diff -Naur linux-2.6.16/drivers/video/cfbimgblt.c linux-2.6.16.16/drivers/video/cfbimgblt.c --- linux-2.6.16/drivers/video/cfbimgblt.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/video/cfbimgblt.c 2006-05-11 04:56:24.000000000 +0300 @@ -169,7 +169,7 @@ while (j--) { l--; - color = (*s & 1 << (FB_BIT_NR(l))) ? fgcolor : bgcolor; + color = (*s & (1 << l)) ? fgcolor : bgcolor; val |= FB_SHIFT_HIGH(color, shift); /* Did the bitshift spill bits to the next long? */ diff -Naur linux-2.6.16/drivers/video/fbmem.c linux-2.6.16.16/drivers/video/fbmem.c --- linux-2.6.16/drivers/video/fbmem.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/video/fbmem.c 2006-05-11 04:56:24.000000000 +0300 @@ -669,13 +669,19 @@ total_size = info->fix.smem_len; if (p > total_size) - return 0; + return -EFBIG; - if (count >= total_size) + if (count > total_size) { + err = -EFBIG; count = total_size; + } + + if (count + p > total_size) { + if (!err) + err = -ENOSPC; - if (count + p > total_size) count = total_size - p; + } buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL); @@ -717,7 +723,7 @@ kfree(buffer); - return (err) ? err : cnt; + return (cnt) ? cnt : err; } #ifdef CONFIG_KMOD diff -Naur linux-2.6.16/drivers/video/i810/i810_main.c linux-2.6.16.16/drivers/video/i810/i810_main.c --- linux-2.6.16/drivers/video/i810/i810_main.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/drivers/video/i810/i810_main.c 2006-05-11 04:56:24.000000000 +0300 @@ -1508,7 +1508,7 @@ int size = ((cursor->image.width + 7) >> 3) * cursor->image.height; int i; - u8 *data = kmalloc(64 * 8, GFP_KERNEL); + u8 *data = kmalloc(64 * 8, GFP_ATOMIC); if (data == NULL) return -ENOMEM; diff -Naur linux-2.6.16/fs/9p/vfs_inode.c linux-2.6.16.16/fs/9p/vfs_inode.c --- linux-2.6.16/fs/9p/vfs_inode.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/fs/9p/vfs_inode.c 2006-05-11 04:56:24.000000000 +0300 @@ -614,6 +614,7 @@ sb = dir->i_sb; v9ses = v9fs_inode2v9ses(dir); + dentry->d_op = &v9fs_dentry_operations; dirfid = v9fs_fid_lookup(dentry->d_parent); if (!dirfid) { @@ -681,8 +682,6 @@ goto FreeFcall; fid->qid = fcall->params.rstat.stat.qid; - - dentry->d_op = &v9fs_dentry_operations; v9fs_stat2inode(&fcall->params.rstat.stat, inode, inode->i_sb); d_add(dentry, inode); diff -Naur linux-2.6.16/fs/char_dev.c linux-2.6.16.16/fs/char_dev.c --- linux-2.6.16/fs/char_dev.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/fs/char_dev.c 2006-05-11 04:56:24.000000000 +0300 @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -26,8 +27,6 @@ static struct kobj_map *cdev_map; -#define MAX_PROBE_HASH 255 /* random */ - static DECLARE_MUTEX(chrdevs_lock); static struct char_device_struct { @@ -38,93 +37,29 @@ char name[64]; struct file_operations *fops; struct cdev *cdev; /* will die */ -} *chrdevs[MAX_PROBE_HASH]; +} *chrdevs[CHRDEV_MAJOR_HASH_SIZE]; /* index in the above */ static inline int major_to_index(int major) { - return major % MAX_PROBE_HASH; -} - -struct chrdev_info { - int index; - struct char_device_struct *cd; -}; - -void *get_next_chrdev(void *dev) -{ - struct chrdev_info *info; - - if (dev == NULL) { - info = kmalloc(sizeof(*info), GFP_KERNEL); - if (!info) - goto out; - info->index=0; - info->cd = chrdevs[info->index]; - if (info->cd) - goto out; - } else { - info = dev; - } - - while (info->index < ARRAY_SIZE(chrdevs)) { - if (info->cd) - info->cd = info->cd->next; - if (info->cd) - goto out; - /* - * No devices on this chain, move to the next - */ - info->index++; - info->cd = (info->index < ARRAY_SIZE(chrdevs)) ? - chrdevs[info->index] : NULL; - if (info->cd) - goto out; - } - -out: - return info; -} - -void *acquire_chrdev_list(void) -{ - down(&chrdevs_lock); - return get_next_chrdev(NULL); -} - -void release_chrdev_list(void *dev) -{ - up(&chrdevs_lock); - kfree(dev); + return major % CHRDEV_MAJOR_HASH_SIZE; } +#ifdef CONFIG_PROC_FS -int count_chrdev_list(void) +void chrdev_show(struct seq_file *f, off_t offset) { struct char_device_struct *cd; - int i, count; - - count = 0; - for (i = 0; i < ARRAY_SIZE(chrdevs) ; i++) { - for (cd = chrdevs[i]; cd; cd = cd->next) - count++; + if (offset < CHRDEV_MAJOR_HASH_SIZE) { + down(&chrdevs_lock); + for (cd = chrdevs[offset]; cd; cd = cd->next) + seq_printf(f, "%3d %s\n", cd->major, cd->name); + up(&chrdevs_lock); } - - return count; } -int get_chrdev_info(void *dev, int *major, char **name) -{ - struct chrdev_info *info = dev; - - if (info->cd == NULL) - return 1; - - *major = info->cd->major; - *name = info->cd->name; - return 0; -} +#endif /* CONFIG_PROC_FS */ /* * Register a single major with a specified minor range. diff -Naur linux-2.6.16/fs/cifs/cifsencrypt.c linux-2.6.16.16/fs/cifs/cifsencrypt.c --- linux-2.6.16/fs/cifs/cifsencrypt.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/fs/cifs/cifsencrypt.c 2006-05-11 04:56:24.000000000 +0300 @@ -56,9 +56,6 @@ int rc = 0; char smb_signature[20]; - /* BB remember to initialize sequence number elsewhere and initialize mac_signing key elsewhere BB */ - /* BB remember to add code to save expected sequence number in midQ entry BB */ - if((cifs_pdu == NULL) || (server == NULL)) return -EINVAL; @@ -85,20 +82,33 @@ static int cifs_calc_signature2(const struct kvec * iov, int n_vec, const char * key, char * signature) { - struct MD5Context context; - - if((iov == NULL) || (signature == NULL)) - return -EINVAL; + struct MD5Context context; + int i; - MD5Init(&context); - MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16); + if((iov == NULL) || (signature == NULL)) + return -EINVAL; -/* MD5Update(&context,cifs_pdu->Protocol,cifs_pdu->smb_buf_length); */ /* BB FIXME BB */ + MD5Init(&context); + MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16); + for(i=0;ii_sb); pTcon = cifs_sb->tcon; + /* + * Don't allow the separator character in a path component. + * The VFS will not allow "/", but "\" is allowed by posix. + */ + if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) { + int i; + for (i = 0; i < direntry->d_name.len; i++) + if (direntry->d_name.name[i] == '\\') { + cFYI(1, ("Invalid file name")); + FreeXid(xid); + return ERR_PTR(-EINVAL); + } + } + /* can not grab the rename sem here since it would deadlock in the cases (beginning of sys_rename itself) in which we already have the sb rename sem */ diff -Naur linux-2.6.16/fs/compat.c linux-2.6.16.16/fs/compat.c --- linux-2.6.16/fs/compat.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/fs/compat.c 2006-05-11 04:56:24.000000000 +0300 @@ -1215,6 +1215,10 @@ if (ret < 0) goto out; + ret = security_file_permission(file, type == READ ? MAY_READ:MAY_WRITE); + if (ret) + goto out; + fnv = NULL; if (type == READ) { fn = file->f_op->read; diff -Naur linux-2.6.16/fs/ext3/resize.c linux-2.6.16.16/fs/ext3/resize.c --- linux-2.6.16/fs/ext3/resize.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/fs/ext3/resize.c 2006-05-11 04:56:24.000000000 +0300 @@ -974,6 +974,7 @@ if (o_blocks_count != le32_to_cpu(es->s_blocks_count)) { ext3_warning(sb, __FUNCTION__, "multiple resizers run on filesystem!"); + unlock_super(sb); err = -EBUSY; goto exit_put; } diff -Naur linux-2.6.16/fs/fuse/file.c linux-2.6.16.16/fs/fuse/file.c --- linux-2.6.16/fs/fuse/file.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/fs/fuse/file.c 2006-05-11 04:56:24.000000000 +0300 @@ -397,8 +397,12 @@ return -EINTR; err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data); - if (!err) - fuse_send_readpages(data.req, file, inode); + if (!err) { + if (data.req->num_pages) + fuse_send_readpages(data.req, file, inode); + else + fuse_put_request(fc, data.req); + } return err; } diff -Naur linux-2.6.16/fs/locks.c linux-2.6.16.16/fs/locks.c --- linux-2.6.16/fs/locks.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/fs/locks.c 2006-05-11 04:56:24.000000000 +0300 @@ -432,15 +432,14 @@ */ static int lease_init(struct file *filp, int type, struct file_lock *fl) { + if (assign_type(fl, type) != 0) + return -EINVAL; + fl->fl_owner = current->files; fl->fl_pid = current->tgid; fl->fl_file = filp; fl->fl_flags = FL_LEASE; - if (assign_type(fl, type) != 0) { - locks_free_lock(fl); - return -EINVAL; - } fl->fl_start = 0; fl->fl_end = OFFSET_MAX; fl->fl_ops = NULL; @@ -452,16 +451,19 @@ static int lease_alloc(struct file *filp, int type, struct file_lock **flp) { struct file_lock *fl = locks_alloc_lock(); - int error; + int error = -ENOMEM; if (fl == NULL) - return -ENOMEM; + goto out; error = lease_init(filp, type, fl); - if (error) - return error; + if (error) { + locks_free_lock(fl); + fl = NULL; + } +out: *flp = fl; - return 0; + return error; } /* Check if two locks overlap each other. @@ -1337,6 +1339,7 @@ goto out; if (my_before != NULL) { + *flp = *my_before; error = lease->fl_lmops->fl_change(my_before, arg); goto out; } @@ -2212,7 +2215,12 @@ lock_kernel(); j = 0; - rcu_read_lock(); + + /* + * We are not taking a ref to the file structures, so + * we need to acquire ->file_lock. + */ + spin_lock(&files->file_lock); fdt = files_fdtable(files); for (;;) { unsigned long set; @@ -2230,7 +2238,7 @@ set >>= 1; } } - rcu_read_unlock(); + spin_unlock(&files->file_lock); unlock_kernel(); } EXPORT_SYMBOL(steal_locks); diff -Naur linux-2.6.16/fs/nfsd/nfs3proc.c linux-2.6.16.16/fs/nfsd/nfs3proc.c --- linux-2.6.16/fs/nfsd/nfs3proc.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/fs/nfsd/nfs3proc.c 2006-05-11 04:56:24.000000000 +0300 @@ -682,7 +682,7 @@ PROC(lookup, dirop, dirop, fhandle2, RC_NOCACHE, ST+FH+pAT+pAT), PROC(access, access, access, fhandle, RC_NOCACHE, ST+pAT+1), PROC(readlink, readlink, readlink, fhandle, RC_NOCACHE, ST+pAT+1+NFS3_MAXPATHLEN/4), - PROC(read, read, read, fhandle, RC_NOCACHE, ST+pAT+4+NFSSVC_MAXBLKSIZE), + PROC(read, read, read, fhandle, RC_NOCACHE, ST+pAT+4+NFSSVC_MAXBLKSIZE/4), PROC(write, write, write, fhandle, RC_REPLBUFF, ST+WC+4), PROC(create, create, create, fhandle2, RC_REPLBUFF, ST+(1+FH+pAT)+WC), PROC(mkdir, mkdir, create, fhandle2, RC_REPLBUFF, ST+(1+FH+pAT)+WC), diff -Naur linux-2.6.16/fs/nfsd/nfs4proc.c linux-2.6.16.16/fs/nfsd/nfs4proc.c --- linux-2.6.16/fs/nfsd/nfs4proc.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/fs/nfsd/nfs4proc.c 2006-05-11 04:56:24.000000000 +0300 @@ -975,7 +975,7 @@ */ static struct svc_procedure nfsd_procedures4[2] = { PROC(null, void, void, void, RC_NOCACHE, 1), - PROC(compound, compound, compound, compound, RC_NOCACHE, NFSD_BUFSIZE) + PROC(compound, compound, compound, compound, RC_NOCACHE, NFSD_BUFSIZE/4) }; struct svc_version nfsd_version4 = { diff -Naur linux-2.6.16/fs/nfsd/nfsproc.c linux-2.6.16.16/fs/nfsd/nfsproc.c --- linux-2.6.16/fs/nfsd/nfsproc.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/fs/nfsd/nfsproc.c 2006-05-11 04:56:24.000000000 +0300 @@ -553,7 +553,7 @@ PROC(none, void, void, none, RC_NOCACHE, ST), PROC(lookup, diropargs, diropres, fhandle, RC_NOCACHE, ST+FH+AT), PROC(readlink, readlinkargs, readlinkres, none, RC_NOCACHE, ST+1+NFS_MAXPATHLEN/4), - PROC(read, readargs, readres, fhandle, RC_NOCACHE, ST+AT+1+NFSSVC_MAXBLKSIZE), + PROC(read, readargs, readres, fhandle, RC_NOCACHE, ST+AT+1+NFSSVC_MAXBLKSIZE/4), PROC(none, void, void, none, RC_NOCACHE, ST), PROC(write, writeargs, attrstat, fhandle, RC_REPLBUFF, ST+AT), PROC(create, createargs, diropres, fhandle, RC_REPLBUFF, ST+FH+AT), diff -Naur linux-2.6.16/fs/open.c linux-2.6.16.16/fs/open.c --- linux-2.6.16/fs/open.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/fs/open.c 2006-05-11 04:56:24.000000000 +0300 @@ -330,7 +330,10 @@ asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length) { - return do_sys_ftruncate(fd, length, 1); + long ret = do_sys_ftruncate(fd, length, 1); + /* avoid REGPARM breakage on x86: */ + prevent_tail_call(ret); + return ret; } /* LFS versions of truncate are only needed on 32 bit machines */ @@ -342,7 +345,10 @@ asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length) { - return do_sys_ftruncate(fd, length, 0); + long ret = do_sys_ftruncate(fd, length, 0); + /* avoid REGPARM breakage on x86: */ + prevent_tail_call(ret); + return ret; } #endif @@ -1083,20 +1089,30 @@ asmlinkage long sys_open(const char __user *filename, int flags, int mode) { + long ret; + if (force_o_largefile()) flags |= O_LARGEFILE; - return do_sys_open(AT_FDCWD, filename, flags, mode); + ret = do_sys_open(AT_FDCWD, filename, flags, mode); + /* avoid REGPARM breakage on x86: */ + prevent_tail_call(ret); + return ret; } EXPORT_SYMBOL_GPL(sys_open); asmlinkage long sys_openat(int dfd, const char __user *filename, int flags, int mode) { + long ret; + if (force_o_largefile()) flags |= O_LARGEFILE; - return do_sys_open(dfd, filename, flags, mode); + ret = do_sys_open(dfd, filename, flags, mode); + /* avoid REGPARM breakage on x86: */ + prevent_tail_call(ret); + return ret; } EXPORT_SYMBOL_GPL(sys_openat); diff -Naur linux-2.6.16/fs/partitions/check.c linux-2.6.16.16/fs/partitions/check.c --- linux-2.6.16/fs/partitions/check.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/fs/partitions/check.c 2006-05-11 04:56:24.000000000 +0300 @@ -345,6 +345,7 @@ char *name; static char *block_str = "block:"; int size; + char *s; size = strlen(block_str) + strlen(disk->disk_name) + 1; name = kmalloc(size, GFP_KERNEL); @@ -352,6 +353,10 @@ return NULL; strcpy(name, block_str); strcat(name, disk->disk_name); + /* ewww... some of these buggers have / in name... */ + s = strchr(name, '/'); + if (s) + *s = '!'; return name; } diff -Naur linux-2.6.16/fs/proc/base.c linux-2.6.16.16/fs/proc/base.c --- linux-2.6.16/fs/proc/base.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/fs/proc/base.c 2006-05-11 04:56:24.000000000 +0300 @@ -294,16 +294,20 @@ files = get_files_struct(task); if (files) { - rcu_read_lock(); + /* + * We are not taking a ref to the file structure, so we must + * hold ->file_lock. + */ + spin_lock(&files->file_lock); file = fcheck_files(files, fd); if (file) { *mnt = mntget(file->f_vfsmnt); *dentry = dget(file->f_dentry); - rcu_read_unlock(); + spin_unlock(&files->file_lock); put_files_struct(files); return 0; } - rcu_read_unlock(); + spin_unlock(&files->file_lock); put_files_struct(files); } return -ENOENT; @@ -1485,7 +1489,12 @@ if (!files) goto out_unlock; inode->i_mode = S_IFLNK; - rcu_read_lock(); + + /* + * We are not taking a ref to the file structure, so we must + * hold ->file_lock. + */ + spin_lock(&files->file_lock); file = fcheck_files(files, fd); if (!file) goto out_unlock2; @@ -1493,7 +1502,7 @@ inode->i_mode |= S_IRUSR | S_IXUSR; if (file->f_mode & 2) inode->i_mode |= S_IWUSR | S_IXUSR; - rcu_read_unlock(); + spin_unlock(&files->file_lock); put_files_struct(files); inode->i_op = &proc_pid_link_inode_operations; inode->i_size = 64; @@ -1503,7 +1512,7 @@ return NULL; out_unlock2: - rcu_read_unlock(); + spin_unlock(&files->file_lock); put_files_struct(files); out_unlock: iput(inode); diff -Naur linux-2.6.16/fs/proc/proc_misc.c linux-2.6.16.16/fs/proc/proc_misc.c --- linux-2.6.16/fs/proc/proc_misc.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/fs/proc/proc_misc.c 2006-05-11 04:56:24.000000000 +0300 @@ -249,144 +249,60 @@ return seq_open(file, &cpuinfo_op); } -enum devinfo_states { - CHR_HDR, - CHR_LIST, - BLK_HDR, - BLK_LIST, - DEVINFO_DONE -}; - -struct devinfo_state { - void *chrdev; - void *blkdev; - unsigned int num_records; - unsigned int cur_record; - enum devinfo_states state; +static struct file_operations proc_cpuinfo_operations = { + .open = cpuinfo_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, }; -static void *devinfo_start(struct seq_file *f, loff_t *pos) +static int devinfo_show(struct seq_file *f, void *v) { - struct devinfo_state *info = f->private; + int i = *(loff_t *) v; - if (*pos) { - if ((info) && (*pos <= info->num_records)) - return info; - return NULL; + if (i < CHRDEV_MAJOR_HASH_SIZE) { + if (i == 0) + seq_printf(f, "Character devices:\n"); + chrdev_show(f, i); + } else { + i -= CHRDEV_MAJOR_HASH_SIZE; + if (i == 0) + seq_printf(f, "\nBlock devices:\n"); + blkdev_show(f, i); } - info = kmalloc(sizeof(*info), GFP_KERNEL); - f->private = info; - info->chrdev = acquire_chrdev_list(); - info->blkdev = acquire_blkdev_list(); - info->state = CHR_HDR; - info->num_records = count_chrdev_list(); - info->num_records += count_blkdev_list(); - info->num_records += 2; /* Character and Block headers */ - *pos = 1; - info->cur_record = *pos; - return info; + return 0; } -static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos) +static void *devinfo_start(struct seq_file *f, loff_t *pos) { - int idummy; - char *ndummy; - struct devinfo_state *info = f->private; - - switch (info->state) { - case CHR_HDR: - info->state = CHR_LIST; - (*pos)++; - /*fallthrough*/ - case CHR_LIST: - if (get_chrdev_info(info->chrdev,&idummy,&ndummy)) { - /* - * The character dev list is complete - */ - info->state = BLK_HDR; - } else { - info->chrdev = get_next_chrdev(info->chrdev); - } - (*pos)++; - break; - case BLK_HDR: - info->state = BLK_LIST; - (*pos)++; - break; - case BLK_LIST: - if (get_blkdev_info(info->blkdev,&idummy,&ndummy)) { - /* - * The block dev list is complete - */ - info->state = DEVINFO_DONE; - } else { - info->blkdev = get_next_blkdev(info->blkdev); - } - (*pos)++; - break; - case DEVINFO_DONE: - (*pos)++; - info->cur_record = *pos; - info = NULL; - break; - default: - break; - } - if (info) - info->cur_record = *pos; - return info; + if (*pos < (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE)) + return pos; + return NULL; } -static void devinfo_stop(struct seq_file *f, void *v) +static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos) { - struct devinfo_state *info = f->private; - - if (info) { - release_chrdev_list(info->chrdev); - release_blkdev_list(info->blkdev); - f->private = NULL; - kfree(info); - } + (*pos)++; + if (*pos >= (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE)) + return NULL; + return pos; } -static int devinfo_show(struct seq_file *f, void *arg) +static void devinfo_stop(struct seq_file *f, void *v) { - int major; - char *name; - struct devinfo_state *info = f->private; - - switch(info->state) { - case CHR_HDR: - seq_printf(f,"Character devices:\n"); - /* fallthrough */ - case CHR_LIST: - if (!get_chrdev_info(info->chrdev,&major,&name)) - seq_printf(f,"%3d %s\n",major,name); - break; - case BLK_HDR: - seq_printf(f,"\nBlock devices:\n"); - /* fallthrough */ - case BLK_LIST: - if (!get_blkdev_info(info->blkdev,&major,&name)) - seq_printf(f,"%3d %s\n",major,name); - break; - default: - break; - } - - return 0; + /* Nothing to do */ } -static struct seq_operations devinfo_op = { - .start = devinfo_start, - .next = devinfo_next, - .stop = devinfo_stop, - .show = devinfo_show, +static struct seq_operations devinfo_ops = { + .start = devinfo_start, + .next = devinfo_next, + .stop = devinfo_stop, + .show = devinfo_show }; -static int devinfo_open(struct inode *inode, struct file *file) +static int devinfo_open(struct inode *inode, struct file *filp) { - return seq_open(file, &devinfo_op); + return seq_open(filp, &devinfo_ops); } static struct file_operations proc_devinfo_operations = { @@ -396,13 +312,6 @@ .release = seq_release, }; -static struct file_operations proc_cpuinfo_operations = { - .open = cpuinfo_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - extern struct seq_operations vmstat_op; static int vmstat_open(struct inode *inode, struct file *file) { diff -Naur linux-2.6.16/fs/proc/vmcore.c linux-2.6.16.16/fs/proc/vmcore.c --- linux-2.6.16/fs/proc/vmcore.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/fs/proc/vmcore.c 2006-05-11 04:56:24.000000000 +0300 @@ -103,8 +103,8 @@ size_t buflen, loff_t *fpos) { ssize_t acc = 0, tmp; - size_t tsz, nr_bytes; - u64 start; + size_t tsz; + u64 start, nr_bytes; struct vmcore *curr_m = NULL; if (buflen == 0 || *fpos >= vmcore_size) diff -Naur linux-2.6.16/fs/reiserfs/xattr_acl.c linux-2.6.16.16/fs/reiserfs/xattr_acl.c --- linux-2.6.16/fs/reiserfs/xattr_acl.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/fs/reiserfs/xattr_acl.c 2006-05-11 04:56:24.000000000 +0300 @@ -408,8 +408,9 @@ acl = reiserfs_get_acl(inode, ACL_TYPE_DEFAULT); reiserfs_read_unlock_xattrs(inode->i_sb); reiserfs_read_unlock_xattr_i(inode); - ret = acl ? 1 : 0; - posix_acl_release(acl); + ret = (acl && !IS_ERR(acl)); + if (ret) + posix_acl_release(acl); } return ret; diff -Naur linux-2.6.16/fs/smbfs/dir.c linux-2.6.16.16/fs/smbfs/dir.c --- linux-2.6.16/fs/smbfs/dir.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/fs/smbfs/dir.c 2006-05-11 04:56:24.000000000 +0300 @@ -434,6 +434,11 @@ if (dentry->d_name.len > SMB_MAXNAMELEN) goto out; + /* Do not allow lookup of names with backslashes in */ + error = -EINVAL; + if (memchr(dentry->d_name.name, '\\', dentry->d_name.len)) + goto out; + lock_kernel(); error = smb_proc_getattr(dentry, &finfo); #ifdef SMBFS_PARANOIA diff -Naur linux-2.6.16/fs/sysfs/dir.c linux-2.6.16.16/fs/sysfs/dir.c --- linux-2.6.16/fs/sysfs/dir.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/fs/sysfs/dir.c 2006-05-11 04:56:24.000000000 +0300 @@ -302,6 +302,7 @@ * Drop reference from dget() on entrance. */ dput(dentry); + kobj->dentry = NULL; } int sysfs_rename_dir(struct kobject * kobj, const char *new_name) diff -Naur linux-2.6.16/fs/sysfs/file.c linux-2.6.16.16/fs/sysfs/file.c --- linux-2.6.16/fs/sysfs/file.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/fs/sysfs/file.c 2006-05-11 04:56:24.000000000 +0300 @@ -183,7 +183,7 @@ return -ENOMEM; if (count >= PAGE_SIZE) - count = PAGE_SIZE; + count = PAGE_SIZE - 1; error = copy_from_user(buffer->page,buf,count); buffer->needs_read_fill = 1; return error ? -EFAULT : count; diff -Naur linux-2.6.16/fs/sysfs/inode.c linux-2.6.16.16/fs/sysfs/inode.c --- linux-2.6.16/fs/sysfs/inode.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/fs/sysfs/inode.c 2006-05-11 04:56:24.000000000 +0300 @@ -227,12 +227,16 @@ void sysfs_hash_and_remove(struct dentry * dir, const char * name) { struct sysfs_dirent * sd; - struct sysfs_dirent * parent_sd = dir->d_fsdata; + struct sysfs_dirent * parent_sd; + + if (!dir) + return; if (dir->d_inode == NULL) /* no inode means this hasn't been made visible yet */ return; + parent_sd = dir->d_fsdata; mutex_lock(&dir->d_inode->i_mutex); list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { if (!sd->s_element) diff -Naur linux-2.6.16/fs/sysfs/symlink.c linux-2.6.16.16/fs/sysfs/symlink.c --- linux-2.6.16/fs/sysfs/symlink.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/fs/sysfs/symlink.c 2006-05-11 04:56:24.000000000 +0300 @@ -66,6 +66,7 @@ if (!error) return 0; + kobject_put(target); kfree(sl->link_name); exit2: kfree(sl); diff -Naur linux-2.6.16/fs/xfs/linux-2.6/xfs_aops.c linux-2.6.16.16/fs/xfs/linux-2.6/xfs_aops.c --- linux-2.6.16/fs/xfs/linux-2.6/xfs_aops.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/fs/xfs/linux-2.6/xfs_aops.c 2006-05-11 04:56:24.000000000 +0300 @@ -616,7 +616,7 @@ acceptable = (type == IOMAP_UNWRITTEN); else if (buffer_delay(bh)) acceptable = (type == IOMAP_DELAY); - else if (buffer_mapped(bh)) + else if (buffer_dirty(bh) && buffer_mapped(bh)) acceptable = (type == 0); else break; diff -Naur linux-2.6.16/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.16.16/fs/xfs/linux-2.6/xfs_iops.c --- linux-2.6.16/fs/xfs/linux-2.6/xfs_iops.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/fs/xfs/linux-2.6/xfs_iops.c 2006-05-11 04:56:24.000000000 +0300 @@ -673,8 +673,7 @@ if (ia_valid & ATTR_ATIME) { vattr.va_mask |= XFS_AT_ATIME; vattr.va_atime = attr->ia_atime; - if (ia_valid & ATTR_ATIME_SET) - inode->i_atime = attr->ia_atime; + inode->i_atime = attr->ia_atime; } if (ia_valid & ATTR_MTIME) { vattr.va_mask |= XFS_AT_MTIME; diff -Naur linux-2.6.16/include/asm-i386/cpufeature.h linux-2.6.16.16/include/asm-i386/cpufeature.h --- linux-2.6.16/include/asm-i386/cpufeature.h 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/include/asm-i386/cpufeature.h 2006-05-11 04:56:24.000000000 +0300 @@ -70,6 +70,7 @@ #define X86_FEATURE_P3 (3*32+ 6) /* P3 */ #define X86_FEATURE_P4 (3*32+ 7) /* P4 */ #define X86_FEATURE_CONSTANT_TSC (3*32+ 8) /* TSC ticks at a constant rate */ +#define X86_FEATURE_FXSAVE_LEAK (3*32+10) /* FXSAVE leaks FOP/FIP/FOP */ /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ diff -Naur linux-2.6.16/include/asm-i386/i387.h linux-2.6.16.16/include/asm-i386/i387.h --- linux-2.6.16/include/asm-i386/i387.h 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/include/asm-i386/i387.h 2006-05-11 04:56:24.000000000 +0300 @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -38,17 +39,38 @@ extern void kernel_fpu_begin(void); #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0) +/* We need a safe address that is cheap to find and that is already + in L1 during context switch. The best choices are unfortunately + different for UP and SMP */ +#ifdef CONFIG_SMP +#define safe_address (__per_cpu_offset[0]) +#else +#define safe_address (kstat_cpu(0).cpustat.user) +#endif + /* * These must be called with preempt disabled */ static inline void __save_init_fpu( struct task_struct *tsk ) { + /* Use more nops than strictly needed in case the compiler + varies code */ alternative_input( - "fnsave %1 ; fwait ;" GENERIC_NOP2, - "fxsave %1 ; fnclex", + "fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4, + "fxsave %[fx]\n" + "bt $7,%[fsw] ; jnc 1f ; fnclex\n1:", X86_FEATURE_FXSR, - "m" (tsk->thread.i387.fxsave) - :"memory"); + [fx] "m" (tsk->thread.i387.fxsave), + [fsw] "m" (tsk->thread.i387.fxsave.swd) : "memory"); + /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception + is pending. Clear the x87 state here by setting it to fixed + values. safe_address is a random variable that should be in L1 */ + alternative_input( + GENERIC_NOP8 GENERIC_NOP2, + "emms\n\t" /* clear stack tags */ + "fildl %[addr]", /* set F?P to defined value */ + X86_FEATURE_FXSAVE_LEAK, + [addr] "m" (safe_address)); task_thread_info(tsk)->status &= ~TS_USEDFPU; } diff -Naur linux-2.6.16/include/asm-i386/pgtable-2level.h linux-2.6.16.16/include/asm-i386/pgtable-2level.h --- linux-2.6.16/include/asm-i386/pgtable-2level.h 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/include/asm-i386/pgtable-2level.h 2006-05-11 04:56:24.000000000 +0300 @@ -18,6 +18,9 @@ #define set_pte_atomic(pteptr, pteval) set_pte(pteptr,pteval) #define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval)) +#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0) +#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) + #define ptep_get_and_clear(mm,addr,xp) __pte(xchg(&(xp)->pte_low, 0)) #define pte_same(a, b) ((a).pte_low == (b).pte_low) #define pte_page(x) pfn_to_page(pte_pfn(x)) diff -Naur linux-2.6.16/include/asm-i386/pgtable-3level.h linux-2.6.16.16/include/asm-i386/pgtable-3level.h --- linux-2.6.16/include/asm-i386/pgtable-3level.h 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/include/asm-i386/pgtable-3level.h 2006-05-11 04:56:24.000000000 +0300 @@ -85,6 +85,26 @@ #define pmd_offset(pud, address) ((pmd_t *) pud_page(*(pud)) + \ pmd_index(address)) +/* + * For PTEs and PDEs, we must clear the P-bit first when clearing a page table + * entry, so clear the bottom half first and enforce ordering with a compiler + * barrier. + */ +static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) +{ + ptep->pte_low = 0; + smp_wmb(); + ptep->pte_high = 0; +} + +static inline void pmd_clear(pmd_t *pmd) +{ + u32 *tmp = (u32 *)pmd; + *tmp = 0; + smp_wmb(); + *(tmp + 1) = 0; +} + static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { pte_t res; diff -Naur linux-2.6.16/include/asm-i386/pgtable.h linux-2.6.16.16/include/asm-i386/pgtable.h --- linux-2.6.16/include/asm-i386/pgtable.h 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/include/asm-i386/pgtable.h 2006-05-11 04:56:24.000000000 +0300 @@ -204,12 +204,10 @@ extern unsigned long pg0[]; #define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE)) -#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0) /* To avoid harmful races, pmd_none(x) should check only the lower when PAE */ #define pmd_none(x) (!(unsigned long)pmd_val(x)) #define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT) -#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) #define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE) @@ -269,7 +267,7 @@ pte_t pte; if (full) { pte = *ptep; - *ptep = __pte(0); + pte_clear(mm, addr, ptep); } else { pte = ptep_get_and_clear(mm, addr, ptep); } diff -Naur linux-2.6.16/include/asm-m32r/smp.h linux-2.6.16.16/include/asm-m32r/smp.h --- linux-2.6.16/include/asm-m32r/smp.h 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/include/asm-m32r/smp.h 2006-05-11 04:56:24.000000000 +0300 @@ -67,7 +67,8 @@ #define raw_smp_processor_id() (current_thread_info()->cpu) extern cpumask_t cpu_callout_map; -#define cpu_possible_map cpu_callout_map +extern cpumask_t cpu_possible_map; +extern cpumask_t cpu_present_map; static __inline__ int hard_smp_processor_id(void) { diff -Naur linux-2.6.16/include/asm-m32r/uaccess.h linux-2.6.16.16/include/asm-m32r/uaccess.h --- linux-2.6.16/include/asm-m32r/uaccess.h 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/include/asm-m32r/uaccess.h 2006-05-11 04:56:24.000000000 +0300 @@ -5,17 +5,9 @@ * linux/include/asm-m32r/uaccess.h * * M32R version. - * Copyright (C) 2004 Hirokazu Takata + * Copyright (C) 2004, 2006 Hirokazu Takata */ -#undef UACCESS_DEBUG - -#ifdef UACCESS_DEBUG -#define UAPRINTK(args...) printk(args) -#else -#define UAPRINTK(args...) -#endif /* UACCESS_DEBUG */ - /* * User space memory access functions */ @@ -38,27 +30,29 @@ #define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) #ifdef CONFIG_MMU + #define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF) #define USER_DS MAKE_MM_SEG(PAGE_OFFSET) -#else -#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF) -#define USER_DS MAKE_MM_SEG(0xFFFFFFFF) -#endif /* CONFIG_MMU */ - #define get_ds() (KERNEL_DS) -#ifdef CONFIG_MMU #define get_fs() (current_thread_info()->addr_limit) #define set_fs(x) (current_thread_info()->addr_limit = (x)) -#else + +#else /* not CONFIG_MMU */ + +#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF) +#define USER_DS MAKE_MM_SEG(0xFFFFFFFF) +#define get_ds() (KERNEL_DS) + static inline mm_segment_t get_fs(void) { - return USER_DS; + return USER_DS; } static inline void set_fs(mm_segment_t s) { } -#endif /* CONFIG_MMU */ + +#endif /* not CONFIG_MMU */ #define segment_eq(a,b) ((a).seg == (b).seg) @@ -83,9 +77,9 @@ " subx %0, %0\n" \ " cmpu %4, %1\n" \ " subx %0, %5\n" \ - : "=&r"(flag), "=r"(sum) \ - : "1"(addr), "r"((int)(size)), \ - "r"(current_thread_info()->addr_limit.seg), "r"(0) \ + : "=&r" (flag), "=r" (sum) \ + : "1" (addr), "r" ((int)(size)), \ + "r" (current_thread_info()->addr_limit.seg), "r" (0) \ : "cbit" ); \ flag; }) @@ -113,10 +107,10 @@ #else static inline int access_ok(int type, const void *addr, unsigned long size) { - extern unsigned long memory_start, memory_end; - unsigned long val = (unsigned long)addr; + extern unsigned long memory_start, memory_end; + unsigned long val = (unsigned long)addr; - return ((val >= memory_start) && ((val + size) < memory_end)); + return ((val >= memory_start) && ((val + size) < memory_end)); } #endif /* CONFIG_MMU */ @@ -155,39 +149,6 @@ * accesses to the same area of user memory). */ -extern void __get_user_1(void); -extern void __get_user_2(void); -extern void __get_user_4(void); - -#ifndef MODULE -#define __get_user_x(size,ret,x,ptr) \ - __asm__ __volatile__( \ - " mv r0, %0\n" \ - " mv r1, %1\n" \ - " bl __get_user_" #size "\n" \ - " mv %0, r0\n" \ - " mv %1, r1\n" \ - : "=r"(ret), "=r"(x) \ - : "0"(ptr) \ - : "r0", "r1", "r14" ) -#else /* MODULE */ -/* - * Use "jl" instead of "bl" for MODULE - */ -#define __get_user_x(size,ret,x,ptr) \ - __asm__ __volatile__( \ - " mv r0, %0\n" \ - " mv r1, %1\n" \ - " seth lr, #high(__get_user_" #size ")\n" \ - " or3 lr, lr, #low(__get_user_" #size ")\n" \ - " jl lr\n" \ - " mv %0, r0\n" \ - " mv %1, r1\n" \ - : "=r"(ret), "=r"(x) \ - : "0"(ptr) \ - : "r0", "r1", "r14" ) -#endif - /* Careful: we have to cast the result to the type of the pointer for sign reasons */ /** @@ -208,20 +169,7 @@ * On error, the variable @x is set to zero. */ #define get_user(x,ptr) \ -({ int __ret_gu; \ - unsigned long __val_gu; \ - __chk_user_ptr(ptr); \ - switch(sizeof (*(ptr))) { \ - case 1: __get_user_x(1,__ret_gu,__val_gu,ptr); break; \ - case 2: __get_user_x(2,__ret_gu,__val_gu,ptr); break; \ - case 4: __get_user_x(4,__ret_gu,__val_gu,ptr); break; \ - default: __get_user_x(X,__ret_gu,__val_gu,ptr); break; \ - } \ - (x) = (__typeof__(*(ptr)))__val_gu; \ - __ret_gu; \ -}) - -extern void __put_user_bad(void); + __get_user_check((x),(ptr),sizeof(*(ptr))) /** * put_user: - Write a simple value into user space. @@ -240,8 +188,7 @@ * Returns zero on success, or -EFAULT on error. */ #define put_user(x,ptr) \ - __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) - + __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) /** * __get_user: - Get a simple variable from user space, with less checking. @@ -264,8 +211,64 @@ * On error, the variable @x is set to zero. */ #define __get_user(x,ptr) \ - __get_user_nocheck((x),(ptr),sizeof(*(ptr))) + __get_user_nocheck((x),(ptr),sizeof(*(ptr))) +#define __get_user_nocheck(x,ptr,size) \ +({ \ + long __gu_err = 0; \ + unsigned long __gu_val; \ + might_sleep(); \ + __get_user_size(__gu_val,(ptr),(size),__gu_err); \ + (x) = (__typeof__(*(ptr)))__gu_val; \ + __gu_err; \ +}) + +#define __get_user_check(x,ptr,size) \ +({ \ + long __gu_err = -EFAULT; \ + unsigned long __gu_val = 0; \ + const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \ + might_sleep(); \ + if (access_ok(VERIFY_READ,__gu_addr,size)) \ + __get_user_size(__gu_val,__gu_addr,(size),__gu_err); \ + (x) = (__typeof__(*(ptr)))__gu_val; \ + __gu_err; \ +}) + +extern long __get_user_bad(void); + +#define __get_user_size(x,ptr,size,retval) \ +do { \ + retval = 0; \ + __chk_user_ptr(ptr); \ + switch (size) { \ + case 1: __get_user_asm(x,ptr,retval,"ub"); break; \ + case 2: __get_user_asm(x,ptr,retval,"uh"); break; \ + case 4: __get_user_asm(x,ptr,retval,""); break; \ + default: (x) = __get_user_bad(); \ + } \ +} while (0) + +#define __get_user_asm(x, addr, err, itype) \ + __asm__ __volatile__( \ + " .fillinsn\n" \ + "1: ld"itype" %1,@%2\n" \ + " .fillinsn\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + " .balign 4\n" \ + "3: ldi %0,%3\n" \ + " seth r14,#high(2b)\n" \ + " or3 r14,r14,#low(2b)\n" \ + " jmp r14\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .balign 4\n" \ + " .long 1b,3b\n" \ + ".previous" \ + : "=&r" (err), "=&r" (x) \ + : "r" (addr), "i" (-EFAULT), "0" (err) \ + : "r14", "memory") /** * __put_user: - Write a simple value into user space, with less checking. @@ -287,11 +290,13 @@ * Returns zero on success, or -EFAULT on error. */ #define __put_user(x,ptr) \ - __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) + __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) + #define __put_user_nocheck(x,ptr,size) \ ({ \ long __pu_err; \ + might_sleep(); \ __put_user_size((x),(ptr),(size),__pu_err); \ __pu_err; \ }) @@ -308,28 +313,28 @@ }) #if defined(__LITTLE_ENDIAN__) -#define __put_user_u64(x, addr, err) \ - __asm__ __volatile__( \ - " .fillinsn\n" \ - "1: st %L1,@%2\n" \ - " .fillinsn\n" \ - "2: st %H1,@(4,%2)\n" \ - " .fillinsn\n" \ - "3:\n" \ - ".section .fixup,\"ax\"\n" \ - " .balign 4\n" \ - "4: ldi %0,%3\n" \ - " seth r14,#high(3b)\n" \ - " or3 r14,r14,#low(3b)\n" \ - " jmp r14\n" \ - ".previous\n" \ - ".section __ex_table,\"a\"\n" \ - " .balign 4\n" \ - " .long 1b,4b\n" \ - " .long 2b,4b\n" \ - ".previous" \ - : "=&r"(err) \ - : "r"(x), "r"(addr), "i"(-EFAULT), "0"(err) \ +#define __put_user_u64(x, addr, err) \ + __asm__ __volatile__( \ + " .fillinsn\n" \ + "1: st %L1,@%2\n" \ + " .fillinsn\n" \ + "2: st %H1,@(4,%2)\n" \ + " .fillinsn\n" \ + "3:\n" \ + ".section .fixup,\"ax\"\n" \ + " .balign 4\n" \ + "4: ldi %0,%3\n" \ + " seth r14,#high(3b)\n" \ + " or3 r14,r14,#low(3b)\n" \ + " jmp r14\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .balign 4\n" \ + " .long 1b,4b\n" \ + " .long 2b,4b\n" \ + ".previous" \ + : "=&r" (err) \ + : "r" (x), "r" (addr), "i" (-EFAULT), "0" (err) \ : "r14", "memory") #elif defined(__BIG_ENDIAN__) @@ -353,13 +358,15 @@ " .long 1b,4b\n" \ " .long 2b,4b\n" \ ".previous" \ - : "=&r"(err) \ - : "r"(x), "r"(addr), "i"(-EFAULT), "0"(err) \ + : "=&r" (err) \ + : "r" (x), "r" (addr), "i" (-EFAULT), "0" (err) \ : "r14", "memory") #else #error no endian defined #endif +extern void __put_user_bad(void); + #define __put_user_size(x,ptr,size,retval) \ do { \ retval = 0; \ @@ -398,52 +405,8 @@ " .balign 4\n" \ " .long 1b,3b\n" \ ".previous" \ - : "=&r"(err) \ - : "r"(x), "r"(addr), "i"(-EFAULT), "0"(err) \ - : "r14", "memory") - -#define __get_user_nocheck(x,ptr,size) \ -({ \ - long __gu_err; \ - unsigned long __gu_val; \ - __get_user_size(__gu_val,(ptr),(size),__gu_err); \ - (x) = (__typeof__(*(ptr)))__gu_val; \ - __gu_err; \ -}) - -extern long __get_user_bad(void); - -#define __get_user_size(x,ptr,size,retval) \ -do { \ - retval = 0; \ - __chk_user_ptr(ptr); \ - switch (size) { \ - case 1: __get_user_asm(x,ptr,retval,"ub"); break; \ - case 2: __get_user_asm(x,ptr,retval,"uh"); break; \ - case 4: __get_user_asm(x,ptr,retval,""); break; \ - default: (x) = __get_user_bad(); \ - } \ -} while (0) - -#define __get_user_asm(x, addr, err, itype) \ - __asm__ __volatile__( \ - " .fillinsn\n" \ - "1: ld"itype" %1,@%2\n" \ - " .fillinsn\n" \ - "2:\n" \ - ".section .fixup,\"ax\"\n" \ - " .balign 4\n" \ - "3: ldi %0,%3\n" \ - " seth r14,#high(2b)\n" \ - " or3 r14,r14,#low(2b)\n" \ - " jmp r14\n" \ - ".previous\n" \ - ".section __ex_table,\"a\"\n" \ - " .balign 4\n" \ - " .long 1b,3b\n" \ - ".previous" \ - : "=&r"(err), "=&r"(x) \ - : "r"(addr), "i"(-EFAULT), "0"(err) \ + : "=&r" (err) \ + : "r" (x), "r" (addr), "i" (-EFAULT), "0" (err) \ : "r14", "memory") /* @@ -453,7 +416,6 @@ * anything, so this is accurate. */ - /* * Copy To/From Userspace */ @@ -511,8 +473,9 @@ " .long 2b,9b\n" \ " .long 3b,9b\n" \ ".previous\n" \ - : "=&r"(__dst), "=&r"(__src), "=&r"(size), "=&r"(__c) \ - : "0"(to), "1"(from), "2"(size), "3"(size / 4) \ + : "=&r" (__dst), "=&r" (__src), "=&r" (size), \ + "=&r" (__c) \ + : "0" (to), "1" (from), "2" (size), "3" (size / 4) \ : "r14", "memory"); \ } while (0) @@ -573,8 +536,9 @@ " .long 2b,7b\n" \ " .long 3b,7b\n" \ ".previous\n" \ - : "=&r"(__dst), "=&r"(__src), "=&r"(size), "=&r"(__c) \ - : "0"(to), "1"(from), "2"(size), "3"(size / 4) \ + : "=&r" (__dst), "=&r" (__src), "=&r" (size), \ + "=&r" (__c) \ + : "0" (to), "1" (from), "2" (size), "3" (size / 4) \ : "r14", "memory"); \ } while (0) @@ -676,7 +640,7 @@ #define copy_from_user(to,from,n) \ ({ \ might_sleep(); \ -__generic_copy_from_user((to),(from),(n)); \ + __generic_copy_from_user((to),(from),(n)); \ }) long __must_check strncpy_from_user(char *dst, const char __user *src, diff -Naur linux-2.6.16/include/asm-mips/bitops.h linux-2.6.16.16/include/asm-mips/bitops.h --- linux-2.6.16/include/asm-mips/bitops.h 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/include/asm-mips/bitops.h 2006-05-11 04:56:24.000000000 +0300 @@ -654,7 +654,12 @@ { #ifdef CONFIG_32BIT #ifdef CONFIG_CPU_MIPS32 - __asm__ ("clz %0, %1" : "=r" (word) : "r" (word)); + __asm__ ( + " .set mips32 \n" + " clz %0, %1 \n" + " .set mips0 \n" + : "=r" (word) + : "r" (word)); return 32 - word; #else @@ -678,7 +683,12 @@ #ifdef CONFIG_64BIT #ifdef CONFIG_CPU_MIPS64 - __asm__ ("dclz %0, %1" : "=r" (word) : "r" (word)); + __asm__ ( + " .set mips64 \n" + " dclz %0, %1 \n" + " .set mips0 \n" + : "=r" (word) + : "r" (word)); return 64 - word; #else diff -Naur linux-2.6.16/include/asm-mips/byteorder.h linux-2.6.16.16/include/asm-mips/byteorder.h --- linux-2.6.16/include/asm-mips/byteorder.h 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/include/asm-mips/byteorder.h 2006-05-11 04:56:24.000000000 +0300 @@ -19,7 +19,9 @@ static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x) { __asm__( + " .set mips32r2 \n" " wsbh %0, %1 \n" + " .set mips0 \n" : "=r" (x) : "r" (x)); @@ -30,8 +32,10 @@ static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x) { __asm__( + " .set mips32r2 \n" " wsbh %0, %1 \n" " rotr %0, %0, 16 \n" + " .set mips0 \n" : "=r" (x) : "r" (x)); diff -Naur linux-2.6.16/include/asm-mips/interrupt.h linux-2.6.16.16/include/asm-mips/interrupt.h --- linux-2.6.16/include/asm-mips/interrupt.h 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/include/asm-mips/interrupt.h 2006-05-11 04:56:24.000000000 +0300 @@ -20,7 +20,9 @@ " .set reorder \n" " .set noat \n" #ifdef CONFIG_CPU_MIPSR2 + " .set mips32r2 \n" " ei \n" + " .set mips0 \n" #else " mfc0 $1,$12 \n" " ori $1,0x1f \n" @@ -63,7 +65,9 @@ " .set push \n" " .set noat \n" #ifdef CONFIG_CPU_MIPSR2 + " .set mips32r2 \n" " di \n" + " .set mips0 \n" #else " mfc0 $1,$12 \n" " ori $1,0x1f \n" @@ -103,8 +107,10 @@ " .set reorder \n" " .set noat \n" #ifdef CONFIG_CPU_MIPSR2 + " .set mips32r2 \n" " di \\result \n" " andi \\result, 1 \n" + " .set mips0 \n" #else " mfc0 \\result, $12 \n" " ori $1, \\result, 0x1f \n" @@ -133,9 +139,11 @@ * Slow, but doesn't suffer from a relativly unlikely race * condition we're having since days 1. */ + " .set mips32r2 \n" " beqz \\flags, 1f \n" " di \n" " ei \n" + " .set mips0 \n" "1: \n" #elif defined(CONFIG_CPU_MIPSR2) /* diff -Naur linux-2.6.16/include/asm-mips/r4kcache.h linux-2.6.16.16/include/asm-mips/r4kcache.h --- linux-2.6.16/include/asm-mips/r4kcache.h 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/include/asm-mips/r4kcache.h 2006-05-11 04:56:24.000000000 +0300 @@ -37,7 +37,7 @@ " cache %0, %1 \n" \ " .set pop \n" \ : \ - : "i" (op), "m" (*(unsigned char *)(addr))) + : "i" (op), "R" (*(unsigned char *)(addr))) static inline void flush_icache_line_indexed(unsigned long addr) { diff -Naur linux-2.6.16/include/asm-powerpc/floppy.h linux-2.6.16.16/include/asm-powerpc/floppy.h --- linux-2.6.16/include/asm-powerpc/floppy.h 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/include/asm-powerpc/floppy.h 2006-05-11 04:56:24.000000000 +0300 @@ -35,6 +35,7 @@ #ifdef CONFIG_PCI #include +#include /* for ppc64_isabridge_dev */ #define fd_dma_setup(addr,size,mode,io) powerpc_fd_dma_setup(addr,size,mode,io) @@ -52,12 +53,12 @@ if (bus_addr && (addr != prev_addr || size != prev_size || dir != prev_dir)) { /* different from last time -- unmap prev */ - pci_unmap_single(NULL, bus_addr, prev_size, prev_dir); + pci_unmap_single(ppc64_isabridge_dev, bus_addr, prev_size, prev_dir); bus_addr = 0; } if (!bus_addr) /* need to map it */ - bus_addr = pci_map_single(NULL, addr, size, dir); + bus_addr = pci_map_single(ppc64_isabridge_dev, addr, size, dir); /* remember this one as prev */ prev_addr = addr; diff -Naur linux-2.6.16/include/asm-x86_64/cpufeature.h linux-2.6.16.16/include/asm-x86_64/cpufeature.h --- linux-2.6.16/include/asm-x86_64/cpufeature.h 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/include/asm-x86_64/cpufeature.h 2006-05-11 04:56:24.000000000 +0300 @@ -64,6 +64,7 @@ #define X86_FEATURE_REP_GOOD (3*32+ 4) /* rep microcode works well on this CPU */ #define X86_FEATURE_CONSTANT_TSC (3*32+5) /* TSC runs at constant rate */ #define X86_FEATURE_SYNC_RDTSC (3*32+6) /* RDTSC syncs CPU core */ +#define X86_FEATURE_FXSAVE_LEAK (3*32+7) /* FIP/FOP/FDP leaks through FXSAVE */ /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ diff -Naur linux-2.6.16/include/asm-x86_64/i387.h linux-2.6.16.16/include/asm-x86_64/i387.h --- linux-2.6.16/include/asm-x86_64/i387.h 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/include/asm-x86_64/i387.h 2006-05-11 04:56:24.000000000 +0300 @@ -72,6 +72,23 @@ #define set_fpu_swd(t,val) ((t)->thread.i387.fxsave.swd = (val)) #define set_fpu_fxsr_twd(t,val) ((t)->thread.i387.fxsave.twd = (val)) +#define X87_FSW_ES (1 << 7) /* Exception Summary */ + +/* AMD CPUs don't save/restore FDP/FIP/FOP unless an exception + is pending. Clear the x87 state here by setting it to fixed + values. The kernel data segment can be sometimes 0 and sometimes + new user value. Both should be ok. + Use the PDA as safe address because it should be already in L1. */ +static inline void clear_fpu_state(struct i387_fxsave_struct *fx) +{ + if (unlikely(fx->swd & X87_FSW_ES)) + asm volatile("fnclex"); + alternative_input(ASM_NOP8 ASM_NOP2, + " emms\n" /* clear stack tags */ + " fildl %%gs:0", /* load to clear state */ + X86_FEATURE_FXSAVE_LEAK); +} + static inline int restore_fpu_checking(struct i387_fxsave_struct *fx) { int err; @@ -119,6 +136,7 @@ #endif if (unlikely(err)) __clear_user(fx, sizeof(struct i387_fxsave_struct)); + /* No need to clear here because the caller clears USED_MATH */ return err; } @@ -149,7 +167,7 @@ "i" (offsetof(__typeof__(*tsk), thread.i387.fxsave))); #endif - __asm__ __volatile__("fnclex"); + clear_fpu_state(&tsk->thread.i387.fxsave); } static inline void kernel_fpu_begin(void) diff -Naur linux-2.6.16/include/linux/cpu.h linux-2.6.16.16/include/linux/cpu.h --- linux-2.6.16/include/linux/cpu.h 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/include/linux/cpu.h 2006-05-11 04:56:24.000000000 +0300 @@ -32,7 +32,7 @@ }; extern int register_cpu(struct cpu *, int, struct node *); -extern struct sys_device *get_cpu_sysdev(int cpu); +extern struct sys_device *get_cpu_sysdev(unsigned cpu); #ifdef CONFIG_HOTPLUG_CPU extern void unregister_cpu(struct cpu *, struct node *); #endif diff -Naur linux-2.6.16/include/linux/cpumask.h linux-2.6.16.16/include/linux/cpumask.h --- linux-2.6.16/include/linux/cpumask.h 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/include/linux/cpumask.h 2006-05-11 04:56:24.000000000 +0300 @@ -408,6 +408,7 @@ }) #define for_each_cpu(cpu) for_each_cpu_mask((cpu), cpu_possible_map) +#define for_each_possible_cpu(cpu) for_each_cpu_mask((cpu), cpu_possible_map) #define for_each_online_cpu(cpu) for_each_cpu_mask((cpu), cpu_online_map) #define for_each_present_cpu(cpu) for_each_cpu_mask((cpu), cpu_present_map) diff -Naur linux-2.6.16/include/linux/fb.h linux-2.6.16.16/include/linux/fb.h --- linux-2.6.16/include/linux/fb.h 2006-05-18 01:12:24.000000000 +0300 +++ linux-2.6.16.16/include/linux/fb.h 2006-05-17 21:41:31.000000000 +0300 @@ -840,12 +840,10 @@ #define FB_LEFT_POS(bpp) (32 - bpp) #define FB_SHIFT_HIGH(val, bits) ((val) >> (bits)) #define FB_SHIFT_LOW(val, bits) ((val) << (bits)) -#define FB_BIT_NR(b) (7 - (b)) #else #define FB_LEFT_POS(bpp) (0) #define FB_SHIFT_HIGH(val, bits) ((val) << (bits)) #define FB_SHIFT_LOW(val, bits) ((val) >> (bits)) -#define FB_BIT_NR(b) (b) #endif /* diff -Naur linux-2.6.16/include/linux/fs.h linux-2.6.16.16/include/linux/fs.h --- linux-2.6.16/include/linux/fs.h 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/include/linux/fs.h 2006-05-11 04:56:24.000000000 +0300 @@ -1383,6 +1383,7 @@ extern void bd_release(struct block_device *); /* fs/char_dev.c */ +#define CHRDEV_MAJOR_HASH_SIZE 255 extern int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *); extern int register_chrdev_region(dev_t, unsigned, const char *); extern int register_chrdev(unsigned int, const char *, @@ -1390,25 +1391,17 @@ extern int unregister_chrdev(unsigned int, const char *); extern void unregister_chrdev_region(dev_t, unsigned); extern int chrdev_open(struct inode *, struct file *); -extern int get_chrdev_list(char *); -extern void *acquire_chrdev_list(void); -extern int count_chrdev_list(void); -extern void *get_next_chrdev(void *); -extern int get_chrdev_info(void *, int *, char **); -extern void release_chrdev_list(void *); +extern void chrdev_show(struct seq_file *,off_t); /* fs/block_dev.c */ +#define BLKDEV_MAJOR_HASH_SIZE 255 #define BDEVNAME_SIZE 32 /* Largest string for a blockdev identifier */ extern const char *__bdevname(dev_t, char *buffer); extern const char *bdevname(struct block_device *bdev, char *buffer); extern struct block_device *lookup_bdev(const char *); extern struct block_device *open_bdev_excl(const char *, int, void *); extern void close_bdev_excl(struct block_device *); -extern void *acquire_blkdev_list(void); -extern int count_blkdev_list(void); -extern void *get_next_blkdev(void *); -extern int get_blkdev_info(void *, int *, char **); -extern void release_blkdev_list(void *); +extern void blkdev_show(struct seq_file *,off_t); extern void init_special_inode(struct inode *, umode_t, dev_t); diff -Naur linux-2.6.16/include/linux/mm.h linux-2.6.16.16/include/linux/mm.h --- linux-2.6.16/include/linux/mm.h 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/include/linux/mm.h 2006-05-11 04:56:24.000000000 +0300 @@ -229,10 +229,9 @@ unsigned long private; /* Mapping-private opaque data: * usually used for buffer_heads * if PagePrivate set; used for - * swp_entry_t if PageSwapCache. - * When page is free, this + * swp_entry_t if PageSwapCache; * indicates order in the buddy - * system. + * system if PG_buddy is set. */ struct address_space *mapping; /* If low bit clear, points to * inode address_space, or NULL. diff -Naur linux-2.6.16/include/linux/page-flags.h linux-2.6.16.16/include/linux/page-flags.h --- linux-2.6.16/include/linux/page-flags.h 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/include/linux/page-flags.h 2006-05-11 04:56:24.000000000 +0300 @@ -74,7 +74,9 @@ #define PG_mappedtodisk 16 /* Has blocks allocated on-disk */ #define PG_reclaim 17 /* To be reclaimed asap */ #define PG_nosave_free 18 /* Free, should not be written */ -#define PG_uncached 19 /* Page has been mapped as uncached */ +#define PG_buddy 19 /* Page is free, on buddy lists */ + +#define PG_uncached 20 /* Page has been mapped as uncached */ /* * Global page accounting. One instance per CPU. Only unsigned longs are @@ -319,6 +321,10 @@ #define SetPageNosaveFree(page) set_bit(PG_nosave_free, &(page)->flags) #define ClearPageNosaveFree(page) clear_bit(PG_nosave_free, &(page)->flags) +#define PageBuddy(page) test_bit(PG_buddy, &(page)->flags) +#define __SetPageBuddy(page) __set_bit(PG_buddy, &(page)->flags) +#define __ClearPageBuddy(page) __clear_bit(PG_buddy, &(page)->flags) + #define PageMappedToDisk(page) test_bit(PG_mappedtodisk, &(page)->flags) #define SetPageMappedToDisk(page) set_bit(PG_mappedtodisk, &(page)->flags) #define ClearPageMappedToDisk(page) clear_bit(PG_mappedtodisk, &(page)->flags) diff -Naur linux-2.6.16/include/linux/proc_fs.h linux-2.6.16.16/include/linux/proc_fs.h --- linux-2.6.16/include/linux/proc_fs.h 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/include/linux/proc_fs.h 2006-05-11 04:56:24.000000000 +0300 @@ -78,7 +78,7 @@ struct vmcore { struct list_head list; unsigned long long paddr; - unsigned long size; + unsigned long long size; loff_t offset; }; diff -Naur linux-2.6.16/include/linux/raid/raid1.h linux-2.6.16.16/include/linux/raid/raid1.h --- linux-2.6.16/include/linux/raid/raid1.h 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/include/linux/raid/raid1.h 2006-05-11 04:56:24.000000000 +0300 @@ -130,6 +130,6 @@ * with failure when last write completes (and all failed). * Record that bi_end_io was called with this flag... */ -#define R1BIO_Returned 4 +#define R1BIO_Returned 6 #endif diff -Naur linux-2.6.16/include/linux/rtc.h linux-2.6.16.16/include/linux/rtc.h --- linux-2.6.16/include/linux/rtc.h 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/include/linux/rtc.h 2006-05-11 04:56:24.000000000 +0300 @@ -11,8 +11,6 @@ #ifndef _LINUX_RTC_H_ #define _LINUX_RTC_H_ -#include - /* * The struct used to pass data via the following ioctl. Similar to the * struct tm in , but it needs to be here so that the kernel @@ -95,6 +93,8 @@ #ifdef __KERNEL__ +#include + typedef struct rtc_task { void (*func)(void *private_data); void *private_data; diff -Naur linux-2.6.16/include/net/ip.h linux-2.6.16.16/include/net/ip.h --- linux-2.6.16/include/net/ip.h 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/include/net/ip.h 2006-05-11 04:56:24.000000000 +0300 @@ -95,6 +95,7 @@ extern int ip_mr_input(struct sk_buff *skb); extern int ip_output(struct sk_buff *skb); extern int ip_mc_output(struct sk_buff *skb); +extern int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)); extern int ip_do_nat(struct sk_buff *skb); extern void ip_send_check(struct iphdr *ip); extern int ip_queue_xmit(struct sk_buff *skb, int ipfragok); diff -Naur linux-2.6.16/include/net/sctp/structs.h linux-2.6.16.16/include/net/sctp/structs.h --- linux-2.6.16/include/net/sctp/structs.h 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/include/net/sctp/structs.h 2006-05-11 04:56:24.000000000 +0300 @@ -702,6 +702,7 @@ __u8 tsn_gap_acked; /* Is this chunk acked by a GAP ACK? */ __s8 fast_retransmit; /* Is this chunk fast retransmitted? */ __u8 tsn_missing_report; /* Data chunk missing counter. */ + __u8 data_accepted; /* At least 1 chunk in this packet accepted */ }; void sctp_chunk_hold(struct sctp_chunk *); diff -Naur linux-2.6.16/ipc/shm.c linux-2.6.16.16/ipc/shm.c --- linux-2.6.16/ipc/shm.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/ipc/shm.c 2006-05-11 04:56:24.000000000 +0300 @@ -161,6 +161,8 @@ ret = shmem_mmap(file, vma); if (ret == 0) { vma->vm_ops = &shm_vm_ops; + if (!(vma->vm_flags & VM_WRITE)) + vma->vm_flags &= ~VM_MAYWRITE; shm_inc(file->f_dentry->d_inode->i_ino); } diff -Naur linux-2.6.16/ipc/util.c linux-2.6.16.16/ipc/util.c --- linux-2.6.16/ipc/util.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/ipc/util.c 2006-05-11 04:56:24.000000000 +0300 @@ -182,8 +182,7 @@ if(new == NULL) return size; new->size = newsize; - memcpy(new->p, ids->entries->p, sizeof(struct kern_ipc_perm *)*size + - sizeof(struct ipc_id_ary)); + memcpy(new->p, ids->entries->p, sizeof(struct kern_ipc_perm *)*size); for(i=size;ip[i] = NULL; } diff -Naur linux-2.6.16/kernel/auditsc.c linux-2.6.16.16/kernel/auditsc.c --- linux-2.6.16/kernel/auditsc.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/kernel/auditsc.c 2006-05-11 04:56:24.000000000 +0300 @@ -966,11 +966,6 @@ if (context->in_syscall) { struct audit_context *newctx; -#if defined(__NR_vm86) && defined(__NR_vm86old) - /* vm86 mode should only be entered once */ - if (major == __NR_vm86 || major == __NR_vm86old) - return; -#endif #if AUDIT_DEBUG printk(KERN_ERR "audit(:%d) pid=%d in syscall=%d;" diff -Naur linux-2.6.16/kernel/exec_domain.c linux-2.6.16.16/kernel/exec_domain.c --- linux-2.6.16/kernel/exec_domain.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/kernel/exec_domain.c 2006-05-11 04:56:24.000000000 +0300 @@ -140,6 +140,7 @@ ep = lookup_exec_domain(personality); if (ep == current_thread_info()->exec_domain) { current->personality = personality; + module_put(ep->module); return 0; } diff -Naur linux-2.6.16/kernel/fork.c linux-2.6.16.16/kernel/fork.c --- linux-2.6.16/kernel/fork.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/kernel/fork.c 2006-05-11 04:56:24.000000000 +0300 @@ -720,7 +720,7 @@ free_fdset (new_fdt->open_fds, new_fdt->max_fdset); free_fd_array(new_fdt->fd, new_fdt->max_fds); kmem_cache_free(files_cachep, newf); - goto out; + return NULL; } static int copy_files(unsigned long clone_flags, struct task_struct * tsk) diff -Naur linux-2.6.16/kernel/power/process.c linux-2.6.16.16/kernel/power/process.c --- linux-2.6.16/kernel/power/process.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/kernel/power/process.c 2006-05-11 04:56:24.000000000 +0300 @@ -25,8 +25,7 @@ (p->flags & PF_NOFREEZE) || (p->exit_state == EXIT_ZOMBIE) || (p->exit_state == EXIT_DEAD) || - (p->state == TASK_STOPPED) || - (p->state == TASK_TRACED)) + (p->state == TASK_STOPPED)) return 0; return 1; } diff -Naur linux-2.6.16/kernel/ptrace.c linux-2.6.16.16/kernel/ptrace.c --- linux-2.6.16/kernel/ptrace.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/kernel/ptrace.c 2006-05-11 04:56:24.000000000 +0300 @@ -57,10 +57,6 @@ signal_wake_up(child, 1); } } - if (child->signal->flags & SIGNAL_GROUP_EXIT) { - sigaddset(&child->pending.signal, SIGKILL); - signal_wake_up(child, 1); - } spin_unlock(&child->sighand->siglock); } @@ -82,7 +78,8 @@ SET_LINKS(child); } - ptrace_untrace(child); + if (child->state == TASK_TRACED) + ptrace_untrace(child); } /* diff -Naur linux-2.6.16/kernel/sched.c linux-2.6.16.16/kernel/sched.c --- linux-2.6.16/kernel/sched.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/kernel/sched.c 2006-05-11 04:56:24.000000000 +0300 @@ -237,6 +237,7 @@ task_t *migration_thread; struct list_head migration_queue; + int cpu; #endif #ifdef CONFIG_SCHEDSTATS @@ -1660,6 +1661,9 @@ /* * double_rq_lock - safely lock two runqueues * + * We must take them in cpu order to match code in + * dependent_sleeper and wake_dependent_sleeper. + * * Note this does not disable interrupts like task_rq_lock, * you need to do so manually before calling. */ @@ -1671,7 +1675,7 @@ spin_lock(&rq1->lock); __acquire(rq2->lock); /* Fake it out ;) */ } else { - if (rq1 < rq2) { + if (rq1->cpu < rq2->cpu) { spin_lock(&rq1->lock); spin_lock(&rq2->lock); } else { @@ -1707,7 +1711,7 @@ __acquires(this_rq->lock) { if (unlikely(!spin_trylock(&busiest->lock))) { - if (busiest < this_rq) { + if (busiest->cpu < this_rq->cpu) { spin_unlock(&this_rq->lock); spin_lock(&busiest->lock); spin_lock(&this_rq->lock); @@ -6035,6 +6039,7 @@ rq->push_cpu = 0; rq->migration_thread = NULL; INIT_LIST_HEAD(&rq->migration_queue); + rq->cpu = i; #endif atomic_set(&rq->nr_iowait, 0); diff -Naur linux-2.6.16/kernel/signal.c linux-2.6.16.16/kernel/signal.c --- linux-2.6.16/kernel/signal.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/kernel/signal.c 2006-05-11 04:56:24.000000000 +0300 @@ -975,7 +975,6 @@ if (t == NULL) /* restart balancing at this thread */ t = p->signal->curr_target = p; - BUG_ON(t->tgid != p->tgid); while (!wants_signal(sig, t)) { t = next_thread(t); @@ -1689,6 +1688,7 @@ /* Let the debugger run. */ set_current_state(TASK_TRACED); spin_unlock_irq(¤t->sighand->siglock); + try_to_freeze(); read_lock(&tasklist_lock); if (likely(current->ptrace & PT_PTRACED) && likely(current->parent != current->real_parent || @@ -1942,9 +1942,9 @@ /* Let the debugger run. */ ptrace_stop(signr, signr, info); - /* We're back. Did the debugger cancel the sig or group_exit? */ + /* We're back. Did the debugger cancel the sig? */ signr = current->exit_code; - if (signr == 0 || current->signal->flags & SIGNAL_GROUP_EXIT) + if (signr == 0) continue; current->exit_code = 0; diff -Naur linux-2.6.16/kernel/sys.c linux-2.6.16.16/kernel/sys.c --- linux-2.6.16/kernel/sys.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/kernel/sys.c 2006-05-11 04:56:24.000000000 +0300 @@ -1657,7 +1657,19 @@ (cputime_eq(current->signal->it_prof_expires, cputime_zero) || new_rlim.rlim_cur <= cputime_to_secs( current->signal->it_prof_expires))) { - cputime_t cputime = secs_to_cputime(new_rlim.rlim_cur); + unsigned long rlim_cur = new_rlim.rlim_cur; + cputime_t cputime; + + if (rlim_cur == 0) { + /* + * The caller is asking for an immediate RLIMIT_CPU + * expiry. But we use the zero value to mean "it was + * never set". So let's cheat and make it one second + * instead + */ + rlim_cur = 1; + } + cputime = secs_to_cputime(rlim_cur); read_lock(&tasklist_lock); spin_lock_irq(¤t->sighand->siglock); set_process_cpu_timer(current, CPUCLOCK_PROF, diff -Naur linux-2.6.16/kernel/uid16.c linux-2.6.16.16/kernel/uid16.c --- linux-2.6.16/kernel/uid16.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/kernel/uid16.c 2006-05-11 04:56:24.000000000 +0300 @@ -20,43 +20,67 @@ asmlinkage long sys_chown16(const char __user * filename, old_uid_t user, old_gid_t group) { - return sys_chown(filename, low2highuid(user), low2highgid(group)); + long ret = sys_chown(filename, low2highuid(user), low2highgid(group)); + /* avoid REGPARM breakage on x86: */ + prevent_tail_call(ret); + return ret; } asmlinkage long sys_lchown16(const char __user * filename, old_uid_t user, old_gid_t group) { - return sys_lchown(filename, low2highuid(user), low2highgid(group)); + long ret = sys_lchown(filename, low2highuid(user), low2highgid(group)); + /* avoid REGPARM breakage on x86: */ + prevent_tail_call(ret); + return ret; } asmlinkage long sys_fchown16(unsigned int fd, old_uid_t user, old_gid_t group) { - return sys_fchown(fd, low2highuid(user), low2highgid(group)); + long ret = sys_fchown(fd, low2highuid(user), low2highgid(group)); + /* avoid REGPARM breakage on x86: */ + prevent_tail_call(ret); + return ret; } asmlinkage long sys_setregid16(old_gid_t rgid, old_gid_t egid) { - return sys_setregid(low2highgid(rgid), low2highgid(egid)); + long ret = sys_setregid(low2highgid(rgid), low2highgid(egid)); + /* avoid REGPARM breakage on x86: */ + prevent_tail_call(ret); + return ret; } asmlinkage long sys_setgid16(old_gid_t gid) { - return sys_setgid(low2highgid(gid)); + long ret = sys_setgid(low2highgid(gid)); + /* avoid REGPARM breakage on x86: */ + prevent_tail_call(ret); + return ret; } asmlinkage long sys_setreuid16(old_uid_t ruid, old_uid_t euid) { - return sys_setreuid(low2highuid(ruid), low2highuid(euid)); + long ret = sys_setreuid(low2highuid(ruid), low2highuid(euid)); + /* avoid REGPARM breakage on x86: */ + prevent_tail_call(ret); + return ret; } asmlinkage long sys_setuid16(old_uid_t uid) { - return sys_setuid(low2highuid(uid)); + long ret = sys_setuid(low2highuid(uid)); + /* avoid REGPARM breakage on x86: */ + prevent_tail_call(ret); + return ret; } asmlinkage long sys_setresuid16(old_uid_t ruid, old_uid_t euid, old_uid_t suid) { - return sys_setresuid(low2highuid(ruid), low2highuid(euid), - low2highuid(suid)); + long ret = sys_setresuid(low2highuid(ruid), low2highuid(euid), + low2highuid(suid)); + /* avoid REGPARM breakage on x86: */ + prevent_tail_call(ret); + return ret; } asmlinkage long sys_getresuid16(old_uid_t __user *ruid, old_uid_t __user *euid, old_uid_t __user *suid) @@ -72,8 +96,11 @@ asmlinkage long sys_setresgid16(old_gid_t rgid, old_gid_t egid, old_gid_t sgid) { - return sys_setresgid(low2highgid(rgid), low2highgid(egid), - low2highgid(sgid)); + long ret = sys_setresgid(low2highgid(rgid), low2highgid(egid), + low2highgid(sgid)); + /* avoid REGPARM breakage on x86: */ + prevent_tail_call(ret); + return ret; } asmlinkage long sys_getresgid16(old_gid_t __user *rgid, old_gid_t __user *egid, old_gid_t __user *sgid) @@ -89,12 +116,18 @@ asmlinkage long sys_setfsuid16(old_uid_t uid) { - return sys_setfsuid(low2highuid(uid)); + long ret = sys_setfsuid(low2highuid(uid)); + /* avoid REGPARM breakage on x86: */ + prevent_tail_call(ret); + return ret; } asmlinkage long sys_setfsgid16(old_gid_t gid) { - return sys_setfsgid(low2highgid(gid)); + long ret = sys_setfsgid(low2highgid(gid)); + /* avoid REGPARM breakage on x86: */ + prevent_tail_call(ret); + return ret; } static int groups16_to_user(old_gid_t __user *grouplist, diff -Naur linux-2.6.16/Makefile linux-2.6.16.16/Makefile --- linux-2.6.16/Makefile 2006-05-18 01:12:20.000000000 +0300 +++ linux-2.6.16.16/Makefile 2006-05-17 21:41:27.000000000 +0300 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 16 -EXTRAVERSION = +EXTRAVERSION = .16 NAME=Sliding Snow Leopard # *DOCUMENTATION* diff -Naur linux-2.6.16/mm/madvise.c linux-2.6.16.16/mm/madvise.c --- linux-2.6.16/mm/madvise.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/mm/madvise.c 2006-05-11 04:56:24.000000000 +0300 @@ -168,6 +168,9 @@ return -EINVAL; } + if ((vma->vm_flags & (VM_SHARED|VM_WRITE)) != (VM_SHARED|VM_WRITE)) + return -EACCES; + mapping = vma->vm_file->f_mapping; offset = (loff_t)(start - vma->vm_start) diff -Naur linux-2.6.16/mm/page_alloc.c linux-2.6.16.16/mm/page_alloc.c --- linux-2.6.16/mm/page_alloc.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/mm/page_alloc.c 2006-05-11 04:56:24.000000000 +0300 @@ -153,7 +153,8 @@ 1 << PG_reclaim | 1 << PG_slab | 1 << PG_swapcache | - 1 << PG_writeback ); + 1 << PG_writeback | + 1 << PG_buddy ); set_page_count(page, 0); reset_page_mapcount(page); page->mapping = NULL; @@ -224,12 +225,12 @@ static inline void set_page_order(struct page *page, int order) { set_page_private(page, order); - __SetPagePrivate(page); + __SetPageBuddy(page); } static inline void rmv_page_order(struct page *page) { - __ClearPagePrivate(page); + __ClearPageBuddy(page); set_page_private(page, 0); } @@ -268,11 +269,13 @@ * This function checks whether a page is free && is the buddy * we can do coalesce a page and its buddy if * (a) the buddy is not in a hole && - * (b) the buddy is free && - * (c) the buddy is on the buddy system && - * (d) a page and its buddy have the same order. - * for recording page's order, we use page_private(page) and PG_private. + * (b) the buddy is in the buddy system && + * (c) a page and its buddy have the same order. + * + * For recording whether a page is in the buddy system, we use PG_buddy. + * Setting, clearing, and testing PG_buddy is serialized by zone->lock. * + * For recording page's order, we use page_private(page). */ static inline int page_is_buddy(struct page *page, int order) { @@ -281,10 +284,10 @@ return 0; #endif - if (PagePrivate(page) && - (page_order(page) == order) && - page_count(page) == 0) + if (PageBuddy(page) && page_order(page) == order) { + BUG_ON(page_count(page) != 0); return 1; + } return 0; } @@ -301,7 +304,7 @@ * as necessary, plus some accounting needed to play nicely with other * parts of the VM system. * At each level, we keep a list of pages, which are heads of continuous - * free pages of length of (1 << order) and marked with PG_Private.Page's + * free pages of length of (1 << order) and marked with PG_buddy. Page's * order is recorded in page_private(page) field. * So when we are allocating or freeing one, we can derive the state of the * other. That is, if we allocate a small block, and both were @@ -364,7 +367,8 @@ 1 << PG_slab | 1 << PG_swapcache | 1 << PG_writeback | - 1 << PG_reserved )))) + 1 << PG_reserved | + 1 << PG_buddy )))) bad_page(page); if (PageDirty(page)) __ClearPageDirty(page); @@ -522,7 +526,8 @@ 1 << PG_slab | 1 << PG_swapcache | 1 << PG_writeback | - 1 << PG_reserved )))) + 1 << PG_reserved | + 1 << PG_buddy )))) bad_page(page); /* diff -Naur linux-2.6.16/net/atm/clip.c linux-2.6.16.16/net/atm/clip.c --- linux-2.6.16/net/atm/clip.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/net/atm/clip.c 2006-05-11 04:56:24.000000000 +0300 @@ -613,12 +613,19 @@ static int clip_device_event(struct notifier_block *this,unsigned long event, - void *dev) + void *arg) { + struct net_device *dev = arg; + + if (event == NETDEV_UNREGISTER) { + neigh_ifdown(&clip_tbl, dev); + return NOTIFY_DONE; + } + /* ignore non-CLIP devices */ - if (((struct net_device *) dev)->type != ARPHRD_ATM || - ((struct net_device *) dev)->hard_start_xmit != clip_start_xmit) + if (dev->type != ARPHRD_ATM || dev->hard_start_xmit != clip_start_xmit) return NOTIFY_DONE; + switch (event) { case NETDEV_UP: DPRINTK("clip_device_event NETDEV_UP\n"); @@ -686,14 +693,12 @@ static void atmarpd_close(struct atm_vcc *vcc) { DPRINTK("atmarpd_close\n"); - atmarpd = NULL; /* assumed to be atomic */ - barrier(); - unregister_inetaddr_notifier(&clip_inet_notifier); - unregister_netdevice_notifier(&clip_dev_notifier); - if (skb_peek(&sk_atm(vcc)->sk_receive_queue)) - printk(KERN_ERR "atmarpd_close: closing with requests " - "pending\n"); + + rtnl_lock(); + atmarpd = NULL; skb_queue_purge(&sk_atm(vcc)->sk_receive_queue); + rtnl_unlock(); + DPRINTK("(done)\n"); module_put(THIS_MODULE); } @@ -714,7 +719,12 @@ static int atm_init_atmarp(struct atm_vcc *vcc) { - if (atmarpd) return -EADDRINUSE; + rtnl_lock(); + if (atmarpd) { + rtnl_unlock(); + return -EADDRINUSE; + } + if (start_timer) { start_timer = 0; init_timer(&idle_timer); @@ -731,10 +741,7 @@ vcc->push = NULL; vcc->pop = NULL; /* crash */ vcc->push_oam = NULL; /* crash */ - if (register_netdevice_notifier(&clip_dev_notifier)) - printk(KERN_ERR "register_netdevice_notifier failed\n"); - if (register_inetaddr_notifier(&clip_inet_notifier)) - printk(KERN_ERR "register_inetaddr_notifier failed\n"); + rtnl_unlock(); return 0; } @@ -992,6 +999,8 @@ clip_tbl_hook = &clip_tbl; register_atm_ioctl(&clip_ioctl_ops); + register_netdevice_notifier(&clip_dev_notifier); + register_inetaddr_notifier(&clip_inet_notifier); #ifdef CONFIG_PROC_FS { @@ -1012,6 +1021,9 @@ remove_proc_entry("arp", atm_proc_root); + unregister_inetaddr_notifier(&clip_inet_notifier); + unregister_netdevice_notifier(&clip_dev_notifier); + deregister_atm_ioctl(&clip_ioctl_ops); /* First, stop the idle timer, so it stops banging diff -Naur linux-2.6.16/net/bridge/br_netfilter.c linux-2.6.16.16/net/bridge/br_netfilter.c --- linux-2.6.16/net/bridge/br_netfilter.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/net/bridge/br_netfilter.c 2006-05-11 04:56:24.000000000 +0300 @@ -739,6 +739,15 @@ return NF_STOLEN; } +static int br_nf_dev_queue_xmit(struct sk_buff *skb) +{ + if (skb->protocol == htons(ETH_P_IP) && + skb->len > skb->dev->mtu && + !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size)) + return ip_fragment(skb, br_dev_queue_push_xmit); + else + return br_dev_queue_push_xmit(skb); +} /* PF_BRIDGE/POST_ROUTING ********************************************/ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb, @@ -798,7 +807,7 @@ realoutdev = nf_bridge->netoutdev; #endif NF_HOOK(pf, NF_IP_POST_ROUTING, skb, NULL, realoutdev, - br_dev_queue_push_xmit); + br_nf_dev_queue_xmit); return NF_STOLEN; @@ -843,7 +852,7 @@ if ((out->hard_start_xmit == br_dev_xmit && okfn != br_nf_forward_finish && okfn != br_nf_local_out_finish && - okfn != br_dev_queue_push_xmit) + okfn != br_nf_dev_queue_xmit) #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) || ((out->priv_flags & IFF_802_1Q_VLAN) && VLAN_DEV_INFO(out)->real_dev->hard_start_xmit == br_dev_xmit) diff -Naur linux-2.6.16/net/core/dev.c linux-2.6.16.16/net/core/dev.c --- linux-2.6.16/net/core/dev.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/net/core/dev.c 2006-05-11 04:56:24.000000000 +0300 @@ -2932,11 +2932,11 @@ switch(dev->reg_state) { case NETREG_REGISTERING: + dev->reg_state = NETREG_REGISTERED; err = netdev_register_sysfs(dev); if (err) printk(KERN_ERR "%s: failed sysfs registration (%d)\n", dev->name, err); - dev->reg_state = NETREG_REGISTERED; break; case NETREG_UNREGISTERING: diff -Naur linux-2.6.16/net/core/sock.c linux-2.6.16.16/net/core/sock.c --- linux-2.6.16/net/core/sock.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/net/core/sock.c 2006-05-11 04:56:24.000000000 +0300 @@ -404,8 +404,9 @@ if (!valbool) { sk->sk_bound_dev_if = 0; } else { - if (optlen > IFNAMSIZ) - optlen = IFNAMSIZ; + if (optlen > IFNAMSIZ - 1) + optlen = IFNAMSIZ - 1; + memset(devname, 0, sizeof(devname)); if (copy_from_user(devname, optval, optlen)) { ret = -EFAULT; break; diff -Naur linux-2.6.16/net/ipv4/fib_trie.c linux-2.6.16.16/net/ipv4/fib_trie.c --- linux-2.6.16/net/ipv4/fib_trie.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/net/ipv4/fib_trie.c 2006-05-11 04:56:24.000000000 +0300 @@ -314,11 +314,6 @@ kfree(container_of(head, struct leaf, rcu)); } -static inline void free_leaf(struct leaf *leaf) -{ - call_rcu(&leaf->rcu, __leaf_free_rcu); -} - static void __leaf_info_free_rcu(struct rcu_head *head) { kfree(container_of(head, struct leaf_info, rcu)); @@ -357,7 +352,12 @@ static inline void tnode_free(struct tnode *tn) { - call_rcu(&tn->rcu, __tnode_free_rcu); + if(IS_LEAF(tn)) { + struct leaf *l = (struct leaf *) tn; + call_rcu_bh(&l->rcu, __leaf_free_rcu); + } + else + call_rcu(&tn->rcu, __tnode_free_rcu); } static struct leaf *leaf_new(void) diff -Naur linux-2.6.16/net/ipv4/ip_output.c linux-2.6.16.16/net/ipv4/ip_output.c --- linux-2.6.16/net/ipv4/ip_output.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/net/ipv4/ip_output.c 2006-05-11 04:56:24.000000000 +0300 @@ -86,8 +86,6 @@ int sysctl_ip_default_ttl = IPDEFTTL; -static int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)); - /* Generate a checksum for an outgoing IP datagram. */ __inline__ void ip_send_check(struct iphdr *iph) { @@ -421,7 +419,7 @@ * single device frame, and queue such a frame for sending. */ -static int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) +int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) { struct iphdr *iph; int raw = 0; @@ -673,6 +671,8 @@ return err; } +EXPORT_SYMBOL(ip_fragment); + int ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb) { @@ -1249,11 +1249,7 @@ iph->tos = inet->tos; iph->tot_len = htons(skb->len); iph->frag_off = df; - if (!df) { - __ip_select_ident(iph, &rt->u.dst, 0); - } else { - iph->id = htons(inet->id++); - } + ip_select_ident(iph, &rt->u.dst, sk); iph->ttl = ttl; iph->protocol = sk->sk_protocol; iph->saddr = rt->rt_src; diff -Naur linux-2.6.16/net/ipv4/netfilter/ip_conntrack_netlink.c linux-2.6.16.16/net/ipv4/netfilter/ip_conntrack_netlink.c --- linux-2.6.16/net/ipv4/netfilter/ip_conntrack_netlink.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/net/ipv4/netfilter/ip_conntrack_netlink.c 2006-05-11 04:56:24.000000000 +0300 @@ -1619,7 +1619,7 @@ printk("ctnetlink: unregistering from nfnetlink.\n"); #ifdef CONFIG_IP_NF_CONNTRACK_EVENTS - ip_conntrack_unregister_notifier(&ctnl_notifier_exp); + ip_conntrack_expect_unregister_notifier(&ctnl_notifier_exp); ip_conntrack_unregister_notifier(&ctnl_notifier); #endif diff -Naur linux-2.6.16/net/ipv4/netfilter/ip_conntrack_proto_sctp.c linux-2.6.16.16/net/ipv4/netfilter/ip_conntrack_proto_sctp.c --- linux-2.6.16/net/ipv4/netfilter/ip_conntrack_proto_sctp.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/net/ipv4/netfilter/ip_conntrack_proto_sctp.c 2006-05-11 04:56:24.000000000 +0300 @@ -235,12 +235,15 @@ flag = 1; } - /* Cookie Ack/Echo chunks not the first OR - Init / Init Ack / Shutdown compl chunks not the only chunks */ - if ((sch->type == SCTP_CID_COOKIE_ACK + /* + * Cookie Ack/Echo chunks not the first OR + * Init / Init Ack / Shutdown compl chunks not the only chunks + * OR zero-length. + */ + if (((sch->type == SCTP_CID_COOKIE_ACK || sch->type == SCTP_CID_COOKIE_ECHO || flag) - && count !=0 ) { + && count !=0) || !sch->length) { DEBUGP("Basic checks failed\n"); return 1; } diff -Naur linux-2.6.16/net/ipv4/route.c linux-2.6.16.16/net/ipv4/route.c --- linux-2.6.16/net/ipv4/route.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/net/ipv4/route.c 2006-05-11 04:56:24.000000000 +0300 @@ -2750,7 +2750,10 @@ /* Reserve room for dummy headers, this skb can pass through good chunk of routing engine. */ - skb->mac.raw = skb->data; + skb->mac.raw = skb->nh.raw = skb->data; + + /* Bugfix: need to give ip_route_input enough of an IP header to not gag. */ + skb->nh.iph->protocol = IPPROTO_ICMP; skb_reserve(skb, MAX_HEADER + sizeof(struct iphdr)); if (rta[RTA_SRC - 1]) diff -Naur linux-2.6.16/net/ipv4/tcp_output.c linux-2.6.16.16/net/ipv4/tcp_output.c --- linux-2.6.16/net/ipv4/tcp_output.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/net/ipv4/tcp_output.c 2006-05-11 04:56:24.000000000 +0300 @@ -537,7 +537,9 @@ buff = sk_stream_alloc_skb(sk, nsize, GFP_ATOMIC); if (buff == NULL) return -ENOMEM; /* We'll just try again later. */ - sk_charge_skb(sk, buff); + + buff->truesize = skb->len - len; + skb->truesize -= buff->truesize; /* Correct the sequence numbers. */ TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len; diff -Naur linux-2.6.16/net/ipv6/exthdrs.c linux-2.6.16.16/net/ipv6/exthdrs.c --- linux-2.6.16/net/ipv6/exthdrs.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/net/ipv6/exthdrs.c 2006-05-11 04:56:24.000000000 +0300 @@ -489,6 +489,18 @@ { struct inet6_skb_parm *opt = IP6CB(skb); + /* + * skb->nh.raw is equal to skb->data, and + * skb->h.raw - skb->nh.raw is always equal to + * sizeof(struct ipv6hdr) by definition of + * hop-by-hop options. + */ + if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + 8) || + !pskb_may_pull(skb, sizeof(struct ipv6hdr) + ((skb->h.raw[1] + 1) << 3))) { + kfree_skb(skb); + return -1; + } + opt->hop = sizeof(struct ipv6hdr); if (ip6_parse_tlv(tlvprochopopt_lst, skb)) { skb->h.raw += (skb->h.raw[1]+1)<<3; diff -Naur linux-2.6.16/net/ipv6/xfrm6_policy.c linux-2.6.16.16/net/ipv6/xfrm6_policy.c --- linux-2.6.16/net/ipv6/xfrm6_policy.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/net/ipv6/xfrm6_policy.c 2006-05-11 04:56:24.000000000 +0300 @@ -191,16 +191,18 @@ static inline void _decode_session6(struct sk_buff *skb, struct flowi *fl) { - u16 offset = sizeof(struct ipv6hdr); + u16 offset = skb->h.raw - skb->nh.raw; struct ipv6hdr *hdr = skb->nh.ipv6h; - struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset); - u8 nexthdr = skb->nh.ipv6h->nexthdr; + struct ipv6_opt_hdr *exthdr; + u8 nexthdr = skb->nh.raw[IP6CB(skb)->nhoff]; memset(fl, 0, sizeof(struct flowi)); ipv6_addr_copy(&fl->fl6_dst, &hdr->daddr); ipv6_addr_copy(&fl->fl6_src, &hdr->saddr); while (pskb_may_pull(skb, skb->nh.raw + offset + 1 - skb->data)) { + exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset); + switch (nexthdr) { case NEXTHDR_ROUTING: case NEXTHDR_HOP: diff -Naur linux-2.6.16/net/netfilter/nf_conntrack_netlink.c linux-2.6.16.16/net/netfilter/nf_conntrack_netlink.c --- linux-2.6.16/net/netfilter/nf_conntrack_netlink.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/net/netfilter/nf_conntrack_netlink.c 2006-05-11 04:56:24.000000000 +0300 @@ -1641,7 +1641,7 @@ printk("ctnetlink: unregistering from nfnetlink.\n"); #ifdef CONFIG_NF_CONNTRACK_EVENTS - nf_conntrack_unregister_notifier(&ctnl_notifier_exp); + nf_conntrack_expect_unregister_notifier(&ctnl_notifier_exp); nf_conntrack_unregister_notifier(&ctnl_notifier); #endif diff -Naur linux-2.6.16/net/netfilter/nf_conntrack_proto_sctp.c linux-2.6.16.16/net/netfilter/nf_conntrack_proto_sctp.c --- linux-2.6.16/net/netfilter/nf_conntrack_proto_sctp.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/net/netfilter/nf_conntrack_proto_sctp.c 2006-05-11 04:56:24.000000000 +0300 @@ -240,12 +240,15 @@ flag = 1; } - /* Cookie Ack/Echo chunks not the first OR - Init / Init Ack / Shutdown compl chunks not the only chunks */ - if ((sch->type == SCTP_CID_COOKIE_ACK + /* + * Cookie Ack/Echo chunks not the first OR + * Init / Init Ack / Shutdown compl chunks not the only chunks + * OR zero-length. + */ + if (((sch->type == SCTP_CID_COOKIE_ACK || sch->type == SCTP_CID_COOKIE_ECHO || flag) - && count !=0 ) { + && count !=0) || !sch->length) { DEBUGP("Basic checks failed\n"); return 1; } diff -Naur linux-2.6.16/net/sctp/inqueue.c linux-2.6.16.16/net/sctp/inqueue.c --- linux-2.6.16/net/sctp/inqueue.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/net/sctp/inqueue.c 2006-05-11 04:56:24.000000000 +0300 @@ -149,6 +149,7 @@ /* This is the first chunk in the packet. */ chunk->singleton = 1; ch = (sctp_chunkhdr_t *) chunk->skb->data; + chunk->data_accepted = 0; } chunk->chunk_hdr = ch; diff -Naur linux-2.6.16/net/sctp/sm_statefuns.c linux-2.6.16.16/net/sctp/sm_statefuns.c --- linux-2.6.16/net/sctp/sm_statefuns.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/net/sctp/sm_statefuns.c 2006-05-11 04:56:24.000000000 +0300 @@ -636,8 +636,9 @@ */ chunk->subh.cookie_hdr = (struct sctp_signed_cookie *)chunk->skb->data; - skb_pull(chunk->skb, - ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t)); + if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) - + sizeof(sctp_chunkhdr_t))) + goto nomem; /* 5.1 D) Upon reception of the COOKIE ECHO chunk, Endpoint * "Z" will reply with a COOKIE ACK chunk after building a TCB @@ -965,7 +966,8 @@ */ chunk->subh.hb_hdr = (sctp_heartbeathdr_t *) chunk->skb->data; paylen = ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t); - skb_pull(chunk->skb, paylen); + if (!pskb_pull(chunk->skb, paylen)) + goto nomem; reply = sctp_make_heartbeat_ack(asoc, chunk, chunk->subh.hb_hdr, paylen); @@ -1860,8 +1862,9 @@ * are in good shape. */ chunk->subh.cookie_hdr = (struct sctp_signed_cookie *)chunk->skb->data; - skb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) - - sizeof(sctp_chunkhdr_t)); + if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) - + sizeof(sctp_chunkhdr_t))) + goto nomem; /* In RFC 2960 5.2.4 3, if both Verification Tags in the State Cookie * of a duplicate COOKIE ECHO match the Verification Tags of the @@ -5151,7 +5154,9 @@ int tmp; __u32 tsn; int account_value; + struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map; struct sock *sk = asoc->base.sk; + int rcvbuf_over = 0; data_hdr = chunk->subh.data_hdr = (sctp_datahdr_t *)chunk->skb->data; skb_pull(chunk->skb, sizeof(sctp_datahdr_t)); @@ -5162,10 +5167,16 @@ /* ASSERT: Now skb->data is really the user data. */ /* - * if we are established, and we have used up our receive - * buffer memory, drop the frame + * If we are established, and we have used up our receive buffer + * memory, think about droping the frame. + * Note that we have an opportunity to improve performance here. + * If we accept one chunk from an skbuff, we have to keep all the + * memory of that skbuff around until the chunk is read into user + * space. Therefore, once we accept 1 chunk we may as well accept all + * remaining chunks in the skbuff. The data_accepted flag helps us do + * that. */ - if (asoc->state == SCTP_STATE_ESTABLISHED) { + if ((asoc->state == SCTP_STATE_ESTABLISHED) && (!chunk->data_accepted)) { /* * If the receive buffer policy is 1, then each * association can allocate up to sk_rcvbuf bytes @@ -5176,9 +5187,25 @@ account_value = atomic_read(&asoc->rmem_alloc); else account_value = atomic_read(&sk->sk_rmem_alloc); - - if (account_value > sk->sk_rcvbuf) - return SCTP_IERROR_IGNORE_TSN; + if (account_value > sk->sk_rcvbuf) { + /* + * We need to make forward progress, even when we are + * under memory pressure, so we always allow the + * next tsn after the ctsn ack point to be accepted. + * This lets us avoid deadlocks in which we have to + * drop frames that would otherwise let us drain the + * receive queue. + */ + if ((sctp_tsnmap_get_ctsn(map) + 1) != tsn) + return SCTP_IERROR_IGNORE_TSN; + + /* + * We're going to accept the frame but we should renege + * to make space for it. This will send us down that + * path later in this function. + */ + rcvbuf_over = 1; + } } /* Process ECN based congestion. @@ -5226,6 +5253,7 @@ datalen -= sizeof(sctp_data_chunk_t); deliver = SCTP_CMD_CHUNK_ULP; + chunk->data_accepted = 1; /* Think about partial delivery. */ if ((datalen >= asoc->rwnd) && (!asoc->ulpq.pd_mode)) { @@ -5242,7 +5270,8 @@ * large spill over. */ if (!asoc->rwnd || asoc->rwnd_over || - (datalen > asoc->rwnd + asoc->frag_point)) { + (datalen > asoc->rwnd + asoc->frag_point) || + rcvbuf_over) { /* If this is the next TSN, consider reneging to make * room. Note: Playing nice with a confused sender. A @@ -5250,8 +5279,8 @@ * space and in the future we may want to detect and * do more drastic reneging. */ - if (sctp_tsnmap_has_gap(&asoc->peer.tsn_map) && - (sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map) + 1) == tsn) { + if (sctp_tsnmap_has_gap(map) && + (sctp_tsnmap_get_ctsn(map) + 1) == tsn) { SCTP_DEBUG_PRINTK("Reneging for tsn:%u\n", tsn); deliver = SCTP_CMD_RENEGE; } else { diff -Naur linux-2.6.16/net/sctp/sm_statetable.c linux-2.6.16.16/net/sctp/sm_statetable.c --- linux-2.6.16/net/sctp/sm_statetable.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/net/sctp/sm_statetable.c 2006-05-11 04:56:24.000000000 +0300 @@ -366,9 +366,9 @@ /* SCTP_STATE_EMPTY */ \ {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \ /* SCTP_STATE_CLOSED */ \ - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ + {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ /* SCTP_STATE_COOKIE_WAIT */ \ - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ + {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ /* SCTP_STATE_COOKIE_ECHOED */ \ {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \ /* SCTP_STATE_ESTABLISHED */ \ @@ -380,7 +380,7 @@ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ + {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ } /* TYPE_SCTP_ECN_ECNE */ #define TYPE_SCTP_ECN_CWR { \ @@ -401,7 +401,7 @@ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ + {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ } /* TYPE_SCTP_ECN_CWR */ #define TYPE_SCTP_SHUTDOWN_COMPLETE { \ @@ -647,7 +647,7 @@ /* SCTP_STATE_EMPTY */ \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ /* SCTP_STATE_CLOSED */ \ - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ + {.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \ /* SCTP_STATE_COOKIE_WAIT */ \ {.fn = sctp_sf_do_prm_requestheartbeat, \ .name = "sctp_sf_do_prm_requestheartbeat"}, \ diff -Naur linux-2.6.16/net/sctp/ulpqueue.c linux-2.6.16.16/net/sctp/ulpqueue.c --- linux-2.6.16/net/sctp/ulpqueue.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/net/sctp/ulpqueue.c 2006-05-11 04:56:24.000000000 +0300 @@ -279,6 +279,7 @@ static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff_head *queue, struct sk_buff *f_frag, struct sk_buff *l_frag) { struct sk_buff *pos; + struct sk_buff *new = NULL; struct sctp_ulpevent *event; struct sk_buff *pnext, *last; struct sk_buff *list = skb_shinfo(f_frag)->frag_list; @@ -297,11 +298,33 @@ */ if (last) last->next = pos; - else - skb_shinfo(f_frag)->frag_list = pos; + else { + if (skb_cloned(f_frag)) { + /* This is a cloned skb, we can't just modify + * the frag_list. We need a new skb to do that. + * Instead of calling skb_unshare(), we'll do it + * ourselves since we need to delay the free. + */ + new = skb_copy(f_frag, GFP_ATOMIC); + if (!new) + return NULL; /* try again later */ + + new->sk = f_frag->sk; + + skb_shinfo(new)->frag_list = pos; + } else + skb_shinfo(f_frag)->frag_list = pos; + } /* Remove the first fragment from the reassembly queue. */ __skb_unlink(f_frag, queue); + + /* if we did unshare, then free the old skb and re-assign */ + if (new) { + kfree_skb(f_frag); + f_frag = new; + } + while (pos) { pnext = pos->next; diff -Naur linux-2.6.16/security/keys/key.c linux-2.6.16.16/security/keys/key.c --- linux-2.6.16/security/keys/key.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/security/keys/key.c 2006-05-11 04:56:24.000000000 +0300 @@ -785,6 +785,10 @@ key_check(keyring); + key_ref = ERR_PTR(-ENOTDIR); + if (keyring->type != &key_type_keyring) + goto error_2; + down_write(&keyring->sem); /* if we're going to allocate a new key, we're going to have diff -Naur linux-2.6.16/security/keys/keyring.c linux-2.6.16.16/security/keys/keyring.c --- linux-2.6.16/security/keys/keyring.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/security/keys/keyring.c 2006-05-11 04:56:24.000000000 +0300 @@ -437,6 +437,7 @@ /* * search the given keyring only (no recursion) * - keyring must be locked by caller + * - caller must guarantee that the keyring is a keyring */ key_ref_t __keyring_search_one(key_ref_t keyring_ref, const struct key_type *ktype, diff -Naur linux-2.6.16/security/selinux/ss/mls.c linux-2.6.16.16/security/selinux/ss/mls.c --- linux-2.6.16/security/selinux/ss/mls.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/security/selinux/ss/mls.c 2006-05-11 04:56:24.000000000 +0300 @@ -264,7 +264,7 @@ if (!selinux_mls_enabled) { if (def_sid != SECSID_NULL && oldc) - *scontext += strlen(*scontext); + *scontext += strlen(*scontext)+1; return 0; } diff -Naur linux-2.6.16/sound/isa/opti9xx/opti92x-ad1848.c linux-2.6.16.16/sound/isa/opti9xx/opti92x-ad1848.c --- linux-2.6.16/sound/isa/opti9xx/opti92x-ad1848.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/sound/isa/opti9xx/opti92x-ad1848.c 2006-05-11 04:56:24.000000000 +0300 @@ -2088,9 +2088,11 @@ int error; struct platform_device *device; +#ifdef CONFIG_PNP pnp_register_card_driver(&opti9xx_pnpc_driver); if (snd_opti9xx_pnp_is_probed) return 0; +#endif if (! is_isapnp_selected()) { error = platform_driver_register(&snd_opti9xx_driver); if (error < 0) @@ -2102,7 +2104,9 @@ } platform_driver_unregister(&snd_opti9xx_driver); } +#ifdef CONFIG_PNP pnp_unregister_card_driver(&opti9xx_pnpc_driver); +#endif #ifdef MODULE printk(KERN_ERR "no OPTi " CHIP_NAME " soundcard found\n"); #endif @@ -2115,7 +2119,9 @@ platform_device_unregister(snd_opti9xx_platform_device); platform_driver_unregister(&snd_opti9xx_driver); } +#ifdef CONFIG_PNP pnp_unregister_card_driver(&opti9xx_pnpc_driver); +#endif } module_init(alsa_card_opti9xx_init) diff -Naur linux-2.6.16/sound/oss/dmasound/tas_common.c linux-2.6.16.16/sound/oss/dmasound/tas_common.c --- linux-2.6.16/sound/oss/dmasound/tas_common.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/sound/oss/dmasound/tas_common.c 2006-05-11 04:56:24.000000000 +0300 @@ -195,8 +195,8 @@ printk(KERN_INFO "tas driver [%s])\n", driver_name); -#ifndef CONFIG_I2C_KEYWEST - request_module("i2c-keywest"); +#ifndef CONFIG_I2C_POWERMAC + request_module("i2c-powermac"); #endif tas_node = find_devices("deq"); if (tas_node == NULL) diff -Naur linux-2.6.16/sound/pci/hda/patch_realtek.c linux-2.6.16.16/sound/pci/hda/patch_realtek.c --- linux-2.6.16/sound/pci/hda/patch_realtek.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/sound/pci/hda/patch_realtek.c 2006-05-11 04:56:24.000000000 +0300 @@ -2948,6 +2948,8 @@ { .modelname = "basic", .config = ALC260_BASIC }, { .pci_subvendor = 0x104d, .pci_subdevice = 0x81bb, .config = ALC260_BASIC }, /* Sony VAIO */ + { .pci_subvendor = 0x152d, .pci_subdevice = 0x0729, + .config = ALC260_BASIC }, /* CTL Travel Master U553W */ { .modelname = "hp", .config = ALC260_HP }, { .pci_subvendor = 0x103c, .pci_subdevice = 0x3010, .config = ALC260_HP }, { .pci_subvendor = 0x103c, .pci_subdevice = 0x3011, .config = ALC260_HP }, diff -Naur linux-2.6.16/sound/ppc/daca.c linux-2.6.16.16/sound/ppc/daca.c --- linux-2.6.16/sound/ppc/daca.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/sound/ppc/daca.c 2006-05-11 04:56:24.000000000 +0300 @@ -256,7 +256,7 @@ #ifdef CONFIG_KMOD if (current->fs->root) - request_module("i2c-keywest"); + request_module("i2c-powermac"); #endif /* CONFIG_KMOD */ mix = kmalloc(sizeof(*mix), GFP_KERNEL); diff -Naur linux-2.6.16/sound/ppc/tumbler.c linux-2.6.16.16/sound/ppc/tumbler.c --- linux-2.6.16/sound/ppc/tumbler.c 2006-03-20 07:53:29.000000000 +0200 +++ linux-2.6.16.16/sound/ppc/tumbler.c 2006-05-11 04:56:24.000000000 +0300 @@ -1314,7 +1314,7 @@ #ifdef CONFIG_KMOD if (current->fs->root) - request_module("i2c-keywest"); + request_module("i2c-powermac"); #endif /* CONFIG_KMOD */ mix = kmalloc(sizeof(*mix), GFP_KERNEL);