summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '2.6.32/1057_linux-2.6.32.58.patch')
-rw-r--r--2.6.32/1057_linux-2.6.32.58.patch1280
1 files changed, 1280 insertions, 0 deletions
diff --git a/2.6.32/1057_linux-2.6.32.58.patch b/2.6.32/1057_linux-2.6.32.58.patch
new file mode 100644
index 0000000..5945acc
--- /dev/null
+++ b/2.6.32/1057_linux-2.6.32.58.patch
@@ -0,0 +1,1280 @@
+diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
+index eea4947..9cc3fe5 100644
+--- a/arch/arm/include/asm/assembler.h
++++ b/arch/arm/include/asm/assembler.h
+@@ -133,6 +133,11 @@
+ disable_irq
+ .endm
+
++ .macro save_and_disable_irqs_notrace, oldcpsr
++ mrs \oldcpsr, cpsr
++ disable_irq_notrace
++ .endm
++
+ /*
+ * Restore interrupt state previously stored in a register. We don't
+ * guarantee that this will preserve the flags.
+diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
+index e1bd975..632b626 100644
+--- a/arch/arm/mm/cache-v7.S
++++ b/arch/arm/mm/cache-v7.S
+@@ -39,9 +39,15 @@ loop1:
+ and r1, r1, #7 @ mask of the bits for current cache only
+ cmp r1, #2 @ see what cache we have at this level
+ blt skip @ skip if no cache, or just i-cache
++#ifdef CONFIG_PREEMPT
++ save_and_disable_irqs_notrace r9 @ make cssr&csidr read atomic
++#endif
+ mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
+ isb @ isb to sych the new cssr&csidr
+ mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
++#ifdef CONFIG_PREEMPT
++ restore_irqs_notrace r9
++#endif
+ and r2, r1, #7 @ extract the length of the cache lines
+ add r2, r2, #4 @ add 4 (line length offset)
+ ldr r4, =0x3ff
+diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h
+index 0c940d3..82c882c 100644
+--- a/arch/s390/include/asm/compat.h
++++ b/arch/s390/include/asm/compat.h
+@@ -171,13 +171,6 @@ static inline int is_compat_task(void)
+ return test_thread_flag(TIF_31BIT);
+ }
+
+-#else
+-
+-static inline int is_compat_task(void)
+-{
+- return 0;
+-}
+-
+ #endif
+
+ static inline void __user *arch_compat_alloc_user_space(long len)
+diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
+index 5417eb5..cea2855 100644
+--- a/arch/s390/kernel/process.c
++++ b/arch/s390/kernel/process.c
+@@ -32,7 +32,6 @@
+ #include <linux/kernel_stat.h>
+ #include <linux/syscalls.h>
+ #include <linux/compat.h>
+-#include <asm/compat.h>
+ #include <asm/uaccess.h>
+ #include <asm/pgtable.h>
+ #include <asm/system.h>
+diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
+index 08f8838..170e7af 100644
+--- a/arch/s390/kernel/ptrace.c
++++ b/arch/s390/kernel/ptrace.c
+@@ -36,8 +36,8 @@
+ #include <linux/regset.h>
+ #include <linux/tracehook.h>
+ #include <linux/seccomp.h>
++#include <linux/compat.h>
+ #include <trace/syscall.h>
+-#include <asm/compat.h>
+ #include <asm/segment.h>
+ #include <asm/page.h>
+ #include <asm/pgtable.h>
+diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
+index 061479f..0b2573a 100644
+--- a/arch/s390/kernel/setup.c
++++ b/arch/s390/kernel/setup.c
+@@ -43,6 +43,7 @@
+ #include <linux/reboot.h>
+ #include <linux/topology.h>
+ #include <linux/ftrace.h>
++#include <linux/compat.h>
+
+ #include <asm/ipl.h>
+ #include <asm/uaccess.h>
+@@ -56,7 +57,6 @@
+ #include <asm/ptrace.h>
+ #include <asm/sections.h>
+ #include <asm/ebcdic.h>
+-#include <asm/compat.h>
+ #include <asm/kvm_virtio.h>
+
+ long psw_kernel_bits = (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY |
+diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c
+index f4558cc..0ab74ae 100644
+--- a/arch/s390/mm/mmap.c
++++ b/arch/s390/mm/mmap.c
+@@ -27,8 +27,8 @@
+ #include <linux/personality.h>
+ #include <linux/mm.h>
+ #include <linux/module.h>
++#include <linux/compat.h>
+ #include <asm/pgalloc.h>
+-#include <asm/compat.h>
+
+ /*
+ * Top of mmap area (just below the process stack).
+diff --git a/crypto/sha512_generic.c b/crypto/sha512_generic.c
+index 88f160b..107f6f7 100644
+--- a/crypto/sha512_generic.c
++++ b/crypto/sha512_generic.c
+@@ -31,11 +31,6 @@ static inline u64 Maj(u64 x, u64 y, u64 z)
+ return (x & y) | (z & (x | y));
+ }
+
+-static inline u64 RORu64(u64 x, u64 y)
+-{
+- return (x >> y) | (x << (64 - y));
+-}
+-
+ static const u64 sha512_K[80] = {
+ 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
+ 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+@@ -66,10 +61,10 @@ static const u64 sha512_K[80] = {
+ 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL,
+ };
+
+-#define e0(x) (RORu64(x,28) ^ RORu64(x,34) ^ RORu64(x,39))
+-#define e1(x) (RORu64(x,14) ^ RORu64(x,18) ^ RORu64(x,41))
+-#define s0(x) (RORu64(x, 1) ^ RORu64(x, 8) ^ (x >> 7))
+-#define s1(x) (RORu64(x,19) ^ RORu64(x,61) ^ (x >> 6))
++#define e0(x) (ror64(x,28) ^ ror64(x,34) ^ ror64(x,39))
++#define e1(x) (ror64(x,14) ^ ror64(x,18) ^ ror64(x,41))
++#define s0(x) (ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7))
++#define s1(x) (ror64(x,19) ^ ror64(x,61) ^ (x >> 6))
+
+ static inline void LOAD_OP(int I, u64 *W, const u8 *input)
+ {
+@@ -78,7 +73,7 @@ static inline void LOAD_OP(int I, u64 *W, const u8 *input)
+
+ static inline void BLEND_OP(int I, u64 *W)
+ {
+- W[I % 16] += s1(W[(I-2) % 16]) + W[(I-7) % 16] + s0(W[(I-15) % 16]);
++ W[I & 15] += s1(W[(I-2) & 15]) + W[(I-7) & 15] + s0(W[(I-15) & 15]);
+ }
+
+ static void
+@@ -89,46 +84,42 @@ sha512_transform(u64 *state, const u8 *input)
+ int i;
+ u64 W[16];
+
+- /* load the input */
+- for (i = 0; i < 16; i++)
+- LOAD_OP(i, W, input);
+-
+ /* load the state into our registers */
+ a=state[0]; b=state[1]; c=state[2]; d=state[3];
+ e=state[4]; f=state[5]; g=state[6]; h=state[7];
+
+-#define SHA512_0_15(i, a, b, c, d, e, f, g, h) \
+- t1 = h + e1(e) + Ch(e, f, g) + sha512_K[i] + W[i]; \
+- t2 = e0(a) + Maj(a, b, c); \
+- d += t1; \
+- h = t1 + t2
+-
+-#define SHA512_16_79(i, a, b, c, d, e, f, g, h) \
+- BLEND_OP(i, W); \
+- t1 = h + e1(e) + Ch(e, f, g) + sha512_K[i] + W[(i)%16]; \
+- t2 = e0(a) + Maj(a, b, c); \
+- d += t1; \
+- h = t1 + t2
+-
+- for (i = 0; i < 16; i += 8) {
+- SHA512_0_15(i, a, b, c, d, e, f, g, h);
+- SHA512_0_15(i + 1, h, a, b, c, d, e, f, g);
+- SHA512_0_15(i + 2, g, h, a, b, c, d, e, f);
+- SHA512_0_15(i + 3, f, g, h, a, b, c, d, e);
+- SHA512_0_15(i + 4, e, f, g, h, a, b, c, d);
+- SHA512_0_15(i + 5, d, e, f, g, h, a, b, c);
+- SHA512_0_15(i + 6, c, d, e, f, g, h, a, b);
+- SHA512_0_15(i + 7, b, c, d, e, f, g, h, a);
+- }
+- for (i = 16; i < 80; i += 8) {
+- SHA512_16_79(i, a, b, c, d, e, f, g, h);
+- SHA512_16_79(i + 1, h, a, b, c, d, e, f, g);
+- SHA512_16_79(i + 2, g, h, a, b, c, d, e, f);
+- SHA512_16_79(i + 3, f, g, h, a, b, c, d, e);
+- SHA512_16_79(i + 4, e, f, g, h, a, b, c, d);
+- SHA512_16_79(i + 5, d, e, f, g, h, a, b, c);
+- SHA512_16_79(i + 6, c, d, e, f, g, h, a, b);
+- SHA512_16_79(i + 7, b, c, d, e, f, g, h, a);
++ /* now iterate */
++ for (i=0; i<80; i+=8) {
++ if (!(i & 8)) {
++ int j;
++
++ if (i < 16) {
++ /* load the input */
++ for (j = 0; j < 16; j++)
++ LOAD_OP(i + j, W, input);
++ } else {
++ for (j = 0; j < 16; j++) {
++ BLEND_OP(i + j, W);
++ }
++ }
++ }
++
++ t1 = h + e1(e) + Ch(e,f,g) + sha512_K[i ] + W[(i & 15)];
++ t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
++ t1 = g + e1(d) + Ch(d,e,f) + sha512_K[i+1] + W[(i & 15) + 1];
++ t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
++ t1 = f + e1(c) + Ch(c,d,e) + sha512_K[i+2] + W[(i & 15) + 2];
++ t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
++ t1 = e + e1(b) + Ch(b,c,d) + sha512_K[i+3] + W[(i & 15) + 3];
++ t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
++ t1 = d + e1(a) + Ch(a,b,c) + sha512_K[i+4] + W[(i & 15) + 4];
++ t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
++ t1 = c + e1(h) + Ch(h,a,b) + sha512_K[i+5] + W[(i & 15) + 5];
++ t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
++ t1 = b + e1(g) + Ch(g,h,a) + sha512_K[i+6] + W[(i & 15) + 6];
++ t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
++ t1 = a + e1(f) + Ch(f,g,h) + sha512_K[i+7] + W[(i & 15) + 7];
++ t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
+ }
+
+ state[0] += a; state[1] += b; state[2] += c; state[3] += d;
+diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
+index f6872f9..9589b7f 100644
+--- a/drivers/base/firmware_class.c
++++ b/drivers/base/firmware_class.c
+@@ -493,8 +493,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
+ if (!firmware) {
+ dev_err(device, "%s: kmalloc(struct firmware) failed\n",
+ __func__);
+- retval = -ENOMEM;
+- goto out;
++ return -ENOMEM;
+ }
+
+ for (builtin = __start_builtin_fw; builtin != __end_builtin_fw;
+@@ -508,6 +507,14 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
+ return 0;
+ }
+
++ read_lock_usermodehelper();
++
++ if (WARN_ON(usermodehelper_is_disabled())) {
++ dev_err(device, "firmware: %s will not be loaded\n", name);
++ retval = -EBUSY;
++ goto out;
++ }
++
+ if (uevent)
+ dev_info(device, "firmware: requesting %s\n", name);
+
+@@ -545,6 +552,7 @@ error_kfree_fw:
+ kfree(firmware);
+ *firmware_p = NULL;
+ out:
++ read_unlock_usermodehelper();
+ return retval;
+ }
+
+diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
+index 59cccc9..a4592ec 100644
+--- a/drivers/cdrom/cdrom.c
++++ b/drivers/cdrom/cdrom.c
+@@ -2057,11 +2057,6 @@ static int cdrom_read_cdda_old(struct cdrom_device_info *cdi, __u8 __user *ubuf,
+ if (!nr)
+ return -ENOMEM;
+
+- if (!access_ok(VERIFY_WRITE, ubuf, nframes * CD_FRAMESIZE_RAW)) {
+- ret = -EFAULT;
+- goto out;
+- }
+-
+ cgc.data_direction = CGC_DATA_READ;
+ while (nframes > 0) {
+ if (nr > nframes)
+@@ -2070,7 +2065,7 @@ static int cdrom_read_cdda_old(struct cdrom_device_info *cdi, __u8 __user *ubuf,
+ ret = cdrom_read_block(cdi, &cgc, lba, nr, 1, CD_FRAMESIZE_RAW);
+ if (ret)
+ break;
+- if (__copy_to_user(ubuf, cgc.buffer, CD_FRAMESIZE_RAW * nr)) {
++ if (copy_to_user(ubuf, cgc.buffer, CD_FRAMESIZE_RAW * nr)) {
+ ret = -EFAULT;
+ break;
+ }
+@@ -2078,7 +2073,6 @@ static int cdrom_read_cdda_old(struct cdrom_device_info *cdi, __u8 __user *ubuf,
+ nframes -= nr;
+ lba += nr;
+ }
+-out:
+ kfree(cgc.buffer);
+ return ret;
+ }
+diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
+index 96b39fc..6476022 100644
+--- a/drivers/gpu/drm/i915/intel_lvds.c
++++ b/drivers/gpu/drm/i915/intel_lvds.c
+@@ -892,6 +892,14 @@ static const struct dmi_system_id intel_no_lvds[] = {
+ },
+ {
+ .callback = intel_no_lvds_dmi_callback,
++ .ident = "AOpen i45GMx-I",
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
++ DMI_MATCH(DMI_BOARD_NAME, "i45GMx-I"),
++ },
++ },
++ {
++ .callback = intel_no_lvds_dmi_callback,
+ .ident = "Aopen i945GTt-VFA",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"),
+diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
+index c9e93ea..a2ae151 100644
+--- a/drivers/gpu/drm/radeon/r100.c
++++ b/drivers/gpu/drm/radeon/r100.c
+@@ -218,9 +218,7 @@ int r100_irq_process(struct radeon_device *rdev)
+ WREG32(RADEON_AIC_CNTL, msi_rearm | RS400_MSI_REARM);
+ break;
+ default:
+- msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN;
+- WREG32(RADEON_MSI_REARM_EN, msi_rearm);
+- WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN);
++ WREG32(RADEON_MSI_REARM_EN, RV370_MSI_REARM_EN);
+ break;
+ }
+ }
+diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
+index 1700297..52b7799 100644
+--- a/drivers/gpu/drm/radeon/rs600.c
++++ b/drivers/gpu/drm/radeon/rs600.c
+@@ -270,9 +270,7 @@ int rs600_irq_process(struct radeon_device *rdev)
+ WREG32(RADEON_BUS_CNTL, msi_rearm | RS600_MSI_REARM);
+ break;
+ default:
+- msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN;
+- WREG32(RADEON_MSI_REARM_EN, msi_rearm);
+- WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN);
++ WREG32(RADEON_MSI_REARM_EN, RV370_MSI_REARM_EN);
+ break;
+ }
+ }
+diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c
+index afebc34..9ae1bae 100644
+--- a/drivers/hwmon/f75375s.c
++++ b/drivers/hwmon/f75375s.c
+@@ -159,7 +159,7 @@ static inline void f75375_write8(struct i2c_client *client, u8 reg,
+ static inline void f75375_write16(struct i2c_client *client, u8 reg,
+ u16 value)
+ {
+- int err = i2c_smbus_write_byte_data(client, reg, (value << 8));
++ int err = i2c_smbus_write_byte_data(client, reg, (value >> 8));
+ if (err)
+ return;
+ i2c_smbus_write_byte_data(client, reg + 1, (value & 0xFF));
+@@ -311,7 +311,7 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val)
+ fanmode |= (3 << FAN_CTRL_MODE(nr));
+ break;
+ case 2: /* AUTOMATIC*/
+- fanmode |= (2 << FAN_CTRL_MODE(nr));
++ fanmode |= (1 << FAN_CTRL_MODE(nr));
+ break;
+ case 3: /* fan speed */
+ break;
+diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c
+index 2eb9dc2..09f0ee0 100644
+--- a/drivers/media/video/hdpvr/hdpvr-video.c
++++ b/drivers/media/video/hdpvr/hdpvr-video.c
+@@ -279,12 +279,13 @@ static int hdpvr_start_streaming(struct hdpvr_device *dev)
+
+ hdpvr_config_call(dev, CTRL_START_STREAMING_VALUE, 0x00);
+
++ dev->status = STATUS_STREAMING;
++
+ INIT_WORK(&dev->worker, hdpvr_transmit_buffers);
+ queue_work(dev->workqueue, &dev->worker);
+
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+ "streaming started\n");
+- dev->status = STATUS_STREAMING;
+
+ return 0;
+ }
+diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
+index 4460e00..ee23d4e 100644
+--- a/drivers/s390/block/dasd_eckd.c
++++ b/drivers/s390/block/dasd_eckd.c
+@@ -19,6 +19,7 @@
+ #include <linux/bio.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
++#include <linux/compat.h>
+
+ #include <asm/debug.h>
+ #include <asm/idals.h>
+diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
+index a5354b8..0400e7c 100644
+--- a/drivers/s390/block/dasd_ioctl.c
++++ b/drivers/s390/block/dasd_ioctl.c
+@@ -13,6 +13,7 @@
+ #define KMSG_COMPONENT "dasd"
+
+ #include <linux/interrupt.h>
++#include <linux/compat.h>
+ #include <linux/major.h>
+ #include <linux/fs.h>
+ #include <linux/blkpg.h>
+diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
+index 097d384..8d1d18c 100644
+--- a/drivers/s390/char/fs3270.c
++++ b/drivers/s390/char/fs3270.c
+@@ -14,6 +14,7 @@
+ #include <linux/list.h>
+ #include <linux/types.h>
+ #include <linux/smp_lock.h>
++#include <linux/compat.h>
+
+ #include <asm/ccwdev.h>
+ #include <asm/cio.h>
+diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c
+index a6087ce..99cc483 100644
+--- a/drivers/s390/char/vmcp.c
++++ b/drivers/s390/char/vmcp.c
+@@ -16,6 +16,7 @@
+
+ #include <linux/fs.h>
+ #include <linux/init.h>
++#include <linux/compat.h>
+ #include <linux/kernel.h>
+ #include <linux/miscdevice.h>
+ #include <linux/module.h>
+diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c
+index cc5144b..d0b03bc 100644
+--- a/drivers/s390/cio/chsc_sch.c
++++ b/drivers/s390/cio/chsc_sch.c
+@@ -11,6 +11,7 @@
+ #include <linux/module.h>
+ #include <linux/uaccess.h>
+ #include <linux/miscdevice.h>
++#include <linux/compat.h>
+
+ #include <asm/cio.h>
+ #include <asm/chsc.h>
+diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c
+index ef681df..2e37ac9 100644
+--- a/drivers/s390/scsi/zfcp_cfdc.c
++++ b/drivers/s390/scsi/zfcp_cfdc.c
+@@ -12,6 +12,7 @@
+
+ #include <linux/types.h>
+ #include <linux/miscdevice.h>
++#include <linux/compat.h>
+ #include <asm/ccwdev.h>
+ #include "zfcp_def.h"
+ #include "zfcp_ext.h"
+diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
+index 3e250ca..1549eea 100644
+--- a/drivers/scsi/3w-9xxx.c
++++ b/drivers/scsi/3w-9xxx.c
+@@ -76,6 +76,7 @@
+ Fix bug in twa_get_param() on 4GB+.
+ Use pci_resource_len() for ioremap().
+ 2.26.02.012 - Add power management support.
++ 2.26.02.013 - Fix bug in twa_load_sgl().
+ */
+
+ #include <linux/module.h>
+@@ -100,7 +101,7 @@
+ #include "3w-9xxx.h"
+
+ /* Globals */
+-#define TW_DRIVER_VERSION "2.26.02.012"
++#define TW_DRIVER_VERSION "2.26.02.013"
+ static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT];
+ static unsigned int twa_device_extension_count;
+ static int twa_major = -1;
+@@ -1378,10 +1379,12 @@ static void twa_load_sgl(TW_Device_Extension *tw_dev, TW_Command_Full *full_comm
+ newcommand = &full_command_packet->command.newcommand;
+ newcommand->request_id__lunl =
+ cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id));
+- newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
+- newcommand->sg_list[0].length = cpu_to_le32(length);
++ if (length) {
++ newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
++ newcommand->sg_list[0].length = cpu_to_le32(length);
++ }
+ newcommand->sgl_entries__lunh =
+- cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->sgl_entries__lunh), 1));
++ cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->sgl_entries__lunh), length ? 1 : 0));
+ } else {
+ oldcommand = &full_command_packet->command.oldcommand;
+ oldcommand->request_id = request_id;
+diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
+index 8213f79..0ff157a 100644
+--- a/drivers/usb/host/pci-quirks.c
++++ b/drivers/usb/host/pci-quirks.c
+@@ -503,7 +503,17 @@ static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev)
+ */
+ if (pdev->vendor == 0x184e) /* vendor Netlogic */
+ return;
++ if (pdev->class != PCI_CLASS_SERIAL_USB_UHCI &&
++ pdev->class != PCI_CLASS_SERIAL_USB_OHCI &&
++ pdev->class != PCI_CLASS_SERIAL_USB_EHCI &&
++ pdev->class != PCI_CLASS_SERIAL_USB_XHCI)
++ return;
+
++ if (pci_enable_device(pdev) < 0) {
++ dev_warn(&pdev->dev, "Can't enable PCI device, "
++ "BIOS handoff failed.\n");
++ return;
++ }
+ if (pdev->class == PCI_CLASS_SERIAL_USB_UHCI)
+ quirk_usb_handoff_uhci(pdev);
+ else if (pdev->class == PCI_CLASS_SERIAL_USB_OHCI)
+@@ -512,5 +522,6 @@ static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev)
+ quirk_usb_disable_ehci(pdev);
+ else if (pdev->class == PCI_CLASS_SERIAL_USB_XHCI)
+ quirk_usb_handoff_xhci(pdev);
++ pci_disable_device(pdev);
+ }
+ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff);
+diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
+index a2f2f79..8c29073 100644
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -472,26 +472,42 @@ static unsigned int xhci_parse_exponent_interval(struct usb_device *udev,
+ }
+
+ /*
+- * Convert bInterval expressed in frames (in 1-255 range) to exponent of
++ * Convert bInterval expressed in microframes (in 1-255 range) to exponent of
+ * microframes, rounded down to nearest power of 2.
+ */
+-static unsigned int xhci_parse_frame_interval(struct usb_device *udev,
+- struct usb_host_endpoint *ep)
++static unsigned int xhci_microframes_to_exponent(struct usb_device *udev,
++ struct usb_host_endpoint *ep, unsigned int desc_interval,
++ unsigned int min_exponent, unsigned int max_exponent)
+ {
+ unsigned int interval;
+
+- interval = fls(8 * ep->desc.bInterval) - 1;
+- interval = clamp_val(interval, 3, 10);
+- if ((1 << interval) != 8 * ep->desc.bInterval)
++ interval = fls(desc_interval) - 1;
++ interval = clamp_val(interval, min_exponent, max_exponent);
++ if ((1 << interval) != desc_interval)
+ dev_warn(&udev->dev,
+ "ep %#x - rounding interval to %d microframes, ep desc says %d microframes\n",
+ ep->desc.bEndpointAddress,
+ 1 << interval,
+- 8 * ep->desc.bInterval);
++ desc_interval);
+
+ return interval;
+ }
+
++static unsigned int xhci_parse_microframe_interval(struct usb_device *udev,
++ struct usb_host_endpoint *ep)
++{
++ return xhci_microframes_to_exponent(udev, ep,
++ ep->desc.bInterval, 0, 15);
++}
++
++
++static unsigned int xhci_parse_frame_interval(struct usb_device *udev,
++ struct usb_host_endpoint *ep)
++{
++ return xhci_microframes_to_exponent(udev, ep,
++ ep->desc.bInterval * 8, 3, 10);
++}
++
+ /* Return the polling or NAK interval.
+ *
+ * The polling interval is expressed in "microframes". If xHCI's Interval field
+@@ -510,7 +526,7 @@ static inline unsigned int xhci_get_endpoint_interval(struct usb_device *udev,
+ /* Max NAK rate */
+ if (usb_endpoint_xfer_control(&ep->desc) ||
+ usb_endpoint_xfer_bulk(&ep->desc)) {
+- interval = ep->desc.bInterval;
++ interval = xhci_parse_microframe_interval(udev, ep);
+ break;
+ }
+ /* Fall through - SS and HS isoc/int have same decoding */
+diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
+index bb16725..feb96e9 100644
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -136,6 +136,8 @@ static struct usb_device_id id_table [] = {
+ { USB_DEVICE(0x16DC, 0x0011) }, /* W-IE-NE-R Plein & Baus GmbH RCM Remote Control for MARATON Power Supply */
+ { USB_DEVICE(0x16DC, 0x0012) }, /* W-IE-NE-R Plein & Baus GmbH MPOD Multi Channel Power Supply */
+ { USB_DEVICE(0x16DC, 0x0015) }, /* W-IE-NE-R Plein & Baus GmbH CML Control, Monitoring and Data Logger */
++ { USB_DEVICE(0x17A8, 0x0001) }, /* Kamstrup Optical Eye/3-wire */
++ { USB_DEVICE(0x17A8, 0x0005) }, /* Kamstrup M-Bus Master MultiPort 250D */
+ { USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */
+ { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */
+ { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
+diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
+index 8f7cdde..5d8d9a0 100644
+--- a/fs/autofs4/autofs_i.h
++++ b/fs/autofs4/autofs_i.h
+@@ -125,6 +125,7 @@ struct autofs_sb_info {
+ int sub_version;
+ int min_proto;
+ int max_proto;
++ int compat_daemon;
+ unsigned long exp_timeout;
+ unsigned int type;
+ int reghost_enabled;
+diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c
+index 00bf8fc..5bb5a2a 100644
+--- a/fs/autofs4/dev-ioctl.c
++++ b/fs/autofs4/dev-ioctl.c
+@@ -389,6 +389,7 @@ static int autofs_dev_ioctl_setpipefd(struct file *fp,
+ sbi->pipefd = pipefd;
+ sbi->pipe = pipe;
+ sbi->catatonic = 0;
++ sbi->compat_daemon = is_compat_task();
+ }
+ out:
+ mutex_unlock(&sbi->wq_mutex);
+diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
+index 69c8142..0ca145a 100644
+--- a/fs/autofs4/inode.c
++++ b/fs/autofs4/inode.c
+@@ -19,6 +19,7 @@
+ #include <linux/parser.h>
+ #include <linux/bitops.h>
+ #include <linux/magic.h>
++#include <linux/compat.h>
+ #include "autofs_i.h"
+ #include <linux/module.h>
+
+@@ -341,6 +342,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
+ set_autofs_type_indirect(&sbi->type);
+ sbi->min_proto = 0;
+ sbi->max_proto = 0;
++ sbi->compat_daemon = is_compat_task();
+ mutex_init(&sbi->wq_mutex);
+ spin_lock_init(&sbi->fs_lock);
+ sbi->queues = NULL;
+diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
+index 2341375..136a0d6 100644
+--- a/fs/autofs4/waitq.c
++++ b/fs/autofs4/waitq.c
+@@ -90,7 +90,24 @@ static int autofs4_write(struct file *file, const void *addr, int bytes)
+
+ return (bytes > 0);
+ }
+-
++
++/*
++ * The autofs_v5 packet was misdesigned.
++ *
++ * The packets are identical on x86-32 and x86-64, but have different
++ * alignment. Which means that 'sizeof()' will give different results.
++ * Fix it up for the case of running 32-bit user mode on a 64-bit kernel.
++ */
++static noinline size_t autofs_v5_packet_size(struct autofs_sb_info *sbi)
++{
++ size_t pktsz = sizeof(struct autofs_v5_packet);
++#if defined(CONFIG_X86_64) && defined(CONFIG_COMPAT)
++ if (sbi->compat_daemon > 0)
++ pktsz -= 4;
++#endif
++ return pktsz;
++}
++
+ static void autofs4_notify_daemon(struct autofs_sb_info *sbi,
+ struct autofs_wait_queue *wq,
+ int type)
+@@ -147,8 +164,7 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi,
+ {
+ struct autofs_v5_packet *packet = &pkt.v5_pkt.v5_packet;
+
+- pktsz = sizeof(*packet);
+-
++ pktsz = autofs_v5_packet_size(sbi);
+ packet->wait_queue_token = wq->wait_queue_token;
+ packet->len = wq->name.len;
+ memcpy(packet->name, wq->name.name, wq->name.len);
+diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
+index 4e25328..3015389 100644
+--- a/fs/ecryptfs/file.c
++++ b/fs/ecryptfs/file.c
+@@ -323,11 +323,11 @@ ecryptfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+
+ const struct file_operations ecryptfs_dir_fops = {
+ .readdir = ecryptfs_readdir,
++ .read = generic_read_dir,
+ .unlocked_ioctl = ecryptfs_unlocked_ioctl,
+ #ifdef CONFIG_COMPAT
+ .compat_ioctl = ecryptfs_compat_ioctl,
+ #endif
+- .mmap = generic_file_mmap,
+ .open = ecryptfs_open,
+ .flush = ecryptfs_flush,
+ .release = ecryptfs_release,
+diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
+index 88ba4d4..4434e8f 100644
+--- a/fs/ecryptfs/inode.c
++++ b/fs/ecryptfs/inode.c
+@@ -575,8 +575,8 @@ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
+ dget(lower_dentry);
+ rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry);
+ dput(lower_dentry);
+- if (!rc)
+- d_delete(lower_dentry);
++ if (!rc && dentry->d_inode)
++ clear_nlink(dentry->d_inode);
+ fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
+ dir->i_nlink = lower_dir_dentry->d_inode->i_nlink;
+ unlock_dir(lower_dir_dentry);
+@@ -758,18 +758,23 @@ upper_size_to_lower_size(struct ecryptfs_crypt_stat *crypt_stat,
+ }
+
+ /**
+- * ecryptfs_truncate
++ * truncate_upper
+ * @dentry: The ecryptfs layer dentry
+- * @new_length: The length to expand the file to
++ * @ia: Address of the ecryptfs inode's attributes
++ * @lower_ia: Address of the lower inode's attributes
+ *
+ * Function to handle truncations modifying the size of the file. Note
+ * that the file sizes are interpolated. When expanding, we are simply
+- * writing strings of 0's out. When truncating, we need to modify the
+- * underlying file size according to the page index interpolations.
++ * writing strings of 0's out. When truncating, we truncate the upper
++ * inode and update the lower_ia according to the page index
++ * interpolations. If ATTR_SIZE is set in lower_ia->ia_valid upon return,
++ * the caller must use lower_ia in a call to notify_change() to perform
++ * the truncation of the lower inode.
+ *
+ * Returns zero on success; non-zero otherwise
+ */
+-int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
++static int truncate_upper(struct dentry *dentry, struct iattr *ia,
++ struct iattr *lower_ia)
+ {
+ int rc = 0;
+ struct inode *inode = dentry->d_inode;
+@@ -780,8 +785,10 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
+ loff_t lower_size_before_truncate;
+ loff_t lower_size_after_truncate;
+
+- if (unlikely((new_length == i_size)))
++ if (unlikely((ia->ia_size == i_size))) {
++ lower_ia->ia_valid &= ~ATTR_SIZE;
+ goto out;
++ }
+ crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
+ /* Set up a fake ecryptfs file, this is used to interface with
+ * the file in the underlying filesystem so that the
+@@ -801,28 +808,30 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
+ &fake_ecryptfs_file,
+ ecryptfs_inode_to_private(dentry->d_inode)->lower_file);
+ /* Switch on growing or shrinking file */
+- if (new_length > i_size) {
++ if (ia->ia_size > i_size) {
+ char zero[] = { 0x00 };
+
++ lower_ia->ia_valid &= ~ATTR_SIZE;
+ /* Write a single 0 at the last position of the file;
+ * this triggers code that will fill in 0's throughout
+ * the intermediate portion of the previous end of the
+ * file and the new and of the file */
+ rc = ecryptfs_write(&fake_ecryptfs_file, zero,
+- (new_length - 1), 1);
+- } else { /* new_length < i_size_read(inode) */
+- /* We're chopping off all the pages down do the page
+- * in which new_length is located. Fill in the end of
+- * that page from (new_length & ~PAGE_CACHE_MASK) to
++ (ia->ia_size - 1), 1);
++ } else { /* ia->ia_size < i_size_read(inode) */
++ /* We're chopping off all the pages down to the page
++ * in which ia->ia_size is located. Fill in the end of
++ * that page from (ia->ia_size & ~PAGE_CACHE_MASK) to
+ * PAGE_CACHE_SIZE with zeros. */
+ size_t num_zeros = (PAGE_CACHE_SIZE
+- - (new_length & ~PAGE_CACHE_MASK));
++ - (ia->ia_size & ~PAGE_CACHE_MASK));
+
+ if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
+- rc = vmtruncate(inode, new_length);
++ rc = vmtruncate(inode, ia->ia_size);
+ if (rc)
+ goto out_free;
+- rc = vmtruncate(lower_dentry->d_inode, new_length);
++ lower_ia->ia_size = ia->ia_size;
++ lower_ia->ia_valid |= ATTR_SIZE;
+ goto out_free;
+ }
+ if (num_zeros) {
+@@ -834,7 +843,7 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
+ goto out_free;
+ }
+ rc = ecryptfs_write(&fake_ecryptfs_file, zeros_virt,
+- new_length, num_zeros);
++ ia->ia_size, num_zeros);
+ kfree(zeros_virt);
+ if (rc) {
+ printk(KERN_ERR "Error attempting to zero out "
+@@ -843,7 +852,7 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
+ goto out_free;
+ }
+ }
+- vmtruncate(inode, new_length);
++ vmtruncate(inode, ia->ia_size);
+ rc = ecryptfs_write_inode_size_to_metadata(inode);
+ if (rc) {
+ printk(KERN_ERR "Problem with "
+@@ -856,10 +865,12 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
+ lower_size_before_truncate =
+ upper_size_to_lower_size(crypt_stat, i_size);
+ lower_size_after_truncate =
+- upper_size_to_lower_size(crypt_stat, new_length);
+- if (lower_size_after_truncate < lower_size_before_truncate)
+- vmtruncate(lower_dentry->d_inode,
+- lower_size_after_truncate);
++ upper_size_to_lower_size(crypt_stat, ia->ia_size);
++ if (lower_size_after_truncate < lower_size_before_truncate) {
++ lower_ia->ia_size = lower_size_after_truncate;
++ lower_ia->ia_valid |= ATTR_SIZE;
++ } else
++ lower_ia->ia_valid &= ~ATTR_SIZE;
+ }
+ out_free:
+ if (ecryptfs_file_to_private(&fake_ecryptfs_file))
+@@ -869,6 +880,33 @@ out:
+ return rc;
+ }
+
++/**
++ * ecryptfs_truncate
++ * @dentry: The ecryptfs layer dentry
++ * @new_length: The length to expand the file to
++ *
++ * Simple function that handles the truncation of an eCryptfs inode and
++ * its corresponding lower inode.
++ *
++ * Returns zero on success; non-zero otherwise
++ */
++int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
++{
++ struct iattr ia = { .ia_valid = ATTR_SIZE, .ia_size = new_length };
++ struct iattr lower_ia = { .ia_valid = 0 };
++ int rc;
++
++ rc = truncate_upper(dentry, &ia, &lower_ia);
++ if (!rc && lower_ia.ia_valid & ATTR_SIZE) {
++ struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
++
++ mutex_lock(&lower_dentry->d_inode->i_mutex);
++ rc = notify_change(lower_dentry, &lower_ia);
++ mutex_unlock(&lower_dentry->d_inode->i_mutex);
++ }
++ return rc;
++}
++
+ static int
+ ecryptfs_permission(struct inode *inode, int mask)
+ {
+@@ -891,6 +929,7 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
+ {
+ int rc = 0;
+ struct dentry *lower_dentry;
++ struct iattr lower_ia;
+ struct inode *inode;
+ struct inode *lower_inode;
+ struct ecryptfs_crypt_stat *crypt_stat;
+@@ -929,15 +968,11 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
+ }
+ }
+ mutex_unlock(&crypt_stat->cs_mutex);
++ memcpy(&lower_ia, ia, sizeof(lower_ia));
++ if (ia->ia_valid & ATTR_FILE)
++ lower_ia.ia_file = ecryptfs_file_to_lower(ia->ia_file);
+ if (ia->ia_valid & ATTR_SIZE) {
+- ecryptfs_printk(KERN_DEBUG,
+- "ia->ia_valid = [0x%x] ATTR_SIZE" " = [0x%x]\n",
+- ia->ia_valid, ATTR_SIZE);
+- rc = ecryptfs_truncate(dentry, ia->ia_size);
+- /* ecryptfs_truncate handles resizing of the lower file */
+- ia->ia_valid &= ~ATTR_SIZE;
+- ecryptfs_printk(KERN_DEBUG, "ia->ia_valid = [%x]\n",
+- ia->ia_valid);
++ rc = truncate_upper(dentry, ia, &lower_ia);
+ if (rc < 0)
+ goto out;
+ }
+@@ -946,11 +981,11 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
+ * mode change is for clearing setuid/setgid bits. Allow lower fs
+ * to interpret this in its own way.
+ */
+- if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
+- ia->ia_valid &= ~ATTR_MODE;
++ if (lower_ia.ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
++ lower_ia.ia_valid &= ~ATTR_MODE;
+
+ mutex_lock(&lower_dentry->d_inode->i_mutex);
+- rc = notify_change(lower_dentry, ia);
++ rc = notify_change(lower_dentry, &lower_ia);
+ mutex_unlock(&lower_dentry->d_inode->i_mutex);
+ out:
+ fsstack_copy_attr_all(inode, lower_inode, NULL);
+diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
+index c6ac85d..e2f18ad 100644
+--- a/fs/ecryptfs/main.c
++++ b/fs/ecryptfs/main.c
+@@ -212,7 +212,8 @@ enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig,
+ ecryptfs_opt_passthrough, ecryptfs_opt_xattr_metadata,
+ ecryptfs_opt_encrypted_view, ecryptfs_opt_fnek_sig,
+ ecryptfs_opt_fn_cipher, ecryptfs_opt_fn_cipher_key_bytes,
+- ecryptfs_opt_unlink_sigs, ecryptfs_opt_err };
++ ecryptfs_opt_unlink_sigs, ecryptfs_opt_check_dev_ruid,
++ ecryptfs_opt_err };
+
+ static const match_table_t tokens = {
+ {ecryptfs_opt_sig, "sig=%s"},
+@@ -227,6 +228,7 @@ static const match_table_t tokens = {
+ {ecryptfs_opt_fn_cipher, "ecryptfs_fn_cipher=%s"},
+ {ecryptfs_opt_fn_cipher_key_bytes, "ecryptfs_fn_key_bytes=%u"},
+ {ecryptfs_opt_unlink_sigs, "ecryptfs_unlink_sigs"},
++ {ecryptfs_opt_check_dev_ruid, "ecryptfs_check_dev_ruid"},
+ {ecryptfs_opt_err, NULL}
+ };
+
+@@ -270,6 +272,7 @@ static void ecryptfs_init_mount_crypt_stat(
+ * ecryptfs_parse_options
+ * @sb: The ecryptfs super block
+ * @options: The options pased to the kernel
++ * @check_ruid: set to 1 if device uid should be checked against the ruid
+ *
+ * Parse mount options:
+ * debug=N - ecryptfs_verbosity level for debug output
+@@ -285,7 +288,8 @@ static void ecryptfs_init_mount_crypt_stat(
+ *
+ * Returns zero on success; non-zero on error
+ */
+-static int ecryptfs_parse_options(struct super_block *sb, char *options)
++static int ecryptfs_parse_options(struct super_block *sb, char *options,
++ uid_t *check_ruid)
+ {
+ char *p;
+ int rc = 0;
+@@ -310,6 +314,8 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options)
+ char *cipher_key_bytes_src;
+ char *fn_cipher_key_bytes_src;
+
++ *check_ruid = 0;
++
+ if (!options) {
+ rc = -EINVAL;
+ goto out;
+@@ -410,6 +416,9 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options)
+ case ecryptfs_opt_unlink_sigs:
+ mount_crypt_stat->flags |= ECRYPTFS_UNLINK_SIGS;
+ break;
++ case ecryptfs_opt_check_dev_ruid:
++ *check_ruid = 1;
++ break;
+ case ecryptfs_opt_err:
+ default:
+ printk(KERN_WARNING
+@@ -487,6 +496,7 @@ out:
+ }
+
+ struct kmem_cache *ecryptfs_sb_info_cache;
++static struct file_system_type ecryptfs_fs_type;
+
+ /**
+ * ecryptfs_fill_super
+@@ -551,7 +561,8 @@ out:
+ * ecryptfs_interpose to create our initial inode and super block
+ * struct.
+ */
+-static int ecryptfs_read_super(struct super_block *sb, const char *dev_name)
++static int ecryptfs_read_super(struct super_block *sb, const char *dev_name,
++ uid_t check_ruid)
+ {
+ struct path path;
+ int rc;
+@@ -561,6 +572,22 @@ static int ecryptfs_read_super(struct super_block *sb, const char *dev_name)
+ ecryptfs_printk(KERN_WARNING, "path_lookup() failed\n");
+ goto out;
+ }
++ if (path.dentry->d_sb->s_type == &ecryptfs_fs_type) {
++ rc = -EINVAL;
++ printk(KERN_ERR "Mount on filesystem of type "
++ "eCryptfs explicitly disallowed due to "
++ "known incompatibilities\n");
++ goto out_free;
++ }
++
++ if (check_ruid && path.dentry->d_inode->i_uid != current_uid()) {
++ rc = -EPERM;
++ printk(KERN_ERR "Mount of device (uid: %d) not owned by "
++ "requested user (uid: %d)\n",
++ path.dentry->d_inode->i_uid, current_uid());
++ goto out_free;
++ }
++
+ ecryptfs_set_superblock_lower(sb, path.dentry->d_sb);
+ sb->s_maxbytes = path.dentry->d_sb->s_maxbytes;
+ sb->s_blocksize = path.dentry->d_sb->s_blocksize;
+@@ -599,6 +626,7 @@ static int ecryptfs_get_sb(struct file_system_type *fs_type, int flags,
+ {
+ int rc;
+ struct super_block *sb;
++ uid_t check_ruid;
+
+ rc = get_sb_nodev(fs_type, flags, raw_data, ecryptfs_fill_super, mnt);
+ if (rc < 0) {
+@@ -606,12 +634,12 @@ static int ecryptfs_get_sb(struct file_system_type *fs_type, int flags,
+ goto out;
+ }
+ sb = mnt->mnt_sb;
+- rc = ecryptfs_parse_options(sb, raw_data);
++ rc = ecryptfs_parse_options(sb, raw_data, &check_ruid);
+ if (rc) {
+ printk(KERN_ERR "Error parsing options; rc = [%d]\n", rc);
+ goto out_abort;
+ }
+- rc = ecryptfs_read_super(sb, dev_name);
++ rc = ecryptfs_read_super(sb, dev_name, check_ruid);
+ if (rc) {
+ printk(KERN_ERR "Reading sb failed; rc = [%d]\n", rc);
+ goto out_abort;
+diff --git a/include/linux/bitops.h b/include/linux/bitops.h
+index c05a29c..56835a7 100644
+--- a/include/linux/bitops.h
++++ b/include/linux/bitops.h
+@@ -46,6 +46,26 @@ static inline unsigned long hweight_long(unsigned long w)
+ }
+
+ /**
++ * rol64 - rotate a 64-bit value left
++ * @word: value to rotate
++ * @shift: bits to roll
++ */
++static inline __u64 rol64(__u64 word, unsigned int shift)
++{
++ return (word << shift) | (word >> (64 - shift));
++}
++
++/**
++ * ror64 - rotate a 64-bit value right
++ * @word: value to rotate
++ * @shift: bits to roll
++ */
++static inline __u64 ror64(__u64 word, unsigned int shift)
++{
++ return (word >> shift) | (word << (64 - shift));
++}
++
++/**
+ * rol32 - rotate a 32-bit value left
+ * @word: value to rotate
+ * @shift: bits to roll
+diff --git a/include/linux/compat.h b/include/linux/compat.h
+index cab23f2..510266f 100644
+--- a/include/linux/compat.h
++++ b/include/linux/compat.h
+@@ -311,5 +311,9 @@ asmlinkage long compat_sys_openat(unsigned int dfd, const char __user *filename,
+
+ extern void __user *compat_alloc_user_space(unsigned long len);
+
++#else
++
++#define is_compat_task() (0)
++
+ #endif /* CONFIG_COMPAT */
+ #endif /* _LINUX_COMPAT_H */
+diff --git a/include/linux/kernel.h b/include/linux/kernel.h
+index 1221fe4..9acb92d 100644
+--- a/include/linux/kernel.h
++++ b/include/linux/kernel.h
+@@ -411,14 +411,13 @@ static inline char *pack_hex_byte(char *buf, u8 byte)
+ * no local ratelimit_state used in the !PRINTK case
+ */
+ #ifdef CONFIG_PRINTK
+-#define printk_ratelimited(fmt, ...) ({ \
+- static struct ratelimit_state _rs = { \
+- .interval = DEFAULT_RATELIMIT_INTERVAL, \
+- .burst = DEFAULT_RATELIMIT_BURST, \
+- }; \
+- \
+- if (!__ratelimit(&_rs)) \
+- printk(fmt, ##__VA_ARGS__); \
++#define printk_ratelimited(fmt, ...) ({ \
++ static DEFINE_RATELIMIT_STATE(_rs, \
++ DEFAULT_RATELIMIT_INTERVAL, \
++ DEFAULT_RATELIMIT_BURST); \
++ \
++ if (__ratelimit(&_rs)) \
++ printk(fmt, ##__VA_ARGS__); \
+ })
+ #else
+ /* No effect, but we still get type checking even in the !PRINTK case: */
+diff --git a/include/linux/kmod.h b/include/linux/kmod.h
+index 384ca8b..0546fe7 100644
+--- a/include/linux/kmod.h
++++ b/include/linux/kmod.h
+@@ -104,7 +104,16 @@ struct file;
+ extern int call_usermodehelper_pipe(char *path, char *argv[], char *envp[],
+ struct file **filp);
+
++#ifdef CONFIG_PM_SLEEP
+ extern int usermodehelper_disable(void);
+ extern void usermodehelper_enable(void);
++extern bool usermodehelper_is_disabled(void);
++extern void read_lock_usermodehelper(void);
++extern void read_unlock_usermodehelper(void);
++#else
++static inline bool usermodehelper_is_disabled(void) { return false; }
++static inline void read_lock_usermodehelper(void) {}
++static inline void read_unlock_usermodehelper(void) {}
++#endif
+
+ #endif /* __LINUX_KMOD_H__ */
+diff --git a/include/linux/proportions.h b/include/linux/proportions.h
+index cf793bb..22653d7 100644
+--- a/include/linux/proportions.h
++++ b/include/linux/proportions.h
+@@ -81,7 +81,11 @@ void prop_inc_percpu(struct prop_descriptor *pd, struct prop_local_percpu *pl)
+ * Limit the time part in order to ensure there are some bits left for the
+ * cycle counter and fraction multiply.
+ */
++#if BITS_PER_LONG == 32
+ #define PROP_MAX_SHIFT (3*BITS_PER_LONG/4)
++#else
++#define PROP_MAX_SHIFT (BITS_PER_LONG/2)
++#endif
+
+ #define PROP_FRAC_SHIFT (BITS_PER_LONG - PROP_MAX_SHIFT - 1)
+ #define PROP_FRAC_BASE (1UL << PROP_FRAC_SHIFT)
+diff --git a/kernel/kmod.c b/kernel/kmod.c
+index d206078..a061472 100644
+--- a/kernel/kmod.c
++++ b/kernel/kmod.c
+@@ -35,6 +35,7 @@
+ #include <linux/resource.h>
+ #include <linux/notifier.h>
+ #include <linux/suspend.h>
++#include <linux/rwsem.h>
+ #include <asm/uaccess.h>
+
+ #include <trace/events/module.h>
+@@ -43,6 +44,8 @@ extern int max_threads;
+
+ static struct workqueue_struct *khelper_wq;
+
++static DECLARE_RWSEM(umhelper_sem);
++
+ #ifdef CONFIG_MODULES
+
+ /*
+@@ -286,6 +289,7 @@ static void __call_usermodehelper(struct work_struct *work)
+ * If set, call_usermodehelper_exec() will exit immediately returning -EBUSY
+ * (used for preventing user land processes from being created after the user
+ * land has been frozen during a system-wide hibernation or suspend operation).
++ * Should always be manipulated under umhelper_sem acquired for write.
+ */
+ static int usermodehelper_disabled;
+
+@@ -304,6 +308,18 @@ static DECLARE_WAIT_QUEUE_HEAD(running_helpers_waitq);
+ */
+ #define RUNNING_HELPERS_TIMEOUT (5 * HZ)
+
++void read_lock_usermodehelper(void)
++{
++ down_read(&umhelper_sem);
++}
++EXPORT_SYMBOL_GPL(read_lock_usermodehelper);
++
++void read_unlock_usermodehelper(void)
++{
++ up_read(&umhelper_sem);
++}
++EXPORT_SYMBOL_GPL(read_unlock_usermodehelper);
++
+ /**
+ * usermodehelper_disable - prevent new helpers from being started
+ */
+@@ -311,8 +327,10 @@ int usermodehelper_disable(void)
+ {
+ long retval;
+
++ down_write(&umhelper_sem);
+ usermodehelper_disabled = 1;
+- smp_mb();
++ up_write(&umhelper_sem);
++
+ /*
+ * From now on call_usermodehelper_exec() won't start any new
+ * helpers, so it is sufficient if running_helpers turns out to
+@@ -325,7 +343,9 @@ int usermodehelper_disable(void)
+ if (retval)
+ return 0;
+
++ down_write(&umhelper_sem);
+ usermodehelper_disabled = 0;
++ up_write(&umhelper_sem);
+ return -EAGAIN;
+ }
+
+@@ -334,8 +354,19 @@ int usermodehelper_disable(void)
+ */
+ void usermodehelper_enable(void)
+ {
++ down_write(&umhelper_sem);
+ usermodehelper_disabled = 0;
++ up_write(&umhelper_sem);
++}
++
++/**
++ * usermodehelper_is_disabled - check if new helpers are allowed to be started
++ */
++bool usermodehelper_is_disabled(void)
++{
++ return usermodehelper_disabled;
+ }
++EXPORT_SYMBOL_GPL(usermodehelper_is_disabled);
+
+ static void helper_lock(void)
+ {
+diff --git a/kernel/relay.c b/kernel/relay.c
+index 760c262..bf343f5 100644
+--- a/kernel/relay.c
++++ b/kernel/relay.c
+@@ -171,10 +171,14 @@ depopulate:
+ */
+ static struct rchan_buf *relay_create_buf(struct rchan *chan)
+ {
+- struct rchan_buf *buf = kzalloc(sizeof(struct rchan_buf), GFP_KERNEL);
+- if (!buf)
++ struct rchan_buf *buf;
++
++ if (chan->n_subbufs > UINT_MAX / sizeof(size_t *))
+ return NULL;
+
++ buf = kzalloc(sizeof(struct rchan_buf), GFP_KERNEL);
++ if (!buf)
++ return NULL;
+ buf->padding = kmalloc(chan->n_subbufs * sizeof(size_t *), GFP_KERNEL);
+ if (!buf->padding)
+ goto free_buf;
+@@ -581,6 +585,8 @@ struct rchan *relay_open(const char *base_filename,
+
+ if (!(subbuf_size && n_subbufs))
+ return NULL;
++ if (subbuf_size > UINT_MAX / n_subbufs)
++ return NULL;
+
+ chan = kzalloc(sizeof(struct rchan), GFP_KERNEL);
+ if (!chan)
+diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
+index 38499c4..759f96f 100644
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -2363,7 +2363,7 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
+ index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn)
+ % tid_agg_rx->buf_size;
+ if (!tid_agg_rx->reorder_buf[index] &&
+- tid_agg_rx->stored_mpdu_num > 1) {
++ tid_agg_rx->stored_mpdu_num) {
+ /*
+ * No buffers ready to be released, but check whether any
+ * frames in the reorder buffer have timed out.