kumquat-buildroot/target/device/AMD/DBAu1500/kernel-patches/001-patch-2.6.16.20.patch
2006-06-23 07:06:48 +00:00

6361 lines
193 KiB
Diff

diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware
index 75c28a1..948f502 100644
--- a/Documentation/dvb/get_dvb_firmware
+++ b/Documentation/dvb/get_dvb_firmware
@@ -240,9 +240,9 @@ sub dibusb {
}
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 @@ sub nxt2002 {
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 --git a/Makefile b/Makefile
index cb57905..600c769 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 16
-EXTRAVERSION =
+EXTRAVERSION = .20
NAME=Sliding Snow Leopard
# *DOCUMENTATION*
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index b4e5f8f..45308bd 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -24,6 +24,7 @@ #include <linux/delay.h>
#include <linux/config.h> /* CONFIG_ALPHA_LCA etc */
#include <linux/mc146818rtc.h>
#include <linux/console.h>
+#include <linux/cpu.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/string.h>
@@ -477,6 +478,22 @@ #undef PFN_DOWN
#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 --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index 02c2db0..1852554 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -439,7 +439,7 @@ setup_smp(void)
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 @@ setup_smp(void)
}
} 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 @@ void __devinit
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 --git a/arch/alpha/lib/strncpy.S b/arch/alpha/lib/strncpy.S
index 338551c..bbdef1b 100644
--- a/arch/alpha/lib/strncpy.S
+++ b/arch/alpha/lib/strncpy.S
@@ -43,8 +43,8 @@ strncpy:
.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 @@ strncpy:
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 --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index 05312a8..558d2d2 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -1081,7 +1081,7 @@ static int apm_console_blank(int blank)
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 --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c
index 0810f81..d2d50cb 100644
--- a/arch/i386/kernel/cpu/amd.c
+++ b/arch/i386/kernel/cpu/amd.c
@@ -207,6 +207,8 @@ #define CBAR_KEY (0X000000CB)
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 --git a/arch/i386/kernel/cpu/cpufreq/Kconfig b/arch/i386/kernel/cpu/cpufreq/Kconfig
index 26892d2..16f2e35 100644
--- a/arch/i386/kernel/cpu/cpufreq/Kconfig
+++ b/arch/i386/kernel/cpu/cpufreq/Kconfig
@@ -203,6 +203,7 @@ config X86_LONGRUN
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 --git a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
index cc73a7a..ebe1848 100644
--- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
+++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
@@ -244,7 +244,7 @@ #endif
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 --git a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
index 28cc5d5..cfc4276 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
@@ -75,7 +75,9 @@ static int speedstep_smi_ownership (void
__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 --git a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c
index 6a93d75..ca2a0cb 100644
--- a/arch/i386/kernel/dmi_scan.c
+++ b/arch/i386/kernel/dmi_scan.c
@@ -106,7 +106,7 @@ static void __init dmi_save_devices(stru
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 --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c
index f51c894..aee14fa 100644
--- a/arch/i386/kernel/vm86.c
+++ b/arch/i386/kernel/vm86.c
@@ -43,6 +43,7 @@ #include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/highmem.h>
#include <linux/ptrace.h>
+#include <linux/audit.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -252,6 +253,7 @@ out:
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 @@ static void do_sys_vm86(struct kernel_vm
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 --git a/arch/m32r/kernel/m32r_ksyms.c b/arch/m32r/kernel/m32r_ksyms.c
index be8b711..6000950 100644
--- a/arch/m32r/kernel/m32r_ksyms.c
+++ b/arch/m32r/kernel/m32r_ksyms.c
@@ -38,10 +38,6 @@ EXPORT_SYMBOL(__udelay);
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 --git a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c
index d742037..542ed93 100644
--- a/arch/m32r/kernel/setup.c
+++ b/arch/m32r/kernel/setup.c
@@ -9,6 +9,7 @@
#include <linux/config.h>
#include <linux/init.h>
+#include <linux/kernel.h>
#include <linux/stddef.h>
#include <linux/fs.h>
#include <linux/sched.h>
@@ -218,8 +219,6 @@ #else /* CONFIG_DISCONTIGMEM */
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 @@ #endif /* CONFIG_DISCONTIGMEM */
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 --git a/arch/m32r/kernel/smpboot.c b/arch/m32r/kernel/smpboot.c
index d7ec16e..840b434 100644
--- a/arch/m32r/kernel/smpboot.c
+++ b/arch/m32r/kernel/smpboot.c
@@ -39,8 +39,10 @@
* Martin J. Bligh : Added support for multi-quad systems
*/
+#include <linux/module.h>
#include <linux/config.h>
#include <linux/init.h>
+#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/smp_lock.h>
#include <linux/irq.h>
@@ -72,11 +74,15 @@ physid_mask_t phys_cpu_present_map;
/* 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 @@ static unsigned int calibration_result;
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 @@ void __init smp_prepare_cpus(unsigned in
}
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 @@ void __init smp_prepare_cpus(unsigned in
* 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 @@ smp_done:
Dprintk("Boot done.\n");
}
-static void __init smp_tune_scheduling(void)
-{
- /* Nothing to do. */
-}
-
/*
* init_ipi_lock : Initialize IPI locks.
*/
@@ -629,4 +631,3 @@ static void __init unmap_cpu_to_physid(i
physid_2_cpu[phys_id] = -1;
cpu_2_physid[cpu_id] = -1;
}
-
diff --git a/arch/m32r/lib/Makefile b/arch/m32r/lib/Makefile
index e632d10..d16b4e4 100644
--- a/arch/m32r/lib/Makefile
+++ b/arch/m32r/lib/Makefile
@@ -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 --git a/arch/m32r/lib/getuser.S b/arch/m32r/lib/getuser.S
deleted file mode 100644
index 58a0db0..0000000
--- a/arch/m32r/lib/getuser.S
+++ /dev/null
@@ -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 <linux/config.h>
-
-/*
- * __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 --git a/arch/m32r/lib/putuser.S b/arch/m32r/lib/putuser.S
deleted file mode 100644
index 218154c..0000000
--- a/arch/m32r/lib/putuser.S
+++ /dev/null
@@ -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 <linux/config.h>
-
-/*
- * __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 --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c
index 374de83..b6232d9 100644
--- a/arch/mips/kernel/branch.c
+++ b/arch/mips/kernel/branch.c
@@ -184,7 +184,7 @@ int __compute_return_epc(struct pt_regs
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 --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 9572ed4..a761f99 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -154,7 +154,8 @@ static inline void blast_icache32_r4600_
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 --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index ba92bab..4c4449b 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -78,6 +78,7 @@ int global_phb_number; /* Global phb co
/* 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 --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index f96c49b..abd758f 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -256,12 +256,10 @@ #endif
/*
* 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 --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 4324f8a..096dfdc 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -213,7 +213,7 @@ static inline void __user * get_sigframe
/* 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 --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index 29c2946..f649750 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -456,11 +456,23 @@ static int pmac_pm_finish(suspend_state_
return 0;
}
+static int pmac_pm_valid(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_DISK:
+ return 1;
+ /* can't do any other states via generic mechanism yet */
+ default:
+ return 0;
+ }
+}
+
static struct pm_ops pmac_pm_ops = {
.pm_disk_mode = PM_DISK_SHUTDOWN,
.prepare = pmac_pm_prepare,
.enter = pmac_pm_enter,
.finish = pmac_pm_finish,
+ .valid = pmac_pm_valid,
};
#endif /* CONFIG_SOFTWARE_SUSPEND */
diff --git a/arch/x86_64/ia32/Makefile b/arch/x86_64/ia32/Makefile
index 929e6b0..e9263b4 100644
--- a/arch/x86_64/ia32/Makefile
+++ b/arch/x86_64/ia32/Makefile
@@ -27,5 +27,5 @@ quiet_cmd_syscall = SYSCALL $@
$(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 --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
index 7c10e90..97583bb 100644
--- a/arch/x86_64/kernel/entry.S
+++ b/arch/x86_64/kernel/entry.S
@@ -180,6 +180,10 @@ rff_trace:
*
* 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 @@ sysret_signal:
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)
@@ -274,13 +281,9 @@ tracesys:
ja 1f
movq %r10,%rcx /* fixup for C */
call *sys_call_table(,%rax,8)
- movq %rax,RAX-ARGOFFSET(%rsp)
-1: SAVE_REST
- movq %rsp,%rdi
- call syscall_trace_leave
- RESTORE_TOP_OF_STACK %rbx
- RESTORE_REST
- jmp ret_from_sys_call
+1: movq %rax,RAX-ARGOFFSET(%rsp)
+ /* Use IRET because user could have changed frame */
+ jmp int_ret_from_sys_call
CFI_ENDPROC
/*
@@ -408,25 +411,9 @@ ENTRY(stub_execve)
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 --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c
index 0c3f052..b9dbe3c 100644
--- a/arch/x86_64/kernel/pci-gart.c
+++ b/arch/x86_64/kernel/pci-gart.c
@@ -114,10 +114,6 @@ static unsigned long alloc_iommu(int siz
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 --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 22a05de..818ab9e 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -527,8 +527,6 @@ __switch_to(struct task_struct *prev_p,
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 @@ __switch_to(struct task_struct *prev_p,
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 --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index aa55e3c..a4a0bb5 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -909,6 +909,10 @@ #endif
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 --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index 28d50dc..a5209fd 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -30,6 +30,7 @@ #include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/nmi.h>
#include <linux/kprobes.h>
+#include <linux/kexec.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -434,6 +435,8 @@ #endif
printk(KERN_ALERT "RIP ");
printk_address(regs->rip);
printk(" RSP <%016lx>\n", regs->rsp);
+ if (kexec_should_crash(current))
+ crash_kexec(regs);
}
void die(const char * str, struct pt_regs * regs, long err)
@@ -456,6 +459,8 @@ void __kprobes die_nmi(char *str, struct
*/
printk(str, safe_smp_processor_id());
show_registers(regs);
+ if (kexec_should_crash(current))
+ crash_kexec(regs);
if (panic_on_timeout || panic_on_oops)
panic("nmi watchdog");
printk("console shuts up ...\n");
diff --git a/block/elevator.c b/block/elevator.c
index 24b702d..ef1e606 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -314,6 +314,7 @@ void elv_insert(request_queue_t *q, stru
{
struct list_head *pos;
unsigned ordseq;
+ int unplug_it = 1;
rq->q = q;
@@ -378,6 +379,11 @@ void elv_insert(request_queue_t *q, stru
}
list_add_tail(&rq->queuelist, pos);
+ /*
+ * most requeues happen because of a busy condition, don't
+ * force unplug of the queue for that case.
+ */
+ unplug_it = 0;
break;
default:
@@ -386,7 +392,7 @@ void elv_insert(request_queue_t *q, stru
BUG();
}
- if (blk_queue_plugged(q)) {
+ if (unplug_it && blk_queue_plugged(q)) {
int nrq = q->rq.count[READ] + q->rq.count[WRITE]
- q->in_flight;
diff --git a/block/genhd.c b/block/genhd.c
index db57546..7f406f9 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -16,8 +16,6 @@ #include <linux/kmod.h>
#include <linux/kobj_map.h>
#include <linux/buffer_head.h>
-#define MAX_PROBE_HASH 255 /* random */
-
static struct subsystem block_subsys;
static DECLARE_MUTEX(block_subsys_sem);
@@ -30,108 +28,29 @@ static struct blk_major_name {
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;
+ struct blk_major_name *dp;
- count = 0;
-
- 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 --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 0ef2971..cd995c3 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -1719,8 +1719,21 @@ void blk_run_queue(struct request_queue
spin_lock_irqsave(q->queue_lock, flags);
blk_remove_plug(q);
- if (!elv_queue_empty(q))
- q->request_fn(q);
+
+ /*
+ * Only recurse once to avoid overrunning the stack, let the unplug
+ * handling reinvoke the handler shortly if we already got there.
+ */
+ if (!elv_queue_empty(q)) {
+ if (!test_and_set_bit(QUEUE_FLAG_REENTER, &q->queue_flags)) {
+ q->request_fn(q);
+ clear_bit(QUEUE_FLAG_REENTER, &q->queue_flags);
+ } else {
+ blk_plug_device(q);
+ kblockd_schedule_work(&q->unplug_work);
+ }
+ }
+
spin_unlock_irqrestore(q->queue_lock, flags);
}
EXPORT_SYMBOL(blk_run_queue);
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 07a7f97..29f3d75 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -141,7 +141,7 @@ #endif
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 --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index e97e911..4723182 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -211,18 +211,20 @@ static int
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 --git a/drivers/base/node.c b/drivers/base/node.c
index 16c513a..c80c3ae 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -106,7 +106,7 @@ static ssize_t node_read_numastat(struct
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 --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 0d65394..71552e1 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -1181,6 +1181,53 @@ static int revalidate_allvol(ctlr_info_t
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; i<cmd->Header.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 @@ static void cciss_update_drive_info(int
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 @@ static void start_io( ctlr_info_t *h)
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 @@ static inline void resend_cciss_cmd( ctl
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; i<cmd->Header.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 @@ clean2:
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 --git a/drivers/block/ub.c b/drivers/block/ub.c
index f04d864..a9485e5 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -704,6 +704,9 @@ static void ub_cleanup(struct ub_dev *sc
kfree(lun);
}
+ usb_set_intfdata(sc->intf, NULL);
+ usb_put_intf(sc->intf);
+ usb_put_dev(sc->dev);
kfree(sc);
}
@@ -2428,7 +2431,12 @@ static int ub_probe(struct usb_interface
// sc->ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
usb_set_intfdata(intf, sc);
usb_get_dev(sc->dev);
- // usb_get_intf(sc->intf); /* Do we need this? */
+ /*
+ * Since we give the interface struct to the block level through
+ * disk->driverfs_dev, we have to pin it. Otherwise, block_uevent
+ * oopses on close after a disconnect (kernels 2.6.16 and up).
+ */
+ usb_get_intf(sc->intf);
snprintf(sc->name, 12, DRV_NAME "(%d.%d)",
sc->dev->bus->busnum, sc->dev->devnum);
@@ -2509,7 +2517,7 @@ #endif
err_diag:
err_dev_desc:
usb_set_intfdata(intf, NULL);
- // usb_put_intf(sc->intf);
+ usb_put_intf(sc->intf);
usb_put_dev(sc->dev);
kfree(sc);
err_core:
@@ -2688,12 +2696,6 @@ static void ub_disconnect(struct usb_int
*/
device_remove_file(&sc->intf->dev, &dev_attr_diag);
- usb_set_intfdata(intf, NULL);
- // usb_put_intf(sc->intf);
- sc->intf = NULL;
- usb_put_dev(sc->dev);
- sc->dev = NULL;
-
ub_put(sc);
}
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 05ba410..8b72a61 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -187,6 +187,7 @@ config MOXA_SMARTIO
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 --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c
index e7aea77..40dfc29 100644
--- a/drivers/char/agp/efficeon-agp.c
+++ b/drivers/char/agp/efficeon-agp.c
@@ -64,6 +64,12 @@ static struct gatt_mask efficeon_generic
{.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 @@ static int efficeon_insert_memory(struct
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 --git a/drivers/char/cs5535_gpio.c b/drivers/char/cs5535_gpio.c
index 5d72f50..46d6603 100644
--- a/drivers/char/cs5535_gpio.c
+++ b/drivers/char/cs5535_gpio.c
@@ -241,9 +241,10 @@ static int __init cs5535_gpio_init(void)
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 --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c
index 58dcdee..0030cd8 100644
--- a/drivers/char/ipmi/ipmi_bt_sm.c
+++ b/drivers/char/ipmi/ipmi_bt_sm.c
@@ -165,7 +165,7 @@ static int bt_start_transaction(struct s
{
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 --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index 5fdf185..b61354a 100644
--- a/drivers/char/pcmcia/cm4000_cs.c
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -2010,10 +2010,6 @@ static int __init cmm_init(void)
if (!cmm_class)
return -1;
- rc = pcmcia_register_driver(&cm4000_driver);
- if (rc < 0)
- return rc;
-
major = register_chrdev(0, DEVICE_NAME, &cm4000_fops);
if (major < 0) {
printk(KERN_WARNING MODULE_NAME
@@ -2021,6 +2017,12 @@ static int __init cmm_init(void)
return -1;
}
+ rc = pcmcia_register_driver(&cm4000_driver);
+ if (rc < 0) {
+ unregister_chrdev(major, DEVICE_NAME);
+ return rc;
+ }
+
return 0;
}
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c
index 466e33b..744b57d 100644
--- a/drivers/char/pcmcia/cm4040_cs.c
+++ b/drivers/char/pcmcia/cm4040_cs.c
@@ -769,16 +769,19 @@ static int __init cm4040_init(void)
if (!cmx_class)
return -1;
- rc = pcmcia_register_driver(&reader_driver);
- if (rc < 0)
- return rc;
-
major = register_chrdev(0, DEVICE_NAME, &reader_fops);
if (major < 0) {
printk(KERN_WARNING MODULE_NAME
": could not get major number\n");
return -1;
}
+
+ rc = pcmcia_register_driver(&reader_driver);
+ if (rc < 0) {
+ unregister_chrdev(major, DEVICE_NAME);
+ return rc;
+ }
+
return 0;
}
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c
index 0e7d216..d22da98 100644
--- a/drivers/char/snsc.c
+++ b/drivers/char/snsc.c
@@ -391,7 +391,8 @@ scdrv_init(void)
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 --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index f8dd852..a90f5d9 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -1341,6 +1341,9 @@ static int __devinit sonypi_probe(struct
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 --git a/drivers/char/tipar.c b/drivers/char/tipar.c
index eb2eb3e..079db5a 100644
--- a/drivers/char/tipar.c
+++ b/drivers/char/tipar.c
@@ -515,7 +515,7 @@ tipar_init_module(void)
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 --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c
index 4c27218..f58ad7f 100644
--- a/drivers/char/tlclk.c
+++ b/drivers/char/tlclk.c
@@ -327,7 +327,7 @@ static ssize_t store_received_ref_clk3a(
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 @@ static ssize_t store_received_ref_clk3b(
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 @@ static ssize_t store_enable_clk3b_output
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 @@ static ssize_t store_enable_clk3a_output
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 @@ static ssize_t store_enable_clkb1_output
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 @@ static ssize_t store_enable_clka1_output
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 @@ static ssize_t store_enable_clkb0_output
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 @@ static ssize_t store_enable_clka0_output
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 @@ static ssize_t store_select_amcb2_transm
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 @@ static ssize_t store_select_amcb1_transm
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 @@ static ssize_t store_select_redundant_cl
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 @@ static ssize_t store_select_ref_frequenc
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 @@ static ssize_t store_filter_select(struc
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 @@ static ssize_t store_hardware_switching_
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 @@ static ssize_t store_hardware_switching(
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 @@ static ssize_t store_refalign (struct de
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 @@ static ssize_t store_mode_select (struct
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 @@ static ssize_t store_reset (struct devic
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 @@ static int __init tlclk_init(void)
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 --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 53d3d06..edaee70 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -2706,7 +2706,11 @@ #else
}
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 @@ #else
break;
}
}
- rcu_read_unlock();
+ spin_unlock(&p->files->file_lock);
}
task_unlock(p);
} while_each_task_pid(session, PIDTYPE_SID, p);
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index 52f3eb4..7ecdb1e 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -71,7 +71,7 @@ config EDAC_E7XXX
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 --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 8e0f315..dfca749 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -478,6 +478,11 @@ static s32 i801_access(struct i2c_adapte
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 --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c
index d3478e0..ad44dd5 100644
--- a/drivers/i2c/busses/scx200_acb.c
+++ b/drivers/i2c/busses/scx200_acb.c
@@ -440,7 +440,6 @@ static int __init scx200_acb_create(int
struct scx200_acb_iface *iface;
struct i2c_adapter *adapter;
int rc = 0;
- char description[64];
iface = kzalloc(sizeof(*iface), GFP_KERNEL);
if (!iface) {
@@ -459,8 +458,7 @@ static int __init scx200_acb_create(int
init_MUTEX(&iface->sem);
- snprintf(description, sizeof(description), "NatSemi SCx200 ACCESS.bus [%s]", adapter->name);
- if (request_region(base, 8, description) == 0) {
+ if (!request_region(base, 8, adapter->name)) {
dev_err(&adapter->dev, "can't allocate io 0x%x-0x%x\n",
base, base + 8-1);
rc = -EBUSY;
diff --git a/drivers/i2c/chips/m41t00.c b/drivers/i2c/chips/m41t00.c
index 2dc3d48..2836fb3 100644
--- a/drivers/i2c/chips/m41t00.c
+++ b/drivers/i2c/chips/m41t00.c
@@ -129,13 +129,13 @@ m41t00_set_tlet(ulong arg)
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 --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
index cf84350..8b24b4f 100644
--- a/drivers/ide/pci/alim15x3.c
+++ b/drivers/ide/pci/alim15x3.c
@@ -731,6 +731,8 @@ static unsigned int __devinit ata66_ali1
if(m5229_revision <= 0x20)
tmpbyte = (tmpbyte & (~0x02)) | 0x01;
+ else if (m5229_revision == 0xc7)
+ tmpbyte |= 0x03;
else
tmpbyte |= 0x01;
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
index b6b96fa..a9a73f7 100644
--- a/drivers/ieee1394/ohci1394.c
+++ b/drivers/ieee1394/ohci1394.c
@@ -2525,7 +2525,7 @@ static irqreturn_t ohci_irq_handler(int
if (phys_dma) {
reg_write(ohci,OHCI1394_PhyReqFilterHiSet, 0xffffffff);
reg_write(ohci,OHCI1394_PhyReqFilterLoSet, 0xffffffff);
- reg_write(ohci,OHCI1394_PhyUpperBound, 0xffff0000);
+ reg_write(ohci,OHCI1394_PhyUpperBound, 0x01000000);
} else {
reg_write(ohci,OHCI1394_PhyReqFilterHiSet, 0x00000000);
reg_write(ohci,OHCI1394_PhyReqFilterLoSet, 0x00000000);
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index eca92eb..d02be4a 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -495,22 +495,17 @@ static struct sbp2_command_info *sbp2uti
/*
* 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 @@ static void sbp2util_free_command_dma(st
/*
* 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);
}
/*
@@ -761,12 +754,17 @@ #endif
/* Register the status FIFO address range. We could use the same FIFO
* for targets at different nodes. However we need different FIFOs per
- * target in order to support multi-unit devices. */
+ * target in order to support multi-unit devices.
+ * The FIFO is located out of the local host controller's physical range
+ * but, if possible, within the posted write area. Status writes will
+ * then be performed as unified transactions. This slightly reduces
+ * bandwidth usage, and some Prolific based devices seem to require it.
+ */
scsi_id->status_fifo_addr = hpsb_allocate_and_register_addrspace(
&sbp2_highlevel, ud->ne->host, &sbp2_ops,
sizeof(struct sbp2_status_block), sizeof(quadlet_t),
- ~0ULL, ~0ULL);
- if (!scsi_id->status_fifo_addr) {
+ 0x010000000000ULL, CSR1212_ALL_SPACE_END);
+ if (scsi_id->status_fifo_addr == ~0ULL) {
SBP2_ERR("failed to allocate status FIFO address range");
goto failed_alloc;
}
@@ -2177,7 +2175,9 @@ static int sbp2_handle_status_write(stru
* 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) {
@@ -2491,9 +2491,20 @@ static int sbp2scsi_slave_alloc(struct s
static int sbp2scsi_slave_configure(struct scsi_device *sdev)
{
+ struct scsi_id_instance_data *scsi_id =
+ (struct scsi_id_instance_data *)sdev->host->hostdata[0];
+
blk_queue_dma_alignment(sdev->request_queue, (512 - 1));
sdev->use_10_for_rw = 1;
sdev->use_10_for_ms = 1;
+
+ if ((scsi_id->sbp2_firmware_revision & 0xffff00) == 0x0a2700 &&
+ (scsi_id->ud->model_id == 0x000021 /* gen.4 iPod */ ||
+ scsi_id->ud->model_id == 0x000023 /* iPod mini */ ||
+ scsi_id->ud->model_id == 0x00007e /* iPod Photo */ )) {
+ SBP2_INFO("enabling iPod workaround: decrement disk capacity");
+ sdev->fix_capacity = 1;
+ }
return 0;
}
@@ -2513,6 +2524,7 @@ static int sbp2scsi_abort(struct scsi_cm
(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 +2535,7 @@ static int sbp2scsi_abort(struct scsi_cm
* 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 +2553,7 @@ static int sbp2scsi_abort(struct scsi_cm
command->Current_done(command->Current_SCpnt);
}
}
+ spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
/*
* Initiate a fetch agent reset.
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index ad62174..b2bed1a 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -300,8 +300,10 @@ static irqreturn_t psmouse_interrupt(str
* Check if this is a new device announcement (0xAA 0x00)
*/
if (unlikely(psmouse->packet[0] == PSMOUSE_RET_BAT && psmouse->pktcnt <= 2)) {
- if (psmouse->pktcnt == 1)
+ if (psmouse->pktcnt == 1) {
+ psmouse->last = jiffies;
goto out;
+ }
if (psmouse->packet[1] == PSMOUSE_RET_ID) {
__psmouse_set_state(psmouse, PSMOUSE_IGNORE);
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index 5ebfd1d..5282fec 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -627,8 +627,8 @@ thermostat_init(void)
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 --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index f3759dd..1ed241d 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -542,8 +542,12 @@ static void snapshot_dtr(struct dm_targe
{
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 @@ static void snapshot_dtr(struct dm_targe
dm_put_device(ti, s->origin);
dm_put_device(ti, s->cow);
- kcopyd_client_destroy(s->kcopyd_client);
+
kfree(s);
}
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 745ca1f..f6c8e8e 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -533,30 +533,35 @@ static void __clone_and_map(struct clone
} 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);
+ do {
+ if (offset) {
+ ti = dm_table_find_target(ci->map, ci->sector);
+ max = max_io_len(ci->md, ci->sector, ti);
- 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);
+ 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 @@ int dm_suspend(struct mapped_device *md,
{
struct dm_table *map = NULL;
DECLARE_WAITQUEUE(wait, current);
+ struct bio *def;
int r = -EINVAL;
down(&md->suspend_lock);
@@ -1152,9 +1158,11 @@ int dm_suspend(struct mapped_device *md,
/* 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 --git a/drivers/md/kcopyd.c b/drivers/md/kcopyd.c
index 8b3515f..fc009cb 100644
--- a/drivers/md/kcopyd.c
+++ b/drivers/md/kcopyd.c
@@ -44,6 +44,9 @@ struct kcopyd_client {
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 @@ static int run_complete_job(struct kcopy
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 do_work(void *ignored)
*/
static void dispatch_job(struct kcopyd_job *job)
{
+ atomic_inc(&job->kc->nr_jobs);
push(&_pages_jobs, job);
wake();
}
@@ -670,6 +679,9 @@ int kcopyd_client_create(unsigned int nr
return r;
}
+ init_waitqueue_head(&kc->destroyq);
+ atomic_set(&kc->nr_jobs, 0);
+
client_add(kc);
*result = kc;
return 0;
@@ -677,6 +689,9 @@ int kcopyd_client_create(unsigned int nr
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 --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index ab90a6d..039ed49 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1436,9 +1436,9 @@ static void raid10d(mddev_t *mddev)
sl--;
d = r10_bio->devs[sl].devnum;
rdev = conf->mirrors[d].rdev;
- atomic_add(s, &rdev->corrected_errors);
if (rdev &&
test_bit(In_sync, &rdev->flags)) {
+ atomic_add(s, &rdev->corrected_errors);
if (sync_page_io(rdev->bdev,
r10_bio->devs[sl].addr +
sect + rdev->data_offset,
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index 162f979..356a09a 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -149,6 +149,15 @@ static int cxusb_power_ctrl(struct dvb_u
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 @@ static struct dvb_usb_properties cxusb_b
.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 @@ static struct dvb_usb_properties cxusb_b
.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 @@ static struct dvb_usb_properties cxusb_b
.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 @@ static struct dvb_usb_properties cxusb_b
.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 --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index d82c8a3..ef42a26 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -349,6 +349,7 @@ config VIDEO_AUDIO_DECODER
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 --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
index 992c717..9e4c178 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/video/saa7127.c
@@ -141,6 +141,7 @@ struct i2c_reg_value {
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 --git a/drivers/media/video/tuner-types.c b/drivers/media/video/tuner-types.c
index 6fe7817..5f3d46d 100644
--- a/drivers/media/video/tuner-types.c
+++ b/drivers/media/video/tuner-types.c
@@ -1087,8 +1087,8 @@ static struct tuner_params tuner_tnf_533
/* ------------ 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 --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 1fc4c13..cfe288a 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -178,17 +178,16 @@ config MTD_NAND_DISKONCHIP_BBTWRITE
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.
-
+
endmenu
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 84dcca3..fa29402 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -3851,6 +3851,7 @@ #endif
skb_shinfo(skb)->nr_frags++;
skb->len += length;
skb->data_len += length;
+ skb->truesize += length;
}
e1000_rx_checksum(adapter, staterr,
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index 8936058..6e2ec56 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -740,7 +740,7 @@ static void irda_usb_receive(struct urb
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 @@ static void irda_usb_receive(struct urb
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 --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 7326036..0618cd5 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -579,8 +579,8 @@ static void sky2_mac_init(struct sky2_hw
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 --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index dce955c..c91e0a4 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -1380,6 +1380,7 @@ enum {
/* 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 --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index caf4102..7d00722 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -7368,21 +7368,23 @@ static int tg3_get_settings(struct net_d
cmd->supported |= (SUPPORTED_1000baseT_Half |
SUPPORTED_1000baseT_Full);
- if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES))
+ if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)) {
cmd->supported |= (SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_MII);
- else
+ cmd->port = PORT_TP;
+ } else {
cmd->supported |= SUPPORTED_FIBRE;
+ cmd->port = PORT_FIBRE;
+ }
cmd->advertising = tp->link_config.advertising;
if (netif_running(dev)) {
cmd->speed = tp->link_config.active_speed;
cmd->duplex = tp->link_config.active_duplex;
}
- cmd->port = 0;
cmd->phy_address = PHY_ADDR;
cmd->transceiver = 0;
cmd->autoneg = tp->link_config.autoneg;
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index 2418715..56864ff 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -129,6 +129,7 @@
- Massive clean-up
- Rewrite PHY, media handling (remove options, full_duplex, backoff)
- Fix Tx engine race for good
+ - Craig Brind: Zero padded aligned buffers for short packets.
*/
@@ -1306,7 +1307,12 @@ static int rhine_start_tx(struct sk_buff
rp->stats.tx_dropped++;
return 0;
}
+
+ /* Padding is not copied and so must be redone. */
skb_copy_and_csum_dev(skb, rp->tx_buf[entry]);
+ if (skb->len < ETH_ZLEN)
+ memset(rp->tx_buf[entry] + skb->len, 0,
+ ETH_ZLEN - skb->len);
rp->tx_skbuff_dma[entry] = 0;
rp->tx_ring[entry].addr = cpu_to_le32(rp->tx_bufs_dma +
(rp->tx_buf[entry] -
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index ef85d76..8101657 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -239,7 +239,8 @@ config IPW2200_DEBUG
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_HERMES
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 PCMCIA_SPECTRUM
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 --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c
index 4a85e63..5f398bd 100644
--- a/drivers/net/wireless/hostap/hostap_80211_tx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_tx.c
@@ -469,7 +469,7 @@ int hostap_master_start_xmit(struct sk_b
}
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 --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 287676a..f42e51a 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -8391,20 +8391,28 @@ static int ipw_wx_get_range(struct net_d
i = 0;
if (priv->ieee->mode & (IEEE_B | IEEE_G)) {
- for (j = 0; j < geo->bg_channels && i < IW_MAX_FREQUENCIES;
- i++, j++) {
+ for (j = 0; j < geo->bg_channels && i < IW_MAX_FREQUENCIES; j++) {
+ if ((priv->ieee->iw_mode == IW_MODE_ADHOC) &&
+ (geo->bg[j].flags & IEEE80211_CH_PASSIVE_ONLY))
+ continue;
+
range->freq[i].i = geo->bg[j].channel;
range->freq[i].m = geo->bg[j].freq * 100000;
range->freq[i].e = 1;
+ i++;
}
}
if (priv->ieee->mode & IEEE_A) {
- for (j = 0; j < geo->a_channels && i < IW_MAX_FREQUENCIES;
- i++, j++) {
+ for (j = 0; j < geo->a_channels && i < IW_MAX_FREQUENCIES; j++) {
+ if ((priv->ieee->iw_mode == IW_MODE_ADHOC) &&
+ (geo->a[j].flags & IEEE80211_CH_PASSIVE_ONLY))
+ continue;
+
range->freq[i].i = geo->a[j].channel;
range->freq[i].m = geo->a[j].freq * 100000;
range->freq[i].e = 1;
+ i++;
}
}
@@ -9956,9 +9964,8 @@ static int ipw_ethtool_set_eeprom(struct
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 --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 6917c6c..c2ecae5 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -33,13 +33,10 @@ acpi_query_osc (
acpi_status status;
struct acpi_object_list input;
union acpi_object in_params[4];
- struct acpi_buffer output;
- union acpi_object out_obj;
+ struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
+ union acpi_object *out_obj;
u32 osc_dw0;
- /* Setting up output buffer */
- output.length = sizeof(out_obj) + 3*sizeof(u32);
- output.pointer = &out_obj;
/* Setting up input parameters */
input.count = 4;
@@ -61,12 +58,15 @@ acpi_query_osc (
"Evaluate _OSC Set fails. Status = 0x%04x\n", status);
return status;
}
- if (out_obj.type != ACPI_TYPE_BUFFER) {
+ out_obj = output.pointer;
+
+ if (out_obj->type != ACPI_TYPE_BUFFER) {
printk(KERN_DEBUG
"Evaluate _OSC returns wrong type\n");
- return AE_TYPE;
+ status = AE_TYPE;
+ goto query_osc_out;
}
- osc_dw0 = *((u32 *) out_obj.buffer.pointer);
+ osc_dw0 = *((u32 *) out_obj->buffer.pointer);
if (osc_dw0) {
if (osc_dw0 & OSC_REQUEST_ERROR)
printk(KERN_DEBUG "_OSC request fails\n");
@@ -76,15 +76,21 @@ acpi_query_osc (
printk(KERN_DEBUG "_OSC invalid revision\n");
if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) {
/* Update Global Control Set */
- global_ctrlsets = *((u32 *)(out_obj.buffer.pointer+8));
- return AE_OK;
+ global_ctrlsets = *((u32 *)(out_obj->buffer.pointer+8));
+ status = AE_OK;
+ goto query_osc_out;
}
- return AE_ERROR;
+ status = AE_ERROR;
+ goto query_osc_out;
}
/* Update Global Control Set */
- global_ctrlsets = *((u32 *)(out_obj.buffer.pointer + 8));
- return AE_OK;
+ global_ctrlsets = *((u32 *)(out_obj->buffer.pointer + 8));
+ status = AE_OK;
+
+query_osc_out:
+ kfree(output.pointer);
+ return status;
}
@@ -96,14 +102,10 @@ acpi_run_osc (
acpi_status status;
struct acpi_object_list input;
union acpi_object in_params[4];
- struct acpi_buffer output;
- union acpi_object out_obj;
+ struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
+ union acpi_object *out_obj;
u32 osc_dw0;
- /* Setting up output buffer */
- output.length = sizeof(out_obj) + 3*sizeof(u32);
- output.pointer = &out_obj;
-
/* Setting up input parameters */
input.count = 4;
input.pointer = in_params;
@@ -124,12 +126,14 @@ acpi_run_osc (
"Evaluate _OSC Set fails. Status = 0x%04x\n", status);
return status;
}
- if (out_obj.type != ACPI_TYPE_BUFFER) {
+ out_obj = output.pointer;
+ if (out_obj->type != ACPI_TYPE_BUFFER) {
printk(KERN_DEBUG
"Evaluate _OSC returns wrong type\n");
- return AE_TYPE;
+ status = AE_TYPE;
+ goto run_osc_out;
}
- osc_dw0 = *((u32 *) out_obj.buffer.pointer);
+ osc_dw0 = *((u32 *) out_obj->buffer.pointer);
if (osc_dw0) {
if (osc_dw0 & OSC_REQUEST_ERROR)
printk(KERN_DEBUG "_OSC request fails\n");
@@ -139,11 +143,17 @@ acpi_run_osc (
printk(KERN_DEBUG "_OSC invalid revision\n");
if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) {
printk(KERN_DEBUG "_OSC FW not grant req. control\n");
- return AE_SUPPORT;
+ status = AE_SUPPORT;
+ goto run_osc_out;
}
- return AE_ERROR;
+ status = AE_ERROR;
+ goto run_osc_out;
}
- return AE_OK;
+ status = AE_OK;
+
+run_osc_out:
+ kfree(output.pointer);
+ return status;
}
/**
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index dda6099..381f36b 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -631,6 +631,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_V
* non-x86 architectures (yes Via exists on PPC among other places),
* we must mask the PCI_INTERRUPT_LINE value versus 0xf to get
* interrupts delivered properly.
+ *
+ * Some of the on-chip devices are actually '586 devices' so they are
+ * listed here.
*/
static void quirk_via_irq(struct pci_dev *dev)
{
@@ -639,13 +642,19 @@ static void quirk_via_irq(struct pci_dev
new_irq = dev->irq & 0xf;
pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
if (new_irq != irq) {
- printk(KERN_INFO "PCI: Via IRQ fixup for %s, from %d to %d\n",
+ printk(KERN_INFO "PCI: VIA IRQ fixup for %s, from %d to %d\n",
pci_name(dev), irq, new_irq);
udelay(15); /* unknown if delay really needed */
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq);
}
}
-DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq);
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, quirk_via_irq);
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, quirk_via_irq);
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, quirk_via_irq);
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_irq);
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_irq);
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_irq);
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, quirk_via_irq);
/*
* VIA VT82C598 has its device ID settable and many BIOSes
@@ -861,6 +870,7 @@ static void __init quirk_eisa_bridge(str
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375, quirk_eisa_bridge );
+#ifndef CONFIG_ACPI_SLEEP
/*
* On ASUS P4B boards, the SMBus PCI Device within the ICH2/4 southbridge
* is not activated. The myth is that Asus said that they do not want the
@@ -872,8 +882,12 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I
* bridge. Unfortunately, this device has no subvendor/subdevice ID. So it
* becomes necessary to do this tweak in two steps -- I've chosen the Host
* bridge as trigger.
+ *
+ * Actually, leaving it unhidden and not redoing the quirk over suspend2ram
+ * will cause thermal management to break down, and causing machine to
+ * overheat.
*/
-static int __initdata asus_hides_smbus = 0;
+static int __initdata asus_hides_smbus;
static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
{
@@ -1008,6 +1022,8 @@ static void __init asus_hides_smbus_lpc_
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6 );
+#endif
+
/*
* SiS 96x south bridge: BIOS typically hides SMBus device...
*/
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index bb96ce1..a4333a8 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -546,7 +546,7 @@ static int pcmcia_device_query(struct pc
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 --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index d9152d0..9132549 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -85,7 +85,7 @@ #include <scsi/scsi_cmnd.h>
#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 @@ static void twa_scsiop_execute_scsi_comp
}
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 --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index 25f678d..e8e41e6 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -1508,10 +1508,12 @@ static void tw_transfer_internal(TW_Devi
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 @@ static void tw_transfer_internal(TW_Devi
sg = (struct scatterlist *)cmd->request_buffer;
kunmap_atomic(buf - sg->offset, KM_IRQ0);
+ local_irq_restore(flags);
}
}
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 4f91b0d..400e9d7 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -4293,6 +4293,7 @@ static int ata_start_drive(struct ata_po
int ata_device_resume(struct ata_port *ap, struct ata_device *dev)
{
if (ap->flags & ATA_FLAG_SUSPENDED) {
+ ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 200000);
ap->flags &= ~ATA_FLAG_SUSPENDED;
ata_set_mode(ap);
}
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index 2770005..b00af08 100644
--- a/drivers/scsi/sata_mv.c
+++ b/drivers/scsi/sata_mv.c
@@ -1102,6 +1102,7 @@ static u8 mv_get_crpb_status(struct ata_
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 @@ static u8 mv_get_crpb_status(struct ata_
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 @@ static u8 mv_get_crpb_status(struct ata_
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 @@ static void mv_host_intr(struct ata_host
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 @@ static void mv_host_intr(struct ata_host
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 --git a/drivers/sn/ioc3.c b/drivers/sn/ioc3.c
index 93449a1..4bd05a0 100644
--- a/drivers/sn/ioc3.c
+++ b/drivers/sn/ioc3.c
@@ -677,7 +677,7 @@ #endif
/* Track PCI-device specific data */
pci_set_drvdata(pdev, idd);
down_write(&ioc3_devices_rwsem);
- list_add(&idd->list, &ioc3_devices);
+ list_add_tail(&idd->list, &ioc3_devices);
idd->id = ioc3_counter++;
up_write(&ioc3_devices_rwsem);
diff --git a/drivers/sn/ioc4.c b/drivers/sn/ioc4.c
index ea75b3d..771e868 100644
--- a/drivers/sn/ioc4.c
+++ b/drivers/sn/ioc4.c
@@ -313,7 +313,7 @@ ioc4_probe(struct pci_dev *pdev, const s
idd->idd_serial_data = NULL;
pci_set_drvdata(idd->idd_pdev, idd);
down_write(&ioc4_devices_rwsem);
- list_add(&idd->idd_list, &ioc4_devices);
+ list_add_tail(&idd->idd_list, &ioc4_devices);
up_write(&ioc4_devices_rwsem);
/* Add this IOC4 to all submodules */
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 7135e54..96cabeb 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1388,11 +1388,13 @@ free_interfaces:
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 --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index ebcca97..88419c6 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -707,6 +707,7 @@ iso_stream_init (
} else {
u32 addr;
int think_time;
+ int hs_transfers;
addr = dev->ttport << 24;
if (!ehci_is_TDI(ehci)
@@ -719,6 +720,7 @@ iso_stream_init (
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 @@ iso_stream_init (
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 --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c
index 167f8ec..8023bb7 100644
--- a/drivers/usb/serial/console.c
+++ b/drivers/usb/serial/console.c
@@ -54,7 +54,7 @@ static struct console usbcons;
* 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 --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 52bdf6f..fd8a50e 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -582,14 +582,14 @@ static void option_setup_urbs(struct usb
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 --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig
index 92be101..be9eec2 100644
--- a/drivers/usb/storage/Kconfig
+++ b/drivers/usb/storage/Kconfig
@@ -48,7 +48,8 @@ config USB_STORAGE_FREECOM
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 --git a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c
index 910e233..8ba6152 100644
--- a/drivers/video/cfbimgblt.c
+++ b/drivers/video/cfbimgblt.c
@@ -169,7 +169,7 @@ static inline void slow_imageblit(const
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 --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 996c7b5..b3094ae 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -669,13 +669,19 @@ fb_write(struct file *file, const char _
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 @@ fb_write(struct file *file, const char _
kfree(buffer);
- return (err) ? err : cnt;
+ return (cnt) ? cnt : err;
}
#ifdef CONFIG_KMOD
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
index d8467c0..788297e 100644
--- a/drivers/video/i810/i810_main.c
+++ b/drivers/video/i810/i810_main.c
@@ -1508,7 +1508,7 @@ static int i810fb_cursor(struct fb_info
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 --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 3ad8455..651a9e1 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -614,6 +614,7 @@ static struct dentry *v9fs_vfs_lookup(st
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 @@ static struct dentry *v9fs_vfs_lookup(st
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 --git a/fs/char_dev.c b/fs/char_dev.c
index 21195c4..4e163af 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -15,6 +15,7 @@ #include <linux/errno.h>
#include <linux/module.h>
#include <linux/smp_lock.h>
#include <linux/devfs_fs_kernel.h>
+#include <linux/seq_file.h>
#include <linux/kobject.h>
#include <linux/kobj_map.h>
@@ -26,8 +27,6 @@ #endif
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 @@ static struct char_device_struct {
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 --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index a2c2485..3f5e38c 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -56,9 +56,6 @@ int cifs_sign_smb(struct smb_hdr * cifs_
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 @@ int cifs_sign_smb(struct smb_hdr * cifs_
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;i<n_vec;i++) {
+ if(iov[i].iov_base == NULL) {
+ cERROR(1,("null iovec entry"));
+ return -EIO;
+ } else if(iov[i].iov_len == 0)
+ break; /* bail out if we are sent nothing to sign */
+ /* The first entry includes a length field (which does not get
+ signed that occupies the first 4 bytes before the header */
+ if(i==0) {
+ if (iov[0].iov_len <= 8 ) /* cmd field at offset 9 */
+ break; /* nothing to sign or corrupt header */
+ MD5Update(&context,iov[0].iov_base+4, iov[0].iov_len-4);
+ } else
+ MD5Update(&context,iov[i].iov_base, iov[i].iov_len);
+ }
- MD5Final(signature,&context);
+ MD5Final(signature,&context);
- return -EOPNOTSUPP;
-/* return 0; */
+ return 0;
}
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index fed55e3..5e562bc 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -441,6 +441,20 @@ cifs_lookup(struct inode *parent_dir_ino
cifs_sb = CIFS_SB(parent_dir_inode->i_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 --git a/fs/compat.c b/fs/compat.c
index 5333c7d..8491bb8 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1215,6 +1215,10 @@ static ssize_t compat_do_readv_writev(in
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;
@@ -1897,7 +1901,7 @@ asmlinkage long compat_sys_ppoll(struct
}
if (sigmask) {
- if (sigsetsize |= sizeof(compat_sigset_t))
+ if (sigsetsize != sizeof(compat_sigset_t))
return -EINVAL;
if (copy_from_user(&ss32, sigmask, sizeof(ss32)))
return -EFAULT;
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c
index 1041dab..14f5f6e 100644
--- a/fs/ext3/resize.c
+++ b/fs/ext3/resize.c
@@ -974,6 +974,7 @@ int ext3_group_extend(struct super_block
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 --git a/fs/fuse/file.c b/fs/fuse/file.c
index 6f05379..ce93cf9 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -397,8 +397,12 @@ static int fuse_readpages(struct file *f
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 --git a/fs/locks.c b/fs/locks.c
index 909eab8..39b038b 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -432,15 +432,14 @@ static struct lock_manager_operations le
*/
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_init(struct file *filp,
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.
@@ -712,8 +714,9 @@ EXPORT_SYMBOL(posix_locks_deadlock);
* at the head of the list, but that's secret knowledge known only to
* flock_lock_file and posix_lock_file.
*/
-static int flock_lock_file(struct file *filp, struct file_lock *new_fl)
+static int flock_lock_file(struct file *filp, struct file_lock *request)
{
+ struct file_lock *new_fl = NULL;
struct file_lock **before;
struct inode * inode = filp->f_dentry->d_inode;
int error = 0;
@@ -728,17 +731,19 @@ static int flock_lock_file(struct file *
continue;
if (filp != fl->fl_file)
continue;
- if (new_fl->fl_type == fl->fl_type)
+ if (request->fl_type == fl->fl_type)
goto out;
found = 1;
locks_delete_lock(before);
break;
}
- unlock_kernel();
- if (new_fl->fl_type == F_UNLCK)
- return 0;
+ if (request->fl_type == F_UNLCK)
+ goto out;
+ new_fl = locks_alloc_lock();
+ if (new_fl == NULL)
+ goto out;
/*
* If a higher-priority process was blocked on the old file lock,
* give it the opportunity to lock the file.
@@ -746,26 +751,27 @@ static int flock_lock_file(struct file *
if (found)
cond_resched();
- lock_kernel();
for_each_lock(inode, before) {
struct file_lock *fl = *before;
if (IS_POSIX(fl))
break;
if (IS_LEASE(fl))
continue;
- if (!flock_locks_conflict(new_fl, fl))
+ if (!flock_locks_conflict(request, fl))
continue;
error = -EAGAIN;
- if (new_fl->fl_flags & FL_SLEEP) {
- locks_insert_block(fl, new_fl);
- }
+ if (request->fl_flags & FL_SLEEP)
+ locks_insert_block(fl, request);
goto out;
}
+ locks_copy_lock(new_fl, request);
locks_insert_lock(&inode->i_flock, new_fl);
- error = 0;
+ new_fl = NULL;
out:
unlock_kernel();
+ if (new_fl)
+ locks_free_lock(new_fl);
return error;
}
@@ -1337,6 +1343,7 @@ static int __setlease(struct file *filp,
goto out;
if (my_before != NULL) {
+ *flp = *my_before;
error = lease->fl_lmops->fl_change(my_before, arg);
goto out;
}
@@ -1529,9 +1536,7 @@ asmlinkage long sys_flock(unsigned int f
error = flock_lock_file_wait(filp, lock);
out_free:
- if (list_empty(&lock->fl_link)) {
- locks_free_lock(lock);
- }
+ locks_free_lock(lock);
out_putf:
fput(filp);
@@ -2212,7 +2217,12 @@ void steal_locks(fl_owner_t from)
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 +2240,7 @@ void steal_locks(fl_owner_t from)
set >>= 1;
}
}
- rcu_read_unlock();
+ spin_unlock(&files->file_lock);
unlock_kernel();
}
EXPORT_SYMBOL(steal_locks);
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 6d2dfed..f61142a 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -682,7 +682,7 @@ static struct svc_procedure nfsd_proced
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 --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 6d63f1d..ca8a4c4 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -975,7 +975,7 @@ #define PROC(name, argt, rest, relt, cac
*/
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 --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index 3e6b75c..06cd0db 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -553,7 +553,7 @@ static struct svc_procedure nfsd_proced
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 --git a/fs/open.c b/fs/open.c
index 70e0230..f697914 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -330,7 +330,10 @@ out:
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_truncate64(const cha
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 @@ long do_sys_open(int dfd, const char __u
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 --git a/fs/partitions/check.c b/fs/partitions/check.c
index f924f45..2ef03aa 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -345,6 +345,7 @@ static char *make_block_name(struct gend
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 @@ static char *make_block_name(struct gend
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 --git a/fs/proc/base.c b/fs/proc/base.c
index 20feb75..c192cb2 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -294,16 +294,20 @@ static int proc_fd_link(struct inode *in
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 @@ static struct dentry *proc_lookupfd(stru
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 @@ static struct dentry *proc_lookupfd(stru
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 @@ static struct dentry *proc_lookupfd(stru
return NULL;
out_unlock2:
- rcu_read_unlock();
+ spin_unlock(&files->file_lock);
put_files_struct(files);
out_unlock:
iput(inode);
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index 1d24fea..0c78312 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -249,144 +249,60 @@ static int cpuinfo_open(struct inode *in
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)
-{
- 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;
+static void devinfo_stop(struct seq_file *f, void *v)
+{
+ /* 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 @@ static struct file_operations proc_devin
.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 --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
index 4063fb3..164a7d0 100644
--- a/fs/proc/vmcore.c
+++ b/fs/proc/vmcore.c
@@ -103,8 +103,8 @@ static ssize_t read_vmcore(struct file *
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 --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c
index ab8894c..9df778a 100644
--- a/fs/reiserfs/xattr_acl.c
+++ b/fs/reiserfs/xattr_acl.c
@@ -408,8 +408,9 @@ int reiserfs_cache_default_acl(struct in
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 --git a/fs/smbfs/dir.c b/fs/smbfs/dir.c
index 0424d06..45862ec 100644
--- a/fs/smbfs/dir.c
+++ b/fs/smbfs/dir.c
@@ -434,6 +434,11 @@ smb_lookup(struct inode *dir, struct den
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 --git a/fs/smbfs/request.c b/fs/smbfs/request.c
index c71c375..c71dd27 100644
--- a/fs/smbfs/request.c
+++ b/fs/smbfs/request.c
@@ -339,9 +339,11 @@ #endif
/*
* On timeout or on interrupt we want to try and remove the
* request from the recvq/xmitq.
+ * First check if the request is still part of a queue. (May
+ * have been removed by some error condition)
*/
smb_lock_server(server);
- if (!(req->rq_flags & SMB_REQ_RECEIVED)) {
+ if (!list_empty(&req->rq_queue)) {
list_del_init(&req->rq_queue);
smb_rput(req);
}
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 49bd219..cfd290d 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -302,6 +302,7 @@ void sysfs_remove_dir(struct kobject * k
* Drop reference from dget() on entrance.
*/
dput(dentry);
+ kobj->dentry = NULL;
}
int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index d0e3d84..2ecc58c 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -183,7 +183,7 @@ fill_write_buffer(struct sysfs_buffer *
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 --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 689f7bc..6beee6f 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -227,12 +227,16 @@ void sysfs_drop_dentry(struct sysfs_dire
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 --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index e38d633..e5ce6e7 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -66,6 +66,7 @@ static int sysfs_add_link(struct dentry
if (!error)
return 0;
+ kobject_put(target);
kfree(sl->link_name);
exit2:
kfree(sl);
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 74d8be8..a980736 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -616,7 +616,7 @@ xfs_is_delayed_page(
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 --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index d7f6f2d..43808e2 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -673,8 +673,7 @@ linvfs_setattr(
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 --git a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h
index c4ec2a4..9d15eec 100644
--- a/include/asm-i386/cpufeature.h
+++ b/include/asm-i386/cpufeature.h
@@ -70,6 +70,7 @@ #define X86_FEATURE_K7 (3*32+ 5) /* Ath
#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 --git a/include/asm-i386/i387.h b/include/asm-i386/i387.h
index 152d0ba..bc1d6ed 100644
--- a/include/asm-i386/i387.h
+++ b/include/asm-i386/i387.h
@@ -13,6 +13,7 @@ #define __ASM_I386_I387_H
#include <linux/sched.h>
#include <linux/init.h>
+#include <linux/kernel_stat.h>
#include <asm/processor.h>
#include <asm/sigcontext.h>
#include <asm/user.h>
@@ -38,17 +39,38 @@ #define restore_fpu(tsk) \
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 --git a/include/asm-i386/pgtable-2level.h b/include/asm-i386/pgtable-2level.h
index 74ef721..d76c61d 100644
--- a/include/asm-i386/pgtable-2level.h
+++ b/include/asm-i386/pgtable-2level.h
@@ -18,6 +18,9 @@ #define set_pte_at(mm,addr,ptep,pteval)
#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 --git a/include/asm-i386/pgtable-3level.h b/include/asm-i386/pgtable-3level.h
index f1a8b45..3dda0f6 100644
--- a/include/asm-i386/pgtable-3level.h
+++ b/include/asm-i386/pgtable-3level.h
@@ -85,6 +85,26 @@ ((unsigned long) __va(pud_val(pud) & PAG
#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 --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h
index 088a945..6313403 100644
--- a/include/asm-i386/pgtable.h
+++ b/include/asm-i386/pgtable.h
@@ -204,12 +204,10 @@ #undef TEST_ACCESS_OK
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 @@ static inline pte_t ptep_get_and_clear_f
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 --git a/include/asm-m32r/smp.h b/include/asm-m32r/smp.h
index 7885b7d..1184293 100644
--- a/include/asm-m32r/smp.h
+++ b/include/asm-m32r/smp.h
@@ -67,7 +67,8 @@ #define cpu_to_physid(cpu_id) cpu_2_phys
#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 --git a/include/asm-m32r/uaccess.h b/include/asm-m32r/uaccess.h
index e8ae619..819cc28 100644
--- a/include/asm-m32r/uaccess.h
+++ b/include/asm-m32r/uaccess.h
@@ -5,17 +5,9 @@ #define _ASM_M32R_UACCESS_H
* linux/include/asm-m32r/uaccess.h
*
* M32R version.
- * Copyright (C) 2004 Hirokazu Takata <takata at linux-m32r.org>
+ * Copyright (C) 2004, 2006 Hirokazu Takata <takata at linux-m32r.org>
*/
-#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 VERIFY_WRITE 1
#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 @@ #define __range_ok(addr,size) ({ \
" 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 @@ #define access_ok(type,addr,size) (likel
#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 @@ extern int fixup_exception(struct pt_reg
* 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 @@ #endif
* 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 @@ extern void __put_user_bad(void);
* 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 @@ #define put_user(x,ptr) \
* 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 @@ #define __get_user(x,ptr) \
* 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 @@ #define __put_user_u64(x, addr, err)
" .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 @@ #define __put_user_asm(x, addr, err, ity
" .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 @@ #define __get_user_asm(x, addr, err, ity
* anything, so this is accurate.
*/
-
/*
* Copy To/From Userspace
*/
@@ -511,8 +473,9 @@ do { \
" .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 @@ do { \
" .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) \
#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 --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h
index 8e80205..849155a 100644
--- a/include/asm-mips/bitops.h
+++ b/include/asm-mips/bitops.h
@@ -654,7 +654,12 @@ static inline unsigned long fls(unsigned
{
#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 @@ #endif /* CONFIG_32BIT */
#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 --git a/include/asm-mips/byteorder.h b/include/asm-mips/byteorder.h
index 584f812..4ce5bc3 100644
--- a/include/asm-mips/byteorder.h
+++ b/include/asm-mips/byteorder.h
@@ -19,7 +19,9 @@ #ifdef CONFIG_CPU_MIPSR2
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 @@ #define __arch__swab16(x) ___arch__swab1
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 --git a/include/asm-mips/interrupt.h b/include/asm-mips/interrupt.h
index 7743487..50baf6b 100644
--- a/include/asm-mips/interrupt.h
+++ b/include/asm-mips/interrupt.h
@@ -20,7 +20,9 @@ __asm__ (
" .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 @@ __asm__ (
" .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 @@ __asm__ (
" .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 @@ #if defined(CONFIG_CPU_MIPSR2) && define
* 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 --git a/include/asm-mips/r4kcache.h b/include/asm-mips/r4kcache.h
index 0bcb79a..d9ee097 100644
--- a/include/asm-mips/r4kcache.h
+++ b/include/asm-mips/r4kcache.h
@@ -37,7 +37,7 @@ #define cache_op(op,addr) \
" 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 --git a/include/asm-powerpc/floppy.h b/include/asm-powerpc/floppy.h
index e258778..608164c 100644
--- a/include/asm-powerpc/floppy.h
+++ b/include/asm-powerpc/floppy.h
@@ -35,6 +35,7 @@ #define fd_free_irq() free_irq
#ifdef CONFIG_PCI
#include <linux/pci.h>
+#include <asm/ppc-pci.h> /* for ppc64_isabridge_dev */
#define fd_dma_setup(addr,size,mode,io) powerpc_fd_dma_setup(addr,size,mode,io)
@@ -52,12 +53,12 @@ static __inline__ int powerpc_fd_dma_set
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 --git a/include/asm-x86_64/cpufeature.h b/include/asm-x86_64/cpufeature.h
index 76bb619..662964b 100644
--- a/include/asm-x86_64/cpufeature.h
+++ b/include/asm-x86_64/cpufeature.h
@@ -64,6 +64,7 @@ #define X86_FEATURE_CENTAUR_MCR (3*32+ 3
#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 --git a/include/asm-x86_64/i387.h b/include/asm-x86_64/i387.h
index 876eb9a..cba8a3b 100644
--- a/include/asm-x86_64/i387.h
+++ b/include/asm-x86_64/i387.h
@@ -72,6 +72,23 @@ #define set_fpu_cwd(t,val) ((t)->thread.
#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 @@ #else
#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 @@ #else
"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 --git a/include/linux/cpu.h b/include/linux/cpu.h
index 0ed1d48..d612b89 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -32,7 +32,7 @@ struct cpu {
};
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 --git a/include/linux/cpumask.h b/include/linux/cpumask.h
index 60e56c6..a47ad70 100644
--- a/include/linux/cpumask.h
+++ b/include/linux/cpumask.h
@@ -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 --git a/include/linux/fb.h b/include/linux/fb.h
index 2cb19e6..2fdd8ae 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -839,12 +839,10 @@ #if defined (__BIG_ENDIAN)
#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 --git a/include/linux/fs.h b/include/linux/fs.h
index 128d008..872042f 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1383,6 +1383,7 @@ extern int bd_claim(struct block_device
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 register_chrdev(unsigned int,
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 --git a/include/linux/mm.h b/include/linux/mm.h
index 498ff87..279446e 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -229,10 +229,9 @@ struct page {
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 --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index d52999c..d7ce72e 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -74,7 +74,9 @@ #define PG_swapcache 15 /* Swap page: s
#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 PageNosaveFree(page) test_bit(PG
#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 --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index aa6322d..6c1e347 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -78,7 +78,7 @@ struct kcore_list {
struct vmcore {
struct list_head list;
unsigned long long paddr;
- unsigned long size;
+ unsigned long long size;
loff_t offset;
};
diff --git a/include/linux/raid/raid1.h b/include/linux/raid/raid1.h
index 9d5494a..3009c81 100644
--- a/include/linux/raid/raid1.h
+++ b/include/linux/raid/raid1.h
@@ -130,6 +130,6 @@ #define R1BIO_BarrierRetry 5
* 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 --git a/include/linux/rtc.h b/include/linux/rtc.h
index 0b2ba67..b739ac1 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -11,8 +11,6 @@
#ifndef _LINUX_RTC_H_
#define _LINUX_RTC_H_
-#include <linux/interrupt.h>
-
/*
* The struct used to pass data via the following ioctl. Similar to the
* struct tm in <time.h>, but it needs to be here so that the kernel
@@ -95,6 +93,8 @@ #define RTC_PLL_SET _IOW('p', 0x12, stru
#ifdef __KERNEL__
+#include <linux/interrupt.h>
+
typedef struct rtc_task {
void (*func)(void *private_data);
void *private_data;
diff --git a/include/net/ip.h b/include/net/ip.h
index fab3d5b..ed84d04 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -95,6 +95,7 @@ extern int ip_local_deliver(struct sk_b
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 --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index e673b2c..aa6033c 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -461,12 +461,12 @@ static inline int sctp_frag_point(const
* there is room for a param header too.
*/
#define sctp_walk_params(pos, chunk, member)\
-_sctp_walk_params((pos), (chunk), WORD_ROUND(ntohs((chunk)->chunk_hdr.length)), member)
+_sctp_walk_params((pos), (chunk), ntohs((chunk)->chunk_hdr.length), member)
#define _sctp_walk_params(pos, chunk, end, member)\
for (pos.v = chunk->member;\
pos.v <= (void *)chunk + end - sizeof(sctp_paramhdr_t) &&\
- pos.v <= (void *)chunk + end - WORD_ROUND(ntohs(pos.p->length)) &&\
+ pos.v <= (void *)chunk + end - ntohs(pos.p->length) &&\
ntohs(pos.p->length) >= sizeof(sctp_paramhdr_t);\
pos.v += WORD_ROUND(ntohs(pos.p->length)))
@@ -477,7 +477,7 @@ #define _sctp_walk_errors(err, chunk_hdr
for (err = (sctp_errhdr_t *)((void *)chunk_hdr + \
sizeof(sctp_chunkhdr_t));\
(void *)err <= (void *)chunk_hdr + end - sizeof(sctp_errhdr_t) &&\
- (void *)err <= (void *)chunk_hdr + end - WORD_ROUND(ntohs(err->length)) &&\
+ (void *)err <= (void *)chunk_hdr + end - ntohs(err->length) &&\
ntohs(err->length) >= sizeof(sctp_errhdr_t); \
err = (sctp_errhdr_t *)((void *)err + WORD_ROUND(ntohs(err->length))))
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 072f407..acb2ce1 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -702,6 +702,7 @@ struct sctp_chunk {
__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 --git a/ipc/shm.c b/ipc/shm.c
index 9162123..f409726 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -161,6 +161,8 @@ static int shm_mmap(struct file * file,
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 --git a/ipc/util.c b/ipc/util.c
index 8626219..303b058 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -182,8 +182,7 @@ static int grow_ary(struct ipc_ids* ids,
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;i<newsize;i++) {
new->p[i] = NULL;
}
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index d7e7e63..cfaa4a2 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -966,11 +966,6 @@ void audit_syscall_entry(struct task_str
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 --git a/kernel/exec_domain.c b/kernel/exec_domain.c
index 867d6db..c01cead 100644
--- a/kernel/exec_domain.c
+++ b/kernel/exec_domain.c
@@ -140,6 +140,7 @@ __set_personality(u_long personality)
ep = lookup_exec_domain(personality);
if (ep == current_thread_info()->exec_domain) {
current->personality = personality;
+ module_put(ep->module);
return 0;
}
diff --git a/kernel/fork.c b/kernel/fork.c
index b373322..9d4e0d8 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -720,7 +720,7 @@ out_release:
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 --git a/kernel/power/process.c b/kernel/power/process.c
index 28de118..67b2cdd 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -25,8 +25,7 @@ static inline int freezeable(struct task
(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 --git a/kernel/ptrace.c b/kernel/ptrace.c
index d95a72c..48453c3 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -57,10 +57,6 @@ void ptrace_untrace(task_t *child)
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 @@ void __ptrace_unlink(task_t *child)
SET_LINKS(child);
}
- ptrace_untrace(child);
+ if (child->state == TASK_TRACED)
+ ptrace_untrace(child);
}
/*
@@ -152,12 +149,34 @@ int ptrace_may_attach(struct task_struct
int ptrace_attach(struct task_struct *task)
{
int retval;
- task_lock(task);
+
retval = -EPERM;
if (task->pid <= 1)
- goto bad;
+ goto out;
if (task->tgid == current->tgid)
- goto bad;
+ goto out;
+
+repeat:
+ /*
+ * Nasty, nasty.
+ *
+ * We want to hold both the task-lock and the
+ * tasklist_lock for writing at the same time.
+ * But that's against the rules (tasklist_lock
+ * is taken for reading by interrupts on other
+ * cpu's that may have task_lock).
+ */
+ task_lock(task);
+ local_irq_disable();
+ if (!write_trylock(&tasklist_lock)) {
+ local_irq_enable();
+ task_unlock(task);
+ do {
+ cpu_relax();
+ } while (!write_can_lock(&tasklist_lock));
+ goto repeat;
+ }
+
/* the same process cannot be attached many times */
if (task->ptrace & PT_PTRACED)
goto bad;
@@ -170,17 +189,15 @@ int ptrace_attach(struct task_struct *ta
? PT_ATTACHED : 0);
if (capable(CAP_SYS_PTRACE))
task->ptrace |= PT_PTRACE_CAP;
- task_unlock(task);
- write_lock_irq(&tasklist_lock);
__ptrace_link(task, current);
- write_unlock_irq(&tasklist_lock);
force_sig_specific(SIGSTOP, task);
- return 0;
bad:
+ write_unlock_irq(&tasklist_lock);
task_unlock(task);
+out:
return retval;
}
@@ -421,21 +438,22 @@ #endif
*/
int ptrace_traceme(void)
{
- int ret;
+ int ret = -EPERM;
/*
* Are we already being traced?
*/
- if (current->ptrace & PT_PTRACED)
- return -EPERM;
- ret = security_ptrace(current->parent, current);
- if (ret)
- return -EPERM;
- /*
- * Set the ptrace bit in the process ptrace flags.
- */
- current->ptrace |= PT_PTRACED;
- return 0;
+ task_lock(current);
+ if (!(current->ptrace & PT_PTRACED)) {
+ ret = security_ptrace(current->parent, current);
+ /*
+ * Set the ptrace bit in the process ptrace flags.
+ */
+ if (!ret)
+ current->ptrace |= PT_PTRACED;
+ }
+ task_unlock(current);
+ return ret;
}
/**
diff --git a/kernel/sched.c b/kernel/sched.c
index 4d46e90..4e7efac 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -237,6 +237,7 @@ #ifdef CONFIG_SMP
task_t *migration_thread;
struct list_head migration_queue;
+ int cpu;
#endif
#ifdef CONFIG_SCHEDSTATS
@@ -1660,6 +1661,9 @@ #ifdef CONFIG_SMP
/*
* 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 @@ static void double_rq_lock(runqueue_t *r
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 @@ static void double_lock_balance(runqueue
__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 @@ #ifdef CONFIG_SMP
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 --git a/kernel/signal.c b/kernel/signal.c
index ea15410..acbccf7 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -975,7 +975,6 @@ __group_complete_signal(int sig, struct
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 @@ static void ptrace_stop(int exit_code, i
/* Let the debugger run. */
set_current_state(TASK_TRACED);
spin_unlock_irq(&current->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 @@ relock:
/* 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 --git a/kernel/sys.c b/kernel/sys.c
index f91218a..105e102 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1657,7 +1657,19 @@ asmlinkage long sys_setrlimit(unsigned i
(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(&current->sighand->siglock);
set_process_cpu_timer(current, CPUCLOCK_PROF,
diff --git a/kernel/uid16.c b/kernel/uid16.c
index aa25605..187e2a4 100644
--- a/kernel/uid16.c
+++ b/kernel/uid16.c
@@ -20,43 +20,67 @@ #include <asm/uaccess.h>
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_getresuid16(old_uid_
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_getresgid16(old_gid_
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 --git a/mm/madvise.c b/mm/madvise.c
index af3d573..4e19615 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -168,6 +168,9 @@ static long madvise_remove(struct vm_are
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 --git a/mm/mempolicy.c b/mm/mempolicy.c
index b21869a..8d7ddf0 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -1796,7 +1796,6 @@ static void gather_stats(struct page *pa
md->mapcount_max = count;
md->node[page_to_nid(page)]++;
- cond_resched();
}
#ifdef CONFIG_HUGETLB_PAGE
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 234bd48..8b3cde1 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -153,7 +153,8 @@ static void bad_page(struct page *page)
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 unsigned long page_order(s
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 @@ __find_combined_index(unsigned long page
* 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 @@ #ifdef CONFIG_HOLES_IN_ZONE
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 @@ #endif
* 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 @@ static inline int free_pages_check(struc
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 @@ static int prep_new_page(struct page *pa
1 << PG_slab |
1 << PG_swapcache |
1 << PG_writeback |
- 1 << PG_reserved ))))
+ 1 << PG_reserved |
+ 1 << PG_buddy ))))
bad_page(page);
/*
@@ -944,7 +949,8 @@ restart:
alloc_flags |= ALLOC_HARDER;
if (gfp_mask & __GFP_HIGH)
alloc_flags |= ALLOC_HIGH;
- alloc_flags |= ALLOC_CPUSET;
+ if (wait)
+ alloc_flags |= ALLOC_CPUSET;
/*
* Go through the zonelist again. Let __GFP_HIGH and allocations
diff --git a/mm/shmem.c b/mm/shmem.c
index 7c455fb..f0eb2f2 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2172,6 +2172,7 @@ #ifdef CONFIG_TMPFS
.prepare_write = shmem_prepare_write,
.commit_write = simple_commit_write,
#endif
+ .migratepage = migrate_page,
};
static struct file_operations shmem_file_operations = {
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 4fe7e3a..1d64dc1 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -949,6 +949,17 @@ redo:
goto unlock_both;
}
+ /* Make sure the dirty bit is up to date */
+ if (try_to_unmap(page, 1) == SWAP_FAIL) {
+ rc = -EPERM;
+ goto unlock_both;
+ }
+
+ if (page_mapcount(page)) {
+ rc = -EAGAIN;
+ goto unlock_both;
+ }
+
/*
* Default handling if a filesystem does not provide
* a migration function. We can only migrate clean
diff --git a/net/atm/clip.c b/net/atm/clip.c
index 73370de..1842a4e 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -613,12 +613,19 @@ static int clip_create(int number)
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 struct notifier_block clip_inet_n
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 struct atm_dev atmarpd_dev = {
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 @@ static int atm_init_atmarp(struct atm_vc
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 @@ static int __init atm_clip_init(void)
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 @@ static void __exit atm_clip_exit(void)
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 --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index e060aad..9e27373 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -739,6 +739,15 @@ out:
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 @@ #if defined(CONFIG_VLAN_8021Q) || define
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 @@ static unsigned int ip_sabotage_out(unsi
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 --git a/net/core/dev.c b/net/core/dev.c
index 2afb0de..12a214c 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2932,11 +2932,11 @@ void netdev_run_todo(void)
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 --git a/net/core/sock.c b/net/core/sock.c
index 6e00811..5621198 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -404,8 +404,9 @@ #ifdef CONFIG_NETDEVICES
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 --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index e320b32..24009be 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -314,11 +314,6 @@ static void __leaf_free_rcu(struct rcu_h
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 void __tnode_free_rcu(struct rcu_
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 --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 8ee4d01..8dcba38 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -86,8 +86,6 @@ #include <linux/tcp.h>
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 @@ #endif
* 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 @@ fail:
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 @@ int ip_push_pending_frames(struct sock *
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 --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 7d7ab94..12bfc25 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -941,7 +941,7 @@ static int do_add_counters(void __user *
write_lock_bh(&t->lock);
private = t->private;
- if (private->number != paddc->num_counters) {
+ if (private->number != tmp.num_counters) {
ret = -EINVAL;
goto unlock_up_free;
}
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
index 84c66db..43f6b45 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -1318,6 +1318,7 @@ getorigdst(struct sock *sk, int optval,
.tuple.dst.u.tcp.port;
sin.sin_addr.s_addr = ct->tuplehash[IP_CT_DIR_ORIGINAL]
.tuple.dst.ip;
+ memset(sin.sin_zero, 0, sizeof(sin.sin_zero));
DEBUGP("SO_ORIGINAL_DST: %u.%u.%u.%u %u\n",
NIPQUAD(sin.sin_addr.s_addr), ntohs(sin.sin_port));
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c
index e0b5926..d4e6d0a 100644
--- a/net/ipv4/netfilter/ip_conntrack_netlink.c
+++ b/net/ipv4/netfilter/ip_conntrack_netlink.c
@@ -1619,7 +1619,7 @@ static void __exit ctnetlink_exit(void)
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 --git a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
index be602e8..df67679 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
@@ -235,12 +235,15 @@ static int do_basic_checks(struct ip_con
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 --git a/net/ipv4/netfilter/ip_nat_snmp_basic.c b/net/ipv4/netfilter/ip_nat_snmp_basic.c
index 4f95d47..df57e7a 100644
--- a/net/ipv4/netfilter/ip_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/ip_nat_snmp_basic.c
@@ -1000,12 +1000,12 @@ static unsigned char snmp_trap_decode(st
return 1;
+err_addr_free:
+ kfree((unsigned long *)trap->ip_address);
+
err_id_free:
kfree(trap->id);
-err_addr_free:
- kfree((unsigned long *)trap->ip_address);
-
return 0;
}
@@ -1123,11 +1123,10 @@ static int snmp_parse_mangle(unsigned ch
struct snmp_v1_trap trap;
unsigned char ret = snmp_trap_decode(&ctx, &trap, map, check);
- /* Discard trap allocations regardless */
- kfree(trap.id);
- kfree((unsigned long *)trap.ip_address);
-
- if (!ret)
+ if (ret) {
+ kfree(trap.id);
+ kfree((unsigned long *)trap.ip_address);
+ } else
return ret;
} else {
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 16f47c6..735d5ff 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -1063,7 +1063,7 @@ do_add_counters(void __user *user, unsig
write_lock_bh(&t->lock);
private = t->private;
- if (private->number != paddc->num_counters) {
+ if (private->number != tmp.num_counters) {
ret = -EINVAL;
goto unlock_up_free;
}
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 6c8624a..62a0f52 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -354,6 +354,7 @@ getorigdst(struct sock *sk, int optval,
.tuple.dst.u.tcp.port;
sin.sin_addr.s_addr = ct->tuplehash[IP_CT_DIR_ORIGINAL]
.tuple.dst.u3.ip;
+ memset(sin.sin_zero, 0, sizeof(sin.sin_zero));
DEBUGP("SO_ORIGINAL_DST: %u.%u.%u.%u %u\n",
NIPQUAD(sin.sin_addr.s_addr), ntohs(sin.sin_port));
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index fca5fe0..a67955e 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2750,7 +2750,10 @@ int inet_rtm_getroute(struct sk_buff *in
/* 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 --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 9f498a6..310f2e6 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -537,7 +537,9 @@ int tcp_fragment(struct sock *sk, struct
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 --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 2a1e7e4..d88cab7 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -489,6 +489,18 @@ int ipv6_parse_hopopts(struct sk_buff *s
{
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 --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 74ff56c..dd6ad42 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1120,7 +1120,7 @@ do_add_counters(void __user *user, unsig
write_lock_bh(&t->lock);
private = t->private;
- if (private->number != paddc->num_counters) {
+ if (private->number != tmp.num_counters) {
ret = -EINVAL;
goto unlock_up_free;
}
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 91cce8b..88c840f 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -191,16 +191,18 @@ error:
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 --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 9ff3463..40edeef 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1641,7 +1641,7 @@ static void __exit ctnetlink_exit(void)
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 --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index cf798e6..cd2326d 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -240,12 +240,15 @@ static int do_basic_checks(struct nf_con
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 --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c
index 297b895..cf0c767 100644
--- a/net/sctp/inqueue.c
+++ b/net/sctp/inqueue.c
@@ -149,6 +149,7 @@ struct sctp_chunk *sctp_inq_pop(struct s
/* 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 --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 2b9a832..9395e09 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -636,8 +636,9 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(co
*/
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 @@ sctp_disposition_t sctp_sf_beat_8_3(cons
*/
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);
@@ -1028,6 +1030,12 @@ sctp_disposition_t sctp_sf_backbeat_8_3(
commands);
hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data;
+ /* Make sure that the length of the parameter is what we expect */
+ if (ntohs(hbinfo->param_hdr.length) !=
+ sizeof(sctp_sender_hb_info_t)) {
+ return SCTP_DISPOSITION_DISCARD;
+ }
+
from_addr = hbinfo->daddr;
link = sctp_assoc_lookup_paddr(asoc, &from_addr);
@@ -1860,8 +1868,9 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupc
* 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 +5160,9 @@ static int sctp_eat_data(const struct sc
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 +5173,16 @@ static int sctp_eat_data(const struct sc
/* 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 (asoc->state == SCTP_STATE_ESTABLISHED) {
+ * 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) && (!chunk->data_accepted)) {
/*
* If the receive buffer policy is 1, then each
* association can allocate up to sk_rcvbuf bytes
@@ -5176,9 +5193,25 @@ static int sctp_eat_data(const struct sc
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 +5259,7 @@ static int sctp_eat_data(const struct sc
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 +5276,8 @@ static int sctp_eat_data(const struct sc
* 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 +5285,8 @@ static int sctp_eat_data(const struct sc
* 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 --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c
index 75ef104..8bcca56 100644
--- a/net/sctp/sm_statetable.c
+++ b/net/sctp/sm_statetable.c
@@ -366,9 +366,9 @@ #define TYPE_SCTP_ECN_ECNE { \
/* 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 @@ #define TYPE_SCTP_ECN_ECNE { \
/* 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 @@ #define TYPE_SCTP_ECN_CWR { \
/* 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 @@ #define TYPE_SCTP_PRIMITIVE_REQUESTHEART
/* 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 --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
index 2080b2d..575e556 100644
--- a/net/sctp/ulpqueue.c
+++ b/net/sctp/ulpqueue.c
@@ -279,6 +279,7 @@ static inline void sctp_ulpq_store_reasm
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 @@ static struct sctp_ulpevent *sctp_make_r
*/
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 --git a/security/keys/key.c b/security/keys/key.c
index 99781b7..0e2584e 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -785,6 +785,10 @@ key_ref_t key_create_or_update(key_ref_t
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 --git a/security/keys/keyring.c b/security/keys/keyring.c
index d65a180..bffa924 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -437,6 +437,7 @@ EXPORT_SYMBOL(keyring_search);
/*
* 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 --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index 640d0bf..84047f6 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -264,7 +264,7 @@ int mls_context_to_sid(char oldc,
if (!selinux_mls_enabled) {
if (def_sid != SECSID_NULL && oldc)
- *scontext += strlen(*scontext);
+ *scontext += strlen(*scontext)+1;
return 0;
}
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 8a76492..6375dd5 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -592,6 +592,10 @@ int security_sid_to_context(u32 sid, cha
*scontext_len = strlen(initial_sid_to_string[sid]) + 1;
scontextp = kmalloc(*scontext_len,GFP_ATOMIC);
+ if (!scontextp) {
+ rc = -ENOMEM;
+ goto out;
+ }
strcpy(scontextp, initial_sid_to_string[sid]);
*scontext = scontextp;
goto out;
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index 63d96be..65b28cb 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -2088,9 +2088,11 @@ static int __init alsa_card_opti9xx_init
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 @@ static int __init alsa_card_opti9xx_init
}
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 @@ static void __exit alsa_card_opti9xx_exi
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 --git a/sound/oss/dmasound/tas_common.c b/sound/oss/dmasound/tas_common.c
index 8131599..882ae98 100644
--- a/sound/oss/dmasound/tas_common.c
+++ b/sound/oss/dmasound/tas_common.c
@@ -195,8 +195,8 @@ tas_init(int driver_id, const char *driv
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 --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index b767552..d5cd3a1 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -2948,6 +2948,8 @@ static struct hda_board_config alc260_cf
{ .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 --git a/sound/ppc/daca.c b/sound/ppc/daca.c
index 08cde51..b96cd94 100644
--- a/sound/ppc/daca.c
+++ b/sound/ppc/daca.c
@@ -256,7 +256,7 @@ int __init snd_pmac_daca_init(struct snd
#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 --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c
index 838fc11..39d4cde 100644
--- a/sound/ppc/tumbler.c
+++ b/sound/ppc/tumbler.c
@@ -1314,7 +1314,7 @@ int __init snd_pmac_tumbler_init(struct
#ifdef CONFIG_KMOD
if (current->fs->root)
- request_module("i2c-keywest");
+ request_module("i2c-powermac");
#endif /* CONFIG_KMOD */
mix = kmalloc(sizeof(*mix), GFP_KERNEL);