summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony G. Basile <blueness@gentoo.org>2011-08-12 16:25:45 -0400
committerAnthony G. Basile <blueness@gentoo.org>2011-08-12 16:25:45 -0400
commitf787d5c7cdd8dc64088acdf5477d87b290b26fbc (patch)
tree729482ac42ef3120372cca4415ee101219c3d7af
parentGrsec/PaX 2.2.2-2.6.32.44-201108111959 (diff)
downloadhardened-patchset-20110811.tar.gz
hardened-patchset-20110811.tar.bz2
hardened-patchset-20110811.zip
Add missing patch to incr to 2.6.32.4420110811
-rw-r--r--2.6.32/0000_README4
-rw-r--r--2.6.32/1043_linux-2.6.32.44.patch1455
2 files changed, 1459 insertions, 0 deletions
diff --git a/2.6.32/0000_README b/2.6.32/0000_README
index 97013da..5e4d4d1 100644
--- a/2.6.32/0000_README
+++ b/2.6.32/0000_README
@@ -3,6 +3,10 @@ README
Individual Patch Descriptions:
-----------------------------------------------------------------------------
+Patch: 1043_linux-2.6.32.44.patch
+From: http://www.kernel.org
+Desc: Linux 2.6.39.44
+
Patch: 4420_grsecurity-2.2.2-2.6.32.44-201108111959.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/2.6.32/1043_linux-2.6.32.44.patch b/2.6.32/1043_linux-2.6.32.44.patch
new file mode 100644
index 0000000..c71b835
--- /dev/null
+++ b/2.6.32/1043_linux-2.6.32.44.patch
@@ -0,0 +1,1455 @@
+diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
+index 62619f2..a94e49c 100644
+--- a/arch/alpha/kernel/osf_sys.c
++++ b/arch/alpha/kernel/osf_sys.c
+@@ -431,7 +431,7 @@ SYSCALL_DEFINE2(osf_getdomainname, char __user *, name, int, namelen)
+ return -EFAULT;
+
+ len = namelen;
+- if (namelen > 32)
++ if (len > 32)
+ len = 32;
+
+ down_read(&uts_sem);
+@@ -618,7 +618,7 @@ SYSCALL_DEFINE3(osf_sysinfo, int, command, char __user *, buf, long, count)
+ down_read(&uts_sem);
+ res = sysinfo_table[offset];
+ len = strlen(res)+1;
+- if (len > count)
++ if ((unsigned long)len > (unsigned long)count)
+ len = count;
+ if (copy_to_user(buf, res, len))
+ err = -EFAULT;
+@@ -673,7 +673,7 @@ SYSCALL_DEFINE5(osf_getsysinfo, unsigned long, op, void __user *, buffer,
+ return 1;
+
+ case GSI_GET_HWRPB:
+- if (nbytes < sizeof(*hwrpb))
++ if (nbytes > sizeof(*hwrpb))
+ return -EINVAL;
+ if (copy_to_user(buffer, hwrpb, nbytes) != 0)
+ return -EFAULT;
+@@ -1035,6 +1035,7 @@ SYSCALL_DEFINE4(osf_wait4, pid_t, pid, int __user *, ustatus, int, options,
+ {
+ struct rusage r;
+ long ret, err;
++ unsigned int status = 0;
+ mm_segment_t old_fs;
+
+ if (!ur)
+@@ -1043,13 +1044,15 @@ SYSCALL_DEFINE4(osf_wait4, pid_t, pid, int __user *, ustatus, int, options,
+ old_fs = get_fs();
+
+ set_fs (KERNEL_DS);
+- ret = sys_wait4(pid, ustatus, options, (struct rusage __user *) &r);
++ ret = sys_wait4(pid, (unsigned int __user *) &status, options,
++ (struct rusage __user *) &r);
+ set_fs (old_fs);
+
+ if (!access_ok(VERIFY_WRITE, ur, sizeof(*ur)))
+ return -EFAULT;
+
+ err = 0;
++ err |= put_user(status, ustatus);
+ err |= __put_user(r.ru_utime.tv_sec, &ur->ru_utime.tv_sec);
+ err |= __put_user(r.ru_utime.tv_usec, &ur->ru_utime.tv_usec);
+ err |= __put_user(r.ru_stime.tv_sec, &ur->ru_stime.tv_sec);
+diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
+index 52dd804..8904495 100644
+--- a/arch/arm/mach-davinci/board-dm365-evm.c
++++ b/arch/arm/mach-davinci/board-dm365-evm.c
+@@ -413,7 +413,7 @@ fail:
+ */
+ if (have_imager()) {
+ label = "HD imager";
+- mux |= 1;
++ mux |= 2;
+
+ /* externally mux MMC1/ENET/AIC33 to imager */
+ mux |= BIT(6) | BIT(5) | BIT(3);
+@@ -434,7 +434,7 @@ fail:
+ resets &= ~BIT(1);
+
+ if (have_tvp7002()) {
+- mux |= 2;
++ mux |= 1;
+ resets &= ~BIT(2);
+ label = "tvp7002 HD";
+ } else {
+diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c
+index 102916f..b6bfe7e 100644
+--- a/arch/arm/mach-pxa/cm-x300.c
++++ b/arch/arm/mach-pxa/cm-x300.c
+@@ -143,10 +143,10 @@ static mfp_cfg_t cm_x300_mfp_cfg[] __initdata = {
+ GPIO99_GPIO, /* Ethernet IRQ */
+
+ /* RTC GPIOs */
+- GPIO95_GPIO, /* RTC CS */
+- GPIO96_GPIO, /* RTC WR */
+- GPIO97_GPIO, /* RTC RD */
+- GPIO98_GPIO, /* RTC IO */
++ GPIO95_GPIO | MFP_LPM_DRIVE_HIGH, /* RTC CS */
++ GPIO96_GPIO | MFP_LPM_DRIVE_HIGH, /* RTC WR */
++ GPIO97_GPIO | MFP_LPM_DRIVE_HIGH, /* RTC RD */
++ GPIO98_GPIO, /* RTC IO */
+
+ /* Standard I2C */
+ GPIO21_I2C_SCL,
+diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c
+index 5009198..d374974 100644
+--- a/arch/powerpc/kernel/crash.c
++++ b/arch/powerpc/kernel/crash.c
+@@ -176,12 +176,8 @@ static void crash_kexec_wait_realmode(int cpu)
+
+ while (paca[i].kexec_state < KEXEC_STATE_REAL_MODE) {
+ barrier();
+- if (!cpu_possible(i)) {
++ if (!cpu_possible(i) || !cpu_online(i) || (msecs <= 0))
+ break;
+- }
+- if (!cpu_online(i)) {
+- break;
+- }
+ msecs--;
+ mdelay(1);
+ }
+diff --git a/arch/powerpc/platforms/pseries/hvconsole.c b/arch/powerpc/platforms/pseries/hvconsole.c
+index 3f6a89b..041e87c 100644
+--- a/arch/powerpc/platforms/pseries/hvconsole.c
++++ b/arch/powerpc/platforms/pseries/hvconsole.c
+@@ -73,7 +73,7 @@ int hvc_put_chars(uint32_t vtermno, const char *buf, int count)
+ if (ret == H_SUCCESS)
+ return count;
+ if (ret == H_BUSY)
+- return 0;
++ return -EAGAIN;
+ return -EIO;
+ }
+
+diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
+index 69cab24..987ef29 100644
+--- a/arch/x86/kernel/hpet.c
++++ b/arch/x86/kernel/hpet.c
+@@ -27,6 +27,9 @@
+ #define HPET_DEV_FSB_CAP 0x1000
+ #define HPET_DEV_PERI_CAP 0x2000
+
++#define HPET_MIN_CYCLES 128
++#define HPET_MIN_PROG_DELTA (HPET_MIN_CYCLES + (HPET_MIN_CYCLES >> 1))
++
+ #define EVT_TO_HPET_DEV(evt) container_of(evt, struct hpet_dev, evt)
+
+ /*
+@@ -298,8 +301,9 @@ static void hpet_legacy_clockevent_register(void)
+ /* Calculate the min / max delta */
+ hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
+ &hpet_clockevent);
+- /* 5 usec minimum reprogramming delta. */
+- hpet_clockevent.min_delta_ns = 5000;
++ /* Setup minimum reprogramming delta. */
++ hpet_clockevent.min_delta_ns = clockevent_delta2ns(HPET_MIN_PROG_DELTA,
++ &hpet_clockevent);
+
+ /*
+ * Start hpet with the boot cpu mask and make it
+@@ -379,36 +383,37 @@ static int hpet_next_event(unsigned long delta,
+ struct clock_event_device *evt, int timer)
+ {
+ u32 cnt;
++ s32 res;
+
+ cnt = hpet_readl(HPET_COUNTER);
+ cnt += (u32) delta;
+ hpet_writel(cnt, HPET_Tn_CMP(timer));
+
+ /*
+- * We need to read back the CMP register on certain HPET
+- * implementations (ATI chipsets) which seem to delay the
+- * transfer of the compare register into the internal compare
+- * logic. With small deltas this might actually be too late as
+- * the counter could already be higher than the compare value
+- * at that point and we would wait for the next hpet interrupt
+- * forever. We found out that reading the CMP register back
+- * forces the transfer so we can rely on the comparison with
+- * the counter register below. If the read back from the
+- * compare register does not match the value we programmed
+- * then we might have a real hardware problem. We can not do
+- * much about it here, but at least alert the user/admin with
+- * a prominent warning.
+- * An erratum on some chipsets (ICH9,..), results in comparator read
+- * immediately following a write returning old value. Workaround
+- * for this is to read this value second time, when first
+- * read returns old value.
++ * HPETs are a complete disaster. The compare register is
++ * based on a equal comparison and neither provides a less
++ * than or equal functionality (which would require to take
++ * the wraparound into account) nor a simple count down event
++ * mode. Further the write to the comparator register is
++ * delayed internally up to two HPET clock cycles in certain
++ * chipsets (ATI, ICH9,10). Some newer AMD chipsets have even
++ * longer delays. We worked around that by reading back the
++ * compare register, but that required another workaround for
++ * ICH9,10 chips where the first readout after write can
++ * return the old stale value. We already had a minimum
++ * programming delta of 5us enforced, but a NMI or SMI hitting
++ * between the counter readout and the comparator write can
++ * move us behind that point easily. Now instead of reading
++ * the compare register back several times, we make the ETIME
++ * decision based on the following: Return ETIME if the
++ * counter value after the write is less than HPET_MIN_CYCLES
++ * away from the event or if the counter is already ahead of
++ * the event. The minimum programming delta for the generic
++ * clockevents code is set to 1.5 * HPET_MIN_CYCLES.
+ */
+- if (unlikely((u32)hpet_readl(HPET_Tn_CMP(timer)) != cnt)) {
+- WARN_ONCE((u32)hpet_readl(HPET_Tn_CMP(timer)) != cnt,
+- KERN_WARNING "hpet: compare register read back failed.\n");
+- }
++ res = (s32)(cnt - (u32)hpet_readl(HPET_COUNTER));
+
+- return (s32)((u32)hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0;
++ return res < HPET_MIN_CYCLES ? -ETIME : 0;
+ }
+
+ static void hpet_legacy_set_mode(enum clock_event_mode mode,
+diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
+index 200fcde..cf98100 100644
+--- a/arch/x86/kernel/reboot.c
++++ b/arch/x86/kernel/reboot.c
+@@ -469,6 +469,14 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1"),
+ },
+ },
++ { /* Handle problems with rebooting on the Latitude E5420. */
++ .callback = set_pci_reboot,
++ .ident = "Dell Latitude E5420",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E5420"),
++ },
++ },
+ { }
+ };
+
+diff --git a/arch/x86/kernel/relocate_kernel_32.S b/arch/x86/kernel/relocate_kernel_32.S
+index 4123553..36818f8 100644
+--- a/arch/x86/kernel/relocate_kernel_32.S
++++ b/arch/x86/kernel/relocate_kernel_32.S
+@@ -97,6 +97,8 @@ relocate_kernel:
+ ret
+
+ identity_mapped:
++ /* set return address to 0 if not preserving context */
++ pushl $0
+ /* store the start address on the stack */
+ pushl %edx
+
+diff --git a/arch/x86/kernel/relocate_kernel_64.S b/arch/x86/kernel/relocate_kernel_64.S
+index 4de8f5b..7a6f3b3 100644
+--- a/arch/x86/kernel/relocate_kernel_64.S
++++ b/arch/x86/kernel/relocate_kernel_64.S
+@@ -100,6 +100,8 @@ relocate_kernel:
+ ret
+
+ identity_mapped:
++ /* set return address to 0 if not preserving context */
++ pushq $0
+ /* store the start address on the stack */
+ pushq %rdx
+
+diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c
+index 9486882..885ebe7 100644
+--- a/arch/xtensa/kernel/ptrace.c
++++ b/arch/xtensa/kernel/ptrace.c
+@@ -136,6 +136,9 @@ int ptrace_setxregs(struct task_struct *child, void __user *uregs)
+ elf_xtregs_t *xtregs = uregs;
+ int ret = 0;
+
++ if (!access_ok(VERIFY_READ, uregs, sizeof(elf_xtregs_t)))
++ return -EFAULT;
++
+ #if XTENSA_HAVE_COPROCESSORS
+ /* Flush all coprocessors before we overwrite them. */
+ coprocessor_flush_all(ti);
+diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
+index fa9bed0..e5bdb9b 100644
+--- a/drivers/ata/libata-eh.c
++++ b/drivers/ata/libata-eh.c
+@@ -2707,10 +2707,11 @@ int ata_eh_reset(struct ata_link *link, int classify,
+ }
+
+ /*
+- * Some controllers can't be frozen very well and may set
+- * spuruious error conditions during reset. Clear accumulated
+- * error information. As reset is the final recovery action,
+- * nothing is lost by doing this.
++ * Some controllers can't be frozen very well and may set spurious
++ * error conditions during reset. Clear accumulated error
++ * information and re-thaw the port if frozen. As reset is the
++ * final recovery action and we cross check link onlineness against
++ * device classification later, no hotplug event is lost by this.
+ */
+ spin_lock_irqsave(link->ap->lock, flags);
+ memset(&link->eh_info, 0, sizeof(link->eh_info));
+@@ -2719,6 +2720,9 @@ int ata_eh_reset(struct ata_link *link, int classify,
+ ap->pflags &= ~ATA_PFLAG_EH_PENDING;
+ spin_unlock_irqrestore(link->ap->lock, flags);
+
++ if (ap->pflags & ATA_PFLAG_FROZEN)
++ ata_eh_thaw_port(ap);
++
+ /*
+ * Make sure onlineness and classification result correspond.
+ * Hotplug could have happened during reset and some
+diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h
+index 5ae1b1c..04d6bf8 100644
+--- a/drivers/block/cciss.h
++++ b/drivers/block/cciss.h
+@@ -165,7 +165,7 @@ static void SA5_submit_command( ctlr_info_t *h, CommandList_struct *c)
+ printk("Sending %x - down to controller\n", c->busaddr );
+ #endif /* CCISS_DEBUG */
+ writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET);
+- readl(h->vaddr + SA5_REQUEST_PORT_OFFSET);
++ readl(h->vaddr + SA5_SCRATCHPAD_OFFSET);
+ h->commands_outstanding++;
+ if ( h->commands_outstanding > h->max_outstanding)
+ h->max_outstanding = h->commands_outstanding;
+diff --git a/drivers/hwmon/max1111.c b/drivers/hwmon/max1111.c
+index 9ac4972..5b6001b 100644
+--- a/drivers/hwmon/max1111.c
++++ b/drivers/hwmon/max1111.c
+@@ -39,6 +39,8 @@ struct max1111_data {
+ struct spi_transfer xfer[2];
+ uint8_t *tx_buf;
+ uint8_t *rx_buf;
++ struct mutex drvdata_lock;
++ /* protect msg, xfer and buffers from multiple access */
+ };
+
+ static int max1111_read(struct device *dev, int channel)
+@@ -47,6 +49,9 @@ static int max1111_read(struct device *dev, int channel)
+ uint8_t v1, v2;
+ int err;
+
++ /* writing to drvdata struct is not thread safe, wait on mutex */
++ mutex_lock(&data->drvdata_lock);
++
+ data->tx_buf[0] = (channel << MAX1111_CTRL_SEL_SH) |
+ MAX1111_CTRL_PD0 | MAX1111_CTRL_PD1 |
+ MAX1111_CTRL_SGL | MAX1111_CTRL_UNI | MAX1111_CTRL_STR;
+@@ -54,12 +59,15 @@ static int max1111_read(struct device *dev, int channel)
+ err = spi_sync(data->spi, &data->msg);
+ if (err < 0) {
+ dev_err(dev, "spi_sync failed with %d\n", err);
++ mutex_unlock(&data->drvdata_lock);
+ return err;
+ }
+
+ v1 = data->rx_buf[0];
+ v2 = data->rx_buf[1];
+
++ mutex_unlock(&data->drvdata_lock);
++
+ if ((v1 & 0xc0) || (v2 & 0x3f))
+ return -EINVAL;
+
+@@ -175,6 +183,8 @@ static int __devinit max1111_probe(struct spi_device *spi)
+ if (err)
+ goto err_free_data;
+
++ mutex_init(&data->drvdata_lock);
++
+ data->spi = spi;
+ spi_set_drvdata(spi, data);
+
+@@ -212,6 +222,7 @@ static int __devexit max1111_remove(struct spi_device *spi)
+
+ hwmon_device_unregister(data->hwmon_dev);
+ sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group);
++ mutex_destroy(&data->drvdata_lock);
+ kfree(data->rx_buf);
+ kfree(data->tx_buf);
+ kfree(data);
+diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
+index fcf717c..b03cd39 100644
+--- a/drivers/md/dm-mpath.c
++++ b/drivers/md/dm-mpath.c
+@@ -778,6 +778,11 @@ static int parse_features(struct arg_set *as, struct multipath *m)
+ if (!argc)
+ return 0;
+
++ if (argc > as->argc) {
++ ti->error = "not enough arguments for features";
++ return -EINVAL;
++ }
++
+ do {
+ param_name = shift(as);
+ argc--;
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index d186687..c988ac2 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -36,6 +36,8 @@ static const char *_name = DM_NAME;
+ static unsigned int major = 0;
+ static unsigned int _major = 0;
+
++static DEFINE_IDR(_minor_idr);
++
+ static DEFINE_SPINLOCK(_minor_lock);
+ /*
+ * For bio-based dm.
+@@ -315,6 +317,12 @@ static void __exit dm_exit(void)
+
+ while (i--)
+ _exits[i]();
++
++ /*
++ * Should be empty by this point.
++ */
++ idr_remove_all(&_minor_idr);
++ idr_destroy(&_minor_idr);
+ }
+
+ /*
+@@ -1663,8 +1671,6 @@ static int dm_any_congested(void *congested_data, int bdi_bits)
+ /*-----------------------------------------------------------------
+ * An IDR is used to keep track of allocated minor numbers.
+ *---------------------------------------------------------------*/
+-static DEFINE_IDR(_minor_idr);
+-
+ static void free_minor(int minor)
+ {
+ spin_lock(&_minor_lock);
+diff --git a/drivers/media/radio/si4713-i2c.c b/drivers/media/radio/si4713-i2c.c
+index 6a0028e..93653c6 100644
+--- a/drivers/media/radio/si4713-i2c.c
++++ b/drivers/media/radio/si4713-i2c.c
+@@ -1003,7 +1003,7 @@ static int si4713_write_econtrol_string(struct si4713_device *sdev,
+ char ps_name[MAX_RDS_PS_NAME + 1];
+
+ len = control->size - 1;
+- if (len > MAX_RDS_PS_NAME) {
++ if (len < 0 || len > MAX_RDS_PS_NAME) {
+ rval = -ERANGE;
+ goto exit;
+ }
+@@ -1025,7 +1025,7 @@ static int si4713_write_econtrol_string(struct si4713_device *sdev,
+ char radio_text[MAX_RDS_RADIO_TEXT + 1];
+
+ len = control->size - 1;
+- if (len > MAX_RDS_RADIO_TEXT) {
++ if (len < 0 || len > MAX_RDS_RADIO_TEXT) {
+ rval = -ERANGE;
+ goto exit;
+ }
+diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
+index d258ed7..f0e9c75 100644
+--- a/drivers/media/video/bt8xx/bttv-driver.c
++++ b/drivers/media/video/bt8xx/bttv-driver.c
+@@ -3532,7 +3532,7 @@ static int radio_s_tuner(struct file *file, void *priv,
+ if (0 != t->index)
+ return -EINVAL;
+
+- bttv_call_all(btv, tuner, g_tuner, t);
++ bttv_call_all(btv, tuner, s_tuner, t);
+ return 0;
+ }
+
+diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+index 13639b3..5891e30 100644
+--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
++++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+@@ -2979,6 +2979,8 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw)
+ if (hdw->input_dirty || hdw->audiomode_dirty || hdw->force_dirty) {
+ struct v4l2_tuner vt;
+ memset(&vt, 0, sizeof(vt));
++ vt.type = (hdw->input_val == PVR2_CVAL_INPUT_RADIO) ?
++ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
+ vt.audmode = hdw->audiomode_val;
+ v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, s_tuner, &vt);
+ }
+@@ -5064,6 +5066,8 @@ void pvr2_hdw_status_poll(struct pvr2_hdw *hdw)
+ {
+ struct v4l2_tuner *vtp = &hdw->tuner_signal_info;
+ memset(vtp, 0, sizeof(*vtp));
++ vtp->type = (hdw->input_val == PVR2_CVAL_INPUT_RADIO) ?
++ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
+ hdw->tuner_signal_stale = 0;
+ /* Note: There apparently is no replacement for VIDIOC_CROPCAP
+ using v4l2-subdev - therefore we can't support that AT ALL right
+diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
+index 30cc334..265bfb5 100644
+--- a/drivers/media/video/v4l2-ioctl.c
++++ b/drivers/media/video/v4l2-ioctl.c
+@@ -1600,6 +1600,8 @@ static long __video_do_ioctl(struct file *file,
+ if (!ops->vidioc_g_tuner)
+ break;
+
++ p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
++ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
+ ret = ops->vidioc_g_tuner(file, fh, p);
+ if (!ret)
+ dbgarg(cmd, "index=%d, name=%s, type=%d, "
+@@ -1618,6 +1620,8 @@ static long __video_do_ioctl(struct file *file,
+
+ if (!ops->vidioc_s_tuner)
+ break;
++ p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
++ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
+ dbgarg(cmd, "index=%d, name=%s, type=%d, "
+ "capability=0x%x, rangelow=%d, "
+ "rangehigh=%d, signal=%d, afc=%d, "
+@@ -1636,6 +1640,8 @@ static long __video_do_ioctl(struct file *file,
+ if (!ops->vidioc_g_frequency)
+ break;
+
++ p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
++ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
+ ret = ops->vidioc_g_frequency(file, fh, p);
+ if (!ret)
+ dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
+diff --git a/drivers/net/jme.c b/drivers/net/jme.c
+index a893f45..0fbca76 100644
+--- a/drivers/net/jme.c
++++ b/drivers/net/jme.c
+@@ -681,20 +681,28 @@ jme_make_new_rx_buf(struct jme_adapter *jme, int i)
+ struct jme_ring *rxring = &(jme->rxring[0]);
+ struct jme_buffer_info *rxbi = rxring->bufinf + i;
+ struct sk_buff *skb;
++ dma_addr_t mapping;
+
+ skb = netdev_alloc_skb(jme->dev,
+ jme->dev->mtu + RX_EXTRA_LEN);
+ if (unlikely(!skb))
+ return -ENOMEM;
+
++ mapping = pci_map_page(jme->pdev, virt_to_page(skb->data),
++ offset_in_page(skb->data), skb_tailroom(skb),
++ PCI_DMA_FROMDEVICE);
++ if (unlikely(pci_dma_mapping_error(jme->pdev, mapping))) {
++ dev_kfree_skb(skb);
++ return -ENOMEM;
++ }
++
++ if (likely(rxbi->mapping))
++ pci_unmap_page(jme->pdev, rxbi->mapping,
++ rxbi->len, PCI_DMA_FROMDEVICE);
++
+ rxbi->skb = skb;
+ rxbi->len = skb_tailroom(skb);
+- rxbi->mapping = pci_map_page(jme->pdev,
+- virt_to_page(skb->data),
+- offset_in_page(skb->data),
+- rxbi->len,
+- PCI_DMA_FROMDEVICE);
+-
++ rxbi->mapping = mapping;
+ return 0;
+ }
+
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
+index 0d3326d..6f8352c 100644
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -1507,7 +1507,7 @@ void pci_enable_ari(struct pci_dev *dev)
+ {
+ int pos;
+ u32 cap;
+- u16 ctrl;
++ u16 flags, ctrl;
+ struct pci_dev *bridge;
+
+ if (!dev->is_pcie || dev->devfn)
+@@ -1525,6 +1525,11 @@ void pci_enable_ari(struct pci_dev *dev)
+ if (!pos)
+ return;
+
++ /* ARI is a PCIe v2 feature */
++ pci_read_config_word(bridge, pos + PCI_EXP_FLAGS, &flags);
++ if ((flags & PCI_EXP_FLAGS_VERS) < 2)
++ return;
++
+ pci_read_config_dword(bridge, pos + PCI_EXP_DEVCAP2, &cap);
+ if (!(cap & PCI_EXP_DEVCAP2_ARI))
+ return;
+diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
+index 33cf988..4f43306 100644
+--- a/drivers/scsi/libsas/sas_expander.c
++++ b/drivers/scsi/libsas/sas_expander.c
+@@ -840,6 +840,9 @@ static struct domain_device *sas_ex_discover_expander(
+
+ res = sas_discover_expander(child);
+ if (res) {
++ spin_lock_irq(&parent->port->dev_list_lock);
++ list_del(&child->dev_list_node);
++ spin_unlock_irq(&parent->port->dev_list_lock);
+ kfree(child);
+ return NULL;
+ }
+diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
+index 483370f..9ab8c86 100644
+--- a/drivers/scsi/pmcraid.c
++++ b/drivers/scsi/pmcraid.c
+@@ -3557,6 +3557,9 @@ static long pmcraid_ioctl_passthrough(
+ pmcraid_err("couldn't build passthrough ioadls\n");
+ goto out_free_buffer;
+ }
++ } else if (request_size < 0) {
++ rc = -EINVAL;
++ goto out_free_buffer;
+ }
+
+ /* If data is being written into the device, copy the data from user
+diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
+index 802e91c..ae0ae2d 100644
+--- a/drivers/scsi/scsi_devinfo.c
++++ b/drivers/scsi/scsi_devinfo.c
+@@ -196,6 +196,7 @@ static struct {
+ {"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+ {"IBM", "2105", NULL, BLIST_RETRY_HWERROR},
+ {"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN},
++ {"IOMEGA", "ZIP", NULL, BLIST_NOTQ | BLIST_NOLUN},
+ {"IOMEGA", "Io20S *F", NULL, BLIST_KEY},
+ {"INSITE", "Floptical F*8I", NULL, BLIST_KEY},
+ {"INSITE", "I325VM", NULL, BLIST_KEY},
+@@ -242,6 +243,7 @@ static struct {
+ {"Tornado-", "F4", "*", BLIST_NOREPORTLUN},
+ {"TOSHIBA", "CDROM", NULL, BLIST_ISROM},
+ {"TOSHIBA", "CD-ROM", NULL, BLIST_ISROM},
++ {"Traxdata", "CDR4120", NULL, BLIST_NOLUN}, /* locks up */
+ {"USB2.0", "SMARTMEDIA/XD", NULL, BLIST_FORCELUN | BLIST_INQUIRY_36},
+ {"WangDAT", "Model 2600", "01.7", BLIST_SELECT_NO_ATN},
+ {"WangDAT", "Model 3200", "02.2", BLIST_SELECT_NO_ATN},
+diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c
+index 3b082dd..340124d 100644
+--- a/drivers/scsi/ses.c
++++ b/drivers/scsi/ses.c
+@@ -157,6 +157,10 @@ static unsigned char *ses_get_page2_descriptor(struct enclosure_device *edev,
+ return NULL;
+ }
+
++/* For device slot and array device slot elements, byte 3 bit 6
++ * is "fault sensed" while byte 3 bit 5 is "fault reqstd". As this
++ * code stands these bits are shifted 4 positions right so in
++ * sysfs they will appear as bits 2 and 1 respectively. Strange. */
+ static void ses_get_fault(struct enclosure_device *edev,
+ struct enclosure_component *ecomp)
+ {
+@@ -178,7 +182,7 @@ static int ses_set_fault(struct enclosure_device *edev,
+ /* zero is disabled */
+ break;
+ case ENCLOSURE_SETTING_ENABLED:
+- desc[2] = 0x02;
++ desc[3] = 0x20;
+ break;
+ default:
+ /* SES doesn't do the SGPIO blink settings */
+diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
+index aaad76e..80a1071 100644
+--- a/drivers/staging/comedi/comedi_fops.c
++++ b/drivers/staging/comedi/comedi_fops.c
+@@ -367,8 +367,8 @@ static int do_devinfo_ioctl(struct comedi_device *dev,
+ /* fill devinfo structure */
+ devinfo.version_code = COMEDI_VERSION_CODE;
+ devinfo.n_subdevs = dev->n_subdevices;
+- memcpy(devinfo.driver_name, dev->driver->driver_name, COMEDI_NAMELEN);
+- memcpy(devinfo.board_name, dev->board_name, COMEDI_NAMELEN);
++ strlcpy(devinfo.driver_name, dev->driver->driver_name, COMEDI_NAMELEN);
++ strlcpy(devinfo.board_name, dev->board_name, COMEDI_NAMELEN);
+
+ if (read_subdev)
+ devinfo.read_subdevice = read_subdev - dev->subdevices;
+diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
+index 5e09664..7adb671 100644
+--- a/drivers/usb/gadget/dummy_hcd.c
++++ b/drivers/usb/gadget/dummy_hcd.c
+@@ -1886,6 +1886,7 @@ static int dummy_hcd_probe(struct platform_device *pdev)
+ if (!hcd)
+ return -ENOMEM;
+ the_controller = hcd_to_dummy (hcd);
++ hcd->has_tt = 1;
+
+ retval = usb_add_hcd(hcd, 0, 0);
+ if (retval != 0) {
+diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
+index 6ac3976..1bcf6ee 100644
+--- a/drivers/usb/host/ehci-hub.c
++++ b/drivers/usb/host/ehci-hub.c
+@@ -758,10 +758,11 @@ static int ehci_hub_control (
+ * power switching; they're allowed to just limit the
+ * current. khubd will turn the power back on.
+ */
+- if (HCS_PPC (ehci->hcs_params)){
++ if ((temp & PORT_OC) && HCS_PPC(ehci->hcs_params)) {
+ ehci_writel(ehci,
+ temp & ~(PORT_RWC_BITS | PORT_POWER),
+ status_reg);
++ temp = ehci_readl(ehci, status_reg);
+ }
+ }
+
+diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
+index f51345f..0ee5b4b 100644
+--- a/drivers/usb/host/ehci-q.c
++++ b/drivers/usb/host/ehci-q.c
+@@ -103,7 +103,7 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd)
+ if (!(hw->hw_info1 & cpu_to_hc32(ehci, 1 << 14))) {
+ unsigned is_out, epnum;
+
+- is_out = !(qtd->hw_token & cpu_to_hc32(ehci, 1 << 8));
++ is_out = qh->is_out;
+ epnum = (hc32_to_cpup(ehci, &hw->hw_info1) >> 8) & 0x0f;
+ if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) {
+ hw->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE);
+@@ -923,6 +923,7 @@ done:
+ hw = qh->hw;
+ hw->hw_info1 = cpu_to_hc32(ehci, info1);
+ hw->hw_info2 = cpu_to_hc32(ehci, info2);
++ qh->is_out = !is_input;
+ usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1);
+ qh_refresh (ehci, qh);
+ return qh;
+diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
+index ac321ef..5b3ca74 100644
+--- a/drivers/usb/host/ehci.h
++++ b/drivers/usb/host/ehci.h
+@@ -366,6 +366,7 @@ struct ehci_qh {
+ #define NO_FRAME ((unsigned short)~0) /* pick new start */
+
+ struct usb_device *dev; /* access to TT */
++ unsigned is_out:1; /* bulk or intr OUT */
+ unsigned clearing_tt:1; /* Clear-TT-Buf in progress */
+ };
+
+diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
+index 464ed97..bcf7a88 100644
+--- a/drivers/usb/host/pci-quirks.c
++++ b/drivers/usb/host/pci-quirks.c
+@@ -34,6 +34,8 @@
+ #define OHCI_INTRSTATUS 0x0c
+ #define OHCI_INTRENABLE 0x10
+ #define OHCI_INTRDISABLE 0x14
++#define OHCI_FMINTERVAL 0x34
++#define OHCI_HCR (1 << 0) /* host controller reset */
+ #define OHCI_OCR (1 << 3) /* ownership change request */
+ #define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */
+ #define OHCI_CTRL_IR (1 << 8) /* interrupt routing */
+@@ -204,6 +206,32 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
+
+ /* reset controller, preserving RWC (and possibly IR) */
+ writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL);
++ readl(base + OHCI_CONTROL);
++
++ /* Some NVIDIA controllers stop working if kept in RESET for too long */
++ if (pdev->vendor == PCI_VENDOR_ID_NVIDIA) {
++ u32 fminterval;
++ int cnt;
++
++ /* drive reset for at least 50 ms (7.1.7.5) */
++ msleep(50);
++
++ /* software reset of the controller, preserving HcFmInterval */
++ fminterval = readl(base + OHCI_FMINTERVAL);
++ writel(OHCI_HCR, base + OHCI_CMDSTATUS);
++
++ /* reset requires max 10 us delay */
++ for (cnt = 30; cnt > 0; --cnt) { /* ... allow extra time */
++ if ((readl(base + OHCI_CMDSTATUS) & OHCI_HCR) == 0)
++ break;
++ udelay(1);
++ }
++ writel(fminterval, base + OHCI_FMINTERVAL);
++
++ /* Now we're in the SUSPEND state with all devices reset
++ * and wakeups and interrupts disabled
++ */
++ }
+
+ /*
+ * disable interrupts
+diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
+index 24212be..b9afd6a 100644
+--- a/drivers/usb/musb/musb_core.c
++++ b/drivers/usb/musb/musb_core.c
+@@ -1634,6 +1634,7 @@ void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit)
+ }
+ }
+ }
++ musb_writeb(musb_base, MUSB_INDEX, musb->context.index);
+ }
+
+ #else
+diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
+index b336017..4a18fd2 100644
+--- a/drivers/usb/serial/pl2303.c
++++ b/drivers/usb/serial/pl2303.c
+@@ -100,6 +100,8 @@ static struct usb_device_id id_table [] = {
+ { USB_DEVICE(ZEAGLE_VENDOR_ID, ZEAGLE_N2ITION3_PRODUCT_ID) },
+ { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
+ { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) },
++ { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) },
++ { USB_DEVICE(WINCHIPHEAD_VENDOR_ID, WINCHIPHEAD_USBSER_PRODUCT_ID) },
+ { } /* Terminating entry */
+ };
+
+diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
+index 4d043e4..ca0d237 100644
+--- a/drivers/usb/serial/pl2303.h
++++ b/drivers/usb/serial/pl2303.h
+@@ -5,7 +5,7 @@
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+- *
++ *
+ */
+
+ #define BENQ_VENDOR_ID 0x04a5
+@@ -140,3 +140,11 @@
+ /* Sanwa KB-USB2 multimeter cable (ID: 11ad:0001) */
+ #define SANWA_VENDOR_ID 0x11ad
+ #define SANWA_PRODUCT_ID 0x0001
++
++/* ADLINK ND-6530 RS232,RS485 and RS422 adapter */
++#define ADLINK_VENDOR_ID 0x0b63
++#define ADLINK_ND6530_PRODUCT_ID 0x6530
++
++/* WinChipHead USB->RS 232 adapter */
++#define WINCHIPHEAD_VENDOR_ID 0x4348
++#define WINCHIPHEAD_USBSER_PRODUCT_ID 0x5523
+diff --git a/fs/block_dev.c b/fs/block_dev.c
+index 16cea86..e65efa2 100644
+--- a/fs/block_dev.c
++++ b/fs/block_dev.c
+@@ -1203,7 +1203,6 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
+ if (!bdev->bd_part)
+ goto out_clear;
+
+- ret = 0;
+ if (disk->fops->open) {
+ ret = disk->fops->open(bdev, mode);
+ if (ret == -ERESTARTSYS) {
+@@ -1219,18 +1218,9 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
+ mutex_unlock(&bdev->bd_mutex);
+ goto restart;
+ }
++ if (ret)
++ goto out_clear;
+ }
+- /*
+- * If the device is invalidated, rescan partition
+- * if open succeeded or failed with -ENOMEDIUM.
+- * The latter is necessary to prevent ghost
+- * partitions on a removed medium.
+- */
+- if (bdev->bd_invalidated && (!ret || ret == -ENOMEDIUM))
+- rescan_partitions(disk, bdev);
+- if (ret)
+- goto out_clear;
+-
+ if (!bdev->bd_openers) {
+ bd_set_size(bdev,(loff_t)get_capacity(disk)<<9);
+ bdi = blk_get_backing_dev_info(bdev);
+@@ -1238,6 +1228,8 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
+ bdi = &default_backing_dev_info;
+ bdev->bd_inode->i_data.backing_dev_info = bdi;
+ }
++ if (bdev->bd_invalidated)
++ rescan_partitions(disk, bdev);
+ } else {
+ struct block_device *whole;
+ whole = bdget_disk(disk, 0);
+@@ -1264,14 +1256,13 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
+ put_disk(disk);
+ disk = NULL;
+ if (bdev->bd_contains == bdev) {
+- ret = 0;
+- if (bdev->bd_disk->fops->open)
++ if (bdev->bd_disk->fops->open) {
+ ret = bdev->bd_disk->fops->open(bdev, mode);
+- /* the same as first opener case, read comment there */
+- if (bdev->bd_invalidated && (!ret || ret == -ENOMEDIUM))
++ if (ret)
++ goto out_unlock_bdev;
++ }
++ if (bdev->bd_invalidated)
+ rescan_partitions(bdev->bd_disk, bdev);
+- if (ret)
+- goto out_unlock_bdev;
+ }
+ }
+ bdev->bd_openers++;
+diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
+index c4dbc63..e29581e 100644
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -33,7 +33,7 @@
+ #define MAX_SHARE_SIZE 64 /* used to be 20, this should still be enough */
+ #define MAX_USERNAME_SIZE 32 /* 32 is to allow for 15 char names + null
+ termination then *2 for unicode versions */
+-#define MAX_PASSWORD_SIZE 16
++#define MAX_PASSWORD_SIZE 512 /* max for windows seems to be 256 wide chars */
+
+ #define CIFS_MIN_RCV_POOL 4
+
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index 6234417..b6bb82e 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -1588,17 +1588,29 @@ out_err:
+ }
+
+ static struct cifsSesInfo *
+-cifs_find_smb_ses(struct TCP_Server_Info *server, char *username)
++cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
+ {
+- struct list_head *tmp;
+ struct cifsSesInfo *ses;
+
+ write_lock(&cifs_tcp_ses_lock);
+- list_for_each(tmp, &server->smb_ses_list) {
+- ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
+- if (strncmp(ses->userName, username, MAX_USERNAME_SIZE))
+- continue;
+-
++ list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
++ switch (server->secType) {
++ case Kerberos:
++ if (vol->linux_uid != ses->linux_uid)
++ continue;
++ break;
++ default:
++ /* anything else takes username/password */
++ if (strncmp(ses->userName, vol->username,
++ MAX_USERNAME_SIZE))
++ continue;
++ if (strlen(vol->username) != 0 &&
++ ses->password != NULL &&
++ strncmp(ses->password,
++ vol->password ? vol->password : "",
++ MAX_PASSWORD_SIZE))
++ continue;
++ }
+ ++ses->ses_count;
+ write_unlock(&cifs_tcp_ses_lock);
+ return ses;
+@@ -2362,7 +2374,7 @@ try_mount_again:
+ goto out;
+ }
+
+- pSesInfo = cifs_find_smb_ses(srvTcp, volume_info->username);
++ pSesInfo = cifs_find_smb_ses(srvTcp, volume_info);
+ if (pSesInfo) {
+ cFYI(1, ("Existing smb sess found (status=%d)",
+ pSesInfo->status));
+diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
+index 387d92d..d7add4c 100644
+--- a/fs/ext3/xattr.c
++++ b/fs/ext3/xattr.c
+@@ -800,8 +800,16 @@ inserted:
+ /* We need to allocate a new block */
+ ext3_fsblk_t goal = ext3_group_first_block_no(sb,
+ EXT3_I(inode)->i_block_group);
+- ext3_fsblk_t block = ext3_new_block(handle, inode,
+- goal, &error);
++ ext3_fsblk_t block;
++
++ /*
++ * Protect us agaist concurrent allocations to the
++ * same inode from ext3_..._writepage(). Reservation
++ * code does not expect racing allocations.
++ */
++ mutex_lock(&EXT3_I(inode)->truncate_mutex);
++ block = ext3_new_block(handle, inode, goal, &error);
++ mutex_unlock(&EXT3_I(inode)->truncate_mutex);
+ if (error)
+ goto cleanup;
+ ea_idebug(inode, "creating block %d", block);
+diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
+index e81b2bf..7ee8ebc 100644
+--- a/fs/nfs/nfs4xdr.c
++++ b/fs/nfs/nfs4xdr.c
+@@ -88,7 +88,7 @@ static int nfs4_stat_to_errno(int);
+ #define encode_getfh_maxsz (op_encode_hdr_maxsz)
+ #define decode_getfh_maxsz (op_decode_hdr_maxsz + 1 + \
+ ((3+NFS4_FHSIZE) >> 2))
+-#define nfs4_fattr_bitmap_maxsz 3
++#define nfs4_fattr_bitmap_maxsz 4
+ #define encode_getattr_maxsz (op_encode_hdr_maxsz + nfs4_fattr_bitmap_maxsz)
+ #define nfs4_name_maxsz (1 + ((3 + NFS4_MAXNAMLEN) >> 2))
+ #define nfs4_path_maxsz (1 + ((3 + NFS4_MAXPATHLEN) >> 2))
+diff --git a/fs/proc/base.c b/fs/proc/base.c
+index 3d09a10..7b5819c 100644
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -2454,6 +2454,9 @@ static int do_io_accounting(struct task_struct *task, char *buffer, int whole)
+ struct task_io_accounting acct = task->ioac;
+ unsigned long flags;
+
++ if (!ptrace_may_access(task, PTRACE_MODE_READ))
++ return -EACCES;
++
+ if (whole && lock_task_sighand(task, &flags)) {
+ struct task_struct *t = task;
+
+@@ -2575,7 +2578,7 @@ static const struct pid_entry tgid_base_stuff[] = {
+ REG("coredump_filter", S_IRUGO|S_IWUSR, proc_coredump_filter_operations),
+ #endif
+ #ifdef CONFIG_TASK_IO_ACCOUNTING
+- INF("io", S_IRUGO, proc_tgid_io_accounting),
++ INF("io", S_IRUSR, proc_tgid_io_accounting),
+ #endif
+ };
+
+@@ -2910,7 +2913,7 @@ static const struct pid_entry tid_base_stuff[] = {
+ REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations),
+ #endif
+ #ifdef CONFIG_TASK_IO_ACCOUNTING
+- INF("io", S_IRUGO, proc_tid_io_accounting),
++ INF("io", S_IRUSR, proc_tid_io_accounting),
+ #endif
+ };
+
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index c27a182..9d7e8f7 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -1164,9 +1164,12 @@ static inline int skb_gro_header_hard(struct sk_buff *skb, unsigned int hlen)
+ static inline void *skb_gro_header_slow(struct sk_buff *skb, unsigned int hlen,
+ unsigned int offset)
+ {
++ if (!pskb_may_pull(skb, hlen))
++ return NULL;
++
+ NAPI_GRO_CB(skb)->frag0 = NULL;
+ NAPI_GRO_CB(skb)->frag0_len = 0;
+- return pskb_may_pull(skb, hlen) ? skb->data + offset : NULL;
++ return skb->data + offset;
+ }
+
+ static inline void *skb_gro_mac_header(struct sk_buff *skb)
+diff --git a/kernel/perf_event.c b/kernel/perf_event.c
+index fc5ab8e..37ebc14 100644
+--- a/kernel/perf_event.c
++++ b/kernel/perf_event.c
+@@ -3694,12 +3694,8 @@ static int __perf_event_overflow(struct perf_event *event, int nmi,
+ if (events && atomic_dec_and_test(&event->event_limit)) {
+ ret = 1;
+ event->pending_kill = POLL_HUP;
+- if (nmi) {
+- event->pending_disable = 1;
+- perf_pending_queue(&event->pending,
+- perf_pending_event);
+- } else
+- perf_event_disable(event);
++ event->pending_disable = 1;
++ perf_pending_queue(&event->pending, perf_pending_event);
+ }
+
+ perf_event_output(event, nmi, data, regs);
+diff --git a/net/atm/br2684.c b/net/atm/br2684.c
+index 26a646d..c9230c3 100644
+--- a/net/atm/br2684.c
++++ b/net/atm/br2684.c
+@@ -554,6 +554,12 @@ static const struct net_device_ops br2684_netdev_ops = {
+ .ndo_validate_addr = eth_validate_addr,
+ };
+
++static const struct net_device_ops br2684_netdev_ops_routed = {
++ .ndo_start_xmit = br2684_start_xmit,
++ .ndo_set_mac_address = br2684_mac_addr,
++ .ndo_change_mtu = eth_change_mtu
++};
++
+ static void br2684_setup(struct net_device *netdev)
+ {
+ struct br2684_dev *brdev = BRPRIV(netdev);
+@@ -569,11 +575,10 @@ static void br2684_setup(struct net_device *netdev)
+ static void br2684_setup_routed(struct net_device *netdev)
+ {
+ struct br2684_dev *brdev = BRPRIV(netdev);
+- brdev->net_dev = netdev;
+
++ brdev->net_dev = netdev;
+ netdev->hard_header_len = 0;
+-
+- netdev->netdev_ops = &br2684_netdev_ops;
++ netdev->netdev_ops = &br2684_netdev_ops_routed;
+ netdev->addr_len = 0;
+ netdev->mtu = 1500;
+ netdev->type = ARPHRD_PPP;
+diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
+index 2114e45..8567d47 100644
+--- a/net/bridge/br_private.h
++++ b/net/bridge/br_private.h
+@@ -75,6 +75,7 @@ struct net_bridge_port
+ bridge_id designated_bridge;
+ u32 path_cost;
+ u32 designated_cost;
++ unsigned long designated_age;
+
+ struct timer_list forward_delay_timer;
+ struct timer_list hold_timer;
+diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c
+index fd3f8d6..c7d6bfc 100644
+--- a/net/bridge/br_stp.c
++++ b/net/bridge/br_stp.c
+@@ -165,8 +165,7 @@ void br_transmit_config(struct net_bridge_port *p)
+ else {
+ struct net_bridge_port *root
+ = br_get_port(br, br->root_port);
+- bpdu.message_age = br->max_age
+- - (root->message_age_timer.expires - jiffies)
++ bpdu.message_age = (jiffies - root->designated_age)
+ + MESSAGE_AGE_INCR;
+ }
+ bpdu.max_age = br->max_age;
+@@ -190,6 +189,7 @@ static inline void br_record_config_information(struct net_bridge_port *p,
+ p->designated_cost = bpdu->root_path_cost;
+ p->designated_bridge = bpdu->bridge_id;
+ p->designated_port = bpdu->port_id;
++ p->designated_age = jiffies + bpdu->message_age;
+
+ mod_timer(&p->message_age_timer, jiffies
+ + (p->br->max_age - bpdu->message_age));
+diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
+index cfab9e4..f614584 100644
+--- a/net/ipv4/ip_gre.c
++++ b/net/ipv4/ip_gre.c
+@@ -1665,14 +1665,15 @@ static int __init ipgre_init(void)
+
+ printk(KERN_INFO "GRE over IPv4 tunneling driver\n");
+
+- if (inet_add_protocol(&ipgre_protocol, IPPROTO_GRE) < 0) {
+- printk(KERN_INFO "ipgre init: can't add protocol\n");
+- return -EAGAIN;
+- }
+-
+ err = register_pernet_gen_device(&ipgre_net_id, &ipgre_net_ops);
+ if (err < 0)
+- goto gen_device_failed;
++ return err;
++
++ err = inet_add_protocol(&ipgre_protocol, IPPROTO_GRE);
++ if (err < 0) {
++ printk(KERN_INFO "ipgre init: can't add protocol\n");
++ goto add_proto_failed;
++ }
+
+ err = rtnl_link_register(&ipgre_link_ops);
+ if (err < 0)
+@@ -1688,9 +1689,9 @@ out:
+ tap_ops_failed:
+ rtnl_link_unregister(&ipgre_link_ops);
+ rtnl_link_failed:
+- unregister_pernet_gen_device(ipgre_net_id, &ipgre_net_ops);
+-gen_device_failed:
+ inet_del_protocol(&ipgre_protocol, IPPROTO_GRE);
++add_proto_failed:
++ unregister_pernet_gen_device(ipgre_net_id, &ipgre_net_ops);
+ goto out;
+ }
+
+@@ -1698,9 +1699,9 @@ static void __exit ipgre_fini(void)
+ {
+ rtnl_link_unregister(&ipgre_tap_ops);
+ rtnl_link_unregister(&ipgre_link_ops);
+- unregister_pernet_gen_device(ipgre_net_id, &ipgre_net_ops);
+ if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0)
+ printk(KERN_INFO "ipgre close: can't remove protocol\n");
++ unregister_pernet_gen_device(ipgre_net_id, &ipgre_net_ops);
+ }
+
+ module_init(ipgre_init);
+diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
+index f37df1a..860b5c5 100644
+--- a/net/ipv4/ipip.c
++++ b/net/ipv4/ipip.c
+@@ -830,15 +830,14 @@ static int __init ipip_init(void)
+
+ printk(banner);
+
+- if (xfrm4_tunnel_register(&ipip_handler, AF_INET)) {
++ err = register_pernet_gen_device(&ipip_net_id, &ipip_net_ops);
++ if (err < 0)
++ return err;
++ err = xfrm4_tunnel_register(&ipip_handler, AF_INET);
++ if (err < 0) {
++ unregister_pernet_device(&ipip_net_ops);
+ printk(KERN_INFO "ipip init: can't register tunnel\n");
+- return -EAGAIN;
+ }
+-
+- err = register_pernet_gen_device(&ipip_net_id, &ipip_net_ops);
+- if (err)
+- xfrm4_tunnel_deregister(&ipip_handler, AF_INET);
+-
+ return err;
+ }
+
+diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
+index 9a95c82..7fb3e02 100644
+--- a/net/ipv6/ip6_tunnel.c
++++ b/net/ipv6/ip6_tunnel.c
+@@ -1466,27 +1466,29 @@ static int __init ip6_tunnel_init(void)
+ {
+ int err;
+
+- if (xfrm6_tunnel_register(&ip4ip6_handler, AF_INET)) {
++ err = register_pernet_device(&ip6_tnl_net_ops);
++ if (err < 0)
++ goto out_pernet;
++
++ err = xfrm6_tunnel_register(&ip4ip6_handler, AF_INET);
++ if (err < 0) {
+ printk(KERN_ERR "ip6_tunnel init: can't register ip4ip6\n");
+- err = -EAGAIN;
+- goto out;
++ goto out_ip4ip6;
+ }
+
+- if (xfrm6_tunnel_register(&ip6ip6_handler, AF_INET6)) {
++ err = xfrm6_tunnel_register(&ip6ip6_handler, AF_INET6);
++ if (err < 0) {
+ printk(KERN_ERR "ip6_tunnel init: can't register ip6ip6\n");
+- err = -EAGAIN;
+- goto unreg_ip4ip6;
++ goto out_ip6ip6;
+ }
+
+- err = register_pernet_gen_device(&ip6_tnl_net_id, &ip6_tnl_net_ops);
+- if (err < 0)
+- goto err_pernet;
+ return 0;
+-err_pernet:
+- xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6);
+-unreg_ip4ip6:
++
++out_ip6ip6:
+ xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET);
+-out:
++out_ip4ip6:
++ unregister_pernet_device(&ip6_tnl_net_ops);
++out_pernet:
+ return err;
+ }
+
+diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
+index de2ffef..b128c07 100644
+--- a/net/ipv6/sit.c
++++ b/net/ipv6/sit.c
+@@ -1086,15 +1086,14 @@ static int __init sit_init(void)
+
+ printk(KERN_INFO "IPv6 over IPv4 tunneling driver\n");
+
+- if (xfrm4_tunnel_register(&sit_handler, AF_INET6) < 0) {
+- printk(KERN_INFO "sit init: Can't add protocol\n");
+- return -EAGAIN;
+- }
+-
+ err = register_pernet_gen_device(&sit_net_id, &sit_net_ops);
+ if (err < 0)
+- xfrm4_tunnel_deregister(&sit_handler, AF_INET6);
+-
++ return err;
++ err = xfrm4_tunnel_register(&sit_handler, AF_INET6);
++ if (err < 0) {
++ unregister_pernet_device(&sit_net_ops);
++ printk(KERN_INFO "sit init: Can't add protocol\n");
++ }
+ return err;
+ }
+
+diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
+index 81a95c0..48bb1e3 100644
+--- a/net/ipv6/xfrm6_tunnel.c
++++ b/net/ipv6/xfrm6_tunnel.c
+@@ -344,32 +344,38 @@ static struct xfrm6_tunnel xfrm46_tunnel_handler = {
+
+ static int __init xfrm6_tunnel_init(void)
+ {
+- if (xfrm_register_type(&xfrm6_tunnel_type, AF_INET6) < 0)
++ int rv;
++
++ rv = xfrm6_tunnel_spi_init();
++ if (rv < 0)
+ goto err;
+- if (xfrm6_tunnel_register(&xfrm6_tunnel_handler, AF_INET6))
+- goto unreg;
+- if (xfrm6_tunnel_register(&xfrm46_tunnel_handler, AF_INET))
+- goto dereg6;
+- if (xfrm6_tunnel_spi_init() < 0)
+- goto dereg46;
++ rv = xfrm_register_type(&xfrm6_tunnel_type, AF_INET6);
++ if (rv < 0)
++ goto out_type;
++ rv = xfrm6_tunnel_register(&xfrm6_tunnel_handler, AF_INET6);
++ if (rv < 0)
++ goto out_xfrm6;
++ rv = xfrm6_tunnel_register(&xfrm46_tunnel_handler, AF_INET);
++ if (rv < 0)
++ goto out_xfrm46;
+ return 0;
+
+-dereg46:
+- xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET);
+-dereg6:
++out_xfrm46:
+ xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
+-unreg:
++out_xfrm6:
+ xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
++out_type:
++ xfrm6_tunnel_spi_fini();
+ err:
+- return -EAGAIN;
++ return rv;
+ }
+
+ static void __exit xfrm6_tunnel_fini(void)
+ {
+- xfrm6_tunnel_spi_fini();
+ xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET);
+ xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
+ xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
++ xfrm6_tunnel_spi_fini();
+ }
+
+ module_init(xfrm6_tunnel_init);
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index 5bea319..e67eea7 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -2308,6 +2308,9 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
+ {
+ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+
++ if (!ifmgd->associated)
++ return;
++
+ if (test_and_clear_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running))
+ add_timer(&ifmgd->timer);
+ if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running))
+diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
+index 830faf4..4418bb4 100644
+--- a/net/sunrpc/rpcb_clnt.c
++++ b/net/sunrpc/rpcb_clnt.c
+@@ -533,7 +533,7 @@ void rpcb_getport_async(struct rpc_task *task)
+ u32 bind_version;
+ struct rpc_xprt *xprt;
+ struct rpc_clnt *rpcb_clnt;
+- static struct rpcbind_args *map;
++ struct rpcbind_args *map;
+ struct rpc_task *child;
+ struct sockaddr_storage addr;
+ struct sockaddr *sap = (struct sockaddr *)&addr;
+diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
+index 9191b2f..570da30 100644
+--- a/net/sunrpc/sched.c
++++ b/net/sunrpc/sched.c
+@@ -613,30 +613,25 @@ static void __rpc_execute(struct rpc_task *task)
+ BUG_ON(RPC_IS_QUEUED(task));
+
+ for (;;) {
++ void (*do_action)(struct rpc_task *);
+
+ /*
+- * Execute any pending callback.
++ * Execute any pending callback first.
+ */
+- if (task->tk_callback) {
+- void (*save_callback)(struct rpc_task *);
+-
+- /*
+- * We set tk_callback to NULL before calling it,
+- * in case it sets the tk_callback field itself:
+- */
+- save_callback = task->tk_callback;
+- task->tk_callback = NULL;
+- save_callback(task);
+- } else {
++ do_action = task->tk_callback;
++ task->tk_callback = NULL;
++ if (do_action == NULL) {
+ /*
+ * Perform the next FSM step.
+- * tk_action may be NULL when the task has been killed
+- * by someone else.
++ * tk_action may be NULL if the task has been killed.
++ * In particular, note that rpc_killall_tasks may
++ * do this at any time, so beware when dereferencing.
+ */
+- if (task->tk_action == NULL)
++ do_action = task->tk_action;
++ if (do_action == NULL)
+ break;
+- task->tk_action(task);
+ }
++ do_action(task);
+
+ /*
+ * Lockless check for whether task is sleeping or not.
+diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
+index df760ad..cc1fb36 100644
+--- a/net/sunrpc/svc_xprt.c
++++ b/net/sunrpc/svc_xprt.c
+@@ -896,12 +896,13 @@ void svc_delete_xprt(struct svc_xprt *xprt)
+ if (!test_and_set_bit(XPT_DETACHED, &xprt->xpt_flags))
+ list_del_init(&xprt->xpt_list);
+ /*
+- * We used to delete the transport from whichever list
+- * it's sk_xprt.xpt_ready node was on, but we don't actually
+- * need to. This is because the only time we're called
+- * while still attached to a queue, the queue itself
+- * is about to be destroyed (in svc_destroy).
++ * The only time we're called while xpt_ready is still on a list
++ * is while the list itself is about to be destroyed (in
++ * svc_destroy). BUT svc_xprt_enqueue could still be attempting
++ * to add new entries to the sp_sockets list, so we can't leave
++ * a freed xprt on it.
+ */
++ list_del_init(&xprt->xpt_ready);
+ if (test_bit(XPT_TEMP, &xprt->xpt_flags))
+ serv->sv_tmpcnt--;
+
+diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
+index 08bfed5..038232d 100644
+--- a/sound/core/pcm_compat.c
++++ b/sound/core/pcm_compat.c
+@@ -341,7 +341,7 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream,
+ kfree(bufs);
+ return -EFAULT;
+ }
+- bufs[ch] = compat_ptr(ptr);
++ bufs[i] = compat_ptr(ptr);
+ bufptr++;
+ }
+ if (dir == SNDRV_PCM_STREAM_PLAYBACK)
+diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
+index 62fbb84..77dae16 100644
+--- a/sound/soc/blackfin/bf5xx-i2s-pcm.c
++++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c
+@@ -139,11 +139,20 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
+ pr_debug("%s enter\n", __func__);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ diff = sport_curr_offset_tx(sport);
+- frames = bytes_to_frames(substream->runtime, diff);
+ } else {
+ diff = sport_curr_offset_rx(sport);
+- frames = bytes_to_frames(substream->runtime, diff);
+ }
++
++ /*
++ * TX at least can report one frame beyond the end of the
++ * buffer if we hit the wraparound case - clamp to within the
++ * buffer as the ALSA APIs require.
++ */
++ if (diff == snd_pcm_lib_buffer_bytes(substream))
++ diff = 0;
++
++ frames = bytes_to_frames(substream->runtime, diff);
++
+ return frames;
+ }
+